Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c55f7459 authored by Jin Seok Park's avatar Jin Seok Park Committed by Android (Google) Code Review
Browse files

Merge "[Media ML] Replace using PendingIntent hidden APIs" into sc-dev

parents c8227c58 b2fcacab
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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();
+1 −1
Original line number Diff line number Diff line
@@ -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);
        }
+47 −65
Original line number Diff line number Diff line
@@ -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;
@@ -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) {
@@ -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
     *
@@ -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;
            }
@@ -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;
            }
@@ -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) {
+5 −2
Original line number Diff line number Diff line
@@ -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.
     */
+3 −2
Original line number Diff line number Diff line
@@ -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)
@@ -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