diff options
| author | 2025-02-24 13:09:22 -0800 | |
|---|---|---|
| committer | 2025-02-24 13:09:22 -0800 | |
| commit | ab6ce1d8221aff9e70cceae1d09f12629d14f094 (patch) | |
| tree | cb569920dbd02ea9b6c8ae67cc0477acf6765170 | |
| parent | 6aeb0c440e4580ca133546f1057b5a122765cadc (diff) | |
| parent | ae7f387e872563b0e6fd4dfe9c9743940529dc25 (diff) | |
Merge changes Ib1e2e57e,I4c0888f7 into main
* changes:
Refactor real caller exemptions
Refactor caller exemptions
| -rw-r--r-- | services/core/java/com/android/server/wm/BackgroundActivityStartController.java | 160 |
1 files changed, 122 insertions, 38 deletions
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java index 119709e86551..aed5e140703c 100644 --- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java +++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java @@ -144,9 +144,9 @@ public class BackgroundActivityStartController { .setPendingIntentCreatorBackgroundActivityStartMode( MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED); - private final ActivityTaskManagerService mService; + private ActivityTaskManagerService mService; - private final ActivityTaskSupervisor mSupervisor; + private ActivityTaskSupervisor mSupervisor; @GuardedBy("mStrictModeBalCallbacks") private final SparseArray<ArrayMap<IBinder, IBackgroundActivityLaunchCallback>> mStrictModeBalCallbacks = new SparseArray<>(); @@ -1026,11 +1026,21 @@ public class BackgroundActivityStartController { } } - /** - * @return A code denoting which BAL rule allows an activity to be started, - * or {@link #BAL_BLOCK} if the launch should be blocked - */ - BalVerdict checkBackgroundActivityStartAllowedByCallerInForeground(BalState state) { + interface BalExemptionCheck { + BalVerdict evaluate(BalState state); + } + + private BalVerdict evaluateChain(BalState state, BalExemptionCheck... checks) { + for (BalExemptionCheck check : checks) { + BalVerdict verdict = check.evaluate(state); + if (verdict != BalVerdict.BLOCK) { + return verdict; + } + } + return BalVerdict.BLOCK; + } + + private final BalExemptionCheck mCheckCallerVisible = state -> { // This is used to block background activity launch even if the app is still // visible to user after user clicking home button. @@ -1044,21 +1054,19 @@ public class BackgroundActivityStartController { return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW, /*background*/ false, "callingUid has visible window"); } + return BalVerdict.BLOCK; + }; + + private final BalExemptionCheck mCheckCallerNonAppVisible = state -> { if (state.mCallingUidHasNonAppVisibleWindow) { return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, /*background*/ false, "callingUid has non-app visible window " + mService.mActiveUids.getNonAppVisibleWindowDetails(state.mCallingUid)); } - // Don't abort if the callerApp or other processes of that uid are considered to be in the - // foreground. - return checkProcessAllowsBal(state.mCallerApp, state, BAL_CHECK_FOREGROUND); - } + return BalVerdict.BLOCK; + }; - /** - * @return A code denoting which BAL rule allows an activity to be started, - * or {@link #BAL_BLOCK} if the launch should be blocked - */ - BalVerdict checkBackgroundActivityStartAllowedByCallerInBackground(BalState state) { + private final BalExemptionCheck mCheckCallerIsAllowlistedUid = state -> { // don't abort for the most important UIDs final int callingAppId = UserHandle.getAppId(state.mCallingUid); if (state.mCallingUid == Process.ROOT_UID @@ -1066,9 +1074,12 @@ public class BackgroundActivityStartController { || callingAppId == Process.NFC_UID) { return new BalVerdict( BAL_ALLOW_ALLOWLISTED_UID, /*background*/ false, - "Important callingUid"); + "Important callingUid"); } + return BalVerdict.BLOCK; + }; + private final BalExemptionCheck mCheckCallerIsAllowlistedComponent = state -> { // Always allow home application to start activities. if (isHomeApp(state.mCallingUid, state.mCallingPackage)) { return new BalVerdict(BAL_ALLOW_ALLOWLISTED_COMPONENT, @@ -1076,6 +1087,7 @@ public class BackgroundActivityStartController { "Home app"); } + final int callingAppId = UserHandle.getAppId(state.mCallingUid); // IME should always be allowed to start activity, like IME settings. final WindowState imeWindow = mService.mRootWindowContainer.getCurrentInputMethodWindow(); @@ -1091,12 +1103,6 @@ public class BackgroundActivityStartController { /*background*/ false, "callingUid is persistent system process"); } - // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission - if (hasBalPermission(state.mCallingUid, state.mCallingPid)) { - return new BalVerdict(BAL_ALLOW_PERMISSION, - /*background*/ true, - "START_ACTIVITIES_FROM_BACKGROUND permission granted"); - } // don't abort if the caller has the same uid as the recents component if (mSupervisor.mRecentTasks.isCallerRecents(state.mCallingUid)) { return new BalVerdict(BAL_ALLOW_ALLOWLISTED_COMPONENT, @@ -1118,12 +1124,28 @@ public class BackgroundActivityStartController { return new BalVerdict(BAL_ALLOW_ALLOWLISTED_COMPONENT, /*background*/ true, "Companion App"); } + return BalVerdict.BLOCK; + }; + + private final BalExemptionCheck mCheckCallerHasBackgroundPermission = state -> { + // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission + if (hasBalPermission(state.mCallingUid, state.mCallingPid)) { + return new BalVerdict(BAL_ALLOW_PERMISSION, + /*background*/ true, + "START_ACTIVITIES_FROM_BACKGROUND permission granted"); + } + return BalVerdict.BLOCK; + }; + private final BalExemptionCheck mCheckCallerHasSawPermission = state -> { // don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission if (mService.hasSystemAlertWindowPermission(state.mCallingUid, state.mCallingPid, state.mCallingPackage)) { return new BalVerdict(BAL_ALLOW_SAW_PERMISSION, /*background*/ true, "SYSTEM_ALERT_WINDOW permission is granted"); } + return BalVerdict.BLOCK; + }; + private final BalExemptionCheck mCheckCallerHasBgStartAppOp = state -> { // don't abort if the callingUid and callingPackage have the // OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION appop if (isSystemExemptFlagEnabled() && mService.getAppOpsManager().checkOpNoThrow( @@ -1132,9 +1154,36 @@ public class BackgroundActivityStartController { return new BalVerdict(BAL_ALLOW_PERMISSION, /*background*/ true, "OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION appop is granted"); } + return BalVerdict.BLOCK; + }; + + + // Don't abort if the callerApp or other processes of that uid are considered to be in the + // foreground. + private final BalExemptionCheck mCheckCallerProcessAllowsForeground = + state -> checkProcessAllowsBal(state.mCallerApp, state, BAL_CHECK_FOREGROUND); + // Don't abort if the callerApp or other processes of that uid are allowed in any way. + private final BalExemptionCheck mCheckCallerProcessAllowsBackground = + state -> checkProcessAllowsBal(state.mCallerApp, state, BAL_CHECK_BACKGROUND); + + /** + * @return A code denoting which BAL rule allows an activity to be started, + * or {@link #BAL_BLOCK} if the launch should be blocked + */ + BalVerdict checkBackgroundActivityStartAllowedByCallerInForeground(BalState state) { + return evaluateChain(state, mCheckCallerVisible, mCheckCallerNonAppVisible, + mCheckCallerProcessAllowsForeground); + } - // Don't abort if the callerApp or other processes of that uid are allowed in any way. - return checkProcessAllowsBal(state.mCallerApp, state, BAL_CHECK_BACKGROUND); + /** + * @return A code denoting which BAL rule allows an activity to be started, + * or {@link #BAL_BLOCK} if the launch should be blocked + */ + BalVerdict checkBackgroundActivityStartAllowedByCallerInBackground(BalState state) { + return evaluateChain(state, mCheckCallerIsAllowlistedUid, + mCheckCallerIsAllowlistedComponent, mCheckCallerHasBackgroundPermission, + mCheckCallerHasSawPermission, mCheckCallerHasBgStartAppOp, + mCheckCallerProcessAllowsBackground); } /** @@ -1151,11 +1200,7 @@ public class BackgroundActivityStartController { return result; } - /** - * @return A code denoting which BAL rule allows an activity to be started, - * or {@link #BAL_BLOCK} if the launch should be blocked - */ - BalVerdict checkBackgroundActivityStartAllowedByRealCallerInForeground(BalState state) { + private final BalExemptionCheck mCheckRealCallerVisible = state -> { // Normal apps with visible app window will be allowed to start activity if app switching // is allowed, or apps like live wallpaper with non app visible window will be allowed. // The home app can start apps even if app switches are usually disallowed. @@ -1166,22 +1211,30 @@ public class BackgroundActivityStartController { return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW, /*background*/ false, "realCallingUid has visible window"); } + return BalVerdict.BLOCK; + }; + + private final BalExemptionCheck mCheckRealCallerNonAppVisible = state -> { if (state.mRealCallingUidHasNonAppVisibleWindow) { return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, /*background*/ false, "realCallingUid has non-app visible window " + mService.mActiveUids.getNonAppVisibleWindowDetails(state.mRealCallingUid)); } + return BalVerdict.BLOCK; + }; + private final BalExemptionCheck mCheckRealCallerProcessAllowsBalForeground = state -> { // Don't abort if the realCallerApp or other processes of that uid are considered to be in // the foreground. return checkProcessAllowsBal(state.mRealCallerApp, state, BAL_CHECK_FOREGROUND); - } + }; - /** - * @return A code denoting which BAL rule allows an activity to be started, - * or {@link #BAL_BLOCK} if the launch should be blocked - */ - BalVerdict checkBackgroundActivityStartAllowedByRealCallerInBackground(BalState state) { + private final BalExemptionCheck mCheckRealCallerProcessAllowsBalBackground = state -> { + // don't abort if the callerApp or other processes of that uid are allowed in any way + return checkProcessAllowsBal(state.mRealCallerApp, state, BAL_CHECK_BACKGROUND); + }; + + private final BalExemptionCheck mCheckRealCallerBalPermission = state -> { boolean allowAlways = state.mCheckedOptions.getPendingIntentBackgroundActivityStartMode() == MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS; if (allowAlways @@ -1190,7 +1243,12 @@ public class BackgroundActivityStartController { /*background*/ false, "realCallingUid has BAL permission."); } + return BalVerdict.BLOCK; + }; + private final BalExemptionCheck mCheckRealCallerSawPermission = state -> { + boolean allowAlways = state.mCheckedOptions.getPendingIntentBackgroundActivityStartMode() + == MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS; // don't abort if the realCallingUid has SYSTEM_ALERT_WINDOW permission if (allowAlways && mService.hasSystemAlertWindowPermission(state.mRealCallingUid, @@ -1198,7 +1256,12 @@ public class BackgroundActivityStartController { return new BalVerdict(BAL_ALLOW_SAW_PERMISSION, /*background*/ true, "SYSTEM_ALERT_WINDOW permission is granted"); } + return BalVerdict.BLOCK; + }; + private final BalExemptionCheck mCheckRealCallerAllowlistedUid = state -> { + boolean allowAlways = state.mCheckedOptions.getPendingIntentBackgroundActivityStartMode() + == MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS; // if the realCallingUid is a persistent system process, abort if the IntentSender // wasn't allowed to start an activity if ((allowAlways || state.mAllowBalExemptionForSystemProcess) @@ -1208,6 +1271,10 @@ public class BackgroundActivityStartController { "realCallingUid is persistent system process AND intent " + "sender forced to allow."); } + return BalVerdict.BLOCK; + }; + + private final BalExemptionCheck mCheckRealCallerAllowlistedComponent = state -> { // don't abort if the realCallingUid is an associated companion app if (mService.isAssociatedCompanionApp( UserHandle.getUserId(state.mRealCallingUid), state.mRealCallingUid)) { @@ -1215,9 +1282,26 @@ public class BackgroundActivityStartController { /*background*/ false, "realCallingUid is a companion app."); } + return BalVerdict.BLOCK; + }; - // don't abort if the callerApp or other processes of that uid are allowed in any way - return checkProcessAllowsBal(state.mRealCallerApp, state, BAL_CHECK_BACKGROUND); + /** + * @return A code denoting which BAL rule allows an activity to be started, + * or {@link #BAL_BLOCK} if the launch should be blocked + */ + BalVerdict checkBackgroundActivityStartAllowedByRealCallerInForeground(BalState state) { + return evaluateChain(state, mCheckRealCallerVisible, mCheckRealCallerNonAppVisible, + mCheckRealCallerProcessAllowsBalForeground); + } + + /** + * @return A code denoting which BAL rule allows an activity to be started, + * or {@link #BAL_BLOCK} if the launch should be blocked + */ + BalVerdict checkBackgroundActivityStartAllowedByRealCallerInBackground(BalState state) { + return evaluateChain(state, mCheckRealCallerBalPermission, mCheckRealCallerSawPermission, + mCheckRealCallerAllowlistedUid, mCheckRealCallerAllowlistedComponent, + mCheckRealCallerProcessAllowsBalBackground); } @VisibleForTesting boolean hasBalPermission(int uid, int pid) { |