AudioService: optimize vol change logs
When logging the previous volume index for the
AudioService events and media.metrics, obtaining
the current volume index (in getStreamVolume() for
the logging) before it is changed requires finding
the current device for that stream type.
This is repeated again when changing the volume.
This change queries the device at logging time,
but then passes it to the next internal method.
Doing so requires differentiating the code path
that is used for setStreamVolume, and setDeviceVolume,
which was previously done by checking if the passed
device was null or not. This is replaced by a boolean,
the "canChangeMuteAndUpdateController" parameter.
Bug: 239091512
Test: adb shell dumpsys audio | grep -A 50 "volume changes"
Test: adb shell dumpsys media.metrics
Change-Id: Ifd0a7dfafb044f2591fcc2d8ecdb6de998582584
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 1ef4333..f048b14 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3999,7 +3999,8 @@
}
setStreamVolume(groupedStream, index, flags, /*device*/ null,
callingPackage, callingPackage,
- attributionTag, Binder.getCallingUid(), true /*hasModifyAudioSettings*/);
+ attributionTag, Binder.getCallingUid(), true /*hasModifyAudioSettings*/,
+ true /*canChangeMuteAndUpdateController*/);
}
}
@@ -4118,7 +4119,9 @@
setStreamVolumeWithAttributionInt(vi.getStreamType(),
mStreamStates[vi.getStreamType()].getMinIndex(),
/*flags*/ 0,
- ada, callingPackage, null);
+ ada, callingPackage, null,
+ //TODO handle unmuting of current audio device
+ false /*canChangeMuteAndUpdateController*/);
return;
}
@@ -4144,7 +4147,8 @@
}
}
setStreamVolumeWithAttributionInt(vi.getStreamType(), index, /*flags*/ 0,
- ada, callingPackage, null);
+ ada, callingPackage, null,
+ false /*canChangeMuteAndUpdateController*/);
}
/** Retain API for unsupported app usage */
@@ -4227,7 +4231,7 @@
return;
}
setStreamVolumeWithAttributionInt(streamType, index, flags, /*device*/ null,
- callingPackage, attributionTag);
+ callingPackage, attributionTag, true /*canChangeMuteAndUpdateController*/);
}
/**
@@ -4240,10 +4244,18 @@
* for which volume is being changed
* @param callingPackage client side-provided package name of caller, not to be trusted
* @param attributionTag client side-provided attribution name, not to be trusted
+ * @param canChangeMuteAndUpdateController true if the calling method is a path where
+ * the volume change is allowed to update the mute state as well as update
+ * the volume controller (the UI). This is intended to be true for a call coming
+ * from AudioManager.setStreamVolume (which is here
+ * {@link #setStreamVolumeForUid(int, int, int, String, int, int, UserHandle, int)},
+ * and false when coming from AudioDeviceVolumeManager.setDeviceVolume (which is here
+ * {@link #setDeviceVolume(VolumeInfo, AudioDeviceAttributes, String)}
*/
protected void setStreamVolumeWithAttributionInt(int streamType, int index, int flags,
- @Nullable AudioDeviceAttributes device,
- String callingPackage, String attributionTag) {
+ @Nullable AudioDeviceAttributes ada,
+ String callingPackage, String attributionTag,
+ boolean canChangeMuteAndUpdateController) {
if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
Log.w(TAG, "Trying to call setStreamVolume() for a11y without"
+ " CHANGE_ACCESSIBILITY_VOLUME callingPackage=" + callingPackage);
@@ -4266,15 +4278,18 @@
return;
}
- if (device == null) {
+ if (ada == null) {
// call was already logged in setDeviceVolume()
+ final int deviceType = getDeviceForStream(streamType);
sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
- index/*val1*/, flags/*val2*/, getStreamVolume(streamType) /*val3*/,
+ index/*val1*/, flags/*val2*/, getStreamVolume(streamType, deviceType) /*val3*/,
callingPackage));
+ ada = new AudioDeviceAttributes(deviceType /*nativeType*/, "" /*address*/);
}
- setStreamVolume(streamType, index, flags, device,
+ setStreamVolume(streamType, index, flags, ada,
callingPackage, callingPackage, attributionTag,
- Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission());
+ Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission(),
+ canChangeMuteAndUpdateController);
}
@android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_ULTRASOUND)
@@ -4562,9 +4577,11 @@
}
private void setStreamVolume(int streamType, int index, int flags,
- @Nullable AudioDeviceAttributes ada,
+ @NonNull AudioDeviceAttributes ada,
String callingPackage, String caller, String attributionTag, int uid,
- boolean hasModifyAudioSettings) {
+ boolean hasModifyAudioSettings,
+ boolean canChangeMuteAndUpdateController) {
+
if (DEBUG_VOL) {
Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index
+ ", dev=" + ada
@@ -4578,9 +4595,7 @@
int streamTypeAlias = mStreamVolumeAlias[streamType];
VolumeStreamState streamState = mStreamStates[streamTypeAlias];
- final int device = (ada == null)
- ? getDeviceForStream(streamType)
- : ada.getInternalType();
+ final int device = ada.getInternalType();
int oldIndex;
// skip a2dp absolute volume control request when the device
@@ -4667,7 +4682,7 @@
onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings,
// ada is non-null when called from setDeviceVolume,
// which shouldn't update the mute state
- ada == null /*canChangeMute*/);
+ canChangeMuteAndUpdateController /*canChangeMute*/);
index = mStreamStates[streamType].getIndex(device);
}
@@ -4677,7 +4692,7 @@
maybeSendSystemAudioStatusCommand(false);
}
}
- if (ada == null) {
+ if (canChangeMuteAndUpdateController) {
// only non-null when coming here from setDeviceVolume
// TODO change test to check early if device is current device or not
sendVolumeUpdate(streamType, oldIndex, index, flags, device);
@@ -5091,6 +5106,10 @@
public int getStreamVolume(int streamType) {
ensureValidStreamType(streamType);
int device = getDeviceForStream(streamType);
+ return getStreamVolume(streamType, device);
+ }
+
+ private int getStreamVolume(int streamType, int device) {
synchronized (VolumeStreamState.class) {
int index = mStreamStates[streamType].getIndex(device);
@@ -6242,7 +6261,8 @@
setStreamVolume(streamType, index, flags, /*device*/ null,
packageName, packageName, null, uid,
- hasAudioSettingsPermission(uid, pid));
+ hasAudioSettingsPermission(uid, pid),
+ true /*canChangeMuteAndUpdateController*/);
}
//==========================================================================================
diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java
index 793752f..c72632f 100644
--- a/services/core/java/com/android/server/audio/SoundDoseHelper.java
+++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java
@@ -1297,7 +1297,8 @@
}
final int index = safeMediaVolumeIndex(nativeDeviceType);
mAudioService.setStreamVolumeWithAttributionInt(STREAM_MUSIC, index / 10, /*flags*/ 0, ada,
- mContext.getOpPackageName(), /*attributionTag=*/null);
+ mContext.getOpPackageName(), /*attributionTag=*/null,
+ true /*canChangeMuteAndUpdateController*/);
}
// StreamVolumeCommand contains the information needed to defer the process of