diff options
| -rw-r--r-- | api/module-lib-current.txt | 3 | ||||
| -rw-r--r-- | media/java/android/media/AudioManager.java | 126 | ||||
| -rw-r--r-- | media/java/android/media/AudioManagerInternal.java | 9 | ||||
| -rwxr-xr-x | media/java/android/media/IAudioService.aidl | 14 | ||||
| -rw-r--r-- | non-updatable-api/module-lib-current.txt | 3 | ||||
| -rw-r--r-- | services/core/java/com/android/server/audio/AudioService.java | 93 | ||||
| -rw-r--r-- | services/core/java/com/android/server/media/MediaSessionRecord.java | 25 | ||||
| -rw-r--r-- | services/core/java/com/android/server/media/MediaSessionService.java | 11 |
8 files changed, 219 insertions, 65 deletions
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt index 73511c0f5b87..806e266efd78 100644 --- a/api/module-lib-current.txt +++ b/api/module-lib-current.txt @@ -35,6 +35,9 @@ package android.graphics { package android.media { public class AudioManager { + method public void adjustStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); + method public void adjustSuggestedStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); + method public void setStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); field public static final int FLAG_FROM_KEY = 4096; // 0x1000 } diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index aa2ff17a307b..e1e55c25b3fa 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -6649,6 +6649,132 @@ public class AudioManager { } } + /** + * Adjusts the volume of the most relevant stream, or the given fallback + * stream. + * <p> + * This method should only be used by applications that replace the + * platform-wide management of audio settings or the main telephony + * application. + * <p> + * This method has no effect if the device implements a fixed volume policy + * as indicated by {@link #isVolumeFixed()}. + * <p>This API checks if the caller has the necessary permissions based on the provided + * component name, uid, and pid values. + * See {@link #adjustSuggestedStreamVolume(int, int, int)}. + * + * @param suggestedStreamType The stream type that will be used if there + * isn't a relevant stream. {@link #USE_DEFAULT_STREAM_TYPE} is + * valid here. + * @param direction The direction to adjust the volume. One of + * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, + * {@link #ADJUST_SAME}, {@link #ADJUST_MUTE}, + * {@link #ADJUST_UNMUTE}, or {@link #ADJUST_TOGGLE_MUTE}. + * @param flags One or more flags. + * @param packageName the package name of client application + * @param uid the uid of client application + * @param pid the pid of client application + * @param targetSdkVersion the target sdk version of client application + * @see #adjustVolume(int, int) + * @see #adjustStreamVolume(int, int, int) + * @see #setStreamVolume(int, int, int) + * @see #isVolumeFixed() + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public void adjustSuggestedStreamVolumeForUid(int suggestedStreamType, int direction, int flags, + @NonNull String packageName, int uid, int pid, int targetSdkVersion) { + try { + getService().adjustSuggestedStreamVolumeForUid(suggestedStreamType, direction, flags, + packageName, uid, pid, UserHandle.getUserHandleForUid(uid), targetSdkVersion); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Adjusts the volume of a particular stream by one step in a direction. + * <p> + * This method should only be used by applications that replace the platform-wide + * management of audio settings or the main telephony application. + * <p>This method has no effect if the device implements a fixed volume policy + * as indicated by {@link #isVolumeFixed()}. + * <p>From N onward, ringer mode adjustments that would toggle Do Not Disturb are not allowed + * unless the app has been granted Do Not Disturb Access. + * See {@link NotificationManager#isNotificationPolicyAccessGranted()}. + * <p>This API checks if the caller has the necessary permissions based on the provided + * component name, uid, and pid values. + * See {@link #adjustStreamVolume(int, int, int)}. + * + * @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL}, + * {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC}, + * {@link #STREAM_ALARM} or {@link #STREAM_ACCESSIBILITY}. + * @param direction The direction to adjust the volume. One of + * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or + * {@link #ADJUST_SAME}. + * @param flags One or more flags. + * @param packageName the package name of client application + * @param uid the uid of client application + * @param pid the pid of client application + * @param targetSdkVersion the target sdk version of client application + * @see #adjustVolume(int, int) + * @see #setStreamVolume(int, int, int) + * @throws SecurityException if the adjustment triggers a Do Not Disturb change + * and the caller is not granted notification policy access. + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public void adjustStreamVolumeForUid(int streamType, int direction, int flags, + @NonNull String packageName, int uid, int pid, int targetSdkVersion) { + try { + getService().adjustStreamVolumeForUid(streamType, direction, flags, packageName, uid, + pid, UserHandle.getUserHandleForUid(uid), targetSdkVersion); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Sets the volume index for a particular stream. + * <p>This method has no effect if the device implements a fixed volume policy + * as indicated by {@link #isVolumeFixed()}. + * <p>From N onward, volume adjustments that would toggle Do Not Disturb are not allowed unless + * the app has been granted Do Not Disturb Access. + * See {@link NotificationManager#isNotificationPolicyAccessGranted()}. + * <p>This API checks if the caller has the necessary permissions based on the provided + * component name, uid, and pid values. + * See {@link #setStreamVolume(int, int, int)}. + * + * @param streamType The stream whose volume index should be set. + * @param index The volume index to set. See + * {@link #getStreamMaxVolume(int)} for the largest valid value. + * @param flags One or more flags. + * @param packageName the package name of client application + * @param uid the uid of client application + * @param pid the pid of client application + * @param targetSdkVersion the target sdk version of client application + * @see #getStreamMaxVolume(int) + * @see #getStreamVolume(int) + * @see #isVolumeFixed() + * @throws SecurityException if the volume change triggers a Do Not Disturb change + * and the caller is not granted notification policy access. + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public void setStreamVolumeForUid(int streamType, int index, int flags, + @NonNull String packageName, int uid, int pid, int targetSdkVersion) { + try { + getService().setStreamVolumeForUid(streamType, index, flags, packageName, uid, pid, + UserHandle.getUserHandleForUid(uid), targetSdkVersion); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** @hide * TODO: make this a @SystemApi */ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java index b44d7bba834f..c827932194ae 100644 --- a/media/java/android/media/AudioManagerInternal.java +++ b/media/java/android/media/AudioManagerInternal.java @@ -28,15 +28,6 @@ import com.android.server.LocalServices; */ public abstract class AudioManagerInternal { - public abstract void adjustSuggestedStreamVolumeForUid(int streamType, int direction, - int flags, String callingPackage, int uid, int pid); - - public abstract void adjustStreamVolumeForUid(int streamType, int direction, int flags, - String callingPackage, int uid, int pid); - - public abstract void setStreamVolumeForUid(int streamType, int direction, int flags, - String callingPackage, int uid, int pid); - public abstract void setRingerModeDelegate(RingerModeDelegate delegate); public abstract int getRingerModeInternal(); diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 85fb67df82d4..47e60000cd04 100755 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -17,6 +17,7 @@ package android.media; import android.bluetooth.BluetoothDevice; +import android.content.ComponentName; import android.media.AudioAttributes; import android.media.AudioDeviceAttributes; import android.media.AudioFocusInfo; @@ -41,6 +42,7 @@ import android.media.audiopolicy.AudioVolumeGroup; import android.media.audiopolicy.IAudioPolicyCallback; import android.media.projection.IMediaProjection; import android.net.Uri; +import android.os.UserHandle; import android.view.KeyEvent; /** @@ -320,4 +322,16 @@ interface IAudioService { oneway void unregisterCapturePresetDevicesRoleDispatcher( ICapturePresetDevicesRoleDispatcher dispatcher); + + oneway void adjustStreamVolumeForUid(int streamType, int direction, int flags, + in String packageName, int uid, int pid, in UserHandle userHandle, + int targetSdkVersion); + + oneway void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, + in String packageName, int uid, int pid, in UserHandle userHandle, + int targetSdkVersion); + + oneway void setStreamVolumeForUid(int streamType, int direction, int flags, + in String packageName, int uid, int pid, in UserHandle userHandle, + int targetSdkVersion); } diff --git a/non-updatable-api/module-lib-current.txt b/non-updatable-api/module-lib-current.txt index d4c5e7ea375d..aec4ff53c1c9 100644 --- a/non-updatable-api/module-lib-current.txt +++ b/non-updatable-api/module-lib-current.txt @@ -35,6 +35,9 @@ package android.graphics { package android.media { public class AudioManager { + method public void adjustStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); + method public void adjustSuggestedStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); + method public void setStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); field public static final int FLAG_FROM_KEY = 4096; // 0x1000 } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 5f6491093453..f63c2ee5ee94 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -4186,6 +4186,62 @@ public class AudioService extends IAudioService.Stub } } + /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */ + @Override + public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, + @NonNull String packageName, int uid, int pid, UserHandle userHandle, + int targetSdkVersion) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Should only be called from system process"); + } + + final boolean hasModifyAudioSettings = + mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) + == PackageManager.PERMISSION_GRANTED; + // direction and stream type swap here because the public + // adjustSuggested has a different order than the other methods. + adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName, uid, + hasModifyAudioSettings, VOL_ADJUST_NORMAL); + } + + /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */ + @Override + public void adjustStreamVolumeForUid(int streamType, int direction, int flags, + @NonNull String packageName, int uid, int pid, UserHandle userHandle, + int targetSdkVersion) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Should only be called from system process"); + } + + if (direction != AudioManager.ADJUST_SAME) { + sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType, + direction/*val1*/, flags/*val2*/, + new StringBuilder(packageName).append(" uid:").append(uid) + .toString())); + } + final boolean hasModifyAudioSettings = + mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) + == PackageManager.PERMISSION_GRANTED; + adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, + hasModifyAudioSettings, VOL_ADJUST_NORMAL); + } + + /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */ + @Override + public void setStreamVolumeForUid(int streamType, int index, int flags, + @NonNull String packageName, int uid, int pid, UserHandle userHandle, + int targetSdkVersion) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Should only be called from system process"); + } + + final boolean hasModifyAudioSettings = + mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) + == PackageManager.PERMISSION_GRANTED; + setStreamVolume(streamType, index, flags, packageName, packageName, uid, + hasModifyAudioSettings); + } + //========================================================================================== // Sound Effects //========================================================================================== @@ -8071,43 +8127,6 @@ public class AudioService extends IAudioService.Stub } @Override - public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, - String callingPackage, int uid, int pid) { - final boolean hasModifyAudioSettings = - mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) - == PackageManager.PERMISSION_GRANTED; - // direction and stream type swap here because the public - // adjustSuggested has a different order than the other methods. - adjustSuggestedStreamVolume(direction, streamType, flags, callingPackage, - callingPackage, uid, hasModifyAudioSettings, VOL_ADJUST_NORMAL); - } - - @Override - public void adjustStreamVolumeForUid(int streamType, int direction, int flags, - String callingPackage, int uid, int pid) { - if (direction != AudioManager.ADJUST_SAME) { - sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType, - direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage) - .append(" uid:").append(uid).toString())); - } - final boolean hasModifyAudioSettings = - mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) - == PackageManager.PERMISSION_GRANTED; - adjustStreamVolume(streamType, direction, flags, callingPackage, - callingPackage, uid, hasModifyAudioSettings, VOL_ADJUST_NORMAL); - } - - @Override - public void setStreamVolumeForUid(int streamType, int direction, int flags, - String callingPackage, int uid, int pid) { - final boolean hasModifyAudioSettings = - mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) - == PackageManager.PERMISSION_GRANTED; - setStreamVolume(streamType, direction, flags, callingPackage, callingPackage, uid, - hasModifyAudioSettings); - } - - @Override public int getRingerModeInternal() { return AudioService.this.getRingerModeInternal(); } diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 1e02f49c43e4..793cfcd77414 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -23,7 +23,6 @@ import android.content.Intent; import android.content.pm.ParceledListSlice; import android.media.AudioAttributes; import android.media.AudioManager; -import android.media.AudioManagerInternal; import android.media.AudioSystem; import android.media.MediaMetadata; import android.media.Rating; @@ -53,8 +52,6 @@ import android.os.SystemClock; import android.util.Log; import android.view.KeyEvent; -import com.android.server.LocalServices; - import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; @@ -144,7 +141,6 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR // Volume handling fields private AudioAttributes mAudioAttrs; private AudioManager mAudioManager; - private AudioManagerInternal mAudioManagerInternal; private int mVolumeType = PlaybackInfo.PLAYBACK_TYPE_LOCAL; private int mVolumeControlType = VolumeProvider.VOLUME_CONTROL_ABSOLUTE; private int mMaxVolume = 0; @@ -179,7 +175,6 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR mContext = mService.getContext(); mHandler = new MessageHandler(handlerLooper); mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); - mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class); mAudioAttrs = DEFAULT_ATTRIBUTES; mPolicies = policies; @@ -328,8 +323,9 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR @Override public void run() { try { - mAudioManagerInternal.setStreamVolumeForUid(stream, volumeValue, flags, - opPackageName, uid, pid); + mAudioManager.setStreamVolumeForUid(stream, volumeValue, flags, + opPackageName, uid, pid, + mContext.getApplicationInfo().targetSdkVersion); } catch (IllegalArgumentException | SecurityException e) { Log.e(TAG, "Cannot set volume: stream=" + stream + ", value=" + volumeValue + ", flags=" + flags, e); @@ -518,16 +514,19 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR try { if (useSuggested) { if (AudioSystem.isStreamActive(stream, 0)) { - mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream, - direction, flags, opPackageName, uid, pid); + mAudioManager.adjustSuggestedStreamVolumeForUid(stream, + direction, flags, opPackageName, uid, pid, + mContext.getApplicationInfo().targetSdkVersion); } else { - mAudioManagerInternal.adjustSuggestedStreamVolumeForUid( + mAudioManager.adjustSuggestedStreamVolumeForUid( AudioManager.USE_DEFAULT_STREAM_TYPE, direction, - flags | previousFlagPlaySound, opPackageName, uid, pid); + flags | previousFlagPlaySound, opPackageName, uid, pid, + mContext.getApplicationInfo().targetSdkVersion); } } else { - mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags, - opPackageName, uid, pid); + mAudioManager.adjustStreamVolumeForUid(stream, direction, flags, + opPackageName, uid, pid, + mContext.getApplicationInfo().targetSdkVersion); } } catch (IllegalArgumentException | SecurityException e) { Log.e(TAG, "Cannot adjust volume: direction=" + direction + ", stream=" diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 9521611c241d..d34502922b66 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -42,7 +42,6 @@ import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.UserInfo; import android.media.AudioManager; -import android.media.AudioManagerInternal; import android.media.AudioPlaybackConfiguration; import android.media.AudioSystem; import android.media.IRemoteVolumeController; @@ -85,7 +84,6 @@ import android.view.ViewConfiguration; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.DumpUtils; -import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.SystemService.TargetUser; import com.android.server.Watchdog; @@ -136,7 +134,7 @@ public class MediaSessionService extends SystemService implements Monitor { new ArrayList<>(); private KeyguardManager mKeyguardManager; - private AudioManagerInternal mAudioManagerInternal; + private AudioManager mAudioManager; private ContentResolver mContentResolver; private boolean mHasFeatureLeanback; @@ -162,6 +160,7 @@ public class MediaSessionService extends SystemService implements Monitor { PowerManager pm = mContext.getSystemService(PowerManager.class); mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleMediaEvent"); mNotificationManager = mContext.getSystemService(NotificationManager.class); + mAudioManager = mContext.getSystemService(AudioManager.class); } @Override @@ -169,7 +168,6 @@ public class MediaSessionService extends SystemService implements Monitor { publishBinderService(Context.MEDIA_SESSION_SERVICE, mSessionManagerImpl); Watchdog.getInstance().addMonitor(this); mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); - mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class); mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance(mContext); mAudioPlayerStateMonitor.registerListener( (config, isRemoved) -> { @@ -2057,8 +2055,9 @@ public class MediaSessionService extends SystemService implements Monitor { callingPid = pid; } try { - mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(suggestedStream, - direction, flags, callingOpPackageName, callingUid, callingPid); + mAudioManager.adjustSuggestedStreamVolumeForUid(suggestedStream, + direction, flags, callingOpPackageName, callingUid, callingPid, + getContext().getApplicationInfo().targetSdkVersion); } catch (SecurityException | IllegalArgumentException e) { Log.e(TAG, "Cannot adjust volume: direction=" + direction + ", suggestedStream=" + suggestedStream + ", flags=" + flags |