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

Commit bdc98a4a authored by Iván Budnik's avatar Iván Budnik Committed by Android (Google) Code Review
Browse files

Merge "Prevent media button receivers targeting activities"

parents 651e3327 fda5a94a
Loading
Loading
Loading
Loading
+18 −10
Original line number Diff line number Diff line
@@ -267,25 +267,33 @@ public final class MediaSession {
    }

    /**
     * Set a pending intent for your media button receiver to allow restarting
     * playback after the session has been stopped. If your app is started in
     * this way an {@link Intent#ACTION_MEDIA_BUTTON} intent will be sent via
     * the pending intent.
     * <p>
     * The pending intent is recommended to be explicit to follow the security recommendation of
     * {@link PendingIntent#getActivity}.
     * Set a pending intent for your media button receiver to allow restarting playback after the
     * session has been stopped.
     *
     * @param mbr The {@link PendingIntent} to send the media button event to.
     * @see PendingIntent#getActivity
     * <p>If your app is started in this way an {@link Intent#ACTION_MEDIA_BUTTON} intent will be
     * sent via the pending intent.
     *
     * <p>The provided {@link PendingIntent} must not target an activity. On apps targeting Android
     * V and above, passing an activity pending intent to this method causes an {@link
     * IllegalArgumentException}. On apps targeting Android U and below, passing an activity pending
     * intent causes the call to be ignored. Refer to this <a
     * href="https://developer.android.com/guide/components/activities/background-starts">guide</a>
     * for more information.
     *
     * <p>The pending intent is recommended to be explicit to follow the security recommendation of
     * {@link PendingIntent#getService}.
     *
     * @param mbr The {@link PendingIntent} to send the media button event to.
     * @deprecated Use {@link #setMediaButtonBroadcastReceiver(ComponentName)} instead.
     * @throws IllegalArgumentException if the pending intent targets an activity on apps targeting
     * Android V and above.
     */
    @Deprecated
    public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
        try {
            mBinder.setMediaButtonReceiver(mbr);
        } catch (RemoteException e) {
            Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
            e.rethrowFromSystemServer();
        }
    }

+24 −1
Original line number Diff line number Diff line
@@ -106,6 +106,16 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
    static final long THROW_FOR_INVALID_BROADCAST_RECEIVER = 270049379L;

    /**
     * {@link MediaSession#setMediaButtonReceiver(PendingIntent)} throws an {@link
     * IllegalArgumentException} if the provided {@link PendingIntent} targets an {@link
     * android.app.Activity activity} for apps targeting Android V and above. For apps targeting
     * Android U and below, the request will be ignored.
     */
    @ChangeId
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
    static final long THROW_FOR_ACTIVITY_MEDIA_BUTTON_RECEIVER = 272737196L;

    private static final String TAG = "MediaSessionRecord";
    private static final String[] ART_URIS = new String[] {
            MediaMetadata.METADATA_KEY_ALBUM_ART_URI,
@@ -1055,13 +1065,26 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
        }

        @Override
        public void setMediaButtonReceiver(PendingIntent pi) throws RemoteException {
        public void setMediaButtonReceiver(@Nullable PendingIntent pi) throws RemoteException {
            final int uid = Binder.getCallingUid();
            final long token = Binder.clearCallingIdentity();
            try {
                if ((mPolicies & MediaSessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER)
                        != 0) {
                    return;
                }

                if (pi != null && pi.isActivity()) {
                    if (CompatChanges.isChangeEnabled(
                            THROW_FOR_ACTIVITY_MEDIA_BUTTON_RECEIVER, uid)) {
                        throw new IllegalArgumentException(
                                "The media button receiver cannot be set to an activity.");
                    } else {
                        Log.w(TAG, "Ignoring invalid media button receiver targeting an activity.");
                        return;
                    }
                }

                mMediaButtonReceiverHolder =
                        MediaButtonReceiverHolder.create(mUserId, pi, mPackageName);
                mService.onMediaButtonReceiverChanged(MediaSessionRecord.this);