Merge "Validate ComponentName for MediaButtonBroadcastReceiver" into sc-dev
This commit is contained in:
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user