Loading media/java/android/media/session/ISession.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ interface ISession { ISessionController getController(); void setFlags(int flags); void setActive(boolean active); void setMediaButtonReceiver(in PendingIntent mbr); void setMediaButtonReceiver(in PendingIntent mbr, String sessionPackageName); void setMediaButtonBroadcastReceiver(in ComponentName broadcastReceiver); void setLaunchPendingIntent(in PendingIntent pi); void destroySession(); Loading media/java/android/media/session/MediaSession.java +1 −1 Original line number Diff line number Diff line Loading @@ -286,7 +286,7 @@ public final class MediaSession { @Deprecated public void setMediaButtonReceiver(@Nullable PendingIntent mbr) { try { mBinder.setMediaButtonReceiver(mbr); mBinder.setMediaButtonReceiver(mbr, mContext.getPackageName()); } catch (RemoteException e) { Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e); } Loading services/core/java/com/android/server/media/MediaButtonReceiverHolder.java +47 −65 Original line number Diff line number Diff line Loading @@ -58,6 +58,9 @@ final class MediaButtonReceiverHolder { private static final String TAG = "PendingIntentHolder"; private static final boolean DEBUG_KEY_EVENT = MediaSessionService.DEBUG_KEY_EVENT; private static final String COMPONENT_NAME_USER_ID_DELIM = ","; // Filter apps regardless of the phone's locked/unlocked state. private static final int PACKAGE_MANAGER_COMMON_FLAGS = PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE; private final int mUserId; private final PendingIntent mPendingIntent; Loading Loading @@ -105,40 +108,22 @@ final class MediaButtonReceiverHolder { * @return Can be {@code null} if pending intent was null. */ public static MediaButtonReceiverHolder create(Context context, int userId, PendingIntent pendingIntent) { PendingIntent pendingIntent, String sessionPackageName) { if (pendingIntent == null) { return null; } ComponentName componentName = (pendingIntent != null && pendingIntent.getIntent() != null) ? pendingIntent.getIntent().getComponent() : null; int componentType = getComponentType(pendingIntent); ComponentName componentName = getComponentName(pendingIntent, componentType); if (componentName != null) { // Explicit intent, where component name is in the PendingIntent. return new MediaButtonReceiverHolder(userId, pendingIntent, componentName, getComponentType(context, componentName)); } // Implicit intent, where component name isn't in the PendingIntent. Try resolve. PackageManager pm = context.getPackageManager(); Intent intent = pendingIntent.getIntent(); if ((componentName = resolveImplicitServiceIntent(pm, intent)) != null) { return new MediaButtonReceiverHolder( userId, pendingIntent, componentName, COMPONENT_TYPE_SERVICE); } else if ((componentName = resolveManifestDeclaredBroadcastReceiverIntent(pm, intent)) != null) { return new MediaButtonReceiverHolder( userId, pendingIntent, componentName, COMPONENT_TYPE_BROADCAST); } else if ((componentName = resolveImplicitActivityIntent(pm, intent)) != null) { return new MediaButtonReceiverHolder( userId, pendingIntent, componentName, COMPONENT_TYPE_ACTIVITY); componentType); } // Failed to resolve target component for the pending intent. It's unlikely to be usable. // However, the pending intent would be still used, just to follow the legacy behavior. // However, the pending intent would be still used, so setting the package name to the // package name of the session that set this pending intent. Log.w(TAG, "Unresolvable implicit intent is set, pi=" + pendingIntent); String packageName = (pendingIntent != null && pendingIntent.getIntent() != null) ? pendingIntent.getIntent().getPackage() : null; return new MediaButtonReceiverHolder(userId, pendingIntent, packageName != null ? packageName : ""); return new MediaButtonReceiverHolder(userId, pendingIntent, sessionPackageName); } public static MediaButtonReceiverHolder create(int userId, ComponentName broadcastReceiver) { Loading Loading @@ -269,6 +254,18 @@ final class MediaButtonReceiverHolder { String.valueOf(mComponentType)); } @ComponentType private static int getComponentType(PendingIntent pendingIntent) { if (pendingIntent.isBroadcast()) { return COMPONENT_TYPE_BROADCAST; } else if (pendingIntent.isActivity()) { return COMPONENT_TYPE_ACTIVITY; } else if (pendingIntent.isForegroundService() || pendingIntent.isService()) { return COMPONENT_TYPE_SERVICE; } return COMPONENT_TYPE_INVALID; } /** * Gets the type of the component * Loading @@ -284,9 +281,7 @@ final class MediaButtonReceiverHolder { PackageManager pm = context.getPackageManager(); try { ActivityInfo activityInfo = pm.getActivityInfo(componentName, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.GET_ACTIVITIES); PACKAGE_MANAGER_COMMON_FLAGS | PackageManager.GET_ACTIVITIES); if (activityInfo != null) { return COMPONENT_TYPE_ACTIVITY; } Loading @@ -294,9 +289,7 @@ final class MediaButtonReceiverHolder { } try { ServiceInfo serviceInfo = pm.getServiceInfo(componentName, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.GET_SERVICES); PACKAGE_MANAGER_COMMON_FLAGS | PackageManager.GET_SERVICES); if (serviceInfo != null) { return COMPONENT_TYPE_SERVICE; } Loading @@ -306,40 +299,29 @@ final class MediaButtonReceiverHolder { return COMPONENT_TYPE_BROADCAST; } private static ComponentName resolveImplicitServiceIntent(PackageManager pm, Intent intent) { // Flag explanations. // - MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE: // filter apps regardless of the phone's locked/unlocked state. // - GET_SERVICES: Return service return createComponentName(pm.resolveService(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.GET_SERVICES)); private static ComponentName getComponentName(PendingIntent pendingIntent, int componentType) { List<ResolveInfo> resolveInfos = null; switch (componentType) { case COMPONENT_TYPE_ACTIVITY: resolveInfos = pendingIntent.queryIntentComponents( PACKAGE_MANAGER_COMMON_FLAGS | PackageManager.MATCH_DEFAULT_ONLY /* Implicit intent receiver should be set as default. Only needed for activity. */ | PackageManager.GET_ACTIVITIES); break; case COMPONENT_TYPE_SERVICE: resolveInfos = pendingIntent.queryIntentComponents( PACKAGE_MANAGER_COMMON_FLAGS | PackageManager.GET_SERVICES); break; case COMPONENT_TYPE_BROADCAST: resolveInfos = pendingIntent.queryIntentComponents( PACKAGE_MANAGER_COMMON_FLAGS | PackageManager.GET_RECEIVERS); break; } private static ComponentName resolveManifestDeclaredBroadcastReceiverIntent( PackageManager pm, Intent intent) { // Flag explanations. // - MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE: // filter apps regardless of the phone's locked/unlocked state. List<ResolveInfo> resolveInfos = pm.queryBroadcastReceivers(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); return (resolveInfos != null && !resolveInfos.isEmpty()) ? createComponentName(resolveInfos.get(0)) : null; if (resolveInfos != null && !resolveInfos.isEmpty()) { return createComponentName(resolveInfos.get(0)); } private static ComponentName resolveImplicitActivityIntent(PackageManager pm, Intent intent) { // Flag explanations. // - MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE: // Filter apps regardless of the phone's locked/unlocked state. // - MATCH_DEFAULT_ONLY: // Implicit intent receiver should be set as default. Only needed for activity. // - GET_ACTIVITIES: Return activity return createComponentName(pm.resolveActivity(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_ACTIVITIES)); return null; } private static ComponentName createComponentName(ResolveInfo resolveInfo) { Loading services/core/java/com/android/server/media/MediaKeyDispatcher.java +5 −2 Original line number Diff line number Diff line Loading @@ -100,9 +100,12 @@ public abstract class MediaKeyDispatcher { /** * Implement this to customize the logic for which MediaButtonReceiver should consume a * dispatched key event. * * Note: This pending intent will have lower priority over the {@link MediaSession.Token} * <p> * This pending intent will have lower priority over the {@link MediaSession.Token} * returned from {@link #getMediaSession(KeyEvent, int, boolean)}. * <p> * Use a pending intent with an explicit intent; setting a pending intent with an implicit * intent that cannot be resolved to a certain component name will fail. * * @return a {@link PendingIntent} instance that should receive the dispatched key event. */ Loading services/core/java/com/android/server/media/MediaSessionRecord.java +3 −2 Original line number Diff line number Diff line Loading @@ -843,7 +843,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } @Override public void setMediaButtonReceiver(PendingIntent pi) throws RemoteException { public void setMediaButtonReceiver(PendingIntent pi, String sessionPackageName) throws RemoteException { final long token = Binder.clearCallingIdentity(); try { if ((mPolicies & SessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER) Loading @@ -851,7 +852,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR return; } mMediaButtonReceiverHolder = MediaButtonReceiverHolder.create(mContext, mUserId, pi); MediaButtonReceiverHolder.create(mContext, mUserId, pi, sessionPackageName); mService.onMediaButtonReceiverChanged(MediaSessionRecord.this); } finally { Binder.restoreCallingIdentity(token); Loading Loading
media/java/android/media/session/ISession.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ interface ISession { ISessionController getController(); void setFlags(int flags); void setActive(boolean active); void setMediaButtonReceiver(in PendingIntent mbr); void setMediaButtonReceiver(in PendingIntent mbr, String sessionPackageName); void setMediaButtonBroadcastReceiver(in ComponentName broadcastReceiver); void setLaunchPendingIntent(in PendingIntent pi); void destroySession(); Loading
media/java/android/media/session/MediaSession.java +1 −1 Original line number Diff line number Diff line Loading @@ -286,7 +286,7 @@ public final class MediaSession { @Deprecated public void setMediaButtonReceiver(@Nullable PendingIntent mbr) { try { mBinder.setMediaButtonReceiver(mbr); mBinder.setMediaButtonReceiver(mbr, mContext.getPackageName()); } catch (RemoteException e) { Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e); } Loading
services/core/java/com/android/server/media/MediaButtonReceiverHolder.java +47 −65 Original line number Diff line number Diff line Loading @@ -58,6 +58,9 @@ final class MediaButtonReceiverHolder { private static final String TAG = "PendingIntentHolder"; private static final boolean DEBUG_KEY_EVENT = MediaSessionService.DEBUG_KEY_EVENT; private static final String COMPONENT_NAME_USER_ID_DELIM = ","; // Filter apps regardless of the phone's locked/unlocked state. private static final int PACKAGE_MANAGER_COMMON_FLAGS = PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE; private final int mUserId; private final PendingIntent mPendingIntent; Loading Loading @@ -105,40 +108,22 @@ final class MediaButtonReceiverHolder { * @return Can be {@code null} if pending intent was null. */ public static MediaButtonReceiverHolder create(Context context, int userId, PendingIntent pendingIntent) { PendingIntent pendingIntent, String sessionPackageName) { if (pendingIntent == null) { return null; } ComponentName componentName = (pendingIntent != null && pendingIntent.getIntent() != null) ? pendingIntent.getIntent().getComponent() : null; int componentType = getComponentType(pendingIntent); ComponentName componentName = getComponentName(pendingIntent, componentType); if (componentName != null) { // Explicit intent, where component name is in the PendingIntent. return new MediaButtonReceiverHolder(userId, pendingIntent, componentName, getComponentType(context, componentName)); } // Implicit intent, where component name isn't in the PendingIntent. Try resolve. PackageManager pm = context.getPackageManager(); Intent intent = pendingIntent.getIntent(); if ((componentName = resolveImplicitServiceIntent(pm, intent)) != null) { return new MediaButtonReceiverHolder( userId, pendingIntent, componentName, COMPONENT_TYPE_SERVICE); } else if ((componentName = resolveManifestDeclaredBroadcastReceiverIntent(pm, intent)) != null) { return new MediaButtonReceiverHolder( userId, pendingIntent, componentName, COMPONENT_TYPE_BROADCAST); } else if ((componentName = resolveImplicitActivityIntent(pm, intent)) != null) { return new MediaButtonReceiverHolder( userId, pendingIntent, componentName, COMPONENT_TYPE_ACTIVITY); componentType); } // Failed to resolve target component for the pending intent. It's unlikely to be usable. // However, the pending intent would be still used, just to follow the legacy behavior. // However, the pending intent would be still used, so setting the package name to the // package name of the session that set this pending intent. Log.w(TAG, "Unresolvable implicit intent is set, pi=" + pendingIntent); String packageName = (pendingIntent != null && pendingIntent.getIntent() != null) ? pendingIntent.getIntent().getPackage() : null; return new MediaButtonReceiverHolder(userId, pendingIntent, packageName != null ? packageName : ""); return new MediaButtonReceiverHolder(userId, pendingIntent, sessionPackageName); } public static MediaButtonReceiverHolder create(int userId, ComponentName broadcastReceiver) { Loading Loading @@ -269,6 +254,18 @@ final class MediaButtonReceiverHolder { String.valueOf(mComponentType)); } @ComponentType private static int getComponentType(PendingIntent pendingIntent) { if (pendingIntent.isBroadcast()) { return COMPONENT_TYPE_BROADCAST; } else if (pendingIntent.isActivity()) { return COMPONENT_TYPE_ACTIVITY; } else if (pendingIntent.isForegroundService() || pendingIntent.isService()) { return COMPONENT_TYPE_SERVICE; } return COMPONENT_TYPE_INVALID; } /** * Gets the type of the component * Loading @@ -284,9 +281,7 @@ final class MediaButtonReceiverHolder { PackageManager pm = context.getPackageManager(); try { ActivityInfo activityInfo = pm.getActivityInfo(componentName, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.GET_ACTIVITIES); PACKAGE_MANAGER_COMMON_FLAGS | PackageManager.GET_ACTIVITIES); if (activityInfo != null) { return COMPONENT_TYPE_ACTIVITY; } Loading @@ -294,9 +289,7 @@ final class MediaButtonReceiverHolder { } try { ServiceInfo serviceInfo = pm.getServiceInfo(componentName, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.GET_SERVICES); PACKAGE_MANAGER_COMMON_FLAGS | PackageManager.GET_SERVICES); if (serviceInfo != null) { return COMPONENT_TYPE_SERVICE; } Loading @@ -306,40 +299,29 @@ final class MediaButtonReceiverHolder { return COMPONENT_TYPE_BROADCAST; } private static ComponentName resolveImplicitServiceIntent(PackageManager pm, Intent intent) { // Flag explanations. // - MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE: // filter apps regardless of the phone's locked/unlocked state. // - GET_SERVICES: Return service return createComponentName(pm.resolveService(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.GET_SERVICES)); private static ComponentName getComponentName(PendingIntent pendingIntent, int componentType) { List<ResolveInfo> resolveInfos = null; switch (componentType) { case COMPONENT_TYPE_ACTIVITY: resolveInfos = pendingIntent.queryIntentComponents( PACKAGE_MANAGER_COMMON_FLAGS | PackageManager.MATCH_DEFAULT_ONLY /* Implicit intent receiver should be set as default. Only needed for activity. */ | PackageManager.GET_ACTIVITIES); break; case COMPONENT_TYPE_SERVICE: resolveInfos = pendingIntent.queryIntentComponents( PACKAGE_MANAGER_COMMON_FLAGS | PackageManager.GET_SERVICES); break; case COMPONENT_TYPE_BROADCAST: resolveInfos = pendingIntent.queryIntentComponents( PACKAGE_MANAGER_COMMON_FLAGS | PackageManager.GET_RECEIVERS); break; } private static ComponentName resolveManifestDeclaredBroadcastReceiverIntent( PackageManager pm, Intent intent) { // Flag explanations. // - MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE: // filter apps regardless of the phone's locked/unlocked state. List<ResolveInfo> resolveInfos = pm.queryBroadcastReceivers(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); return (resolveInfos != null && !resolveInfos.isEmpty()) ? createComponentName(resolveInfos.get(0)) : null; if (resolveInfos != null && !resolveInfos.isEmpty()) { return createComponentName(resolveInfos.get(0)); } private static ComponentName resolveImplicitActivityIntent(PackageManager pm, Intent intent) { // Flag explanations. // - MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE: // Filter apps regardless of the phone's locked/unlocked state. // - MATCH_DEFAULT_ONLY: // Implicit intent receiver should be set as default. Only needed for activity. // - GET_ACTIVITIES: Return activity return createComponentName(pm.resolveActivity(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_ACTIVITIES)); return null; } private static ComponentName createComponentName(ResolveInfo resolveInfo) { Loading
services/core/java/com/android/server/media/MediaKeyDispatcher.java +5 −2 Original line number Diff line number Diff line Loading @@ -100,9 +100,12 @@ public abstract class MediaKeyDispatcher { /** * Implement this to customize the logic for which MediaButtonReceiver should consume a * dispatched key event. * * Note: This pending intent will have lower priority over the {@link MediaSession.Token} * <p> * This pending intent will have lower priority over the {@link MediaSession.Token} * returned from {@link #getMediaSession(KeyEvent, int, boolean)}. * <p> * Use a pending intent with an explicit intent; setting a pending intent with an implicit * intent that cannot be resolved to a certain component name will fail. * * @return a {@link PendingIntent} instance that should receive the dispatched key event. */ Loading
services/core/java/com/android/server/media/MediaSessionRecord.java +3 −2 Original line number Diff line number Diff line Loading @@ -843,7 +843,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } @Override public void setMediaButtonReceiver(PendingIntent pi) throws RemoteException { public void setMediaButtonReceiver(PendingIntent pi, String sessionPackageName) throws RemoteException { final long token = Binder.clearCallingIdentity(); try { if ((mPolicies & SessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER) Loading @@ -851,7 +852,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR return; } mMediaButtonReceiverHolder = MediaButtonReceiverHolder.create(mContext, mUserId, pi); MediaButtonReceiverHolder.create(mContext, mUserId, pi, sessionPackageName); mService.onMediaButtonReceiverChanged(MediaSessionRecord.this); } finally { Binder.restoreCallingIdentity(token); Loading