From 188ab3277892f1ced469531619574d52ea2bf08d Mon Sep 17 00:00:00 2001 From: Bishoy Gendy Date: Fri, 3 Feb 2023 17:28:27 +0000 Subject: [PATCH 1/2] Fix volume controls show media instead of call volume during a call. - On some apps like Signal, When the app is in the foreground and there is a active phone call, volume controls show media volume control instead of call volume control. - Investigation showed that with apps having the right behaviour "MediaSession.dispatchVolumeKeyEvent" is called, while with apps having the wrong behaviour "MediaSessionService.dispatchVolumeKeyEventToSessionAsSystemService" is called. - Following this guided to the cause of the steps to reproduce it in other apps by calling "Activty.setMediaController". - Issue was reproducible on the Sample MediaRouter App. - Fixed it through checking not being in a call before forwarding the volume event to the session. Bug: 240705522 Test: Manual using Signal App / Youtube and Sample MediaRouter App. Change-Id: Iabac3c80631fd429daba23454488fceedbcc584d (cherry picked from commit ed9f9d1b0adfb55557b34bdd76504ab8abdeae7e) Merged-In: Iabac3c80631fd429daba23454488fceedbcc584d --- .../android/internal/policy/PhoneWindow.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index bb69192f187fe..7d3a2a397ad52 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -1950,9 +1950,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_VOLUME_MUTE: { - // If we have a session send it the volume command, otherwise - // use the suggested stream. - if (mMediaController != null) { + // If we have a session and no active phone call send it the volume command, + // otherwise use the suggested stream. + if (mMediaController != null && !isActivePhoneCallKnown()) { getMediaSessionManager().dispatchVolumeKeyEventToSessionAsSystemService(event, mMediaController.getSessionToken()); } else { @@ -2003,6 +2003,18 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { return false; } + private boolean isActivePhoneCallKnown() { + boolean isActivePhoneCallKnown = false; + AudioManager audioManager = + (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE); + int audioManagerMode = audioManager.getMode(); + if (audioManagerMode == AudioManager.MODE_IN_CALL + || audioManagerMode == AudioManager.MODE_IN_COMMUNICATION) { + isActivePhoneCallKnown = true; + } + return isActivePhoneCallKnown; + } + private KeyguardManager getKeyguardManager() { if (mKeyguardManager == null) { mKeyguardManager = (KeyguardManager) getContext().getSystemService( From 57ff593ed504c8a8668e4843bf52deefa823b9bd Mon Sep 17 00:00:00 2001 From: Bishoy Gendy Date: Fri, 3 Mar 2023 10:08:34 +0000 Subject: [PATCH 2/2] Change AudioManger getMode() binder call to addOnModeChangedListener() - Remove binder call from running each time with clicking on volume up and down keys. Replace it with listener instead. Bug: 240705522 Test: Manual using Signal App / Youtube and Sample MediaRouter App. Change-Id: I842133770a583217940ebc929d8d929f4cd27a51 --- core/java/android/view/Window.java | 5 +++ .../android/internal/policy/PhoneWindow.java | 35 +++++++++++++------ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 02027e4a39693..293f9082670d7 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -823,6 +823,11 @@ public abstract class Window { /** @hide */ public final void destroy() { mDestroyed = true; + onDestroy(); + } + + /** @hide */ + protected void onDestroy() { } /** @hide */ diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 7d3a2a397ad52..e603e2ed57f1a 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -295,6 +295,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private boolean mClosingActionMenu; private int mVolumeControlStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE; + private int mAudioMode = AudioManager.MODE_NORMAL; private MediaController mMediaController; private AudioManager mAudioManager; @@ -317,6 +318,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } }; + private AudioManager.OnModeChangedListener mOnModeChangedListener; + private Transition mEnterTransition = null; private Transition mReturnTransition = USE_DEFAULT_TRANSITION; private Transition mExitTransition = null; @@ -1952,7 +1955,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { case KeyEvent.KEYCODE_VOLUME_MUTE: { // If we have a session and no active phone call send it the volume command, // otherwise use the suggested stream. - if (mMediaController != null && !isActivePhoneCallKnown()) { + if (mMediaController != null && !isActivePhoneCallOngoing()) { getMediaSessionManager().dispatchVolumeKeyEventToSessionAsSystemService(event, mMediaController.getSessionToken()); } else { @@ -2003,16 +2006,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { return false; } - private boolean isActivePhoneCallKnown() { - boolean isActivePhoneCallKnown = false; - AudioManager audioManager = - (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE); - int audioManagerMode = audioManager.getMode(); - if (audioManagerMode == AudioManager.MODE_IN_CALL - || audioManagerMode == AudioManager.MODE_IN_COMMUNICATION) { - isActivePhoneCallKnown = true; - } - return isActivePhoneCallKnown; + private boolean isActivePhoneCallOngoing() { + return mAudioMode == AudioManager.MODE_IN_CALL + || mAudioMode == AudioManager.MODE_IN_COMMUNICATION; } private KeyguardManager getKeyguardManager() { @@ -2338,6 +2334,14 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } } + @Override + protected void onDestroy() { + if (mOnModeChangedListener != null) { + getAudioManager().removeOnModeChangedListener(mOnModeChangedListener); + mOnModeChangedListener = null; + } + } + private class PanelMenuPresenterCallback implements MenuPresenter.Callback { @Override public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { @@ -3220,6 +3224,15 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { @Override public void setMediaController(MediaController controller) { mMediaController = controller; + if (controller != null && mOnModeChangedListener == null) { + mAudioMode = getAudioManager().getMode(); + mOnModeChangedListener = mode -> mAudioMode = mode; + getAudioManager().addOnModeChangedListener(getContext().getMainExecutor(), + mOnModeChangedListener); + } else if (mOnModeChangedListener != null) { + getAudioManager().removeOnModeChangedListener(mOnModeChangedListener); + mOnModeChangedListener = null; + } } @Override