From 870c5a6593f723211a4a90766be9191c69f38570 Mon Sep 17 00:00:00 2001 From: RoboErik Date: Tue, 2 Dec 2014 15:08:26 -0800 Subject: [PATCH] Tweak the behavior of the MediaSessionStack This makes the following changes in behavior: -We will only cache a pending intent for a session if it reaches the one of the playing states. -If a previously priority session is removed the next session only gets priority if it is in a playing state. Otherwise we use the removed session's PendingIntent. -The last session to have been playing or to have been added gets priority after any currently playing sessions, but only if it is still in the list of active sessions. -We will only use a session that isn't playing and isn't the most recently playing/added if we don't have a PendingIntent from the last playing session to fall back on. bug:18589421 Change-Id: I650c56a782bb1f1d5e64d7574a7d2387606f3b17 --- .../server/media/MediaSessionService.java | 8 +++-- .../server/media/MediaSessionStack.java | 31 +++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 053c988823299..f11a3f9fd445b 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -443,7 +443,7 @@ public class MediaSessionService extends SystemService implements Monitor { synchronized (mLock) { List records = mPriorityStack.getActiveSessions(userId); int size = records.size(); - if (size > 0) { + if (size > 0 && records.get(0).isPlaybackActive(false)) { rememberMediaButtonReceiverLocked(records.get(0)); } ArrayList tokens = new ArrayList(); @@ -702,8 +702,12 @@ public class MediaSessionService extends SystemService implements Monitor { try { synchronized (mLock) { + // If we don't have a media button receiver to fall back on + // include non-playing sessions for dispatching + boolean useNotPlayingSessions = mUserRecords.get( + ActivityManager.getCurrentUser()).mLastMediaButtonReceiver == null; MediaSessionRecord session = mPriorityStack - .getDefaultMediaButtonSession(mCurrentUserId); + .getDefaultMediaButtonSession(mCurrentUserId, useNotPlayingSessions); if (isVoiceKey(keyEvent.getKeyCode())) { handleVoiceKeyEventLocked(keyEvent, needWakeLock, session); } else { diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java index c48a075fbca07..611718ebacb56 100644 --- a/services/core/java/com/android/server/media/MediaSessionStack.java +++ b/services/core/java/com/android/server/media/MediaSessionStack.java @@ -51,6 +51,9 @@ public class MediaSessionStack { private MediaSessionRecord mGlobalPrioritySession; + // The last record that either entered one of the playing states or was + // added. + private MediaSessionRecord mLastInterestingRecord; private MediaSessionRecord mCachedButtonReceiver; private MediaSessionRecord mCachedDefault; private MediaSessionRecord mCachedVolumeDefault; @@ -65,6 +68,7 @@ public class MediaSessionStack { public void addSession(MediaSessionRecord record) { mSessions.add(record); clearCache(); + mLastInterestingRecord = record; } /** @@ -93,6 +97,9 @@ public class MediaSessionStack { mSessions.remove(record); mSessions.add(0, record); clearCache(); + // This becomes the last interesting record since it entered a + // playing state + mLastInterestingRecord = record; return true; } else if (!MediaSession.isActiveState(newState)) { // Just clear the volume cache when a state goes inactive @@ -168,9 +175,11 @@ public class MediaSessionStack { * Get the highest priority session that can handle media buttons. * * @param userId The user to check. + * @param includeNotPlaying Return a non-playing session if nothing else is + * available * @return The default media button session or null. */ - public MediaSessionRecord getDefaultMediaButtonSession(int userId) { + public MediaSessionRecord getDefaultMediaButtonSession(int userId, boolean includeNotPlaying) { if (mGlobalPrioritySession != null && mGlobalPrioritySession.isActive()) { return mGlobalPrioritySession; } @@ -180,7 +189,25 @@ public class MediaSessionStack { ArrayList records = getPriorityListLocked(true, MediaSession.FLAG_HANDLES_MEDIA_BUTTONS, userId); if (records.size() > 0) { - mCachedButtonReceiver = records.get(0); + MediaSessionRecord record = records.get(0); + if (record.isPlaybackActive(false)) { + // Since we're going to send a button event to this record make + // it the last interesting one. + mLastInterestingRecord = record; + mCachedButtonReceiver = record; + } else if (mLastInterestingRecord != null) { + if (records.contains(mLastInterestingRecord)) { + mCachedButtonReceiver = mLastInterestingRecord; + } else { + // That record is no longer used. Clear its reference. + mLastInterestingRecord = null; + } + } + if (includeNotPlaying && mCachedButtonReceiver == null) { + // If we really want a record and we didn't find one yet use the + // highest priority session even if it's not playing. + mCachedButtonReceiver = record; + } } return mCachedButtonReceiver; }