diff options
5 files changed, 43 insertions, 33 deletions
diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl index 9bf126b7a875..31fb8d03c4a0 100644 --- a/media/java/android/media/session/ISession.aidl +++ b/media/java/android/media/session/ISession.aidl @@ -35,7 +35,7 @@ interface ISession { ISessionController getController(); void setFlags(int flags); void setActive(boolean active); - void setMediaButtonReceiver(in PendingIntent mbr, String sessionPackageName); + void setMediaButtonReceiver(in PendingIntent mbr); void setMediaButtonBroadcastReceiver(in ComponentName broadcastReceiver); void setLaunchPendingIntent(in PendingIntent pi); void destroySession(); diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index 9e265d8339dd..1bd12afdc026 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -286,7 +286,7 @@ public final class MediaSession { @Deprecated public void setMediaButtonReceiver(@Nullable PendingIntent mbr) { try { - mBinder.setMediaButtonReceiver(mbr, mContext.getPackageName()); + mBinder.setMediaButtonReceiver(mbr); } catch (RemoteException e) { Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e); } diff --git a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java index b1e8b407d6e8..dcdb881df12b 100644 --- a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java +++ b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java @@ -18,6 +18,7 @@ package com.android.server.media; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.BroadcastOptions; import android.app.PendingIntent; import android.content.ComponentName; @@ -37,6 +38,7 @@ import android.view.KeyEvent; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Collections; import java.util.List; /** @@ -102,15 +104,19 @@ final class MediaButtonReceiverHolder { } /** - * Creates a new instance. + * Creates a new instance from a {@link PendingIntent}. + * + * <p>This method assumes the session package name has been validated and effectively belongs to + * the media session's owner. * - * @param context context * @param userId userId - * @param pendingIntent pending intent - * @return Can be {@code null} if pending intent was null. + * @param pendingIntent pending intent that will receive media button events + * @param sessionPackageName package name of media session owner + * @return {@link MediaButtonReceiverHolder} instance or {@code null} if pending intent was + * null. */ - public static MediaButtonReceiverHolder create(Context context, int userId, - PendingIntent pendingIntent, String sessionPackageName) { + public static MediaButtonReceiverHolder create( + int userId, @Nullable PendingIntent pendingIntent, String sessionPackageName) { if (pendingIntent == null) { return null; } @@ -315,7 +321,7 @@ final class MediaButtonReceiverHolder { } private static ComponentName getComponentName(PendingIntent pendingIntent, int componentType) { - List<ResolveInfo> resolveInfos = null; + List<ResolveInfo> resolveInfos = Collections.emptyList(); switch (componentType) { case COMPONENT_TYPE_ACTIVITY: resolveInfos = pendingIntent.queryIntentComponents( @@ -333,32 +339,37 @@ final class MediaButtonReceiverHolder { PACKAGE_MANAGER_COMMON_FLAGS | PackageManager.GET_RECEIVERS); break; } - if (resolveInfos != null && !resolveInfos.isEmpty()) { - return createComponentName(resolveInfos.get(0)); + + for (ResolveInfo resolveInfo : resolveInfos) { + ComponentInfo componentInfo = getComponentInfo(resolveInfo); + if (componentInfo != null && TextUtils.equals(componentInfo.packageName, + pendingIntent.getCreatorPackage()) + && componentInfo.packageName != null && componentInfo.name != null) { + return new ComponentName(componentInfo.packageName, componentInfo.name); + } } + return null; } - private static ComponentName createComponentName(ResolveInfo resolveInfo) { - if (resolveInfo == null) { - return null; - } - ComponentInfo componentInfo; + /** + * Retrieves the {@link ComponentInfo} from a {@link ResolveInfo} instance. Similar to {@link + * ResolveInfo#getComponentInfo()}, but returns {@code null} if this {@link ResolveInfo} points + * to a content provider. + * + * @param resolveInfo Where to extract the {@link ComponentInfo} from. + * @return Either a non-null {@link ResolveInfo#activityInfo} or {@link + * ResolveInfo#serviceInfo}. Otherwise {@code null} if {@link ResolveInfo#providerInfo} is + * not {@code null}. + */ + private static ComponentInfo getComponentInfo(@NonNull ResolveInfo resolveInfo) { // Code borrowed from ResolveInfo#getComponentInfo(). if (resolveInfo.activityInfo != null) { - componentInfo = resolveInfo.activityInfo; + return resolveInfo.activityInfo; } else if (resolveInfo.serviceInfo != null) { - componentInfo = resolveInfo.serviceInfo; + return resolveInfo.serviceInfo; } else { - // We're not interested in content provider. - return null; - } - // Code borrowed from ComponentInfo#getComponentName(). - try { - return new ComponentName(componentInfo.packageName, componentInfo.name); - } catch (IllegalArgumentException | NullPointerException e) { - // This may be happen if resolveActivity() end up with matching multiple activities. - // see PackageManager#resolveActivity(). + // We're not interested in content providers. return null; } } diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 28c7a39ef726..16155a01d73a 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -914,8 +914,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } @Override - public void setMediaButtonReceiver(PendingIntent pi, String sessionPackageName) - throws RemoteException { + public void setMediaButtonReceiver(PendingIntent pi) throws RemoteException { final long token = Binder.clearCallingIdentity(); try { if ((mPolicies & MediaSessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER) @@ -923,7 +922,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR return; } mMediaButtonReceiverHolder = - MediaButtonReceiverHolder.create(mContext, mUserId, pi, sessionPackageName); + MediaButtonReceiverHolder.create(mUserId, pi, mPackageName); mService.onMediaButtonReceiverChanged(MediaSessionRecord.this); } finally { Binder.restoreCallingIdentity(token); diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index b89147ea181a..d08150cf0a56 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -2285,9 +2285,9 @@ public class MediaSessionService extends SystemService implements Monitor { PendingIntent pi = mCustomMediaKeyDispatcher.getMediaButtonReceiver(keyEvent, uid, asSystemService); if (pi != null) { - mediaButtonReceiverHolder = MediaButtonReceiverHolder.create(mContext, - mCurrentFullUserRecord.mFullUserId, pi, - /* sessionPackageName= */ ""); + mediaButtonReceiverHolder = + MediaButtonReceiverHolder.create( + mCurrentFullUserRecord.mFullUserId, pi, ""); } } } |