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 Bug: 271845008 Test: manual Change-Id: I0dd32765755732a7a9141e3be2b04b7eed696928 Merged-In: I0dd32765755732a7a9141e3be2b04b7eed696928
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
@@ -4117,7 +4117,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
|
||||||
|
|||||||
@@ -253,12 +253,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
|
||||||
|
|||||||
@@ -258,8 +258,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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -137,8 +136,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;
|
||||||
@@ -163,7 +160,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);
|
|
||||||
|
|
||||||
mNotificationTestHelper = new NotificationTestHelper(
|
mNotificationTestHelper = new NotificationTestHelper(
|
||||||
mContext,
|
mContext,
|
||||||
@@ -387,7 +383,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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user