Loading services/core/java/com/android/server/wm/ActivityStarter.java +39 −4 Original line number Diff line number Diff line Loading @@ -1195,7 +1195,23 @@ class ActivityStarter { } } if (mService.getBalAppSwitchesProtectionEnabled()) { // Only allow app switching to be resumed if activity is not a restricted background // activity and target app is not home process, otherwise any background activity // started in background task can stop home button protection mode. // As the targeted app is not a home process and we don't need to wait for the 2nd // activity to be started to resume app switching, we can just enable app switching // directly. WindowProcessController homeProcess = mService.mHomeProcess; boolean isHomeProcess = homeProcess != null && aInfo.applicationInfo.uid == homeProcess.mUid; if (!restrictedBgActivity && !isHomeProcess) { mService.resumeAppSwitches(); } } else { mService.onStartActivitySetDidAppSwitch(); } mController.doPendingActivityLaunches(false); mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession, Loading Loading @@ -1260,6 +1276,20 @@ class ActivityStarter { return false; } // Always allow home application to start activities. if (mService.mHomeProcess != null && callingUid == mService.mHomeProcess.mUid) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed for home app callingUid (" + callingUid + ")"); } return false; } // App switching will be allowed if BAL app switching flag is not enabled, or if // its app switching rule allows it. // This is used to block background activity launch even if the app is still // visible to user after user clicking home button. final boolean appSwitchAllowed = mService.getBalAppSwitchesAllowed(); // don't abort if the callingUid has a visible window or is a persistent system process final int callingUidProcState = mService.getUidState(callingUid); final boolean callingUidHasAnyVisibleWindow = Loading @@ -1269,7 +1299,8 @@ class ActivityStarter { || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP; final boolean isCallingUidPersistentSystemProcess = callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; if (callingUidHasAnyVisibleWindow || isCallingUidPersistentSystemProcess) { if ((appSwitchAllowed && callingUidHasAnyVisibleWindow) || isCallingUidPersistentSystemProcess) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid + ", isCallingUidPersistentSystemProcess = " Loading @@ -1295,6 +1326,7 @@ class ActivityStarter { || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; if (realCallingUid != callingUid) { // 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 Loading Loading @@ -1376,7 +1408,7 @@ class ActivityStarter { // don't abort if the callerApp or other processes of that uid are allowed in any way if (callerApp != null) { // first check the original calling process if (callerApp.areBackgroundActivityStartsAllowed()) { if (callerApp.areBackgroundActivityStartsAllowed(appSwitchAllowed)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Background activity start allowed: callerApp process (pid = " + callerApp.getPid() + ", uid = " + callerAppUid + ") is allowed"); Loading @@ -1389,7 +1421,8 @@ class ActivityStarter { if (uidProcesses != null) { for (int i = uidProcesses.size() - 1; i >= 0; i--) { final WindowProcessController proc = uidProcesses.valueAt(i); if (proc != callerApp && proc.areBackgroundActivityStartsAllowed()) { if (proc != callerApp && proc.areBackgroundActivityStartsAllowed(appSwitchAllowed)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Background activity start allowed: process " + proc.getPid() Loading @@ -1403,6 +1436,8 @@ class ActivityStarter { // anything that has fallen through would currently be aborted Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage + "; callingUid: " + callingUid + "; appSwitchAllowed: " + appSwitchAllowed + "; balAppSwitchEnabled: " + mService.getBalAppSwitchesProtectionEnabled() + "; isCallingUidForeground: " + isCallingUidForeground + "; callingUidHasAnyVisibleWindow: " + callingUidHasAnyVisibleWindow + "; callingUidProcState: " + DebugUtils.valueToString(ActivityManager.class, Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +44 −1 Original line number Diff line number Diff line Loading @@ -161,9 +161,11 @@ import android.app.WindowConfiguration; import android.app.admin.DevicePolicyCache; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.compat.CompatChanges; import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.EnterPipRequestedItem; import android.app.usage.UsageStatsManagerInternal; import android.compat.annotation.ChangeId; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.ContentResolver; Loading Loading @@ -214,6 +216,7 @@ import android.os.UserManager; import android.os.WorkSource; import android.os.storage.IStorageManager; import android.os.storage.StorageManager; import android.provider.DeviceConfig; import android.provider.Settings; import android.service.dreams.DreamActivity; import android.service.voice.IVoiceInteractionSession; Loading Loading @@ -342,6 +345,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** This activity is being relaunched due to a free-resize operation. */ public static final int RELAUNCH_REASON_FREE_RESIZE = 2; /** * Apps are blocked from starting activities in the foreground after the user presses home. */ public static final String BLOCK_ACTIVITY_STARTS_AFTER_HOME_FLAG = "am_block_activity_starts_after_home"; Context mContext; /** Loading Loading @@ -396,6 +405,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { volatile WindowProcessController mHeavyWeightProcess; boolean mHasHeavyWeightFeature; boolean mHasLeanbackFeature; boolean mBlockActivityAfterHomeEnabled; /** The process of the top most activity. */ volatile WindowProcessController mTopApp; /** Loading Loading @@ -759,6 +769,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mVrController.onSystemReady(); mRecentTasks.onSystemReadyLocked(); mStackSupervisor.onSystemReady(); mBlockActivityAfterHomeEnabled = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, BLOCK_ACTIVITY_STARTS_AFTER_HOME_FLAG, false); } } Loading Loading @@ -2630,8 +2643,35 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { throw new SecurityException(msg); } /** * Return true if app switch protection will be handled by background activity launch logic. */ boolean getBalAppSwitchesProtectionEnabled() { return mBlockActivityAfterHomeEnabled; } /** * Return true if app switching is allowed. */ boolean getBalAppSwitchesAllowed() { if (getBalAppSwitchesProtectionEnabled()) { // Apps no longer able to start BAL again until app switching is resumed. return mAppSwitchesAllowedTime == 0; } else { // Legacy behavior, BAL logic won't block app switching. return true; } } boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, int callingPid, int callingUid, String name) { // Background activity launch logic replaces app switching protection, so allow // apps to start activity here now. if (getBalAppSwitchesProtectionEnabled()) { return true; } if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { return true; } Loading Loading @@ -4666,9 +4706,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME; mLastStopAppSwitchesTime = SystemClock.uptimeMillis(); mDidAppSwitch = false; // If BAL app switching enabled, app switches are blocked not delayed. if (!getBalAppSwitchesProtectionEnabled()) { getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME); } } } @Override public void resumeAppSwitches() { Loading services/core/java/com/android/server/wm/WindowProcessController.java +25 −21 Original line number Diff line number Diff line Loading @@ -516,7 +516,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio } } boolean areBackgroundActivityStartsAllowed() { boolean areBackgroundActivityStartsAllowed(boolean appSwitchAllowed) { // If app switching is not allowed, we ignore all the start activity grace period // exception so apps cannot start itself in onPause() after pressing home button. if (appSwitchAllowed) { // allow if any activity in the caller has either started or finished very recently, and // it must be started or finished after last stop app switches time. final long now = SystemClock.uptimeMillis(); Loading @@ -540,6 +543,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio } } } // allow if the proc is instrumenting with background activity starts privs if (mInstrumentingWithBackgroundActivityStartPrivileges) { if (DEBUG_ACTIVITY_STARTS) { Loading @@ -550,7 +554,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio return true; } // allow if the caller has an activity in any foreground task if (hasActivityInVisibleTask()) { if (appSwitchAllowed && hasActivityInVisibleTask()) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "[WindowProcessController(" + mPid + ")] Activity start allowed: process has activity in foreground task"); Loading Loading
services/core/java/com/android/server/wm/ActivityStarter.java +39 −4 Original line number Diff line number Diff line Loading @@ -1195,7 +1195,23 @@ class ActivityStarter { } } if (mService.getBalAppSwitchesProtectionEnabled()) { // Only allow app switching to be resumed if activity is not a restricted background // activity and target app is not home process, otherwise any background activity // started in background task can stop home button protection mode. // As the targeted app is not a home process and we don't need to wait for the 2nd // activity to be started to resume app switching, we can just enable app switching // directly. WindowProcessController homeProcess = mService.mHomeProcess; boolean isHomeProcess = homeProcess != null && aInfo.applicationInfo.uid == homeProcess.mUid; if (!restrictedBgActivity && !isHomeProcess) { mService.resumeAppSwitches(); } } else { mService.onStartActivitySetDidAppSwitch(); } mController.doPendingActivityLaunches(false); mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession, Loading Loading @@ -1260,6 +1276,20 @@ class ActivityStarter { return false; } // Always allow home application to start activities. if (mService.mHomeProcess != null && callingUid == mService.mHomeProcess.mUid) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed for home app callingUid (" + callingUid + ")"); } return false; } // App switching will be allowed if BAL app switching flag is not enabled, or if // its app switching rule allows it. // This is used to block background activity launch even if the app is still // visible to user after user clicking home button. final boolean appSwitchAllowed = mService.getBalAppSwitchesAllowed(); // don't abort if the callingUid has a visible window or is a persistent system process final int callingUidProcState = mService.getUidState(callingUid); final boolean callingUidHasAnyVisibleWindow = Loading @@ -1269,7 +1299,8 @@ class ActivityStarter { || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP; final boolean isCallingUidPersistentSystemProcess = callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; if (callingUidHasAnyVisibleWindow || isCallingUidPersistentSystemProcess) { if ((appSwitchAllowed && callingUidHasAnyVisibleWindow) || isCallingUidPersistentSystemProcess) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid + ", isCallingUidPersistentSystemProcess = " Loading @@ -1295,6 +1326,7 @@ class ActivityStarter { || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; if (realCallingUid != callingUid) { // 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 Loading Loading @@ -1376,7 +1408,7 @@ class ActivityStarter { // don't abort if the callerApp or other processes of that uid are allowed in any way if (callerApp != null) { // first check the original calling process if (callerApp.areBackgroundActivityStartsAllowed()) { if (callerApp.areBackgroundActivityStartsAllowed(appSwitchAllowed)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Background activity start allowed: callerApp process (pid = " + callerApp.getPid() + ", uid = " + callerAppUid + ") is allowed"); Loading @@ -1389,7 +1421,8 @@ class ActivityStarter { if (uidProcesses != null) { for (int i = uidProcesses.size() - 1; i >= 0; i--) { final WindowProcessController proc = uidProcesses.valueAt(i); if (proc != callerApp && proc.areBackgroundActivityStartsAllowed()) { if (proc != callerApp && proc.areBackgroundActivityStartsAllowed(appSwitchAllowed)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Background activity start allowed: process " + proc.getPid() Loading @@ -1403,6 +1436,8 @@ class ActivityStarter { // anything that has fallen through would currently be aborted Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage + "; callingUid: " + callingUid + "; appSwitchAllowed: " + appSwitchAllowed + "; balAppSwitchEnabled: " + mService.getBalAppSwitchesProtectionEnabled() + "; isCallingUidForeground: " + isCallingUidForeground + "; callingUidHasAnyVisibleWindow: " + callingUidHasAnyVisibleWindow + "; callingUidProcState: " + DebugUtils.valueToString(ActivityManager.class, Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +44 −1 Original line number Diff line number Diff line Loading @@ -161,9 +161,11 @@ import android.app.WindowConfiguration; import android.app.admin.DevicePolicyCache; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.compat.CompatChanges; import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.EnterPipRequestedItem; import android.app.usage.UsageStatsManagerInternal; import android.compat.annotation.ChangeId; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.ContentResolver; Loading Loading @@ -214,6 +216,7 @@ import android.os.UserManager; import android.os.WorkSource; import android.os.storage.IStorageManager; import android.os.storage.StorageManager; import android.provider.DeviceConfig; import android.provider.Settings; import android.service.dreams.DreamActivity; import android.service.voice.IVoiceInteractionSession; Loading Loading @@ -342,6 +345,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** This activity is being relaunched due to a free-resize operation. */ public static final int RELAUNCH_REASON_FREE_RESIZE = 2; /** * Apps are blocked from starting activities in the foreground after the user presses home. */ public static final String BLOCK_ACTIVITY_STARTS_AFTER_HOME_FLAG = "am_block_activity_starts_after_home"; Context mContext; /** Loading Loading @@ -396,6 +405,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { volatile WindowProcessController mHeavyWeightProcess; boolean mHasHeavyWeightFeature; boolean mHasLeanbackFeature; boolean mBlockActivityAfterHomeEnabled; /** The process of the top most activity. */ volatile WindowProcessController mTopApp; /** Loading Loading @@ -759,6 +769,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mVrController.onSystemReady(); mRecentTasks.onSystemReadyLocked(); mStackSupervisor.onSystemReady(); mBlockActivityAfterHomeEnabled = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, BLOCK_ACTIVITY_STARTS_AFTER_HOME_FLAG, false); } } Loading Loading @@ -2630,8 +2643,35 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { throw new SecurityException(msg); } /** * Return true if app switch protection will be handled by background activity launch logic. */ boolean getBalAppSwitchesProtectionEnabled() { return mBlockActivityAfterHomeEnabled; } /** * Return true if app switching is allowed. */ boolean getBalAppSwitchesAllowed() { if (getBalAppSwitchesProtectionEnabled()) { // Apps no longer able to start BAL again until app switching is resumed. return mAppSwitchesAllowedTime == 0; } else { // Legacy behavior, BAL logic won't block app switching. return true; } } boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, int callingPid, int callingUid, String name) { // Background activity launch logic replaces app switching protection, so allow // apps to start activity here now. if (getBalAppSwitchesProtectionEnabled()) { return true; } if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { return true; } Loading Loading @@ -4666,9 +4706,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME; mLastStopAppSwitchesTime = SystemClock.uptimeMillis(); mDidAppSwitch = false; // If BAL app switching enabled, app switches are blocked not delayed. if (!getBalAppSwitchesProtectionEnabled()) { getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME); } } } @Override public void resumeAppSwitches() { Loading
services/core/java/com/android/server/wm/WindowProcessController.java +25 −21 Original line number Diff line number Diff line Loading @@ -516,7 +516,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio } } boolean areBackgroundActivityStartsAllowed() { boolean areBackgroundActivityStartsAllowed(boolean appSwitchAllowed) { // If app switching is not allowed, we ignore all the start activity grace period // exception so apps cannot start itself in onPause() after pressing home button. if (appSwitchAllowed) { // allow if any activity in the caller has either started or finished very recently, and // it must be started or finished after last stop app switches time. final long now = SystemClock.uptimeMillis(); Loading @@ -540,6 +543,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio } } } // allow if the proc is instrumenting with background activity starts privs if (mInstrumentingWithBackgroundActivityStartPrivileges) { if (DEBUG_ACTIVITY_STARTS) { Loading @@ -550,7 +554,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio return true; } // allow if the caller has an activity in any foreground task if (hasActivityInVisibleTask()) { if (appSwitchAllowed && hasActivityInVisibleTask()) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "[WindowProcessController(" + mPid + ")] Activity start allowed: process has activity in foreground task"); Loading