Media: Add MSM#getMediaKeyEventSession

Add MediaSessionManager#getMediaKeyEventSession
for system apps to get the current media key event session,
which may be different from the first session in
MediaSessionManager#getActiveSessions().

Bug: 181383356
Test: atest MediaSessionManagerTest
Change-Id: I56ece75e352150693a5658e2660f39b5702d8612
This commit is contained in:
Kyunglyul Hyun
2021-02-25 15:08:08 +00:00
parent 720ebdc401
commit 64971a5106
4 changed files with 107 additions and 1 deletions

View File

@@ -5433,6 +5433,8 @@ package android.media.session {
public final class MediaSessionManager {
method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void addOnMediaKeyEventDispatchedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.session.MediaSessionManager.OnMediaKeyEventDispatchedListener);
method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void addOnMediaKeyEventSessionChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.session.MediaSessionManager.OnMediaKeyEventSessionChangedListener);
method @Nullable @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public android.media.session.MediaSession.Token getMediaKeyEventSession();
method @NonNull @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public String getMediaKeyEventSessionPackageName();
method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void removeOnMediaKeyEventDispatchedListener(@NonNull android.media.session.MediaSessionManager.OnMediaKeyEventDispatchedListener);
method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void removeOnMediaKeyEventSessionChangedListener(@NonNull android.media.session.MediaSessionManager.OnMediaKeyEventSessionChangedListener);
method @RequiresPermission(android.Manifest.permission.SET_MEDIA_KEY_LISTENER) public void setOnMediaKeyListener(android.media.session.MediaSessionManager.OnMediaKeyListener, @Nullable android.os.Handler);

View File

@@ -39,6 +39,8 @@ interface ISessionManager {
ISession createSession(String packageName, in ISessionCallback sessionCb, String tag,
in Bundle sessionInfo, int userId);
List<MediaSession.Token> getSessions(in ComponentName compName, int userId);
MediaSession.Token getMediaKeyEventSession();
String getMediaKeyEventSessionPackageName();
void dispatchMediaKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent,
boolean needWakeLock);
boolean dispatchMediaKeyEventToSessionAsSystemService(String packageName,

View File

@@ -194,6 +194,44 @@ public final class MediaSessionManager {
return getActiveSessionsForUser(notificationListener, UserHandle.myUserId());
}
/**
* Gets the media key event session, which would receive a media key event unless specified.
* @return The media key event session, which would receive key events by default, unless
* the caller has specified the target. Can be {@code null}.
* @hide
*/
@SystemApi
@RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
@Nullable
public MediaSession.Token getMediaKeyEventSession() {
try {
return mService.getMediaKeyEventSession();
} catch (RemoteException ex) {
Log.e(TAG, "Failed to get media key event session", ex);
}
return null;
}
/**
* Gets the package name of the media key event session.
* @return The package name of the media key event session or the last session's media button
* receiver if the media key event session is {@code null}.
* @see #getMediaKeyEventSession()
* @hide
*/
@SystemApi
@RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
@NonNull
public String getMediaKeyEventSessionPackageName() {
try {
String packageName = mService.getMediaKeyEventSessionPackageName();
return (packageName != null) ? packageName : "";
} catch (RemoteException ex) {
Log.e(TAG, "Failed to get media key event session", ex);
}
return "";
}
/**
* Get active sessions for the given user.
* <p>
@@ -856,7 +894,7 @@ public final class MediaSessionManager {
}
/**
* Add a {@link OnMediaKeyEventDispatchedListener}.
* Add a {@link OnMediaKeyEventSessionChangedListener}.
*
* @param executor The executor on which the listener should be invoked
* @param listener A {@link OnMediaKeyEventSessionChangedListener}.

View File

@@ -1224,6 +1224,70 @@ public class MediaSessionService extends SystemService implements Monitor {
}
}
@Override
public MediaSession.Token getMediaKeyEventSession() {
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
final long token = Binder.clearCallingIdentity();
try {
if (!hasMediaControlPermission(pid, uid)) {
throw new SecurityException("MEDIA_CONTENT_CONTROL permission is required to"
+ " get the media key event session");
}
MediaSessionRecordImpl record;
synchronized (mLock) {
FullUserRecord user = getFullUserRecordLocked(userId);
if (user == null) {
Log.w(TAG, "No matching user record to get the media key event session"
+ ", userId=" + userId);
return null;
}
record = user.getMediaButtonSessionLocked();
}
if (record instanceof MediaSessionRecord) {
return ((MediaSessionRecord) record).getSessionToken();
}
//TODO: Handle media session 2 case
return null;
} finally {
Binder.restoreCallingIdentity(token);
}
}
@Override
public String getMediaKeyEventSessionPackageName() {
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
final long token = Binder.clearCallingIdentity();
try {
if (!hasMediaControlPermission(pid, uid)) {
throw new SecurityException("MEDIA_CONTENT_CONTROL permission is required to"
+ " get the media key event session package");
}
MediaSessionRecordImpl record;
synchronized (mLock) {
FullUserRecord user = getFullUserRecordLocked(userId);
if (user == null) {
Log.w(TAG, "No matching user record to get the media key event session"
+ " package , userId=" + userId);
return "";
}
record = user.getMediaButtonSessionLocked();
if (record instanceof MediaSessionRecord) {
return record.getPackageName();
//TODO: Handle media session 2 case
} else if (user.mLastMediaButtonReceiverHolder != null) {
return user.mLastMediaButtonReceiverHolder.getPackageName();
}
}
return "";
} finally {
Binder.restoreCallingIdentity(token);
}
}
@Override
public void addSessionsListener(IActiveSessionsListener listener,
ComponentName componentName, int userId) throws RemoteException {