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

Commit 6b780315 authored by John Wu's avatar John Wu
Browse files

Update ActivityIntentHelper to use PendingIntents directly

Use PendingIntent.queryIntentComponents to query components instead of
going through the intent contained. This allows package manager to
properly determine the identity to perform the intent resolution.

Bug: 238415222
Test: manual
Change-Id: I0dd32765755732a7a9141e3be2b04b7eed696928
parent 6110caff
Loading
Loading
Loading
Loading
+54 −7
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.systemui;
package com.android.systemui;


import android.app.PendingIntent;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo;
@@ -34,12 +35,12 @@ import javax.inject.Inject;
@SysUISingleton
@SysUISingleton
public class ActivityIntentHelper {
public class ActivityIntentHelper {


    private final Context mContext;
    private final PackageManager mPm;


    @Inject
    @Inject
    public ActivityIntentHelper(Context context) {
    public ActivityIntentHelper(Context context) {
        // TODO: inject a package manager, not a context.
        // TODO: inject a package manager, not a context.
        mContext = context;
        mPm = context.getPackageManager();
    }
    }


    /**
    /**
@@ -56,6 +57,15 @@ public class ActivityIntentHelper {
        return targetActivityInfo == null;
        return targetActivityInfo == null;
    }
    }


    /**
     * @see #wouldLaunchResolverActivity(Intent, int)
     */
    public boolean wouldPendingLaunchResolverActivity(PendingIntent intent, int currentUserId) {
        ActivityInfo targetActivityInfo = getPendingTargetActivityInfo(intent, currentUserId,
                false /* onlyDirectBootAware */);
        return targetActivityInfo == null;
    }

    /**
    /**
     * Returns info about the target Activity of a given intent, or null if the intent does not
     * Returns info about the target Activity of a given intent, or null if the intent does not
     * resolve to a specific component meeting the requirements.
     * resolve to a specific component meeting the requirements.
@@ -68,19 +78,45 @@ public class ActivityIntentHelper {
     */
     */
    public ActivityInfo getTargetActivityInfo(Intent intent, int currentUserId,
    public ActivityInfo getTargetActivityInfo(Intent intent, int currentUserId,
            boolean onlyDirectBootAware) {
            boolean onlyDirectBootAware) {
        PackageManager packageManager = mContext.getPackageManager();
        int flags = PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA;
        int flags = PackageManager.MATCH_DEFAULT_ONLY;
        if (!onlyDirectBootAware) {
        if (!onlyDirectBootAware) {
            flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE
            flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE
                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
        }
        }
        final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
        final List<ResolveInfo> appList = mPm.queryIntentActivitiesAsUser(
                intent, flags, currentUserId);
                intent, flags, currentUserId);
        if (appList.size() == 0) {
        if (appList.size() == 0) {
            return null;
            return null;
        }
        }
        ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
        if (appList.size() == 1) {
                flags | PackageManager.GET_META_DATA, currentUserId);
            return appList.get(0).activityInfo;
        }
        ResolveInfo resolved = mPm.resolveActivityAsUser(intent, flags, currentUserId);
        if (resolved == null || wouldLaunchResolverActivity(resolved, appList)) {
            return null;
        } else {
            return resolved.activityInfo;
        }
    }

    /**
     * @see #getTargetActivityInfo(Intent, int, boolean)
     */
    public ActivityInfo getPendingTargetActivityInfo(PendingIntent intent, int currentUserId,
            boolean onlyDirectBootAware) {
        int flags = PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA;
        if (!onlyDirectBootAware) {
            flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE
                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
        }
        final List<ResolveInfo> appList = intent.queryIntentComponents(flags);
        if (appList.size() == 0) {
            return null;
        }
        if (appList.size() == 1) {
            return appList.get(0).activityInfo;
        }
        ResolveInfo resolved = mPm.resolveActivityAsUser(intent.getIntent(), flags, currentUserId);
        if (resolved == null || wouldLaunchResolverActivity(resolved, appList)) {
        if (resolved == null || wouldLaunchResolverActivity(resolved, appList)) {
            return null;
            return null;
        } else {
        } else {
@@ -103,6 +139,17 @@ public class ActivityIntentHelper {
                | ActivityInfo.FLAG_SHOW_FOR_ALL_USERS)) > 0;
                | ActivityInfo.FLAG_SHOW_FOR_ALL_USERS)) > 0;
    }
    }


    /**
     * @see #wouldShowOverLockscreen(Intent, int)
     */
    public boolean wouldPendingShowOverLockscreen(PendingIntent intent, int currentUserId) {
        ActivityInfo targetActivityInfo = getPendingTargetActivityInfo(intent,
                currentUserId, false /* onlyDirectBootAware */);
        return targetActivityInfo != null
                && (targetActivityInfo.flags & (ActivityInfo.FLAG_SHOW_WHEN_LOCKED
                | ActivityInfo.FLAG_SHOW_FOR_ALL_USERS)) > 0;
    }

    /**
    /**
     * Determines if sending the given intent would result in starting an Intent resolver activity,
     * Determines if sending the given intent would result in starting an Intent resolver activity,
     * instead of resolving to a specific component.
     * instead of resolving to a specific component.
+1 −1
Original line number Original line Diff line number Diff line
@@ -4084,7 +4084,7 @@ public class CentralSurfacesImpl extends CoreStartable implements
            final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback,
            final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback,
            @Nullable ActivityLaunchAnimator.Controller animationController) {
            @Nullable ActivityLaunchAnimator.Controller animationController) {
        final boolean willLaunchResolverActivity = intent.isActivity()
        final boolean willLaunchResolverActivity = intent.isActivity()
                && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
                && mActivityIntentHelper.wouldPendingLaunchResolverActivity(intent,
                mLockscreenUserManager.getCurrentUserId());
                mLockscreenUserManager.getCurrentUserId());


        boolean animate = !willLaunchResolverActivity
        boolean animate = !willLaunchResolverActivity
+2 −2
Original line number Original line Diff line number Diff line
@@ -223,12 +223,12 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte


        boolean isActivityIntent = intent != null && intent.isActivity() && !isBubble;
        boolean isActivityIntent = intent != null && intent.isActivity() && !isBubble;
        final boolean willLaunchResolverActivity = isActivityIntent
        final boolean willLaunchResolverActivity = isActivityIntent
                && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
                && mActivityIntentHelper.wouldPendingLaunchResolverActivity(intent,
                mLockscreenUserManager.getCurrentUserId());
                mLockscreenUserManager.getCurrentUserId());
        final boolean animate = !willLaunchResolverActivity
        final boolean animate = !willLaunchResolverActivity
                && mCentralSurfaces.shouldAnimateLaunch(isActivityIntent);
                && mCentralSurfaces.shouldAnimateLaunch(isActivityIntent);
        boolean showOverLockscreen = mKeyguardStateController.isShowing() && intent != null
        boolean showOverLockscreen = mKeyguardStateController.isShowing() && intent != null
                && mActivityIntentHelper.wouldShowOverLockscreen(intent.getIntent(),
                && mActivityIntentHelper.wouldPendingShowOverLockscreen(intent,
                mLockscreenUserManager.getCurrentUserId());
                mLockscreenUserManager.getCurrentUserId());
        ActivityStarter.OnDismissAction postKeyguardAction = new ActivityStarter.OnDismissAction() {
        ActivityStarter.OnDismissAction postKeyguardAction = new ActivityStarter.OnDismissAction() {
            @Override
            @Override
+3 −2
Original line number Original line Diff line number Diff line
@@ -259,8 +259,9 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks,
        final boolean isActivity = pendingIntent.isActivity();
        final boolean isActivity = pendingIntent.isActivity();
        if (isActivity || appRequestedAuth) {
        if (isActivity || appRequestedAuth) {
            mActionClickLogger.logWaitingToCloseKeyguard(pendingIntent);
            mActionClickLogger.logWaitingToCloseKeyguard(pendingIntent);
            final boolean afterKeyguardGone = mActivityIntentHelper.wouldLaunchResolverActivity(
            final boolean afterKeyguardGone = mActivityIntentHelper
                    pendingIntent.getIntent(), mLockscreenUserManager.getCurrentUserId());
                    .wouldPendingLaunchResolverActivity(pendingIntent,
                            mLockscreenUserManager.getCurrentUserId());
            mActivityStarter.dismissKeyguardThenExecute(() -> {
            mActivityStarter.dismissKeyguardThenExecute(() -> {
                mActionClickLogger.logKeyguardGone(pendingIntent);
                mActionClickLogger.logKeyguardGone(pendingIntent);


+0 −5
Original line number Original line Diff line number Diff line
@@ -37,7 +37,6 @@ import android.app.KeyguardManager;
import android.app.Notification;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Handler;
import android.os.Handler;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserHandle;
@@ -135,8 +134,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
    @Mock
    @Mock
    private PendingIntent mContentIntent;
    private PendingIntent mContentIntent;
    @Mock
    @Mock
    private Intent mContentIntentInner;
    @Mock
    private OnUserInteractionCallback mOnUserInteractionCallback;
    private OnUserInteractionCallback mOnUserInteractionCallback;
    @Mock
    @Mock
    private Runnable mFutureDismissalRunnable;
    private Runnable mFutureDismissalRunnable;
@@ -159,7 +156,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
        MockitoAnnotations.initMocks(this);
        MockitoAnnotations.initMocks(this);
        when(mContentIntent.isActivity()).thenReturn(true);
        when(mContentIntent.isActivity()).thenReturn(true);
        when(mContentIntent.getCreatorUserHandle()).thenReturn(UserHandle.of(1));
        when(mContentIntent.getCreatorUserHandle()).thenReturn(UserHandle.of(1));
        when(mContentIntent.getIntent()).thenReturn(mContentIntentInner);


        NotificationTestHelper notificationTestHelper = new NotificationTestHelper(
        NotificationTestHelper notificationTestHelper = new NotificationTestHelper(
                mContext,
                mContext,
@@ -377,7 +373,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
                eq(entry.getKey()), any(NotificationVisibility.class));
                eq(entry.getKey()), any(NotificationVisibility.class));


        // The content intent should NOT be sent on click.
        // The content intent should NOT be sent on click.
        verify(mContentIntent).getIntent();
        verify(mContentIntent).isActivity();
        verify(mContentIntent).isActivity();
        verifyNoMoreInteractions(mContentIntent);
        verifyNoMoreInteractions(mContentIntent);