summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/module-lib-current.txt3
-rw-r--r--media/java/android/media/AudioManager.java126
-rw-r--r--media/java/android/media/AudioManagerInternal.java9
-rwxr-xr-xmedia/java/android/media/IAudioService.aidl14
-rw-r--r--non-updatable-api/module-lib-current.txt3
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java93
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java25
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java11
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