From d61a87baf09203cf24b1a2904a3458a0e34bb943 Mon Sep 17 00:00:00 2001 From: Jaewan Kim Date: Fri, 17 Feb 2017 23:14:10 +0900 Subject: [PATCH] MediaSessionService: Notify volume key long-presses when the screen is off When the screen is off, MediaSessionService doesn't get the volume key long-press events from the PhoneWindowManager because PhoneWindowManager intercepts them and only sends initial down and up events. This is intended because users cannot see the safety warning dialog which warns users about too loud volume. This CL assumes that volume key is long-pressed if the key up doesn't happen after the initial down within the long-press timeout, and notify them with IOnVolumeKeyLongPressListener. Bug: 35328001 Test: Manual test Change-Id: I3b5aec4c2dd66a181bf41786f1417cc65874356c --- .../server/media/MediaSessionService.java | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 407262b083924..36f328716306f 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -64,6 +64,7 @@ import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.view.KeyEvent; +import android.view.ViewConfiguration; import com.android.server.LocalServices; import com.android.server.SystemService; @@ -99,6 +100,7 @@ public class MediaSessionService extends SystemService implements Monitor { private final Object mLock = new Object(); private final MessageHandler mHandler = new MessageHandler(); private final PowerManager.WakeLock mMediaEventWakeLock; + private final int mLongPressTimeout; private KeyguardManager mKeyguardManager; private IAudioService mAudioService; @@ -120,6 +122,7 @@ public class MediaSessionService extends SystemService implements Monitor { mPriorityStack = new MediaSessionStack(); PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleMediaEvent"); + mLongPressTimeout = ViewConfiguration.getLongPressTimeout(); } @Override @@ -536,6 +539,16 @@ public class MediaSessionService extends SystemService implements Monitor { return ""; } + private void dispatchVolumeKeyLongPressLocked(KeyEvent keyEvent) { + // Only consider full user. + UserRecord user = mUserRecords.get(mCurrentUserIdList.get(0)); + try { + user.mOnVolumeKeyLongPressListener.onVolumeKeyLongPress(keyEvent); + } catch (RemoteException e) { + Log.w(TAG, "Failed to send " + keyEvent + " to volume key long-press listener"); + } + } + /** * Information about a particular user. The contents of this object is * guarded by mLock. @@ -944,7 +957,8 @@ public class MediaSessionService extends SystemService implements Monitor { try { synchronized (mLock) { // Only consider full user. - UserRecord user = mUserRecords.get(mCurrentUserIdList.get(0)); + int userId = mCurrentUserIdList.get(0); + UserRecord user = mUserRecords.get(userId); if (mPriorityStack.isGlobalPriorityActive() || user.mOnVolumeKeyLongPressListener == null) { @@ -954,11 +968,17 @@ public class MediaSessionService extends SystemService implements Monitor { // at the same time. if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) { if (keyEvent.getRepeatCount() == 0) { - user.mInitialDownVolumeKeyEvent = keyEvent; + // Keeps the copy of the KeyEvent because it can be reused. + user.mInitialDownVolumeKeyEvent = KeyEvent.obtain(keyEvent); user.mInitialDownVolumeStream = stream; user.mInitialDownMusicOnly = musicOnly; + mHandler.sendMessageDelayed( + mHandler.obtainMessage( + MessageHandler.MSG_VOLUME_INITIAL_DOWN, userId, 0), + mLongPressTimeout); } if (keyEvent.getRepeatCount() > 0 || keyEvent.isLongPress()) { + mHandler.removeMessages(MessageHandler.MSG_VOLUME_INITIAL_DOWN); if (user.mInitialDownVolumeKeyEvent != null) { dispatchVolumeKeyLongPressLocked( user.mInitialDownVolumeKeyEvent); @@ -968,6 +988,7 @@ public class MediaSessionService extends SystemService implements Monitor { dispatchVolumeKeyLongPressLocked(keyEvent); } } else { // if up + mHandler.removeMessages(MessageHandler.MSG_VOLUME_INITIAL_DOWN); if (user.mInitialDownVolumeKeyEvent != null && user.mInitialDownVolumeKeyEvent.getDownTime() == keyEvent.getDownTime()) { @@ -988,16 +1009,6 @@ public class MediaSessionService extends SystemService implements Monitor { } } - private void dispatchVolumeKeyLongPressLocked(KeyEvent keyEvent) { - // Only consider full user. - UserRecord user = mUserRecords.get(mCurrentUserIdList.get(0)); - try { - user.mOnVolumeKeyLongPressListener.onVolumeKeyLongPress(keyEvent); - } catch (RemoteException e) { - Log.w(TAG, "Failed to send " + keyEvent + " to volume key long-press listener"); - } - } - private void dispatchVolumeKeyEventLocked( KeyEvent keyEvent, int stream, boolean musicOnly) { boolean down = keyEvent.getAction() == KeyEvent.ACTION_DOWN; @@ -1480,6 +1491,7 @@ public class MediaSessionService extends SystemService implements Monitor { final class MessageHandler extends Handler { private static final int MSG_SESSIONS_CHANGED = 1; + private static final int MSG_VOLUME_INITIAL_DOWN = 2; @Override public void handleMessage(Message msg) { @@ -1487,6 +1499,16 @@ public class MediaSessionService extends SystemService implements Monitor { case MSG_SESSIONS_CHANGED: pushSessionsChanged(msg.arg1); break; + case MSG_VOLUME_INITIAL_DOWN: + synchronized (mLock) { + UserRecord user = mUserRecords.get((int) msg.arg1); + if (user != null && user.mInitialDownVolumeKeyEvent != null) { + dispatchVolumeKeyLongPressLocked(user.mInitialDownVolumeKeyEvent); + // Mark that the key is already handled. + user.mInitialDownVolumeKeyEvent = null; + } + } + break; } }