Merge "Add hidden flag in ActivityOptions to ignore PendingIntent creator foreground state" into tm-dev

This commit is contained in:
Ricky Wai
2022-04-08 11:13:22 +00:00
committed by Android (Google) Code Review
4 changed files with 109 additions and 60 deletions

View File

@@ -365,6 +365,9 @@ public class ActivityOptions extends ComponentOptions {
private static final String KEY_DISMISS_KEYGUARD_IF_INSECURE = private static final String KEY_DISMISS_KEYGUARD_IF_INSECURE =
"android.activity.dismissKeyguardIfInsecure"; "android.activity.dismissKeyguardIfInsecure";
private static final String KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE =
"android.activity.ignorePendingIntentCreatorForegroundState";
/** /**
* @see #setLaunchCookie * @see #setLaunchCookie
* @hide * @hide
@@ -462,6 +465,7 @@ public class ActivityOptions extends ComponentOptions {
private boolean mTransientLaunch; private boolean mTransientLaunch;
private PictureInPictureParams mLaunchIntoPipParams; private PictureInPictureParams mLaunchIntoPipParams;
private boolean mDismissKeyguardIfInsecure; private boolean mDismissKeyguardIfInsecure;
private boolean mIgnorePendingIntentCreatorForegroundState;
/** /**
* Create an ActivityOptions specifying a custom animation to run when * Create an ActivityOptions specifying a custom animation to run when
@@ -1260,6 +1264,8 @@ public class ActivityOptions extends ComponentOptions {
mIsEligibleForLegacyPermissionPrompt = mIsEligibleForLegacyPermissionPrompt =
opts.getBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE); opts.getBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE);
mDismissKeyguardIfInsecure = opts.getBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE); mDismissKeyguardIfInsecure = opts.getBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE);
mIgnorePendingIntentCreatorForegroundState = opts.getBoolean(
KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE);
} }
/** /**
@@ -1876,6 +1882,23 @@ public class ActivityOptions extends ComponentOptions {
return mDismissKeyguardIfInsecure; return mDismissKeyguardIfInsecure;
} }
/**
* Sets background activity launch logic won't use pending intent creator foreground state.
* @hide
*/
public void setIgnorePendingIntentCreatorForegroundState(boolean state) {
mIgnorePendingIntentCreatorForegroundState = state;
}
/**
* @return whether background activity launch logic should use pending intent creator
* foreground state.
* @hide
*/
public boolean getIgnorePendingIntentCreatorForegroundState() {
return mIgnorePendingIntentCreatorForegroundState;
}
/** /**
* Update the current values in this ActivityOptions from those supplied * Update the current values in this ActivityOptions from those supplied
* in <var>otherOptions</var>. Any values * in <var>otherOptions</var>. Any values
@@ -2140,6 +2163,10 @@ public class ActivityOptions extends ComponentOptions {
if (mDismissKeyguardIfInsecure) { if (mDismissKeyguardIfInsecure) {
b.putBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE, mDismissKeyguardIfInsecure); b.putBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE, mDismissKeyguardIfInsecure);
} }
if (mIgnorePendingIntentCreatorForegroundState) {
b.putBoolean(KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE,
mIgnorePendingIntentCreatorForegroundState);
}
return b; return b;
} }

View File

@@ -26,6 +26,7 @@ import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import android.annotation.UserIdInt; import android.annotation.UserIdInt;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityManagerInternal; import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.AlarmManager; import android.app.AlarmManager;
import android.app.AppGlobals; import android.app.AppGlobals;
import android.app.AppOpsManager; import android.app.AppOpsManager;
@@ -970,13 +971,16 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
intent.setComponent(provider.getInfoLocked(mContext).configure); intent.setComponent(provider.getInfoLocked(mContext).configure);
intent.setFlags(secureFlags); intent.setFlags(secureFlags);
final ActivityOptions options = ActivityOptions.makeBasic();
options.setIgnorePendingIntentCreatorForegroundState(true);
// All right, create the sender. // All right, create the sender.
final long identity = Binder.clearCallingIdentity(); final long identity = Binder.clearCallingIdentity();
try { try {
return PendingIntent.getActivityAsUser( return PendingIntent.getActivityAsUser(
mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT
| PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT, | PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT,
null, new UserHandle(provider.getUserId())) options.toBundle(), new UserHandle(provider.getUserId()))
.getIntentSender(); .getIntentSender();
} finally { } finally {
Binder.restoreCallingIdentity(identity); Binder.restoreCallingIdentity(identity);

View File

@@ -55,6 +55,7 @@ import android.annotation.Nullable;
import android.annotation.UserIdInt; import android.annotation.UserIdInt;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityManagerInternal; import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.AnrController; import android.app.AnrController;
import android.app.AppOpsManager; import android.app.AppOpsManager;
import android.app.IActivityManager; import android.app.IActivityManager;
@@ -3534,9 +3535,12 @@ class StorageManagerService extends IStorageManager.Stub
appInfo.manageSpaceActivityName); appInfo.manageSpaceActivityName);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK); intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
final ActivityOptions options = ActivityOptions.makeBasic();
options.setIgnorePendingIntentCreatorForegroundState(true);
PendingIntent activity = PendingIntent.getActivity(targetAppContext, requestCode, PendingIntent activity = PendingIntent.getActivity(targetAppContext, requestCode,
intent, intent,
FLAG_ONE_SHOT | FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE); FLAG_ONE_SHOT | FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE, options.toBundle());
return activity; return activity;
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
throw new IllegalArgumentException( throw new IllegalArgumentException(

View File

@@ -1268,29 +1268,36 @@ class ActivityStarter {
boolean allowBackgroundActivityStart, Intent intent, ActivityOptions checkedOptions) { boolean allowBackgroundActivityStart, Intent intent, ActivityOptions checkedOptions) {
// don't abort for the most important UIDs // don't abort for the most important UIDs
final int callingAppId = UserHandle.getAppId(callingUid); final int callingAppId = UserHandle.getAppId(callingUid);
if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID final boolean useCallingUidState =
|| callingAppId == Process.NFC_UID) { originatingPendingIntent == null || checkedOptions == null
if (DEBUG_ACTIVITY_STARTS) { || !checkedOptions.getIgnorePendingIntentCreatorForegroundState();
Slog.d(TAG, "Activity start allowed for important callingUid (" + callingUid + ")"); if (useCallingUidState) {
if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID
|| callingAppId == Process.NFC_UID) {
if (DEBUG_ACTIVITY_STARTS) {
Slog.d(TAG,
"Activity start allowed for important callingUid (" + callingUid + ")");
}
return false;
} }
return false;
}
// Always allow home application to start activities. // Always allow home application to start activities.
if (isHomeApp(callingUid, callingPackage)) { if (isHomeApp(callingUid, callingPackage)) {
if (DEBUG_ACTIVITY_STARTS) { if (DEBUG_ACTIVITY_STARTS) {
Slog.d(TAG, "Activity start allowed for home app callingUid (" + callingUid + ")"); Slog.d(TAG,
"Activity start allowed for home app callingUid (" + callingUid + ")");
}
return false;
} }
return false;
}
// IME should always be allowed to start activity, like IME settings. // IME should always be allowed to start activity, like IME settings.
final WindowState imeWindow = mRootWindowContainer.getCurrentInputMethodWindow(); final WindowState imeWindow = mRootWindowContainer.getCurrentInputMethodWindow();
if (imeWindow != null && callingAppId == imeWindow.mOwnerUid) { if (imeWindow != null && callingAppId == imeWindow.mOwnerUid) {
if (DEBUG_ACTIVITY_STARTS) { if (DEBUG_ACTIVITY_STARTS) {
Slog.d(TAG, "Activity start allowed for active ime (" + callingUid + ")"); Slog.d(TAG, "Activity start allowed for active ime (" + callingUid + ")");
}
return false;
} }
return false;
} }
// This is used to block background activity launch even if the app is still // This is used to block background activity launch even if the app is still
@@ -1310,9 +1317,11 @@ class ActivityStarter {
// is allowed, or apps like live wallpaper with non app visible window will be allowed. // is allowed, or apps like live wallpaper with non app visible window will be allowed.
final boolean appSwitchAllowedOrFg = final boolean appSwitchAllowedOrFg =
appSwitchState == APP_SWITCH_ALLOW || appSwitchState == APP_SWITCH_FG_ONLY; appSwitchState == APP_SWITCH_ALLOW || appSwitchState == APP_SWITCH_FG_ONLY;
if (((appSwitchAllowedOrFg || mService.mActiveUids.hasNonAppVisibleWindow(callingUid)) final boolean allowCallingUidStartActivity =
((appSwitchAllowedOrFg || mService.mActiveUids.hasNonAppVisibleWindow(callingUid))
&& callingUidHasAnyVisibleWindow) && callingUidHasAnyVisibleWindow)
|| isCallingUidPersistentSystemProcess) { || isCallingUidPersistentSystemProcess;
if (useCallingUidState && allowCallingUidStartActivity) {
if (DEBUG_ACTIVITY_STARTS) { if (DEBUG_ACTIVITY_STARTS) {
Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid
+ ", isCallingUidPersistentSystemProcess = " + ", isCallingUidPersistentSystemProcess = "
@@ -1400,47 +1409,52 @@ class ActivityStarter {
return false; return false;
} }
} }
// don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission if (useCallingUidState) {
if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid) // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
== PERMISSION_GRANTED) { if (mService.checkPermission(
if (DEBUG_ACTIVITY_STARTS) { START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
Slog.d(TAG, == PERMISSION_GRANTED) {
"Background activity start allowed: START_ACTIVITIES_FROM_BACKGROUND " if (DEBUG_ACTIVITY_STARTS) {
+ "permission granted for uid " Slog.d(TAG,
+ callingUid); "Background activity start allowed: START_ACTIVITIES_FROM_BACKGROUND "
+ "permission granted for uid "
+ callingUid);
}
return false;
} }
return false; // don't abort if the caller has the same uid as the recents component
} if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
// don't abort if the caller has the same uid as the recents component if (DEBUG_ACTIVITY_STARTS) {
if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) { Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
if (DEBUG_ACTIVITY_STARTS) { + ") is recents");
Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid }
+ ") is recents"); return false;
} }
return false; // don't abort if the callingUid is the device owner
} if (mService.isDeviceOwner(callingUid)) {
// don't abort if the callingUid is the device owner if (DEBUG_ACTIVITY_STARTS) {
if (mService.isDeviceOwner(callingUid)) { Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
if (DEBUG_ACTIVITY_STARTS) { + ") is device owner");
Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid }
+ ") is device owner"); return false;
} }
return false; // don't abort if the callingUid has companion device
} final int callingUserId = UserHandle.getUserId(callingUid);
// don't abort if the callingUid has companion device if (mService.isAssociatedCompanionApp(callingUserId,
final int callingUserId = UserHandle.getUserId(callingUid); callingUid)) {
if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) { if (DEBUG_ACTIVITY_STARTS) {
if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid + ") is companion app");
+ ") is companion app"); }
return false;
}
// don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
if (mService.hasSystemAlertWindowPermission(callingUid,
callingPid, callingPackage)) {
Slog.w(TAG, "Background activity start for " + callingPackage
+ " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
return false;
} }
return false;
}
// don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
if (mService.hasSystemAlertWindowPermission(callingUid, callingPid, callingPackage)) {
Slog.w(TAG, "Background activity start for " + callingPackage
+ " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
return false;
} }
// If we don't have callerApp at this point, no caller was provided to startActivity(). // If we don't have callerApp at this point, no caller was provided to startActivity().
// That's the case for PendingIntent-based starts, since the creator's process might not be // That's the case for PendingIntent-based starts, since the creator's process might not be
@@ -1452,7 +1466,7 @@ class ActivityStarter {
callerAppUid = realCallingUid; callerAppUid = realCallingUid;
} }
// don't abort if the callerApp or other processes of that uid are allowed in any way // don't abort if the callerApp or other processes of that uid are allowed in any way
if (callerApp != null) { if (callerApp != null && useCallingUidState) {
// first check the original calling process // first check the original calling process
if (callerApp.areBackgroundActivityStartsAllowed(appSwitchState)) { if (callerApp.areBackgroundActivityStartsAllowed(appSwitchState)) {
if (DEBUG_ACTIVITY_STARTS) { if (DEBUG_ACTIVITY_STARTS) {