MediaSessionManager: Add getSession2Tokens()

This currently only returns tokens with the TYPE_SESSION.
Follow up CLs will change this to also return tokens with other types.

Bug: 122234817
Test: Build and flash manually.
Change-Id: Ia2f67983393696439020d5ea58976b9ed1662566
This commit is contained in:
Jaewan Kim
2019-01-04 03:34:38 +09:00
parent b42f9c93cb
commit bbce3333fc
3 changed files with 92 additions and 6 deletions

View File

@@ -35,6 +35,7 @@ interface ISessionManager {
ISession createSession(String packageName, in ISessionCallback cb, String tag, int userId);
void notifySession2Created(in Session2Token sessionToken);
List<IBinder> getSessions(in ComponentName compName, int userId);
List<Session2Token> getSession2Tokens(int userId);
void dispatchMediaKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent,
boolean needWakeLock);
void dispatchVolumeKeyEvent(String packageName, String opPackageName, boolean asSystemService,

View File

@@ -178,6 +178,44 @@ public final class MediaSessionManager {
return controllers;
}
/**
* Gets a list of {@link Session2Token} with type {@link Session2Token#TYPE_SESSION} for the
* current user.
* <p>
* Although this API can be used without any restriction, each session owners can accept or
* reject your uses of {@link MediaSession2}.
*
* @return A list of {@link Session2Token}.
* @hide
*/
// TODO: unhide
@NonNull
public List<Session2Token> getSession2Tokens() {
return getSession2Tokens(UserHandle.myUserId());
}
/**
* Gets a list of {@link Session2Token} with type {@link Session2Token#TYPE_SESSION} for the
* given user.
* <p>
* If you want to get tokens for another user, you must hold the
* {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission.
*
* @param userId The user id to fetch sessions for.
* @return A list of {@link Session2Token}
* @hide
*/
// TODO: unhide
@NonNull
public List<Session2Token> getSession2Tokens(int userId) {
try {
return mService.getSession2Tokens(userId);
} catch (RemoteException e) {
Log.e(TAG, "Failed to get session tokens", e);
}
return new ArrayList<>();
}
/**
* Add a listener to be notified when the list of active sessions
* changes.This requires the

View File

@@ -114,10 +114,11 @@ public class MediaSessionService extends SystemService implements Monitor {
@GuardedBy("mLock")
private final ArrayList<SessionsListenerRecord> mSessionsListeners
= new ArrayList<SessionsListenerRecord>();
// Map user id as index to list of Session2Tokens
// TODO: Keep session2 info in MediaSessionStack for prioritizing both session1 and session2 in
// one place.
@GuardedBy("mLock")
private final List<Session2Token> mSession2Tokens = new ArrayList<>();
private final SparseArray<List<Session2Token>> mSession2TokensPerUser = new SparseArray<>();
private KeyguardManager mKeyguardManager;
private IAudioService mAudioService;
@@ -305,10 +306,13 @@ public class MediaSessionService extends SystemService implements Monitor {
updateUser();
}
// Called when the user with the userId is removed.
@Override
public void onStopUser(int userId) {
if (DEBUG) Log.d(TAG, "onStopUser: " + userId);
synchronized (mLock) {
// TODO: Also handle removing user in updateUser() because adding/switching user is
// handled in updateUser().
FullUserRecord user = getFullUserRecordLocked(userId);
if (user != null) {
if (user.mFullUserId == userId) {
@@ -318,6 +322,7 @@ public class MediaSessionService extends SystemService implements Monitor {
user.destroySessionsForUserLocked(userId);
}
}
mSession2TokensPerUser.remove(userId);
updateUser();
}
}
@@ -363,6 +368,9 @@ public class MediaSessionService extends SystemService implements Monitor {
mUserRecords.put(userInfo.id, new FullUserRecord(userInfo.id));
}
}
if (mSession2TokensPerUser.get(userInfo.id) == null) {
mSession2TokensPerUser.put(userInfo.id, new ArrayList<>());
}
}
}
// Ensure that the current full user exists.
@@ -372,6 +380,9 @@ public class MediaSessionService extends SystemService implements Monitor {
Log.w(TAG, "Cannot find FullUserInfo for the current user " + currentFullUserId);
mCurrentFullUserRecord = new FullUserRecord(currentFullUserId);
mUserRecords.put(currentFullUserId, mCurrentFullUserRecord);
if (mSession2TokensPerUser.get(currentFullUserId) == null) {
mSession2TokensPerUser.put(currentFullUserId, new ArrayList<>());
}
}
mFullUserIds.put(currentFullUserId, currentFullUserId);
}
@@ -732,9 +743,15 @@ public class MediaSessionService extends SystemService implements Monitor {
pw.println(indent + "Restored MediaButtonReceiverComponentType: "
+ mRestoredMediaButtonReceiverComponentType);
mPriorityStack.dump(pw, indent);
pw.println(indent + "Session2Tokens - " + mSession2Tokens.size());
for (Session2Token session2Token : mSession2Tokens) {
pw.println(indent + " " + session2Token);
pw.println(indent + "Session2Tokens:");
for (int i = 0; i < mSession2TokensPerUser.size(); i++) {
List<Session2Token> list = mSession2TokensPerUser.valueAt(i);
if (list == null || list.size() == 0) {
continue;
}
for (Session2Token token : list) {
pw.println(indent + " " + token);
}
}
}
@@ -955,6 +972,34 @@ public class MediaSessionService extends SystemService implements Monitor {
}
}
@Override
public List<Session2Token> getSession2Tokens(int userId) {
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
// Check that they can make calls on behalf of the user and
// get the final user id
int resolvedUserId = ActivityManager.handleIncomingUser(pid, uid, userId,
true /* allowAll */, true /* requireFull */, "getSession2Tokens",
null /* optional packageName */);
List<Session2Token> result = new ArrayList<>();
synchronized (mLock) {
if (resolvedUserId == UserHandle.USER_ALL) {
for (int i = 0; i < mSession2TokensPerUser.size(); i++) {
result.addAll(mSession2TokensPerUser.valueAt(i));
}
} else {
result.addAll(mSession2TokensPerUser.get(userId));
}
}
return result;
} finally {
Binder.restoreCallingIdentity(token);
}
}
@Override
public void addSessionsListener(IActiveSessionsListener listener,
ComponentName componentName, int userId) throws RemoteException {
@@ -1965,14 +2010,16 @@ public class MediaSessionService extends SystemService implements Monitor {
@Override
public void onConnected(MediaController2 controller, Session2CommandGroup allowedCommands) {
synchronized (mLock) {
mSession2Tokens.add(mToken);
int userId = UserHandle.getUserId(mToken.getUid());
mSession2TokensPerUser.get(userId).add(mToken);
}
}
@Override
public void onDisconnected(MediaController2 controller) {
synchronized (mLock) {
mSession2Tokens.remove(mToken);
int userId = UserHandle.getUserId(mToken.getUid());
mSession2TokensPerUser.get(userId).remove(mToken);
}
}
}