Loading media/java/android/media/session/ISessionManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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, Loading media/java/android/media/session/MediaSessionManager.java +38 −0 Original line number Diff line number Diff line Loading @@ -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 Loading services/core/java/com/android/server/media/MediaSessionService.java +53 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -318,6 +322,7 @@ public class MediaSessionService extends SystemService implements Monitor { user.destroySessionsForUserLocked(userId); } } mSession2TokensPerUser.remove(userId); updateUser(); } } Loading Loading @@ -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. Loading @@ -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); } Loading Loading @@ -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); } } } Loading Loading @@ -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 { Loading Loading @@ -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); } } } Loading Loading
media/java/android/media/session/ISessionManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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, Loading
media/java/android/media/session/MediaSessionManager.java +38 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
services/core/java/com/android/server/media/MediaSessionService.java +53 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -318,6 +322,7 @@ public class MediaSessionService extends SystemService implements Monitor { user.destroySessionsForUserLocked(userId); } } mSession2TokensPerUser.remove(userId); updateUser(); } } Loading Loading @@ -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. Loading @@ -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); } Loading Loading @@ -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); } } } Loading Loading @@ -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 { Loading Loading @@ -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); } } } Loading