diff options
| author | 2022-04-08 11:13:22 +0000 | |
|---|---|---|
| committer | 2022-04-08 11:13:22 +0000 | |
| commit | 417df3f1e983382bd9f7b33ee9def3da106d27aa (patch) | |
| tree | b3d2d6dfb19bdeb7bce5cff12793d082b24b5e4a | |
| parent | 52f1d5eca6595be7d8c8ef8353d85562f119074d (diff) | |
| parent | b8a05514f70c0ef8b7d221fa26b7ee8563c0ab08 (diff) | |
Merge "Add hidden flag in ActivityOptions to ignore PendingIntent creator foreground state" into tm-dev
4 files changed, 109 insertions, 60 deletions
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 0f54ce5f7a91..709272ce0e26 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -365,6 +365,9 @@ public class ActivityOptions extends ComponentOptions { private static final String KEY_DISMISS_KEYGUARD_IF_INSECURE = "android.activity.dismissKeyguardIfInsecure"; + private static final String KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE = + "android.activity.ignorePendingIntentCreatorForegroundState"; + /** * @see #setLaunchCookie * @hide @@ -462,6 +465,7 @@ public class ActivityOptions extends ComponentOptions { private boolean mTransientLaunch; private PictureInPictureParams mLaunchIntoPipParams; private boolean mDismissKeyguardIfInsecure; + private boolean mIgnorePendingIntentCreatorForegroundState; /** * Create an ActivityOptions specifying a custom animation to run when @@ -1260,6 +1264,8 @@ public class ActivityOptions extends ComponentOptions { mIsEligibleForLegacyPermissionPrompt = opts.getBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE); mDismissKeyguardIfInsecure = opts.getBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE); + mIgnorePendingIntentCreatorForegroundState = opts.getBoolean( + KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE); } /** @@ -1877,6 +1883,23 @@ public class ActivityOptions extends ComponentOptions { } /** + * 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 * in <var>otherOptions</var>. Any values * defined in <var>otherOptions</var> replace those in the base options. @@ -2140,6 +2163,10 @@ public class ActivityOptions extends ComponentOptions { if (mDismissKeyguardIfInsecure) { b.putBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE, mDismissKeyguardIfInsecure); } + if (mIgnorePendingIntentCreatorForegroundState) { + b.putBoolean(KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE, + mIgnorePendingIntentCreatorForegroundState); + } return b; } diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 312105a42b30..d7554cc42749 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -26,6 +26,7 @@ import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityManagerInternal; +import android.app.ActivityOptions; import android.app.AlarmManager; import android.app.AppGlobals; import android.app.AppOpsManager; @@ -970,13 +971,16 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku intent.setComponent(provider.getInfoLocked(mContext).configure); intent.setFlags(secureFlags); + final ActivityOptions options = ActivityOptions.makeBasic(); + options.setIgnorePendingIntentCreatorForegroundState(true); + // All right, create the sender. final long identity = Binder.clearCallingIdentity(); try { return PendingIntent.getActivityAsUser( mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT, - null, new UserHandle(provider.getUserId())) + options.toBundle(), new UserHandle(provider.getUserId())) .getIntentSender(); } finally { Binder.restoreCallingIdentity(identity); diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 7ab3008585ce..991c7a9e0a4d 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -55,6 +55,7 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityManagerInternal; +import android.app.ActivityOptions; import android.app.AnrController; import android.app.AppOpsManager; import android.app.IActivityManager; @@ -3534,9 +3535,12 @@ class StorageManagerService extends IStorageManager.Stub appInfo.manageSpaceActivityName); intent.setFlags(FLAG_ACTIVITY_NEW_TASK); + final ActivityOptions options = ActivityOptions.makeBasic(); + options.setIgnorePendingIntentCreatorForegroundState(true); + PendingIntent activity = PendingIntent.getActivity(targetAppContext, requestCode, intent, - FLAG_ONE_SHOT | FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE); + FLAG_ONE_SHOT | FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE, options.toBundle()); return activity; } catch (PackageManager.NameNotFoundException e) { throw new IllegalArgumentException( diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index f6396556ae22..d72e0ba6e2c8 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1268,29 +1268,36 @@ class ActivityStarter { boolean allowBackgroundActivityStart, Intent intent, ActivityOptions checkedOptions) { // don't abort for the most important UIDs final int callingAppId = UserHandle.getAppId(callingUid); - 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 + ")"); + final boolean useCallingUidState = + originatingPendingIntent == null || checkedOptions == null + || !checkedOptions.getIgnorePendingIntentCreatorForegroundState(); + 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. - if (isHomeApp(callingUid, callingPackage)) { - if (DEBUG_ACTIVITY_STARTS) { - Slog.d(TAG, "Activity start allowed for home app callingUid (" + callingUid + ")"); + // Always allow home application to start activities. + if (isHomeApp(callingUid, callingPackage)) { + if (DEBUG_ACTIVITY_STARTS) { + 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. - final WindowState imeWindow = mRootWindowContainer.getCurrentInputMethodWindow(); - if (imeWindow != null && callingAppId == imeWindow.mOwnerUid) { - if (DEBUG_ACTIVITY_STARTS) { - Slog.d(TAG, "Activity start allowed for active ime (" + callingUid + ")"); + // IME should always be allowed to start activity, like IME settings. + final WindowState imeWindow = mRootWindowContainer.getCurrentInputMethodWindow(); + if (imeWindow != null && callingAppId == imeWindow.mOwnerUid) { + if (DEBUG_ACTIVITY_STARTS) { + 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 @@ -1310,9 +1317,11 @@ class ActivityStarter { // is allowed, or apps like live wallpaper with non app visible window will be allowed. final boolean appSwitchAllowedOrFg = appSwitchState == APP_SWITCH_ALLOW || appSwitchState == APP_SWITCH_FG_ONLY; - if (((appSwitchAllowedOrFg || mService.mActiveUids.hasNonAppVisibleWindow(callingUid)) + final boolean allowCallingUidStartActivity = + ((appSwitchAllowedOrFg || mService.mActiveUids.hasNonAppVisibleWindow(callingUid)) && callingUidHasAnyVisibleWindow) - || isCallingUidPersistentSystemProcess) { + || isCallingUidPersistentSystemProcess; + if (useCallingUidState && allowCallingUidStartActivity) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid + ", isCallingUidPersistentSystemProcess = " @@ -1400,47 +1409,52 @@ class ActivityStarter { return false; } } - // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission - if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid) - == PERMISSION_GRANTED) { - if (DEBUG_ACTIVITY_STARTS) { - Slog.d(TAG, - "Background activity start allowed: START_ACTIVITIES_FROM_BACKGROUND " - + "permission granted for uid " - + callingUid); + if (useCallingUidState) { + // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission + if (mService.checkPermission( + START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid) + == PERMISSION_GRANTED) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, + "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)) { - if (DEBUG_ACTIVITY_STARTS) { - Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid - + ") is recents"); + // don't abort if the caller has the same uid as the recents component + if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) { + if (DEBUG_ACTIVITY_STARTS) { + 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)) { - if (DEBUG_ACTIVITY_STARTS) { - Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid - + ") is device owner"); + // don't abort if the callingUid is the device owner + if (mService.isDeviceOwner(callingUid)) { + if (DEBUG_ACTIVITY_STARTS) { + 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); - if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) { - if (DEBUG_ACTIVITY_STARTS) { - Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid - + ") is companion app"); + // don't abort if the callingUid has companion device + final int callingUserId = UserHandle.getUserId(callingUid); + if (mService.isAssociatedCompanionApp(callingUserId, + callingUid)) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid + + ") 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(). // That's the case for PendingIntent-based starts, since the creator's process might not be @@ -1452,7 +1466,7 @@ class ActivityStarter { callerAppUid = realCallingUid; } // 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 if (callerApp.areBackgroundActivityStartsAllowed(appSwitchState)) { if (DEBUG_ACTIVITY_STARTS) { |