Prevent media button receivers targeting activities
This enforcement prevents a bypass of background activity launches. Bug: 272737196 Test: atest MediaSessionHostTest MediaSessionTest (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:edf219ab08fdf5390aac6dd18fcdab76daa3488a) Change-Id: I07c2521f3d97f94e245a25bbb6f49f75cf54a808
This commit is contained in:
@@ -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.
|
||||
*
|
||||
* <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.
|
||||
* @see PendingIntent#getActivity
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user