Merge "Validate ComponentName for MediaButtonBroadcastReceiver" into sc-dev

This commit is contained in:
Iván Budnik
2023-05-26 10:55:01 +00:00
committed by Android (Google) Code Review
2 changed files with 38 additions and 3 deletions

View File

@@ -297,9 +297,11 @@ public final class MediaSession {
* class that should receive media buttons. This allows 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 to the broadcast receiver.
* <p>
* Note: The given {@link android.content.BroadcastReceiver} should belong to the same package
* as the context that was given when creating {@link MediaSession}.
*
* <p>Note: The given {@link android.content.BroadcastReceiver} should belong to the same
* package as the context that was given when creating {@link MediaSession}.
*
* <p>Calls with invalid or non-existent receivers will be ignored.
*
* @param broadcastReceiver the component name of the BroadcastReceiver class
*/

View File

@@ -16,12 +16,17 @@
package com.android.server.media;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.AudioSystem;
@@ -52,6 +57,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemClock;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
@@ -879,6 +885,22 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
}
};
@RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
private static boolean componentNameExists(
@NonNull ComponentName componentName, @NonNull Context context, int userId) {
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
mediaButtonIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
mediaButtonIntent.setComponent(componentName);
UserHandle userHandle = UserHandle.of(userId);
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfos =
pm.queryBroadcastReceiversAsUser(
mediaButtonIntent, /* flags */ 0, userHandle);
return !resolveInfos.isEmpty();
}
private final class SessionStub extends ISession.Stub {
@Override
public void destroySession() throws RemoteException {
@@ -949,6 +971,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
}
@Override
@RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
public void setMediaButtonBroadcastReceiver(ComponentName receiver) throws RemoteException {
final long token = Binder.clearCallingIdentity();
try {
@@ -964,6 +987,16 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
!= 0) {
return;
}
if (!componentNameExists(receiver, mContext, mUserId)) {
Log.w(
TAG,
"setMediaButtonBroadcastReceiver(): "
+ "Ignoring invalid component name="
+ receiver);
return;
}
mMediaButtonReceiverHolder = MediaButtonReceiverHolder.create(mUserId, receiver);
mService.onMediaButtonReceiverChanged(MediaSessionRecord.this);
} finally {