MediaSessionService: Cache active sessions per an user
This fixes an issue that MediaSessionManager.getActiveSessions() may return media sessions of the wrong user. This had been an issue since the Android M. Bug: 36227938 Test: Run the CtsMediaTest (MediaSessionTest and MediaSessionManagerTest) and CtsMediaHostTestCases Change-Id: I8a8297e4d182f52c84f654bdb0ba78bc16a1c058
This commit is contained in:
@@ -23,6 +23,7 @@ import android.os.Debug;
|
||||
import android.os.UserHandle;
|
||||
import android.util.IntArray;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
@@ -38,7 +39,7 @@ class MediaSessionStack {
|
||||
private static final String TAG = "MediaSessionStack";
|
||||
|
||||
/**
|
||||
* Listens the change in the media button session.
|
||||
* Listen the change in the media button session.
|
||||
*/
|
||||
interface OnMediaButtonSessionChangedListener {
|
||||
/**
|
||||
@@ -85,7 +86,12 @@ class MediaSessionStack {
|
||||
|
||||
private MediaSessionRecord mCachedDefault;
|
||||
private MediaSessionRecord mCachedVolumeDefault;
|
||||
private ArrayList<MediaSessionRecord> mCachedActiveList;
|
||||
|
||||
/**
|
||||
* Cache the result of the {@link #getActiveSessions} per user.
|
||||
*/
|
||||
private final SparseArray<ArrayList<MediaSessionRecord>> mCachedActiveLists =
|
||||
new SparseArray<>();
|
||||
|
||||
MediaSessionStack(AudioPlaybackMonitor monitor, OnMediaButtonSessionChangedListener listener) {
|
||||
mAudioPlaybackMonitor = monitor;
|
||||
@@ -99,7 +105,7 @@ class MediaSessionStack {
|
||||
*/
|
||||
public void addSession(MediaSessionRecord record) {
|
||||
mSessions.add(record);
|
||||
clearCache();
|
||||
clearCache(record.getUserId());
|
||||
|
||||
// Update the media button session.
|
||||
// The added session could be the session from the package with the audio playback.
|
||||
@@ -119,7 +125,7 @@ class MediaSessionStack {
|
||||
// in the media button session app.
|
||||
onMediaSessionChangeInMediaButtonSessionApp();
|
||||
}
|
||||
clearCache();
|
||||
clearCache(record.getUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,7 +146,7 @@ class MediaSessionStack {
|
||||
if (shouldUpdatePriority(oldState, newState)) {
|
||||
mSessions.remove(record);
|
||||
mSessions.add(0, record);
|
||||
clearCache();
|
||||
clearCache(record.getUserId());
|
||||
} else if (!MediaSession.isActiveState(newState)) {
|
||||
// Just clear the volume cache when a state goes inactive
|
||||
mCachedVolumeDefault = null;
|
||||
@@ -163,7 +169,7 @@ class MediaSessionStack {
|
||||
public void onSessionStateChange(MediaSessionRecord record) {
|
||||
// For now just clear the cache. Eventually we'll selectively clear
|
||||
// depending on what changed.
|
||||
clearCache();
|
||||
clearCache(record.getUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -245,14 +251,17 @@ class MediaSessionStack {
|
||||
* Get the current priority sorted list of active sessions. The most
|
||||
* important session is at index 0 and the least important at size - 1.
|
||||
*
|
||||
* @param userId The user to check.
|
||||
* @param userId The user to check. It can be {@link UserHandle#USER_ALL} to get all sessions
|
||||
* for all users in this {@link MediaSessionStack}.
|
||||
* @return All the active sessions in priority order.
|
||||
*/
|
||||
public ArrayList<MediaSessionRecord> getActiveSessions(int userId) {
|
||||
if (mCachedActiveList == null) {
|
||||
mCachedActiveList = getPriorityList(true, userId);
|
||||
ArrayList<MediaSessionRecord> cachedActiveList = mCachedActiveLists.get(userId);
|
||||
if (cachedActiveList == null) {
|
||||
cachedActiveList = getPriorityList(true, userId);
|
||||
mCachedActiveLists.put(userId, cachedActiveList);
|
||||
}
|
||||
return mCachedActiveList;
|
||||
return cachedActiveList;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -382,9 +391,12 @@ class MediaSessionStack {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void clearCache() {
|
||||
private void clearCache(int userId) {
|
||||
mCachedDefault = null;
|
||||
mCachedVolumeDefault = null;
|
||||
mCachedActiveList = null;
|
||||
mCachedActiveLists.remove(userId);
|
||||
// mCachedActiveLists may also include the list of sessions for UserHandle.USER_ALL,
|
||||
// so they also need to be cleared.
|
||||
mCachedActiveLists.remove(UserHandle.USER_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user