diff options
26 files changed, 221 insertions, 115 deletions
diff --git a/api/current.txt b/api/current.txt index cca6921..e714550 100644 --- a/api/current.txt +++ b/api/current.txt @@ -22577,9 +22577,9 @@ package android.os { method public abstract void cancel(); method public abstract boolean hasVibrator(); method public void vibrate(long); - method public void vibrate(long, int); + method public void vibrate(long, android.media.AudioAttributes); method public void vibrate(long[], int); - method public void vibrate(long[], int, int); + method public void vibrate(long[], int, android.media.AudioAttributes); } public class WorkSource implements android.os.Parcelable { diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index c91c90c..990ea85 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -17,10 +17,12 @@ package android.app; import android.Manifest; +import android.media.AudioAttributes.AttributeUsage; import android.os.Binder; import android.os.IBinder; import android.os.UserManager; import android.util.ArrayMap; + import com.android.internal.app.IAppOpsService; import com.android.internal.app.IAppOpsCallback; @@ -954,15 +956,16 @@ public class AppOpsManager { * defined by {@link #setMode}. * * @param code The operation to restrict. - * @param stream The {@link android.media.AudioManager} stream type. + * @param usage The {@link android.media.AudioAttributes} usage value. * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict. * @param exceptionPackages Optional list of packages to exclude from the restriction. * @hide */ - public void setRestriction(int code, int stream, int mode, String[] exceptionPackages) { + public void setRestriction(int code, @AttributeUsage int usage, int mode, + String[] exceptionPackages) { try { final int uid = Binder.getCallingUid(); - mService.setAudioRestriction(code, stream, uid, mode, exceptionPackages); + mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages); } catch (RemoteException e) { } } diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index b5efa8e..e5995b0 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -21,6 +21,7 @@ import com.android.internal.util.ArrayUtils; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.content.Context; +import android.media.AudioAttributes; import android.os.Binder; import android.os.Handler; import android.os.IBinder; @@ -857,8 +858,7 @@ public final class InputManager { * @hide */ @Override - public void vibrate(int uid, String opPkg, long milliseconds, - int streamHint) { + public void vibrate(int uid, String opPkg, long milliseconds, AudioAttributes attributes) { vibrate(new long[] { 0, milliseconds}, -1); } @@ -867,7 +867,7 @@ public final class InputManager { */ @Override public void vibrate(int uid, String opPkg, long[] pattern, int repeat, - int streamHint) { + AudioAttributes attributes) { if (repeat >= pattern.length) { throw new ArrayIndexOutOfBoundsException(); } diff --git a/core/java/android/os/IVibratorService.aidl b/core/java/android/os/IVibratorService.aidl index 4d05e2d..6f2857d 100644 --- a/core/java/android/os/IVibratorService.aidl +++ b/core/java/android/os/IVibratorService.aidl @@ -20,8 +20,8 @@ package android.os; interface IVibratorService { boolean hasVibrator(); - void vibrate(int uid, String opPkg, long milliseconds, int streamHint, IBinder token); - void vibratePattern(int uid, String opPkg, in long[] pattern, int repeat, int streamHint, IBinder token); + void vibrate(int uid, String opPkg, long milliseconds, int usageHint, IBinder token); + void vibratePattern(int uid, String opPkg, in long[] pattern, int repeat, int usageHint, IBinder token); void cancelVibrate(IBinder token); } diff --git a/core/java/android/os/NullVibrator.java b/core/java/android/os/NullVibrator.java index 7b870ac..f14d965 100644 --- a/core/java/android/os/NullVibrator.java +++ b/core/java/android/os/NullVibrator.java @@ -16,6 +16,8 @@ package android.os; +import android.media.AudioAttributes; + /** * Vibrator implementation that does nothing. * @@ -40,7 +42,7 @@ public class NullVibrator extends Vibrator { * @hide */ @Override - public void vibrate(int uid, String opPkg, long milliseconds, int streamHint) { + public void vibrate(int uid, String opPkg, long milliseconds, AudioAttributes attributes) { vibrate(milliseconds); } @@ -49,7 +51,7 @@ public class NullVibrator extends Vibrator { */ @Override public void vibrate(int uid, String opPkg, long[] pattern, int repeat, - int streamHint) { + AudioAttributes attributes) { if (repeat >= pattern.length) { throw new ArrayIndexOutOfBoundsException(); } diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java index 8d9cf54..c488811 100644 --- a/core/java/android/os/SystemVibrator.java +++ b/core/java/android/os/SystemVibrator.java @@ -17,6 +17,7 @@ package android.os; import android.content.Context; +import android.media.AudioAttributes; import android.util.Log; /** @@ -58,13 +59,13 @@ public class SystemVibrator extends Vibrator { * @hide */ @Override - public void vibrate(int uid, String opPkg, long milliseconds, int streamHint) { + public void vibrate(int uid, String opPkg, long milliseconds, AudioAttributes attributes) { if (mService == null) { Log.w(TAG, "Failed to vibrate; no vibrator service."); return; } try { - mService.vibrate(uid, opPkg, milliseconds, streamHint, mToken); + mService.vibrate(uid, opPkg, milliseconds, usageForAttributes(attributes), mToken); } catch (RemoteException e) { Log.w(TAG, "Failed to vibrate.", e); } @@ -75,7 +76,7 @@ public class SystemVibrator extends Vibrator { */ @Override public void vibrate(int uid, String opPkg, long[] pattern, int repeat, - int streamHint) { + AudioAttributes attributes) { if (mService == null) { Log.w(TAG, "Failed to vibrate; no vibrator service."); return; @@ -85,7 +86,7 @@ public class SystemVibrator extends Vibrator { // anyway if (repeat < pattern.length) { try { - mService.vibratePattern(uid, opPkg, pattern, repeat, streamHint, + mService.vibratePattern(uid, opPkg, pattern, repeat, usageForAttributes(attributes), mToken); } catch (RemoteException e) { Log.w(TAG, "Failed to vibrate.", e); @@ -95,6 +96,10 @@ public class SystemVibrator extends Vibrator { } } + private static int usageForAttributes(AudioAttributes attributes) { + return attributes != null ? attributes.getUsage() : AudioAttributes.USAGE_UNKNOWN; + } + @Override public void cancel() { if (mService == null) { diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java index c1d4d4c..152cc12 100644 --- a/core/java/android/os/Vibrator.java +++ b/core/java/android/os/Vibrator.java @@ -18,7 +18,7 @@ package android.os; import android.app.ActivityThread; import android.content.Context; -import android.media.AudioManager; +import android.media.AudioAttributes; /** * Class that operates the vibrator on the device. @@ -62,7 +62,7 @@ public abstract class Vibrator { * @param milliseconds The number of milliseconds to vibrate. */ public void vibrate(long milliseconds) { - vibrate(milliseconds, AudioManager.USE_DEFAULT_STREAM_TYPE); + vibrate(milliseconds, null); } /** @@ -71,12 +71,13 @@ public abstract class Vibrator { * {@link android.Manifest.permission#VIBRATE}. * * @param milliseconds The number of milliseconds to vibrate. - * @param streamHint An {@link AudioManager} stream type corresponding to the vibration type. - * For example, specify {@link AudioManager#STREAM_ALARM} for alarm vibrations or - * {@link AudioManager#STREAM_RING} for vibrations associated with incoming calls. + * @param attributes {@link AudioAttributes} corresponding to the vibration. For example, + * specify {@link AudioAttributes#USAGE_ALARM} for alarm vibrations or + * {@link AudioAttributes#USAGE_NOTIFICATION_TELEPHONY_RINGTONE} for + * vibrations associated with incoming calls. */ - public void vibrate(long milliseconds, int streamHint) { - vibrate(Process.myUid(), mPackageName, milliseconds, streamHint); + public void vibrate(long milliseconds, AudioAttributes attributes) { + vibrate(Process.myUid(), mPackageName, milliseconds, attributes); } /** @@ -100,7 +101,7 @@ public abstract class Vibrator { * you don't want to repeat. */ public void vibrate(long[] pattern, int repeat) { - vibrate(pattern, repeat, AudioManager.USE_DEFAULT_STREAM_TYPE); + vibrate(pattern, repeat, null); } /** @@ -122,29 +123,30 @@ public abstract class Vibrator { * @param pattern an array of longs of times for which to turn the vibrator on or off. * @param repeat the index into pattern at which to repeat, or -1 if * you don't want to repeat. - * @param streamHint An {@link AudioManager} stream type corresponding to the vibration type. - * For example, specify {@link AudioManager#STREAM_ALARM} for alarm vibrations or - * {@link AudioManager#STREAM_RING} for vibrations associated with incoming calls. + * @param attributes {@link AudioAttributes} corresponding to the vibration. For example, + * specify {@link AudioAttributes#USAGE_ALARM} for alarm vibrations or + * {@link AudioAttributes#USAGE_NOTIFICATION_TELEPHONY_RINGTONE} for + * vibrations associated with incoming calls. */ - public void vibrate(long[] pattern, int repeat, int streamHint) { - vibrate(Process.myUid(), mPackageName, pattern, repeat, streamHint); + public void vibrate(long[] pattern, int repeat, AudioAttributes attributes) { + vibrate(Process.myUid(), mPackageName, pattern, repeat, attributes); } /** * @hide - * Like {@link #vibrate(long, int)}, but allowing the caller to specify that + * Like {@link #vibrate(long, AudioAttributes)}, but allowing the caller to specify that * the vibration is owned by someone else. */ - public abstract void vibrate(int uid, String opPkg, - long milliseconds, int streamHint); + public abstract void vibrate(int uid, String opPkg, long milliseconds, + AudioAttributes attributes); /** * @hide - * Like {@link #vibrate(long[], int, int)}, but allowing the caller to specify that + * Like {@link #vibrate(long[], int, AudioAttributes)}, but allowing the caller to specify that * the vibration is owned by someone else. */ - public abstract void vibrate(int uid, String opPkg, - long[] pattern, int repeat, int streamHint); + public abstract void vibrate(int uid, String opPkg, long[] pattern, int repeat, + AudioAttributes attributes); /** * Turn the vibrator off. diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl index 8e6fa58..9ff2cf4 100644 --- a/core/java/com/android/internal/app/IAppOpsService.aidl +++ b/core/java/com/android/internal/app/IAppOpsService.aidl @@ -37,8 +37,8 @@ interface IAppOpsService { List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops); void setMode(int code, int uid, String packageName, int mode); void resetAllModes(); - int checkAudioOperation(int code, int stream, int uid, String packageName); - void setAudioRestriction(int code, int stream, int uid, int mode, in String[] exceptionPackages); + int checkAudioOperation(int code, int usage, int uid, String packageName); + void setAudioRestriction(int code, int usage, int uid, int mode, in String[] exceptionPackages); void setDeviceOwner(String packageName); void setProfileOwner(String packageName, int userHandle); diff --git a/core/java/com/android/internal/widget/RotarySelector.java b/core/java/com/android/internal/widget/RotarySelector.java index 64ce918..866f89b 100644 --- a/core/java/com/android/internal/widget/RotarySelector.java +++ b/core/java/com/android/internal/widget/RotarySelector.java @@ -24,7 +24,7 @@ import android.graphics.Paint; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; -import android.media.AudioManager; +import android.media.AudioAttributes; import android.os.UserHandle; import android.os.Vibrator; import android.provider.Settings; @@ -54,6 +54,11 @@ public class RotarySelector extends View { private static final boolean DBG = false; private static final boolean VISUAL_DEBUG = false; + private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .build(); + // Listener for onDialTrigger() callbacks. private OnDialTriggerListener mOnDialTriggerListener; @@ -679,7 +684,7 @@ public class RotarySelector extends View { mVibrator = (android.os.Vibrator) getContext() .getSystemService(Context.VIBRATOR_SERVICE); } - mVibrator.vibrate(duration, AudioManager.STREAM_SYSTEM); + mVibrator.vibrate(duration, VIBRATION_ATTRIBUTES); } } diff --git a/core/java/com/android/internal/widget/SlidingTab.java b/core/java/com/android/internal/widget/SlidingTab.java index deb0fd7..65feab1 100644 --- a/core/java/com/android/internal/widget/SlidingTab.java +++ b/core/java/com/android/internal/widget/SlidingTab.java @@ -21,7 +21,7 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.media.AudioManager; +import android.media.AudioAttributes; import android.os.UserHandle; import android.os.Vibrator; import android.provider.Settings; @@ -67,6 +67,11 @@ public class SlidingTab extends ViewGroup { private boolean mHoldLeftOnTransition = true; private boolean mHoldRightOnTransition = true; + private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .build(); + private OnTriggerListener mOnTriggerListener; private int mGrabbedState = OnTriggerListener.NO_HANDLE; private boolean mTriggered = false; @@ -822,7 +827,7 @@ public class SlidingTab extends ViewGroup { mVibrator = (android.os.Vibrator) getContext() .getSystemService(Context.VIBRATOR_SERVICE); } - mVibrator.vibrate(duration, AudioManager.STREAM_SYSTEM); + mVibrator.vibrate(duration, VIBRATION_ATTRIBUTES); } } diff --git a/core/java/com/android/internal/widget/WaveView.java b/core/java/com/android/internal/widget/WaveView.java index 86f14b3..9e7a649 100644 --- a/core/java/com/android/internal/widget/WaveView.java +++ b/core/java/com/android/internal/widget/WaveView.java @@ -25,7 +25,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; -import android.media.AudioManager; +import android.media.AudioAttributes; import android.os.UserHandle; import android.os.Vibrator; import android.provider.Settings; @@ -81,6 +81,11 @@ public class WaveView extends View implements ValueAnimator.AnimatorUpdateListen */ private static final float GRAB_HANDLE_RADIUS_SCALE_ACCESSIBILITY_ENABLED = 1.0f; + private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .build(); + private Vibrator mVibrator; private OnTriggerListener mOnTriggerListener; private ArrayList<DrawableHolder> mDrawables = new ArrayList<DrawableHolder>(3); @@ -583,7 +588,7 @@ public class WaveView extends View implements ValueAnimator.AnimatorUpdateListen mVibrator = (android.os.Vibrator) getContext() .getSystemService(Context.VIBRATOR_SERVICE); } - mVibrator.vibrate(duration, AudioManager.STREAM_SYSTEM); + mVibrator.vibrate(duration, VIBRATION_ATTRIBUTES); } } diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java index 841a02a..b680fab 100644 --- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java +++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java @@ -30,7 +30,7 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.drawable.Drawable; -import android.media.AudioManager; +import android.media.AudioAttributes; import android.os.Bundle; import android.os.UserHandle; import android.os.Vibrator; @@ -94,6 +94,11 @@ public class GlowPadView extends View { private static final float RING_SCALE_EXPANDED = 1.0f; private static final float RING_SCALE_COLLAPSED = 0.5f; + private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .build(); + private ArrayList<TargetDrawable> mTargetDrawables = new ArrayList<TargetDrawable>(); private AnimationBundle mWaveAnimations = new AnimationBundle(); private AnimationBundle mTargetAnimations = new AnimationBundle(); @@ -565,7 +570,7 @@ public class GlowPadView extends View { mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1, UserHandle.USER_CURRENT) != 0; if (mVibrator != null && hapticEnabled) { - mVibrator.vibrate(mVibrationDuration, AudioManager.STREAM_SYSTEM); + mVibrator.vibrate(mVibrationDuration, VIBRATION_ATTRIBUTES); } } diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index 0fb77d5..ca58b97 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -367,47 +367,39 @@ public final class AudioAttributes implements Parcelable { switch(streamType) { case AudioSystem.STREAM_VOICE_CALL: mContentType = CONTENT_TYPE_SPEECH; - mUsage = USAGE_VOICE_COMMUNICATION; break; case AudioSystem.STREAM_SYSTEM_ENFORCED: mFlags |= FLAG_AUDIBILITY_ENFORCED; // intended fall through, attributes in common with STREAM_SYSTEM case AudioSystem.STREAM_SYSTEM: mContentType = CONTENT_TYPE_SONIFICATION; - mUsage = USAGE_ASSISTANCE_SONIFICATION; break; case AudioSystem.STREAM_RING: mContentType = CONTENT_TYPE_SONIFICATION; - mUsage = USAGE_NOTIFICATION_TELEPHONY_RINGTONE; break; case AudioSystem.STREAM_MUSIC: mContentType = CONTENT_TYPE_MUSIC; - mUsage = USAGE_MEDIA; break; case AudioSystem.STREAM_ALARM: mContentType = CONTENT_TYPE_SONIFICATION; - mUsage = USAGE_ALARM; break; case AudioSystem.STREAM_NOTIFICATION: mContentType = CONTENT_TYPE_SONIFICATION; - mUsage = USAGE_NOTIFICATION; break; case AudioSystem.STREAM_BLUETOOTH_SCO: mContentType = CONTENT_TYPE_SPEECH; - mUsage = USAGE_VOICE_COMMUNICATION; mFlags |= FLAG_SCO; break; case AudioSystem.STREAM_DTMF: mContentType = CONTENT_TYPE_SONIFICATION; - mUsage = USAGE_VOICE_COMMUNICATION_SIGNALLING; break; case AudioSystem.STREAM_TTS: mContentType = CONTENT_TYPE_SPEECH; - mUsage = USAGE_ASSISTANCE_ACCESSIBILITY; break; default: Log.e(TAG, "Invalid stream type " + streamType + " in for AudioAttributes"); } + mUsage = usageForLegacyStreamType(streamType); return this; } }; @@ -488,7 +480,12 @@ public final class AudioAttributes implements Parcelable { /** @hide */ public String usageToString() { - switch(mUsage) { + return usageToString(mUsage); + } + + /** @hide */ + public static String usageToString(int usage) { + switch(usage) { case USAGE_UNKNOWN: return new String("USAGE_UNKNOWN"); case USAGE_MEDIA: @@ -520,7 +517,34 @@ public final class AudioAttributes implements Parcelable { case USAGE_GAME: return new String("USAGE_GAME"); default: - return new String("unknown usage " + mUsage); + return new String("unknown usage " + usage); + } + } + + /** @hide */ + public static int usageForLegacyStreamType(int streamType) { + switch(streamType) { + case AudioSystem.STREAM_VOICE_CALL: + return USAGE_VOICE_COMMUNICATION; + case AudioSystem.STREAM_SYSTEM_ENFORCED: + case AudioSystem.STREAM_SYSTEM: + return USAGE_ASSISTANCE_SONIFICATION; + case AudioSystem.STREAM_RING: + return USAGE_NOTIFICATION_TELEPHONY_RINGTONE; + case AudioSystem.STREAM_MUSIC: + return USAGE_MEDIA; + case AudioSystem.STREAM_ALARM: + return USAGE_ALARM; + case AudioSystem.STREAM_NOTIFICATION: + return USAGE_NOTIFICATION; + case AudioSystem.STREAM_BLUETOOTH_SCO: + return USAGE_VOICE_COMMUNICATION; + case AudioSystem.STREAM_DTMF: + return USAGE_VOICE_COMMUNICATION_SIGNALLING; + case AudioSystem.STREAM_TTS: + return USAGE_ASSISTANCE_ACCESSIBILITY; + default: + return USAGE_UNKNOWN; } } diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index a8a4710..9669bf6 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -1130,7 +1130,8 @@ public class AudioTrack private boolean isRestricted() { try { - final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO, mStreamType, + final int usage = AudioAttributes.usageForLegacyStreamType(mStreamType); + final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO, usage, Process.myUid(), ActivityThread.currentPackageName()); return mode != AppOpsManager.MODE_ALLOWED; } catch (RemoteException e) { diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index b15bd69..9eb3e16 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -591,6 +591,7 @@ public class MediaPlayer implements SubtitleController.Listener private boolean mStayAwake; private final IAppOpsService mAppOps; private int mStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE; + private int mUsage = -1; /** * Default constructor. Consider using one of the create() methods for @@ -1141,8 +1142,10 @@ public class MediaPlayer implements SubtitleController.Listener private boolean isRestricted() { try { - final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO, - getAudioStreamType(), Process.myUid(), ActivityThread.currentPackageName()); + final int usage = mUsage != -1 ? mUsage + : AudioAttributes.usageForLegacyStreamType(getAudioStreamType()); + final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO, usage, + Process.myUid(), ActivityThread.currentPackageName()); return mode != AppOpsManager.MODE_ALLOWED; } catch (RemoteException e) { return false; @@ -1528,6 +1531,7 @@ public class MediaPlayer implements SubtitleController.Listener final String msg = "Cannot set AudioAttributes to null"; throw new IllegalArgumentException(msg); } + mUsage = attributes.getUsage(); Parcel pattributes = Parcel.obtain(); attributes.writeToParcel(pattributes, AudioAttributes.FLATTEN_TAGS); setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, pattributes); diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java index 14f0c69..44c193f 100644 --- a/media/java/android/media/SoundPool.java +++ b/media/java/android/media/SoundPool.java @@ -548,8 +548,9 @@ public class SoundPool { private boolean isRestricted() { try { + final int usage = AudioAttributes.usageForLegacyStreamType(mStreamType); final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO, - mStreamType, Process.myUid(), ActivityThread.currentPackageName()); + usage, Process.myUid(), ActivityThread.currentPackageName()); return mode != AppOpsManager.MODE_ALLOWED; } catch (RemoteException e) { return false; diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java index 006619b..bbda536 100644 --- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java +++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java @@ -21,6 +21,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.content.Context; +import android.media.AudioAttributes; import android.media.AudioManager; import android.os.Vibrator; import android.util.Log; @@ -66,6 +67,11 @@ public class ExpandHelper implements Gefingerpoken { // overstretch fills the range (GLOW_BASE, 1.0] private static final float GLOW_BASE = 0.5f; + private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .build(); + @SuppressWarnings("unused") private Context mContext; @@ -550,7 +556,7 @@ public class ExpandHelper implements Gefingerpoken { mVibrator = (android.os.Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); } - mVibrator.vibrate(duration, AudioManager.STREAM_SYSTEM); + mVibrator.vibrate(duration, VIBRATION_ATTRIBUTES); } } diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java index 09aa60f..ed03733 100644 --- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java @@ -25,7 +25,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.res.Resources; -import android.media.AudioManager; +import android.media.AudioAttributes; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; @@ -58,6 +58,12 @@ public class SearchPanelView extends FrameLayout implements public static final boolean DEBUG_GESTURES = true; private static final String ASSIST_ICON_METADATA_NAME = "com.android.systemui.action_assist_icon"; + + private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .build(); + private final Context mContext; private BaseStatusBar mBar; @@ -209,7 +215,7 @@ public class SearchPanelView extends FrameLayout implements Resources res = context.getResources(); Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); vibrator.vibrate(res.getInteger(R.integer.config_search_panel_view_vibration_duration), - AudioManager.STREAM_SYSTEM); + VIBRATION_ATTRIBUTES); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index e975045..fb0f1c1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -56,7 +56,7 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.inputmethodservice.InputMethodService; -import android.media.AudioManager; +import android.media.AudioAttributes; import android.media.MediaMetadata; import android.media.session.MediaController; import android.media.session.MediaSession; @@ -193,6 +193,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, */ private static final int HINT_RESET_DELAY_MS = 1200; + private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .build(); + PhoneStatusBarPolicy mIconPolicy; // These are no longer handled by the policy, because we need custom strategies for them @@ -2958,7 +2963,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, void vibrate() { android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService( Context.VIBRATOR_SERVICE); - vib.vibrate(250, AudioManager.STREAM_SYSTEM); + vib.vibrate(250, VIBRATION_ATTRIBUTES); } Runnable mStartTracing = new Runnable() { diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java index 0c5d2a5..4ada5ec 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java @@ -27,6 +27,7 @@ import android.content.IntentFilter; import android.content.res.Resources; import android.graphics.PixelFormat; import android.graphics.drawable.ColorDrawable; +import android.media.AudioAttributes; import android.media.AudioManager; import android.media.AudioService; import android.media.AudioSystem; @@ -108,6 +109,11 @@ public class VolumePanel extends Handler { private static final int STREAM_MASTER = -100; // Pseudo stream type for remote volume is defined in AudioService.STREAM_REMOTE_MUSIC + private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .build(); + private final String mTag; protected final Context mContext; private final AudioManager mAudioManager; @@ -969,7 +975,7 @@ public class VolumePanel extends Handler { return; } - mVibrator.vibrate(VIBRATE_DURATION, AudioManager.STREAM_SYSTEM); + mVibrator.vibrate(VIBRATE_DURATION, VIBRATION_ATTRIBUTES); } protected void onRemoteVolumeChanged(MediaController controller, int flags) { diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index ba4c588..71f1d21 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -41,6 +41,7 @@ import android.content.res.TypedArray; import android.database.ContentObserver; import android.graphics.PixelFormat; import android.graphics.Rect; +import android.media.AudioAttributes; import android.media.AudioManager; import android.media.IAudioService; import android.media.Ringtone; @@ -188,6 +189,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { | View.NAVIGATION_BAR_TRANSLUCENT | View.SYSTEM_UI_TRANSPARENT; + private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .build(); + /** * Keyguard stuff */ @@ -5435,10 +5441,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { } if (pattern.length == 1) { // One-shot vibration - mVibrator.vibrate(owningUid, owningPackage, pattern[0], AudioManager.STREAM_SYSTEM); + mVibrator.vibrate(owningUid, owningPackage, pattern[0], VIBRATION_ATTRIBUTES); } else { // Pattern vibration - mVibrator.vibrate(owningUid, owningPackage, pattern, -1, AudioManager.STREAM_SYSTEM); + mVibrator.vibrate(owningUid, owningPackage, pattern, -1, VIBRATION_ATTRIBUTES); } return true; } diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index 14a462e..579c449 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -36,7 +36,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; -import android.media.AudioService; +import android.media.AudioAttributes; import android.os.AsyncTask; import android.os.Binder; import android.os.Bundle; @@ -46,7 +46,6 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; -import android.os.UserManager; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; @@ -62,7 +61,6 @@ import com.android.internal.app.IAppOpsService; import com.android.internal.app.IAppOpsCallback; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; -import com.google.android.util.AbstractMessageParser.MusicTrack; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -577,9 +575,9 @@ public class AppOpsService extends IAppOpsService.Stub { } @Override - public int checkAudioOperation(int code, int stream, int uid, String packageName) { + public int checkAudioOperation(int code, int usage, int uid, String packageName) { synchronized (this) { - final int mode = checkRestrictionLocked(code, stream, uid, packageName); + final int mode = checkRestrictionLocked(code, usage, uid, packageName); if (mode != AppOpsManager.MODE_ALLOWED) { return mode; } @@ -587,10 +585,10 @@ public class AppOpsService extends IAppOpsService.Stub { return checkOperation(code, uid, packageName); } - private int checkRestrictionLocked(int code, int stream, int uid, String packageName) { - final SparseArray<Restriction> streamRestrictions = mAudioRestrictions.get(code); - if (streamRestrictions != null) { - final Restriction r = streamRestrictions.get(stream); + private int checkRestrictionLocked(int code, int usage, int uid, String packageName) { + final SparseArray<Restriction> usageRestrictions = mAudioRestrictions.get(code); + if (usageRestrictions != null) { + final Restriction r = usageRestrictions.get(usage); if (r != null && !r.exceptionPackages.contains(packageName)) { return r.mode; } @@ -599,17 +597,17 @@ public class AppOpsService extends IAppOpsService.Stub { } @Override - public void setAudioRestriction(int code, int stream, int uid, int mode, + public void setAudioRestriction(int code, int usage, int uid, int mode, String[] exceptionPackages) { verifyIncomingUid(uid); verifyIncomingOp(code); synchronized (this) { - SparseArray<Restriction> streamRestrictions = mAudioRestrictions.get(code); - if (streamRestrictions == null) { - streamRestrictions = new SparseArray<Restriction>(); - mAudioRestrictions.put(code, streamRestrictions); + SparseArray<Restriction> usageRestrictions = mAudioRestrictions.get(code); + if (usageRestrictions == null) { + usageRestrictions = new SparseArray<Restriction>(); + mAudioRestrictions.put(code, usageRestrictions); } - streamRestrictions.remove(stream); + usageRestrictions.remove(usage); if (mode != AppOpsManager.MODE_ALLOWED) { final Restriction r = new Restriction(); r.mode = mode; @@ -623,7 +621,7 @@ public class AppOpsService extends IAppOpsService.Stub { } } } - streamRestrictions.put(stream, r); + usageRestrictions.put(usage, r); } } } @@ -1205,9 +1203,9 @@ public class AppOpsService extends IAppOpsService.Stub { printedHeader = true; needSep = true; } - final int stream = restrictions.keyAt(i); + final int usage = restrictions.keyAt(i); pw.print(" "); pw.print(op); - pw.print(" stream="); pw.print(AudioService.streamToString(stream)); + pw.print(" usage="); pw.print(AudioAttributes.usageToString(usage)); Restriction r = restrictions.valueAt(i); pw.print(": mode="); pw.println(r.mode); if (!r.exceptionPackages.isEmpty()) { diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java index fdaf55e..51be98a 100644 --- a/services/core/java/com/android/server/VibratorService.java +++ b/services/core/java/com/android/server/VibratorService.java @@ -42,7 +42,7 @@ import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.util.Slog; import android.view.InputDevice; -import android.media.AudioManager; +import android.media.AudioAttributes; import com.android.internal.app.IAppOpsService; import com.android.internal.app.IBatteryStats; @@ -90,27 +90,27 @@ public class VibratorService extends IVibratorService.Stub private final long mStartTime; private final long[] mPattern; private final int mRepeat; - private final int mStreamHint; + private final int mUsageHint; private final int mUid; private final String mOpPkg; - Vibration(IBinder token, long millis, int streamHint, int uid, String opPkg) { - this(token, millis, null, 0, streamHint, uid, opPkg); + Vibration(IBinder token, long millis, int usageHint, int uid, String opPkg) { + this(token, millis, null, 0, usageHint, uid, opPkg); } - Vibration(IBinder token, long[] pattern, int repeat, int streamHint, int uid, + Vibration(IBinder token, long[] pattern, int repeat, int usageHint, int uid, String opPkg) { - this(token, 0, pattern, repeat, streamHint, uid, opPkg); + this(token, 0, pattern, repeat, usageHint, uid, opPkg); } private Vibration(IBinder token, long millis, long[] pattern, - int repeat, int streamHint, int uid, String opPkg) { + int repeat, int usageHint, int uid, String opPkg) { mToken = token; mTimeout = millis; mStartTime = SystemClock.uptimeMillis(); mPattern = pattern; mRepeat = repeat; - mStreamHint = streamHint; + mUsageHint = usageHint; mUid = uid; mOpPkg = opPkg; } @@ -220,7 +220,7 @@ public class VibratorService extends IVibratorService.Stub Binder.getCallingPid(), Binder.getCallingUid(), null); } - public void vibrate(int uid, String opPkg, long milliseconds, int streamHint, + public void vibrate(int uid, String opPkg, long milliseconds, int usageHint, IBinder token) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED) { @@ -237,7 +237,7 @@ public class VibratorService extends IVibratorService.Stub return; } - Vibration vib = new Vibration(token, milliseconds, streamHint, uid, opPkg); + Vibration vib = new Vibration(token, milliseconds, usageHint, uid, opPkg); final long ident = Binder.clearCallingIdentity(); try { @@ -263,7 +263,7 @@ public class VibratorService extends IVibratorService.Stub } public void vibratePattern(int uid, String packageName, long[] pattern, int repeat, - int streamHint, IBinder token) { + int usageHint, IBinder token) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires VIBRATE permission"); @@ -288,7 +288,7 @@ public class VibratorService extends IVibratorService.Stub return; } - Vibration vib = new Vibration(token, pattern, repeat, streamHint, uid, packageName); + Vibration vib = new Vibration(token, pattern, repeat, usageHint, uid, packageName); try { token.linkToDeath(vib, 0); } catch (RemoteException e) { @@ -372,12 +372,13 @@ public class VibratorService extends IVibratorService.Stub // Lock held on mVibrations private void startVibrationLocked(final Vibration vib) { try { - if (mLowPowerMode && vib.mStreamHint != AudioManager.STREAM_RING) { + if (mLowPowerMode + && vib.mUsageHint != AudioAttributes.USAGE_NOTIFICATION_TELEPHONY_RINGTONE) { return; } int mode = mAppOpsService.checkAudioOperation(AppOpsManager.OP_VIBRATE, - vib.mStreamHint, vib.mUid, vib.mOpPkg); + vib.mUsageHint, vib.mUid, vib.mOpPkg); if (mode == AppOpsManager.MODE_ALLOWED) { mode = mAppOpsService.startOperation(AppOpsManager.getToken(mAppOpsService), AppOpsManager.OP_VIBRATE, vib.mUid, vib.mOpPkg); @@ -392,7 +393,7 @@ public class VibratorService extends IVibratorService.Stub } catch (RemoteException e) { } if (vib.mTimeout != 0) { - doVibratorOn(vib.mTimeout, vib.mUid, vib.mStreamHint); + doVibratorOn(vib.mTimeout, vib.mUid, vib.mUsageHint); mH.postDelayed(mVibrationRunnable, vib.mTimeout); } else { // mThread better be null here. doCancelVibrate should always be @@ -513,7 +514,7 @@ public class VibratorService extends IVibratorService.Stub return vibratorExists(); } - private void doVibratorOn(long millis, int uid, int streamHint) { + private void doVibratorOn(long millis, int uid, int usageHint) { synchronized (mInputDeviceVibrators) { try { mBatteryStatsService.noteVibratorOn(uid, millis); @@ -522,8 +523,10 @@ public class VibratorService extends IVibratorService.Stub } final int vibratorCount = mInputDeviceVibrators.size(); if (vibratorCount != 0) { + final AudioAttributes attributes = new AudioAttributes.Builder().setUsage(usageHint) + .build(); for (int i = 0; i < vibratorCount; i++) { - mInputDeviceVibrators.get(i).vibrate(millis, streamHint); + mInputDeviceVibrators.get(i).vibrate(millis, attributes); } } else { vibratorOn(millis); @@ -586,7 +589,7 @@ public class VibratorService extends IVibratorService.Stub final int len = pattern.length; final int repeat = mVibration.mRepeat; final int uid = mVibration.mUid; - final int streamHint = mVibration.mStreamHint; + final int usageHint = mVibration.mUsageHint; int index = 0; long duration = 0; @@ -607,7 +610,7 @@ public class VibratorService extends IVibratorService.Stub // duration is saved for delay() at top of loop duration = pattern[index++]; if (duration > 0) { - VibratorService.this.doVibratorOn(duration, uid, streamHint); + VibratorService.this.doVibratorOn(duration, uid, usageHint); } } else { if (repeat < 0) { diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 0e18776..f7cb346 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -43,6 +43,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ParceledListSlice; import android.content.res.Resources; import android.database.ContentObserver; +import android.media.AudioAttributes; import android.media.AudioManager; import android.media.IRingtonePlayer; import android.net.Uri; @@ -1716,7 +1717,7 @@ public class NotificationManagerService extends SystemService { useDefaultVibrate ? mDefaultVibrationPattern : mFallbackVibrationPattern, ((notification.flags & Notification.FLAG_INSISTENT) != 0) - ? 0: -1, notification.audioStreamType); + ? 0: -1, audioAttributesForNotification(notification)); } finally { Binder.restoreCallingIdentity(identity); } @@ -1726,7 +1727,7 @@ public class NotificationManagerService extends SystemService { mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), notification.vibrate, ((notification.flags & Notification.FLAG_INSISTENT) != 0) - ? 0: -1, notification.audioStreamType); + ? 0: -1, audioAttributesForNotification(notification)); } } } @@ -1748,6 +1749,10 @@ public class NotificationManagerService extends SystemService { } } + private static AudioAttributes audioAttributesForNotification(Notification n) { + return new AudioAttributes.Builder().setLegacyStreamType(n.audioStreamType).build(); + } + void showNextToastLocked() { ToastRecord record = mToastQueue.get(0); while (record != null) { diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 118b9fc..7e82ce5 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -16,6 +16,10 @@ package com.android.server.notification; +import static android.media.AudioAttributes.USAGE_ALARM; +import static android.media.AudioAttributes.USAGE_NOTIFICATION_TELEPHONY_RINGTONE; +import static android.media.AudioAttributes.USAGE_UNKNOWN; + import android.app.AlarmManager; import android.app.AppOpsManager; import android.app.Notification; @@ -193,24 +197,24 @@ public class ZenModeHelper { // call restrictions final boolean muteCalls = zen && !mConfig.allowCalls; - mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, AudioManager.STREAM_RING, + mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, USAGE_NOTIFICATION_TELEPHONY_RINGTONE, muteCalls ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED, exceptionPackages); - mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, AudioManager.STREAM_RING, + mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, USAGE_NOTIFICATION_TELEPHONY_RINGTONE, muteCalls ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED, exceptionPackages); // restrict vibrations with no hints - mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, AudioManager.USE_DEFAULT_STREAM_TYPE, + mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, USAGE_UNKNOWN, zen ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED, exceptionPackages); // alarm restrictions final boolean muteAlarms = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS; - mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, AudioManager.STREAM_ALARM, + mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, USAGE_ALARM, muteAlarms ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED, exceptionPackages); - mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, AudioManager.STREAM_ALARM, + mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, USAGE_ALARM, muteAlarms ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED, exceptionPackages); diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java index 956e3e6..5f3da07 100644 --- a/services/core/java/com/android/server/power/ShutdownThread.java +++ b/services/core/java/com/android/server/power/ShutdownThread.java @@ -24,7 +24,7 @@ import android.app.IActivityManager; import android.app.ProgressDialog; import android.bluetooth.BluetoothAdapter; import android.bluetooth.IBluetoothManager; -import android.media.AudioManager; +import android.media.AudioAttributes; import android.nfc.NfcAdapter; import android.nfc.INfcAdapter; import android.content.BroadcastReceiver; @@ -78,7 +78,12 @@ public final class ShutdownThread extends Thread { // static instance of this thread private static final ShutdownThread sInstance = new ShutdownThread(); - + + private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .build(); + private final Object mActionDoneSync = new Object(); private boolean mActionDone; private Context mContext; @@ -508,7 +513,7 @@ public final class ShutdownThread extends Thread { // vibrate before shutting down Vibrator vibrator = new SystemVibrator(); try { - vibrator.vibrate(SHUTDOWN_VIBRATE_MS, AudioManager.STREAM_SYSTEM); + vibrator.vibrate(SHUTDOWN_VIBRATE_MS, VIBRATION_ATTRIBUTES); } catch (Exception e) { // Failure to vibrate shouldn't interrupt shutdown. Just log it. Log.w(TAG, "Failed to vibrate during shutdown.", e); |