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; }