summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Woodman <olly@google.com>2021-11-17 20:38:01 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-12-26 15:02:20 +0000
commitd7868c44f1dcdf2a0b316b11b4b7203e91ca5c8c (patch)
treec0efe06de72c518af2883e2ade0d17b381d5cac4
parent57358e94146f7cd1dea30c4e0900b30b136ac9dc (diff)
downloadbase-d7868c44f1dcdf2a0b316b11b4b7203e91ca5c8c.tar.gz
Fix SysUI volume controls not appearing
SysUI listens to volume change events to trigger showing its volume control overlay UI. Normally when a hardware volume key is pressed, a volume (either locally or for a session corresponding to a remote playback) is changed, SysUI receives an event and the UI is displayed. In the case that a remote session doesn't allow volume adjustment, the key event is still routed to the session if that session is top of the stack. However, since the volume is not adjusted and an event is not dispatched, the SysUI volume control overlay doesn't appear. To the user it seems like the volume hardware key is broken, neither adjusting a volume or displaying the volume control overlay UI. This change fires volume change events for sessions that don't support actually changing the volume, to ensure that the SysUI is still displayed. It also seems more consistent, since there are other existing cases where the volume doesn't actually change for which an event is still fired (e.g., adjusting up when already at max volume). An alternative would be to change MediaSessionRecord's canHandleVolumeKey to return false for sessions that don't support volume adjustment, which would mean the key event would be handled by the next session in the stack (or, in most cases, to make a local volume adjustment). This is likely more confusing, since the user will generally expect the top session to be adjusted (surfacing that it could not is less confusing than just adjusting some other volume instead). Bug: 197586676 Bug: 202500642 Test: manual Merged-In: Ic44b48bb5605699b476af05407b90f2be5d70cd3 Change-Id: Ic44b48bb5605699b476af05407b90f2be5d70cd3 (cherry picked from commit 771b7ebe5d10f867a44101aa7a0b0a779bacfd32) Merged-In:Ic44b48bb5605699b476af05407b90f2be5d70cd3
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java85
1 files changed, 46 insertions, 39 deletions
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index e4ed0e5d4186..4822d6a62ac7 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -291,35 +291,39 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
asSystemService, useSuggested, previousFlagPlaySound);
} else {
if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) {
- // Nothing to do, the volume cannot be changed
- return;
- }
- if (direction == AudioManager.ADJUST_TOGGLE_MUTE
+ if (DEBUG) {
+ Log.d(TAG, "Session does not support volume adjustment");
+ }
+ } else if (direction == AudioManager.ADJUST_TOGGLE_MUTE
|| direction == AudioManager.ADJUST_MUTE
|| direction == AudioManager.ADJUST_UNMUTE) {
Log.w(TAG, "Muting remote playback is not supported");
- return;
- }
- if (DEBUG) {
- Log.w(TAG, "adjusting volume, pkg=" + packageName + ", asSystemService="
- + asSystemService + ", dir=" + direction);
- }
- mSessionCb.adjustVolume(packageName, pid, uid, asSystemService, direction);
+ } else {
+ if (DEBUG) {
+ Log.w(TAG, "adjusting volume, pkg=" + packageName + ", asSystemService="
+ + asSystemService + ", dir=" + direction);
+ }
+ mSessionCb.adjustVolume(packageName, pid, uid, asSystemService, direction);
+
+ int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
+ mOptimisticVolume = volumeBefore + direction;
+ mOptimisticVolume = Math.max(0, Math.min(mOptimisticVolume, mMaxVolume));
+ mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
+ mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
+ if (volumeBefore != mOptimisticVolume) {
+ pushVolumeUpdate();
+ }
- int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
- mOptimisticVolume = volumeBefore + direction;
- mOptimisticVolume = Math.max(0, Math.min(mOptimisticVolume, mMaxVolume));
- mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
- mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
- if (volumeBefore != mOptimisticVolume) {
- pushVolumeUpdate();
+ if (DEBUG) {
+ Log.d(TAG, "Adjusted optimistic volume to " + mOptimisticVolume + " max is "
+ + mMaxVolume);
+ }
}
+ // Always notify, even if the volume hasn't changed. This is important to ensure that
+ // System UI receives an event if a hardware volume key is pressed but the session that
+ // handles it does not allow volume adjustment. Without such an event, System UI would
+ // not show volume controls to the user.
mService.notifyRemoteVolumeChanged(flags, this);
-
- if (DEBUG) {
- Log.d(TAG, "Adjusted optimistic volume to " + mOptimisticVolume + " max is "
- + mMaxVolume);
- }
}
}
@@ -343,25 +347,28 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
});
} else {
if (mVolumeControlType != VolumeProvider.VOLUME_CONTROL_ABSOLUTE) {
- // Nothing to do. The volume can't be set directly.
- return;
- }
- value = Math.max(0, Math.min(value, mMaxVolume));
- mSessionCb.setVolumeTo(packageName, pid, uid, value);
+ if (DEBUG) {
+ Log.d(TAG, "Session does not support setting volume");
+ }
+ } else {
+ value = Math.max(0, Math.min(value, mMaxVolume));
+ mSessionCb.setVolumeTo(packageName, pid, uid, value);
+
+ int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
+ mOptimisticVolume = Math.max(0, Math.min(value, mMaxVolume));
+ mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
+ mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
+ if (volumeBefore != mOptimisticVolume) {
+ pushVolumeUpdate();
+ }
- int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
- mOptimisticVolume = Math.max(0, Math.min(value, mMaxVolume));
- mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
- mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
- if (volumeBefore != mOptimisticVolume) {
- pushVolumeUpdate();
+ if (DEBUG) {
+ Log.d(TAG, "Set optimistic volume to " + mOptimisticVolume + " max is "
+ + mMaxVolume);
+ }
}
+ // Always notify, even if the volume hasn't changed.
mService.notifyRemoteVolumeChanged(flags, this);
-
- if (DEBUG) {
- Log.d(TAG, "Set optimistic volume to " + mOptimisticVolume + " max is "
- + mMaxVolume);
- }
}
}