diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index e0017b502ee04..38c615791d9f0 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -171,19 +171,63 @@ public class MediaSessionService extends SystemService implements Monitor { public void updateSession(MediaSessionRecord record) { synchronized (mLock) { FullUserRecord user = getFullUserRecordLocked(record.getUserId()); - if (user == null || !user.mPriorityStack.contains(record)) { - Log.d(TAG, "Unknown session updated. Ignoring."); + if (user == null) { + Log.w(TAG, "Unknown session updated. Ignoring."); return; } - user.mPriorityStack.onSessionStateChange(record); if ((record.getFlags() & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) { - mGlobalPrioritySession = record; + if (mGlobalPrioritySession != record) { + Log.d(TAG, "Global priority session is changed from " + mGlobalPrioritySession + + " to " + record); + mGlobalPrioritySession = record; + if (user != null && user.mPriorityStack.contains(record)) { + // Handle the global priority session separately. + // Otherwise, it will be the media button session even after it becomes + // inactive because it has been the lastly played media app. + user.mPriorityStack.removeSession(record); + } + } + if (DEBUG_KEY_EVENT) { + Log.d(TAG, "Global priority session is updated, active=" + record.isActive()); + } user.pushAddressedPlayerChangedLocked(); + } else { + if (!user.mPriorityStack.contains(record)) { + Log.w(TAG, "Unknown session updated. Ignoring."); + return; + } + user.mPriorityStack.onSessionStateChange(record); } mHandler.postSessionsChanged(record.getUserId()); } } + private List getActiveSessionsLocked(int userId) { + List records; + if (userId == UserHandle.USER_ALL) { + records = new ArrayList<>(); + int size = mUserRecords.size(); + for (int i = 0; i < size; i++) { + records.addAll(mUserRecords.valueAt(i).mPriorityStack.getActiveSessions(userId)); + } + } else { + FullUserRecord user = getFullUserRecordLocked(userId); + if (user == null) { + Log.w(TAG, "getSessions failed. Unknown user " + userId); + return new ArrayList<>(); + } + records = user.mPriorityStack.getActiveSessions(userId); + } + + // Return global priority session at the first whenever it's asked. + if (isGlobalPriorityActiveLocked() + && (userId == UserHandle.USER_ALL + || userId == mGlobalPrioritySession.getUserId())) { + records.add(0, mGlobalPrioritySession); + } + return records; + } + /** * Tells the system UI that volume has changed on an active remote session. */ @@ -339,16 +383,16 @@ public class MediaSessionService extends SystemService implements Monitor { if (DEBUG) { Log.d(TAG, "Destroying " + session); } - int userId = session.getUserId(); - FullUserRecord user = getFullUserRecordLocked(userId); - if (user != null) { - user.removeSessionLocked(session); - } + FullUserRecord user = getFullUserRecordLocked(session.getUserId()); if (mGlobalPrioritySession == session) { mGlobalPrioritySession = null; if (session.isActive() && user != null) { user.pushAddressedPlayerChangedLocked(); } + } else { + if (user != null) { + user.mPriorityStack.removeSession(session); + } } try { @@ -484,7 +528,7 @@ public class MediaSessionService extends SystemService implements Monitor { throw new RuntimeException("Media Session owner died prematurely.", e); } - user.addSessionLocked(session); + user.mPriorityStack.addSession(session); mHandler.postSessionsChanged(userId); if (DEBUG) { @@ -509,7 +553,7 @@ public class MediaSessionService extends SystemService implements Monitor { Log.w(TAG, "pushSessionsChanged failed. No user with id=" + userId); return; } - List records = user.mPriorityStack.getActiveSessions(userId); + List records = getActiveSessionsLocked(userId); int size = records.size(); ArrayList tokens = new ArrayList(); for (int i = 0; i < size; i++) { @@ -637,14 +681,6 @@ public class MediaSessionService extends SystemService implements Monitor { } } - public void addSessionLocked(MediaSessionRecord session) { - mPriorityStack.addSession(session); - } - - public void removeSessionLocked(MediaSessionRecord session) { - mPriorityStack.removeSession(session); - } - public void dumpLocked(PrintWriter pw, String prefix) { pw.print(prefix + "Record for full_user=" + mFullUserId); // Dump managed profile user ids associated with this user. @@ -816,27 +852,9 @@ public class MediaSessionService extends SystemService implements Monitor { int resolvedUserId = verifySessionsRequest(componentName, userId, pid, uid); ArrayList binders = new ArrayList(); synchronized (mLock) { - if (resolvedUserId == UserHandle.USER_ALL) { - int size = mUserRecords.size(); - for (int i = 0; i < size; i++) { - List records = - mUserRecords.valueAt(i).mPriorityStack.getActiveSessions( - resolvedUserId); - for (MediaSessionRecord record : records) { - binders.add(record.getControllerBinder().asBinder()); - } - } - } else { - FullUserRecord user = getFullUserRecordLocked(resolvedUserId); - if (user == null) { - Log.w(TAG, "getSessions failed. Unknown user " + userId); - return binders; - } - List records = user.mPriorityStack - .getActiveSessions(resolvedUserId); - for (MediaSessionRecord record : records) { - binders.add(record.getControllerBinder().asBinder()); - } + List records = getActiveSessionsLocked(resolvedUserId); + for (MediaSessionRecord record : records) { + binders.add(record.getControllerBinder().asBinder()); } } return binders; @@ -1292,6 +1310,9 @@ public class MediaSessionService extends SystemService implements Monitor { synchronized (mLock) { pw.println(mSessionsListeners.size() + " sessions listeners."); pw.println("Global priority session is " + mGlobalPrioritySession); + if (mGlobalPrioritySession != null) { + mGlobalPrioritySession.dump(pw, " "); + } pw.println("User Records:"); int count = mUserRecords.size(); for (int i = 0; i < count; i++) { diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java index f474769bfd319..f03f630d0e57a 100644 --- a/services/core/java/com/android/server/media/MediaSessionStack.java +++ b/services/core/java/com/android/server/media/MediaSessionStack.java @@ -310,7 +310,6 @@ class MediaSessionStack { * Get a priority sorted list of sessions. Can filter to only return active * sessions or sessions. *

Here's the priority order. - *

  • System priority session (session with FLAG_EXCLUSIVE_GLOBAL_PRIORITY)
  • *
  • Active sessions whose PlaybackState is active
  • *
  • Active sessions whose PlaybackState is inactive
  • *
  • Inactive sessions
  • @@ -344,13 +343,7 @@ class MediaSessionStack { continue; } - if (session.isSystemPriority()) { - // System priority sessions are special and always go at the - // front. We expect there to only be one of these at a time. - result.add(0, session); - lastPlaybackActiveIndex++; - lastActiveIndex++; - } else if (session.isPlaybackActive()) { + if (session.isPlaybackActive()) { result.add(lastPlaybackActiveIndex++, session); lastActiveIndex++; } else {