Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64971a51 authored by Kyunglyul Hyun's avatar Kyunglyul Hyun
Browse files

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
parent 720ebdc4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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,
+39 −1
Original line number Diff line number Diff line
@@ -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}.
+64 −0
Original line number Diff line number Diff line
@@ -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 {