diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index c144195de724c..f2078a1508adc 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -930,8 +930,8 @@ public class AudioManager { public void adjustStreamVolume(int streamType, int direction, int flags) { final IAudioService service = getService(); try { - service.adjustStreamVolume(streamType, direction, flags, - getContext().getOpPackageName()); + service.adjustStreamVolumeWithAttribution(streamType, direction, flags, + getContext().getOpPackageName(), getContext().getAttributionTag()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1001,7 +1001,7 @@ public class AudioManager { final IAudioService service = getService(); try { service.setMasterMute(mute, flags, getContext().getOpPackageName(), - UserHandle.getCallingUserId()); + UserHandle.getCallingUserId(), getContext().getAttributionTag()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1254,7 +1254,8 @@ public class AudioManager { public void setStreamVolume(int streamType, int index, int flags) { final IAudioService service = getService(); try { - service.setStreamVolume(streamType, index, flags, getContext().getOpPackageName()); + service.setStreamVolumeWithAttribution(streamType, index, flags, + getContext().getOpPackageName(), getContext().getAttributionTag()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1279,7 +1280,7 @@ public class AudioManager { final IAudioService service = getService(); try { service.setVolumeIndexForAttributes(attr, index, flags, - getContext().getOpPackageName()); + getContext().getOpPackageName(), getContext().getAttributionTag()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2739,7 +2740,7 @@ public class AudioManager { final IAudioService service = getService(); try { service.setMicrophoneMute(on, getContext().getOpPackageName(), - UserHandle.getCallingUserId()); + UserHandle.getCallingUserId(), getContext().getAttributionTag()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4266,7 +4267,9 @@ public class AudioManager { afr.getFocusGain(), mICallBack, mAudioFocusDispatcher, clientId, - getContext().getOpPackageName() /* package name */, afr.getFlags(), + getContext().getOpPackageName() /* package name */, + getContext().getAttributionTag(), + afr.getFlags(), ap != null ? ap.cb() : null, sdk); } catch (RemoteException e) { @@ -4371,6 +4374,7 @@ public class AudioManager { durationHint, mICallBack, null, AudioSystem.IN_VOICE_COMM_FOCUS_ID, getContext().getOpPackageName(), + getContext().getAttributionTag(), AUDIOFOCUS_FLAG_LOCK, null /* policy token */, 0 /* sdk n/a here*/); } catch (RemoteException e) { diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index c08c368af55aa..357c414955120 100755 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -77,15 +77,17 @@ interface IAudioService { oneway void playerSessionId(in int piid, in int sessionId); // Java-only methods below. - - oneway void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, - String callingPackage, String caller); - void adjustStreamVolume(int streamType, int direction, int flags, String callingPackage); + void adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, + in String callingPackage, in String attributionTag); + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setStreamVolume(int streamType, int index, int flags, String callingPackage); + void setStreamVolumeWithAttribution(int streamType, int index, int flags, + in String callingPackage, in String attributionTag); + oneway void handleVolumeKey(in KeyEvent event, boolean isOnTv, String callingPackage, String caller); @@ -95,7 +97,8 @@ interface IAudioService { boolean isMasterMute(); - void setMasterMute(boolean mute, int flags, String callingPackage, int userId); + void setMasterMute(boolean mute, int flags, String callingPackage, int userId, + in String attributionTag); @UnsupportedAppUsage int getStreamVolume(int streamType); @@ -107,7 +110,8 @@ interface IAudioService { List getAudioVolumeGroups(); - void setVolumeIndexForAttributes(in AudioAttributes aa, int index, int flags, String callingPackage); + void setVolumeIndexForAttributes(in AudioAttributes aa, int index, int flags, + String callingPackage, in String attributionTag); int getVolumeIndexForAttributes(in AudioAttributes aa); @@ -125,7 +129,7 @@ interface IAudioService { boolean isMicrophoneMuted(); - void setMicrophoneMute(boolean on, String callingPackage, int userId); + void setMicrophoneMute(boolean on, String callingPackage, int userId, in String attributionTag); oneway void setMicrophoneMuteFromSwitch(boolean on); @@ -182,8 +186,8 @@ interface IAudioService { boolean isBluetoothA2dpOn(); int requestAudioFocus(in AudioAttributes aa, int durationHint, IBinder cb, - IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, - IAudioPolicyCallback pcb, int sdk); + IAudioFocusDispatcher fd, in String clientId, in String callingPackageName, + in String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk); int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, in AudioAttributes aa, in String callingPackageName); diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index 345d9b27c8a8f..4de63f980ca59 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -2034,8 +2034,8 @@ public class MediaRouter { public void requestSetVolume(int volume) { if (mPlaybackType == PLAYBACK_TYPE_LOCAL) { try { - sStatic.mAudioService.setStreamVolume(mPlaybackStream, volume, 0, - ActivityThread.currentPackageName()); + sStatic.mAudioService.setStreamVolumeWithAttribution(mPlaybackStream, volume, 0, + ActivityThread.currentPackageName(), null); } catch (RemoteException e) { Log.e(TAG, "Error setting local stream volume", e); } @@ -2053,8 +2053,8 @@ public class MediaRouter { try { final int volume = Math.max(0, Math.min(getVolume() + direction, getVolumeMax())); - sStatic.mAudioService.setStreamVolume(mPlaybackStream, volume, 0, - ActivityThread.currentPackageName()); + sStatic.mAudioService.setStreamVolumeWithAttribution(mPlaybackStream, volume, 0, + ActivityThread.currentPackageName(), null); } catch (RemoteException e) { Log.e(TAG, "Error setting local stream volume", e); } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 17cee670c9ac6..5210099e6921f 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -2585,14 +2585,6 @@ public class AudioService extends IAudioService.Stub } } - /** @see AudioManager#adjustVolume(int, int) */ - public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, - String callingPackage, String caller) { - adjustSuggestedStreamVolume(direction, suggestedStreamType, flags, callingPackage, - caller, Binder.getCallingUid(), callingHasAudioSettingsPermission(), - VOL_ADJUST_NORMAL); - } - public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) { mNavigationRepeatSoundEffectsEnabled = enabled; } @@ -2615,6 +2607,7 @@ public class AudioService extends IAudioService.Stub return mHomeSoundEffectEnabled; } + /** All callers come from platform apps/system server, so no attribution tag is needed */ private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, String caller, int uid, boolean hasModifyAudioSettings, int keyEventMode) { @@ -2690,7 +2683,7 @@ public class AudioService extends IAudioService.Stub } adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, - hasModifyAudioSettings, keyEventMode); + null, hasModifyAudioSettings, keyEventMode); } private boolean notifyExternalVolumeController(int direction) { @@ -2708,10 +2701,16 @@ public class AudioService extends IAudioService.Stub return true; } - /** @see AudioManager#adjustStreamVolume(int, int, int) - * Part of service interface, check permissions here */ + /** Retain API for unsupported app usage */ public void adjustStreamVolume(int streamType, int direction, int flags, String callingPackage) { + adjustStreamVolumeWithAttribution(streamType, direction, flags, callingPackage, null); + } + + /** @see AudioManager#adjustStreamVolume(int, int, int) + * Part of service interface, check permissions here */ + public void adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, + String callingPackage, String attributionTag) { if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without" + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage); @@ -2721,13 +2720,13 @@ public class AudioService extends IAudioService.Stub sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType, direction/*val1*/, flags/*val2*/, callingPackage)); adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage, - Binder.getCallingUid(), callingHasAudioSettingsPermission(), + Binder.getCallingUid(), attributionTag, callingHasAudioSettingsPermission(), VOL_ADJUST_NORMAL); } protected void adjustStreamVolume(int streamType, int direction, int flags, - String callingPackage, String caller, int uid, boolean hasModifyAudioSettings, - int keyEventMode) { + String callingPackage, String caller, int uid, String attributionTag, + boolean hasModifyAudioSettings, int keyEventMode) { if (mUseFixedVolume) { return; } @@ -2792,8 +2791,8 @@ public class AudioService extends IAudioService.Stub if (uid == android.os.Process.SYSTEM_UID) { uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); } - if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage) - != AppOpsManager.MODE_ALLOWED) { + if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, + callingPackage, attributionTag, null) != AppOpsManager.MODE_ALLOWED) { return; } @@ -3159,7 +3158,7 @@ public class AudioService extends IAudioService.Stub /** @see AudioManager#setVolumeIndexForAttributes(attr, int, int) */ public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags, - String callingPackage) { + String callingPackage, String attributionTag) { enforceModifyAudioRoutingPermission(); Objects.requireNonNull(attr, "attr must not be null"); final int volumeGroup = getVolumeGroupIdForAttributes(attr); @@ -3184,7 +3183,7 @@ public class AudioService extends IAudioService.Stub continue; } setStreamVolume(groupedStream, index, flags, callingPackage, callingPackage, - Binder.getCallingUid(), true /*hasModifyAudioSettings*/); + attributionTag, Binder.getCallingUid(), true /*hasModifyAudioSettings*/); } } @@ -3226,9 +3225,15 @@ public class AudioService extends IAudioService.Stub return AudioSystem.getMinVolumeIndexForAttributes(attr); } + /** Retain API for unsupported app usage */ + public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { + setStreamVolumeWithAttribution(streamType, index, flags, callingPackage, null); + } + /** @see AudioManager#setStreamVolume(int, int, int) * Part of service interface, check permissions here */ - public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { + public void setStreamVolumeWithAttribution(int streamType, int index, int flags, + String callingPackage, String attributionTag) { if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { Log.w(TAG, "Trying to call setStreamVolume() for a11y without" + " CHANGE_ACCESSIBILITY_VOLUME callingPackage=" + callingPackage); @@ -3254,7 +3259,7 @@ public class AudioService extends IAudioService.Stub sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType, index/*val1*/, flags/*val2*/, callingPackage)); setStreamVolume(streamType, index, flags, callingPackage, callingPackage, - Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission()); + attributionTag, Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission()); } private boolean canChangeAccessibilityVolume() { @@ -3489,7 +3494,8 @@ public class AudioService extends IAudioService.Stub } private void setStreamVolume(int streamType, int index, int flags, String callingPackage, - String caller, int uid, boolean hasModifyAudioSettings) { + String caller, String attributionTag, int uid, + boolean hasModifyAudioSettings) { if (DEBUG_VOL) { Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index + ", calling=" + callingPackage + ")"); @@ -3516,8 +3522,8 @@ public class AudioService extends IAudioService.Stub if (uid == android.os.Process.SYSTEM_UID) { uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); } - if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage) - != AppOpsManager.MODE_ALLOWED) { + if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, + callingPackage, attributionTag, null) != AppOpsManager.MODE_ALLOWED) { return; } @@ -3945,15 +3951,15 @@ public class AudioService extends IAudioService.Stub } private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, - int userId) { + int userId, String attributionTag) { // If we are being called by the system check for user we are going to change // so we handle user restrictions correctly. if (uid == android.os.Process.SYSTEM_UID) { uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); } // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting. - if (!mute && mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage) - != AppOpsManager.MODE_ALLOWED) { + if (!mute && mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, + callingPackage, attributionTag, null) != AppOpsManager.MODE_ALLOWED) { return; } if (userId != UserHandle.getCallingUserId() && @@ -3995,10 +4001,12 @@ public class AudioService extends IAudioService.Stub return AudioSystem.getMasterMute(); } - public void setMasterMute(boolean mute, int flags, String callingPackage, int userId) { + /** @see AudioManager#setMasterMute(boolean, int) */ + public void setMasterMute(boolean mute, int flags, String callingPackage, int userId, + String attributionTag) { enforceModifyAudioRoutingPermission(); - setMasterMuteInternal(mute, flags, callingPackage, Binder.getCallingUid(), - userId); + setMasterMuteInternal(mute, flags, callingPackage, + Binder.getCallingUid(), userId, attributionTag); } /** @see AudioManager#getStreamVolume(int) */ @@ -4069,7 +4077,8 @@ public class AudioService extends IAudioService.Stub /** @see AudioManager#setMicrophoneMute(boolean) */ @Override - public void setMicrophoneMute(boolean on, String callingPackage, int userId) { + public void setMicrophoneMute(boolean on, String callingPackage, int userId, + String attributionTag) { // If we are being called by the system check for user we are going to change // so we handle user restrictions correctly. int uid = Binder.getCallingUid(); @@ -4084,8 +4093,8 @@ public class AudioService extends IAudioService.Stub ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE); // If OP_MUTE_MICROPHONE is set, disallow unmuting. - if (!on && mAppOps.noteOp(AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage) - != AppOpsManager.MODE_ALLOWED) { + if (!on && mAppOps.noteOp(AppOpsManager.OP_MUTE_MICROPHONE, uid, + callingPackage, attributionTag, null) != AppOpsManager.MODE_ALLOWED) { mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record(); return; } @@ -4921,7 +4930,7 @@ public class AudioService extends IAudioService.Stub } adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, - hasAudioSettingsPermission(uid, pid), VOL_ADJUST_NORMAL); + null, hasAudioSettingsPermission(uid, pid), VOL_ADJUST_NORMAL); } /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */ @@ -4933,7 +4942,7 @@ public class AudioService extends IAudioService.Stub throw new SecurityException("Should only be called from system process"); } - setStreamVolume(streamType, index, flags, packageName, packageName, uid, + setStreamVolume(streamType, index, flags, packageName, packageName, null, uid, hasAudioSettingsPermission(uid, pid)); } @@ -8069,8 +8078,8 @@ public class AudioService extends IAudioService.Stub } public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, - IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, - IAudioPolicyCallback pcb, int sdk) { + IAudioFocusDispatcher fd, String clientId, String callingPackageName, + String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk) { final int uid = Binder.getCallingUid(); MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") .setUid(uid) @@ -8122,7 +8131,7 @@ public class AudioService extends IAudioService.Stub } mmi.record(); return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, - clientId, callingPackageName, flags, sdk, + clientId, callingPackageName, attributionTag, flags, sdk, forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/); } @@ -8139,7 +8148,7 @@ public class AudioService extends IAudioService.Stub return AudioManager.AUDIOFOCUS_REQUEST_FAILED; } return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, - clientId, callingPackageName, AudioManager.AUDIOFOCUS_FLAG_TEST, + clientId, callingPackageName, null, AudioManager.AUDIOFOCUS_FLAG_TEST, sdk, false /*forceDuck*/, fakeUid); } diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java index e6c4abfa20861..6fe129527b2db 100644 --- a/services/core/java/com/android/server/audio/MediaFocusControl.java +++ b/services/core/java/com/android/server/audio/MediaFocusControl.java @@ -857,6 +857,7 @@ public class MediaFocusControl implements PlayerFocusEnforcer { * @param fd * @param clientId * @param callingPackageName + * @param attributionTag * @param flags * @param sdk * @param forceDuck only true if @@ -868,7 +869,7 @@ public class MediaFocusControl implements PlayerFocusEnforcer { */ protected int requestAudioFocus(@NonNull AudioAttributes aa, int focusChangeHint, IBinder cb, IAudioFocusDispatcher fd, @NonNull String clientId, @NonNull String callingPackageName, - int flags, int sdk, boolean forceDuck, int testUid) { + String attributionTag, int flags, int sdk, boolean forceDuck, int testUid) { new MediaMetrics.Item(mMetricsId) .setUid(Binder.getCallingUid()) .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) @@ -903,7 +904,7 @@ public class MediaFocusControl implements PlayerFocusEnforcer { if ((flags != AudioManager.AUDIOFOCUS_FLAG_TEST) // note we're using the real uid for appOp evaluation && (mAppOps.noteOp(AppOpsManager.OP_TAKE_AUDIO_FOCUS, Binder.getCallingUid(), - callingPackageName) != AppOpsManager.MODE_ALLOWED)) { + callingPackageName, attributionTag, null) != AppOpsManager.MODE_ALLOWED)) { return AudioManager.AUDIOFOCUS_REQUEST_FAILED; } diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java index 54945fbc2dd2e..c0ba3c72beb48 100644 --- a/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java @@ -75,7 +75,7 @@ public class AudioServiceTest { for (boolean muted : new boolean[] { true, false}) { testAudioSystem.configureIsMicrophoneMuted(!muted); mAudioService.setMicrophoneMute(muted, mContext.getOpPackageName(), - UserHandle.getCallingUserId()); + UserHandle.getCallingUserId(), null); Assert.assertEquals("mic mute reporting wrong value", muted, mAudioService.isMicrophoneMuted()); // verify the intent for mic mute changed is supposed to be fired @@ -100,7 +100,7 @@ public class AudioServiceTest { for (boolean muted : new boolean[] { true, false}) { testAudioSystem.configureIsMicrophoneMuted(!muted); mAudioService.setMicrophoneMute(muted, mContext.getOpPackageName(), - UserHandle.getCallingUserId()); + UserHandle.getCallingUserId(), null); Assert.assertEquals("mic mute reporting wrong value", !muted, mAudioService.isMicrophoneMuted()); // verify the intent for mic mute changed is supposed to be fired