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

Commit a05a1d3a authored by Hyundo Moon's avatar Hyundo Moon Committed by Android (Google) Code Review
Browse files

Merge changes from topic "public_media_key_session_changed_listener"

* changes:
  Add public getMediaKeyEventSession(PackageName)
  Add public add/removeOnMediaKeyEventSessionChangedListener
parents 9e495f20 33f8af14
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -25266,13 +25266,17 @@ package android.media.session {
  public final class MediaSessionManager {
    method public void addOnActiveSessionsChangedListener(@NonNull android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, @Nullable android.content.ComponentName);
    method public void addOnActiveSessionsChangedListener(@NonNull android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, @Nullable android.content.ComponentName, @Nullable android.os.Handler);
    method public void addOnMediaKeyEventSessionChangedListener(@NonNull android.content.ComponentName, @NonNull java.util.concurrent.Executor, @NonNull android.media.session.MediaSessionManager.OnMediaKeyEventSessionChangedListener);
    method public void addOnSession2TokensChangedListener(@NonNull android.media.session.MediaSessionManager.OnSession2TokensChangedListener);
    method public void addOnSession2TokensChangedListener(@NonNull android.media.session.MediaSessionManager.OnSession2TokensChangedListener, @NonNull android.os.Handler);
    method @NonNull public java.util.List<android.media.session.MediaController> getActiveSessions(@Nullable android.content.ComponentName);
    method @Nullable public android.media.session.MediaSession.Token getMediaKeyEventSession(@NonNull android.content.ComponentName);
    method @NonNull public String getMediaKeyEventSessionPackageName(@NonNull android.content.ComponentName);
    method @NonNull public java.util.List<android.media.Session2Token> getSession2Tokens();
    method public boolean isTrustedForMediaControl(@NonNull android.media.session.MediaSessionManager.RemoteUserInfo);
    method @Deprecated public void notifySession2Created(@NonNull android.media.Session2Token);
    method public void removeOnActiveSessionsChangedListener(@NonNull android.media.session.MediaSessionManager.OnActiveSessionsChangedListener);
    method public void removeOnMediaKeyEventSessionChangedListener(@NonNull android.media.session.MediaSessionManager.OnMediaKeyEventSessionChangedListener);
    method public void removeOnSession2TokensChangedListener(@NonNull android.media.session.MediaSessionManager.OnSession2TokensChangedListener);
  }
@@ -25280,6 +25284,10 @@ package android.media.session {
    method public void onActiveSessionsChanged(@Nullable java.util.List<android.media.session.MediaController>);
  }
  public static interface MediaSessionManager.OnMediaKeyEventSessionChangedListener {
    method public void onMediaKeyEventSessionChanged(@NonNull String, @Nullable android.media.session.MediaSession.Token);
  }
  public static interface MediaSessionManager.OnSession2TokensChangedListener {
    method public void onSession2TokensChanged(@NonNull java.util.List<android.media.Session2Token>);
  }
+0 −5
Original line number Diff line number Diff line
@@ -5587,7 +5587,6 @@ package android.media.session {
    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);
    method @RequiresPermission(android.Manifest.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER) public void setOnVolumeKeyLongPressListener(android.media.session.MediaSessionManager.OnVolumeKeyLongPressListener, @Nullable android.os.Handler);
  }
@@ -5596,10 +5595,6 @@ package android.media.session {
    method public void onMediaKeyEventDispatched(@NonNull android.view.KeyEvent, @NonNull String, @Nullable android.media.session.MediaSession.Token);
  }
  public static interface MediaSessionManager.OnMediaKeyEventSessionChangedListener {
    method public void onMediaKeyEventSessionChanged(@NonNull String, @Nullable android.media.session.MediaSession.Token);
  }
  public static interface MediaSessionManager.OnMediaKeyListener {
    method public boolean onMediaKey(android.view.KeyEvent);
  }
+4 −3
Original line number Diff line number Diff line
@@ -39,8 +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();
    MediaSession.Token getMediaKeyEventSession(in ComponentName compName);
    String getMediaKeyEventSessionPackageName(in ComponentName compName);
    void dispatchMediaKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent,
            boolean needWakeLock);
    boolean dispatchMediaKeyEventToSessionAsSystemService(String packageName,
@@ -66,7 +66,8 @@ interface ISessionManager {
    void addOnMediaKeyEventDispatchedListener(in IOnMediaKeyEventDispatchedListener listener);
    void removeOnMediaKeyEventDispatchedListener(in IOnMediaKeyEventDispatchedListener listener);
    void addOnMediaKeyEventSessionChangedListener(
            in IOnMediaKeyEventSessionChangedListener listener);
            in IOnMediaKeyEventSessionChangedListener listener,
            in ComponentName notificationListener);
    void removeOnMediaKeyEventSessionChangedListener(
            in IOnMediaKeyEventSessionChangedListener listener);
    void setOnVolumeKeyLongPressListener(in IOnVolumeKeyLongPressListener listener);
+84 −18
Original line number Diff line number Diff line
@@ -205,7 +205,28 @@ public final class MediaSessionManager {
    @Nullable
    public MediaSession.Token getMediaKeyEventSession() {
        try {
            return mService.getMediaKeyEventSession();
            return mService.getMediaKeyEventSession(null);
        } catch (RemoteException ex) {
            Log.e(TAG, "Failed to get media key event session", ex);
        }
        return null;
    }

    /**
     * Gets the media key event session, which would receive a media key event unless specified.
     * <p>
     * This requires that your app is an enabled notificationlistener using the
     * {@link NotificationListenerService} APIs, in which case you must pass
     * the {@link ComponentName} of your enabled listener.
     *
     * @return The media key event session, which would receive key events by default, unless
     *          the caller has specified the target. Can be {@code null}.
     */
    @Nullable
    public MediaSession.Token getMediaKeyEventSession(@NonNull ComponentName notificationListener) {
        Objects.requireNonNull(notificationListener, "notificationListener shouldn't be null");
        try {
            return mService.getMediaKeyEventSession(notificationListener);
        } catch (RemoteException ex) {
            Log.e(TAG, "Failed to get media key event session", ex);
        }
@@ -224,10 +245,34 @@ public final class MediaSessionManager {
    @NonNull
    public String getMediaKeyEventSessionPackageName() {
        try {
            String packageName = mService.getMediaKeyEventSessionPackageName();
            String packageName = mService.getMediaKeyEventSessionPackageName(null);
            return (packageName != null) ? packageName : "";
        } catch (RemoteException ex) {
            Log.e(TAG, "Failed to get media key event session", ex);
            Log.e(TAG, "Failed to get media key event session package name", ex);
        }
        return "";
    }

    /**
     * Gets the package name of the media key event session.
     * <p>
     * This requires that your app is an enabled notificationlistener using the
     * {@link NotificationListenerService} APIs, in which case you must pass
     * the {@link ComponentName} of your enabled listener.
     *
     * @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}. Returns an empty string
     *          if neither of them exists.
     * @see #getMediaKeyEventSession(ComponentName)
     */
    @NonNull
    public String getMediaKeyEventSessionPackageName(@NonNull ComponentName notificationListener) {
        Objects.requireNonNull(notificationListener, "notificationListener shouldn't be null");
        try {
            String packageName = mService.getMediaKeyEventSessionPackageName(notificationListener);
            return (packageName != null) ? packageName : "";
        } catch (RemoteException ex) {
            Log.e(TAG, "Failed to get media key event session package name", ex);
        }
        return "";
    }
@@ -905,44 +950,67 @@ public final class MediaSessionManager {
    public void addOnMediaKeyEventSessionChangedListener(
            @NonNull @CallbackExecutor Executor executor,
            @NonNull OnMediaKeyEventSessionChangedListener listener) {
        addOnMediaKeyEventSessionChangedListenerInternal(null, executor, listener);
    }

    /**
     * Add a listener to be notified when the media key session is changed.
     * <p>
     * This requires that your app is an enabled notificationlistener using the
     * {@link NotificationListenerService} APIs, in which case you must pass
     * the {@link ComponentName} of your enabled listener.
     *
     * @param notificationListener The enabled notification listener component.
     * @param executor The executor on which the listener should be invoked.
     * @param listener A {@link OnMediaKeyEventSessionChangedListener}.
     */
    public void addOnMediaKeyEventSessionChangedListener(
            @NonNull ComponentName notificationListener,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull OnMediaKeyEventSessionChangedListener listener) {
        Objects.requireNonNull(notificationListener, "notificationListener shouldn't be null");
        addOnMediaKeyEventSessionChangedListenerInternal(notificationListener, executor, listener);
    }

    private void addOnMediaKeyEventSessionChangedListenerInternal(
            @Nullable ComponentName notificationListener,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull OnMediaKeyEventSessionChangedListener listener) {
        Objects.requireNonNull(executor, "executor shouldn't be null");
        Objects.requireNonNull(listener, "listener shouldn't be null");
        synchronized (mLock) {
            try {
                if (mMediaKeyEventSessionChangedCallbacks.isEmpty()) {
                    mService.addOnMediaKeyEventSessionChangedListener(
                            mOnMediaKeyEventSessionChangedListenerStub, notificationListener);
                }
                mMediaKeyEventSessionChangedCallbacks.put(listener, executor);
                executor.execute(
                        () -> listener.onMediaKeyEventSessionChanged(
                                mCurMediaKeyEventSessionPackage, mCurMediaKeyEventSession));
                if (mMediaKeyEventSessionChangedCallbacks.size() == 1) {
                    mService.addOnMediaKeyEventSessionChangedListener(
                            mOnMediaKeyEventSessionChangedListenerStub);
                }
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to set media key listener", e);
                Log.e(TAG, "Failed to add MediaKeyEventSessionChangedListener", e);
            }
        }
    }

    /**
     * Remove a {@link OnMediaKeyEventSessionChangedListener}.
     * Stop receiving updates on media key event session change on the specified listener.
     *
     * @param listener A {@link OnMediaKeyEventSessionChangedListener}.
     * @hide
     */
    @SystemApi
    @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
    public void removeOnMediaKeyEventSessionChangedListener(
            @NonNull OnMediaKeyEventSessionChangedListener listener) {
        Objects.requireNonNull(listener, "listener shouldn't be null");
        synchronized (mLock) {
            try {
                mMediaKeyEventSessionChangedCallbacks.remove(listener);
                if (mMediaKeyEventSessionChangedCallbacks.size() == 0) {
                if (mMediaKeyEventSessionChangedCallbacks.remove(listener) != null
                        && mMediaKeyEventSessionChangedCallbacks.isEmpty()) {
                    mService.removeOnMediaKeyEventSessionChangedListener(
                            mOnMediaKeyEventSessionChangedListenerStub);
                }
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to set media key listener", e);
                Log.e(TAG, "Failed to remove MediaKeyEventSessionChangedListener", e);
            }
        }
    }
@@ -1124,16 +1192,14 @@ public final class MediaSessionManager {
    /**
     * Listener to receive changes in the media key event session, which would receive a media key
     * event unless specified.
     * @hide
     */
    @SystemApi
    public interface OnMediaKeyEventSessionChangedListener {
        /**
         * Called when the media key session is changed to the given media session. The key event
         * session is the media session which would receive key event by default, unless the caller
         * has specified the target.
         * <p>
         * The session token can be {@link null} if the media button session is unset. In that case,
         * The session token can be {@code null} if the media button session is unset. In that case,
         * packageName will return the package name of the last session's media button receiver, or
         * an empty string if the last session didn't set a media button receiver.
         *
+33 −21
Original line number Diff line number Diff line
@@ -1237,15 +1237,19 @@ public class MediaSessionService extends SystemService implements Monitor {
        }

        @Override
        public MediaSession.Token getMediaKeyEventSession() {
        public MediaSession.Token getMediaKeyEventSession(ComponentName notificationListener) {
            final int pid = Binder.getCallingPid();
            final int uid = Binder.getCallingUid();
            final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
            final UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
            final int userId = userHandle.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");
                if (!hasMediaControlPermission(pid, uid)
                        && !isEnabledNotificationListener(
                                notificationListener, userHandle, userId)) {
                    throw new SecurityException("MEDIA_CONTENT_CONTROL permission or an enabled"
                            + " notification listener is required to"
                            + " get media key event session.");
                }
                MediaSessionRecordImpl record;
                synchronized (mLock) {
@@ -1268,15 +1272,19 @@ public class MediaSessionService extends SystemService implements Monitor {
        }

        @Override
        public String getMediaKeyEventSessionPackageName() {
        public String getMediaKeyEventSessionPackageName(ComponentName notificationListener) {
            final int pid = Binder.getCallingPid();
            final int uid = Binder.getCallingUid();
            final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
            final UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
            final int userId = userHandle.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");
                if (!hasMediaControlPermission(pid, uid)
                        && !isEnabledNotificationListener(
                        notificationListener, userHandle, userId)) {
                    throw new SecurityException("MEDIA_CONTENT_CONTROL permission or an enabled"
                            + " notification listener is required to"
                            + " get media key event session package name");
                }
                MediaSessionRecordImpl record;
                synchronized (mLock) {
@@ -1588,19 +1596,25 @@ public class MediaSessionService extends SystemService implements Monitor {

        @Override
        public void addOnMediaKeyEventSessionChangedListener(
                final IOnMediaKeyEventSessionChangedListener listener) {
                final IOnMediaKeyEventSessionChangedListener listener,
                final ComponentName notificationListener) {
            if (listener == null) {
                Log.w(TAG, "addOnMediaKeyEventSessionChangedListener: lister is null, ignoring");
                Log.w(TAG, "addOnMediaKeyEventSessionChangedListener: listener is null, ignoring");
                return;
            }

            final int pid = Binder.getCallingPid();
            final int uid = Binder.getCallingUid();
            final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
            final UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
            final int userId = userHandle.getIdentifier();
            final long token = Binder.clearCallingIdentity();
            try {
                if (!hasMediaControlPermission(pid, uid)) {
                    throw new SecurityException("MEDIA_CONTENT_CONTROL permission is required to"
                            + "  add MediaKeyEventSessionChangedListener");
                if (!hasMediaControlPermission(pid, uid)
                        && !isEnabledNotificationListener(
                                notificationListener, userHandle, userId)) {
                    throw new SecurityException("MEDIA_CONTENT_CONTROL permission or an enabled"
                            + " notification listener is required to"
                            + " add MediaKeyEventSessionChangedListener.");
                }
                synchronized (mLock) {
                    FullUserRecord user = getFullUserRecordLocked(userId);
@@ -1622,18 +1636,16 @@ public class MediaSessionService extends SystemService implements Monitor {
        public void removeOnMediaKeyEventSessionChangedListener(
                final IOnMediaKeyEventSessionChangedListener listener) {
            if (listener == null) {
                Log.w(TAG, "removeOnMediaKeyEventSessionChangedListener: lister is null, ignoring");
                Log.w(TAG, "removeOnMediaKeyEventSessionChangedListener: listener is null,"
                        + " ignoring");
                return;
            }

            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"
                            + "  remove MediaKeyEventSessionChangedListener");
                }
                synchronized (mLock) {
                    FullUserRecord user = getFullUserRecordLocked(userId);
                    if (user == null || user.mFullUserId != userId) {