Loading services/core/java/com/android/server/wm/ActivityStartController.java +7 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,8 @@ public class ActivityStartController { boolean mCheckedForSetup = false; private final BackgroundActivityStartController mBalController; /** * TODO(b/64750076): Capture information necessary for dump and * {@link #postStartActivityProcessingForLastStarter} rather than keeping the entire object Loading @@ -112,6 +114,7 @@ public class ActivityStartController { mFactory.setController(this); mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock, service.mH); mBalController = new BackgroundActivityStartController(mService, mSupervisor); } /** Loading Loading @@ -581,4 +584,8 @@ public class ActivityStartController { pw.println("(nothing)"); } } BackgroundActivityStartController getBackgroundActivityLaunchController() { return mBalController; } } services/core/java/com/android/server/wm/ActivityStarter.java +14 −291 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.server.wm; import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.app.Activity.RESULT_CANCELED; import static android.app.ActivityManager.START_ABORTED; import static android.app.ActivityManager.START_CANCELED; Loading Loading @@ -51,7 +50,6 @@ import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE_PER_TASK; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Process.INVALID_UID; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.TRANSIT_OPEN; Loading @@ -59,7 +57,6 @@ import static android.view.WindowManager.TRANSIT_OPEN; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; import static com.android.server.wm.ActivityRecord.State.RESUMED; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING; Loading @@ -70,8 +67,6 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.ActivityTaskManagerService.ANIMATE; import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW; import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_FG_ONLY; import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME; import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP; import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; Loading @@ -95,7 +90,6 @@ import android.app.WaitResult; import android.app.WindowConfiguration; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.content.ComponentName; import android.content.IIntentSender; import android.content.Intent; import android.content.IntentSender; Loading @@ -111,15 +105,12 @@ import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.service.voice.IVoiceInteractionSession; import android.text.TextUtils; import android.util.ArraySet; import android.util.DebugUtils; import android.util.Pools.SynchronizedPool; import android.util.Slog; import android.window.RemoteTransition; Loading Loading @@ -256,8 +247,6 @@ class ActivityStarter { /** * Generates an {@link ActivityStarter} that is ready to handle a new start request. * @param controller The {@link ActivityStartController} which the starter who will own * this instance. * @return an {@link ActivityStarter} */ ActivityStarter obtain(); Loading Loading @@ -1028,10 +1017,20 @@ class ActivityStarter { try { Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "shouldAbortBackgroundActivityStart"); restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, realCallingUid, realCallingPid, callerApp, request.originatingPendingIntent, request.allowBackgroundActivityStart, intent, checkedOptions); BackgroundActivityStartController balController = mController.getBackgroundActivityLaunchController(); restrictedBgActivity = balController.shouldAbortBackgroundActivityStart( callingUid, callingPid, callingPackage, realCallingUid, realCallingPid, callerApp, request.originatingPendingIntent, request.allowBackgroundActivityStart, intent, checkedOptions); } finally { Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); } Loading Loading @@ -1261,282 +1260,6 @@ class ActivityStarter { mController.onExecutionComplete(this); } private boolean isHomeApp(int uid, @Nullable String packageName) { if (mService.mHomeProcess != null) { // Fast check return uid == mService.mHomeProcess.mUid; } if (packageName == null) { return false; } ComponentName activity = mService.getPackageManagerInternalLocked().getDefaultHomeActivity( UserHandle.getUserId(uid)); return activity != null && packageName.equals(activity.getPackageName()); } boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid, final String callingPackage, int realCallingUid, int realCallingPid, WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart, Intent intent, ActivityOptions checkedOptions) { // don't abort for the most important UIDs final int callingAppId = UserHandle.getAppId(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; } // 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; } // 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; } } // This is used to block background activity launch even if the app is still // visible to user after user clicking home button. final int appSwitchState = mService.getBalAppSwitchesState(); // don't abort if the callingUid has a visible window or is a persistent system process final int callingUidProcState = mService.mActiveUids.getUidState(callingUid); final boolean callingUidHasAnyVisibleWindow = mService.hasActiveVisibleWindow(callingUid); final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow || callingUidProcState == ActivityManager.PROCESS_STATE_TOP || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP; final boolean isCallingUidPersistentSystemProcess = callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; // 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. final boolean appSwitchAllowedOrFg = appSwitchState == APP_SWITCH_ALLOW || appSwitchState == APP_SWITCH_FG_ONLY; final boolean allowCallingUidStartActivity = ((appSwitchAllowedOrFg || mService.mActiveUids.hasNonAppVisibleWindow(callingUid)) && callingUidHasAnyVisibleWindow) || isCallingUidPersistentSystemProcess; if (useCallingUidState && allowCallingUidStartActivity) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid + ", isCallingUidPersistentSystemProcess = " + isCallingUidPersistentSystemProcess); } return false; } // take realCallingUid into consideration final int realCallingUidProcState = (callingUid == realCallingUid) ? callingUidProcState : mService.mActiveUids.getUidState(realCallingUid); final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid) ? callingUidHasAnyVisibleWindow : mService.hasActiveVisibleWindow(realCallingUid); final boolean isRealCallingUidForeground = (callingUid == realCallingUid) ? isCallingUidForeground : realCallingUidHasAnyVisibleWindow || realCallingUidProcState == ActivityManager.PROCESS_STATE_TOP; final int realCallingAppId = UserHandle.getAppId(realCallingUid); final boolean isRealCallingUidPersistentSystemProcess = (callingUid == realCallingUid) ? isCallingUidPersistentSystemProcess : (realCallingAppId == Process.SYSTEM_UID) || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; // In the case of an SDK sandbox calling uid, check if the corresponding app uid has a // visible window. if (Process.isSdkSandboxUid(realCallingUid)) { int realCallingSdkSandboxUidToAppUid = Process.getAppUidForSdkSandboxUid( UserHandle.getAppId(realCallingUid)); if (mService.hasActiveVisibleWindow(realCallingSdkSandboxUidToAppUid)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: uid in SDK sandbox (" + realCallingUid + ") has visible (non-toast) window."); } return false; } } // Legacy behavior allows to use caller foreground state to bypass BAL restriction. final boolean balAllowedByPiSender = PendingIntentRecord.isPendingIntentBalAllowedByCaller(checkedOptions); if (balAllowedByPiSender && realCallingUid != callingUid) { final boolean useCallerPermission = PendingIntentRecord.isPendingIntentBalAllowedByPermission(checkedOptions); if (useCallerPermission && ActivityManager.checkComponentPermission( android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, realCallingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid + ") has BAL permission."); } return false; } // don't abort if the realCallingUid has a visible window // TODO(b/171459802): We should check appSwitchAllowed also if (realCallingUidHasAnyVisibleWindow) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid + ") has visible (non-toast) window"); } return false; } // if the realCallingUid is a persistent system process, abort if the IntentSender // wasn't allowed to start an activity if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid + ") is persistent system process AND intent sender allowed " + "(allowBackgroundActivityStart = true)"); } return false; } // don't abort if the realCallingUid is an associated companion app if (mService.isAssociatedCompanionApp(UserHandle.getUserId(realCallingUid), realCallingUid)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid + ") is companion app"); } return false; } } 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; } // 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; } // 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; } // 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; } } // 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 // up and alive. If that's the case, we retrieve the WindowProcessController for the send() // caller if caller allows, so that we can make the decision based on its state. int callerAppUid = callingUid; if (callerApp == null && balAllowedByPiSender) { callerApp = mService.getProcessController(realCallingPid, realCallingUid); callerAppUid = realCallingUid; } // don't abort if the callerApp or other processes of that uid are allowed in any way if (callerApp != null && useCallingUidState) { // first check the original calling process if (callerApp.areBackgroundActivityStartsAllowed(appSwitchState)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Background activity start allowed: callerApp process (pid = " + callerApp.getPid() + ", uid = " + callerAppUid + ") is allowed"); } return false; } // only if that one wasn't allowed, check the other ones final ArraySet<WindowProcessController> uidProcesses = mService.mProcessMap.getProcesses(callerAppUid); if (uidProcesses != null) { for (int i = uidProcesses.size() - 1; i >= 0; i--) { final WindowProcessController proc = uidProcesses.valueAt(i); if (proc != callerApp && proc.areBackgroundActivityStartsAllowed(appSwitchState)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Background activity start allowed: process " + proc.getPid() + " from uid " + callerAppUid + " is allowed"); } return false; } } } } // anything that has fallen through would currently be aborted Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage + "; callingUid: " + callingUid + "; appSwitchState: " + appSwitchState + "; isCallingUidForeground: " + isCallingUidForeground + "; callingUidHasAnyVisibleWindow: " + callingUidHasAnyVisibleWindow + "; callingUidProcState: " + DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", callingUidProcState) + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess + "; realCallingUid: " + realCallingUid + "; isRealCallingUidForeground: " + isRealCallingUidForeground + "; realCallingUidHasAnyVisibleWindow: " + realCallingUidHasAnyVisibleWindow + "; realCallingUidProcState: " + DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", realCallingUidProcState) + "; isRealCallingUidPersistentSystemProcess: " + isRealCallingUidPersistentSystemProcess + "; originatingPendingIntent: " + originatingPendingIntent + "; allowBackgroundActivityStart: " + allowBackgroundActivityStart + "; intent: " + intent + "; callerApp: " + callerApp + "; inVisibleTask: " + (callerApp != null && callerApp.hasActivityInVisibleTask()) + "]"); // log aborted activity start to TRON if (mService.isActivityStartsLoggingEnabled()) { mSupervisor.getActivityMetricsLogger().logAbortedBgActivityStart(intent, callerApp, callingUid, callingPackage, callingUidProcState, callingUidHasAnyVisibleWindow, realCallingUid, realCallingUidProcState, realCallingUidHasAnyVisibleWindow, (originatingPendingIntent != null)); } return true; } /** * Creates a launch intent for the given auxiliary resolution data. */ Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +13 −4 Original line number Diff line number Diff line Loading @@ -2132,10 +2132,19 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (appThread != null) { callerApp = getProcessController(appThread); } final ActivityStarter starter = getActivityStartController().obtainStarter( null /* intent */, "moveTaskToFront"); if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, -1, -1, callerApp, null, false, null, null)) { final BackgroundActivityStartController balController = getActivityStartController().getBackgroundActivityLaunchController(); if (balController.shouldAbortBackgroundActivityStart( callingUid, callingPid, callingPackage, -1, -1, callerApp, null, false, null, null)) { if (!isBackgroundActivityStartsEnabled()) { return; } Loading services/core/java/com/android/server/wm/AppTaskImpl.java +14 −4 Original line number Diff line number Diff line Loading @@ -119,10 +119,20 @@ class AppTaskImpl extends IAppTask.Stub { if (appThread != null) { callerApp = mService.getProcessController(appThread); } final ActivityStarter starter = mService.getActivityStartController().obtainStarter( null /* intent */, "moveToFront"); if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, -1, -1, callerApp, null, false, null, null)) { final BackgroundActivityStartController balController = mService.getActivityStartController() .getBackgroundActivityLaunchController(); if (balController.shouldAbortBackgroundActivityStart( callingUid, callingPid, callingPackage, -1, -1, callerApp, null, false, null, null)) { if (!mService.isBackgroundActivityStartsEnabled()) { return; } Loading services/core/java/com/android/server/wm/BackgroundActivityStartController.java 0 → 100644 +421 −0 File added.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/wm/ActivityStartController.java +7 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,8 @@ public class ActivityStartController { boolean mCheckedForSetup = false; private final BackgroundActivityStartController mBalController; /** * TODO(b/64750076): Capture information necessary for dump and * {@link #postStartActivityProcessingForLastStarter} rather than keeping the entire object Loading @@ -112,6 +114,7 @@ public class ActivityStartController { mFactory.setController(this); mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock, service.mH); mBalController = new BackgroundActivityStartController(mService, mSupervisor); } /** Loading Loading @@ -581,4 +584,8 @@ public class ActivityStartController { pw.println("(nothing)"); } } BackgroundActivityStartController getBackgroundActivityLaunchController() { return mBalController; } }
services/core/java/com/android/server/wm/ActivityStarter.java +14 −291 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.server.wm; import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.app.Activity.RESULT_CANCELED; import static android.app.ActivityManager.START_ABORTED; import static android.app.ActivityManager.START_CANCELED; Loading Loading @@ -51,7 +50,6 @@ import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE_PER_TASK; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Process.INVALID_UID; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.TRANSIT_OPEN; Loading @@ -59,7 +57,6 @@ import static android.view.WindowManager.TRANSIT_OPEN; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; import static com.android.server.wm.ActivityRecord.State.RESUMED; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING; Loading @@ -70,8 +67,6 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.ActivityTaskManagerService.ANIMATE; import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW; import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_FG_ONLY; import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME; import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP; import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; Loading @@ -95,7 +90,6 @@ import android.app.WaitResult; import android.app.WindowConfiguration; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.content.ComponentName; import android.content.IIntentSender; import android.content.Intent; import android.content.IntentSender; Loading @@ -111,15 +105,12 @@ import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.service.voice.IVoiceInteractionSession; import android.text.TextUtils; import android.util.ArraySet; import android.util.DebugUtils; import android.util.Pools.SynchronizedPool; import android.util.Slog; import android.window.RemoteTransition; Loading Loading @@ -256,8 +247,6 @@ class ActivityStarter { /** * Generates an {@link ActivityStarter} that is ready to handle a new start request. * @param controller The {@link ActivityStartController} which the starter who will own * this instance. * @return an {@link ActivityStarter} */ ActivityStarter obtain(); Loading Loading @@ -1028,10 +1017,20 @@ class ActivityStarter { try { Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "shouldAbortBackgroundActivityStart"); restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, realCallingUid, realCallingPid, callerApp, request.originatingPendingIntent, request.allowBackgroundActivityStart, intent, checkedOptions); BackgroundActivityStartController balController = mController.getBackgroundActivityLaunchController(); restrictedBgActivity = balController.shouldAbortBackgroundActivityStart( callingUid, callingPid, callingPackage, realCallingUid, realCallingPid, callerApp, request.originatingPendingIntent, request.allowBackgroundActivityStart, intent, checkedOptions); } finally { Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); } Loading Loading @@ -1261,282 +1260,6 @@ class ActivityStarter { mController.onExecutionComplete(this); } private boolean isHomeApp(int uid, @Nullable String packageName) { if (mService.mHomeProcess != null) { // Fast check return uid == mService.mHomeProcess.mUid; } if (packageName == null) { return false; } ComponentName activity = mService.getPackageManagerInternalLocked().getDefaultHomeActivity( UserHandle.getUserId(uid)); return activity != null && packageName.equals(activity.getPackageName()); } boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid, final String callingPackage, int realCallingUid, int realCallingPid, WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart, Intent intent, ActivityOptions checkedOptions) { // don't abort for the most important UIDs final int callingAppId = UserHandle.getAppId(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; } // 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; } // 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; } } // This is used to block background activity launch even if the app is still // visible to user after user clicking home button. final int appSwitchState = mService.getBalAppSwitchesState(); // don't abort if the callingUid has a visible window or is a persistent system process final int callingUidProcState = mService.mActiveUids.getUidState(callingUid); final boolean callingUidHasAnyVisibleWindow = mService.hasActiveVisibleWindow(callingUid); final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow || callingUidProcState == ActivityManager.PROCESS_STATE_TOP || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP; final boolean isCallingUidPersistentSystemProcess = callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; // 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. final boolean appSwitchAllowedOrFg = appSwitchState == APP_SWITCH_ALLOW || appSwitchState == APP_SWITCH_FG_ONLY; final boolean allowCallingUidStartActivity = ((appSwitchAllowedOrFg || mService.mActiveUids.hasNonAppVisibleWindow(callingUid)) && callingUidHasAnyVisibleWindow) || isCallingUidPersistentSystemProcess; if (useCallingUidState && allowCallingUidStartActivity) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid + ", isCallingUidPersistentSystemProcess = " + isCallingUidPersistentSystemProcess); } return false; } // take realCallingUid into consideration final int realCallingUidProcState = (callingUid == realCallingUid) ? callingUidProcState : mService.mActiveUids.getUidState(realCallingUid); final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid) ? callingUidHasAnyVisibleWindow : mService.hasActiveVisibleWindow(realCallingUid); final boolean isRealCallingUidForeground = (callingUid == realCallingUid) ? isCallingUidForeground : realCallingUidHasAnyVisibleWindow || realCallingUidProcState == ActivityManager.PROCESS_STATE_TOP; final int realCallingAppId = UserHandle.getAppId(realCallingUid); final boolean isRealCallingUidPersistentSystemProcess = (callingUid == realCallingUid) ? isCallingUidPersistentSystemProcess : (realCallingAppId == Process.SYSTEM_UID) || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; // In the case of an SDK sandbox calling uid, check if the corresponding app uid has a // visible window. if (Process.isSdkSandboxUid(realCallingUid)) { int realCallingSdkSandboxUidToAppUid = Process.getAppUidForSdkSandboxUid( UserHandle.getAppId(realCallingUid)); if (mService.hasActiveVisibleWindow(realCallingSdkSandboxUidToAppUid)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: uid in SDK sandbox (" + realCallingUid + ") has visible (non-toast) window."); } return false; } } // Legacy behavior allows to use caller foreground state to bypass BAL restriction. final boolean balAllowedByPiSender = PendingIntentRecord.isPendingIntentBalAllowedByCaller(checkedOptions); if (balAllowedByPiSender && realCallingUid != callingUid) { final boolean useCallerPermission = PendingIntentRecord.isPendingIntentBalAllowedByPermission(checkedOptions); if (useCallerPermission && ActivityManager.checkComponentPermission( android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, realCallingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid + ") has BAL permission."); } return false; } // don't abort if the realCallingUid has a visible window // TODO(b/171459802): We should check appSwitchAllowed also if (realCallingUidHasAnyVisibleWindow) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid + ") has visible (non-toast) window"); } return false; } // if the realCallingUid is a persistent system process, abort if the IntentSender // wasn't allowed to start an activity if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid + ") is persistent system process AND intent sender allowed " + "(allowBackgroundActivityStart = true)"); } return false; } // don't abort if the realCallingUid is an associated companion app if (mService.isAssociatedCompanionApp(UserHandle.getUserId(realCallingUid), realCallingUid)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid + ") is companion app"); } return false; } } 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; } // 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; } // 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; } // 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; } } // 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 // up and alive. If that's the case, we retrieve the WindowProcessController for the send() // caller if caller allows, so that we can make the decision based on its state. int callerAppUid = callingUid; if (callerApp == null && balAllowedByPiSender) { callerApp = mService.getProcessController(realCallingPid, realCallingUid); callerAppUid = realCallingUid; } // don't abort if the callerApp or other processes of that uid are allowed in any way if (callerApp != null && useCallingUidState) { // first check the original calling process if (callerApp.areBackgroundActivityStartsAllowed(appSwitchState)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Background activity start allowed: callerApp process (pid = " + callerApp.getPid() + ", uid = " + callerAppUid + ") is allowed"); } return false; } // only if that one wasn't allowed, check the other ones final ArraySet<WindowProcessController> uidProcesses = mService.mProcessMap.getProcesses(callerAppUid); if (uidProcesses != null) { for (int i = uidProcesses.size() - 1; i >= 0; i--) { final WindowProcessController proc = uidProcesses.valueAt(i); if (proc != callerApp && proc.areBackgroundActivityStartsAllowed(appSwitchState)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Background activity start allowed: process " + proc.getPid() + " from uid " + callerAppUid + " is allowed"); } return false; } } } } // anything that has fallen through would currently be aborted Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage + "; callingUid: " + callingUid + "; appSwitchState: " + appSwitchState + "; isCallingUidForeground: " + isCallingUidForeground + "; callingUidHasAnyVisibleWindow: " + callingUidHasAnyVisibleWindow + "; callingUidProcState: " + DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", callingUidProcState) + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess + "; realCallingUid: " + realCallingUid + "; isRealCallingUidForeground: " + isRealCallingUidForeground + "; realCallingUidHasAnyVisibleWindow: " + realCallingUidHasAnyVisibleWindow + "; realCallingUidProcState: " + DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", realCallingUidProcState) + "; isRealCallingUidPersistentSystemProcess: " + isRealCallingUidPersistentSystemProcess + "; originatingPendingIntent: " + originatingPendingIntent + "; allowBackgroundActivityStart: " + allowBackgroundActivityStart + "; intent: " + intent + "; callerApp: " + callerApp + "; inVisibleTask: " + (callerApp != null && callerApp.hasActivityInVisibleTask()) + "]"); // log aborted activity start to TRON if (mService.isActivityStartsLoggingEnabled()) { mSupervisor.getActivityMetricsLogger().logAbortedBgActivityStart(intent, callerApp, callingUid, callingPackage, callingUidProcState, callingUidHasAnyVisibleWindow, realCallingUid, realCallingUidProcState, realCallingUidHasAnyVisibleWindow, (originatingPendingIntent != null)); } return true; } /** * Creates a launch intent for the given auxiliary resolution data. */ Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +13 −4 Original line number Diff line number Diff line Loading @@ -2132,10 +2132,19 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (appThread != null) { callerApp = getProcessController(appThread); } final ActivityStarter starter = getActivityStartController().obtainStarter( null /* intent */, "moveTaskToFront"); if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, -1, -1, callerApp, null, false, null, null)) { final BackgroundActivityStartController balController = getActivityStartController().getBackgroundActivityLaunchController(); if (balController.shouldAbortBackgroundActivityStart( callingUid, callingPid, callingPackage, -1, -1, callerApp, null, false, null, null)) { if (!isBackgroundActivityStartsEnabled()) { return; } Loading
services/core/java/com/android/server/wm/AppTaskImpl.java +14 −4 Original line number Diff line number Diff line Loading @@ -119,10 +119,20 @@ class AppTaskImpl extends IAppTask.Stub { if (appThread != null) { callerApp = mService.getProcessController(appThread); } final ActivityStarter starter = mService.getActivityStartController().obtainStarter( null /* intent */, "moveToFront"); if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, -1, -1, callerApp, null, false, null, null)) { final BackgroundActivityStartController balController = mService.getActivityStartController() .getBackgroundActivityLaunchController(); if (balController.shouldAbortBackgroundActivityStart( callingUid, callingPid, callingPackage, -1, -1, callerApp, null, false, null, null)) { if (!mService.isBackgroundActivityStartsEnabled()) { return; } Loading
services/core/java/com/android/server/wm/BackgroundActivityStartController.java 0 → 100644 +421 −0 File added.Preview size limit exceeded, changes collapsed. Show changes