Prevent media button receivers targeting activities

This enforcement prevents a bypass of background activity launches. For
Android U, the enforcement just ignores the request and logs a warning.

This change is a backport of ag/23810567.

Test: Manually.
Bug: 272737196
Bug: 272024837
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:d455e21711c167223f7d0696809a4e411683182c)
Merged-In: I2412633c0b3afda6776244c72043d0dd78a4c8a1
Change-Id: I2412633c0b3afda6776244c72043d0dd78a4c8a1
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 29e8716..6121b88 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -267,17 +267,22 @@
     }
 
     /**
-     * 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.
+     *
+     * <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. Passing an activity
+     * pending intent will cause 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.
      * @see PendingIntent#getActivity
-     *
      * @deprecated Use {@link #setMediaButtonBroadcastReceiver(ComponentName)} instead.
      */
     @Deprecated
@@ -285,7 +290,7 @@
         try {
             mBinder.setMediaButtonReceiver(mbr);
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
+            e.rethrowFromSystemServer();
         }
     }
 
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 9185a00..4084462 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -1062,6 +1062,14 @@
                         != 0) {
                     return;
                 }
+
+                if (pi != null && pi.isActivity()) {
+                    Log.w(
+                            TAG,
+                            "Ignoring invalid media button receiver targeting an activity: " + pi);
+                    return;
+                }
+
                 mMediaButtonReceiverHolder =
                         MediaButtonReceiverHolder.create(mUserId, pi, mPackageName);
                 mService.onMediaButtonReceiverChanged(MediaSessionRecord.this);