Merge "Introduce Background Activity Launch home mode"
This commit is contained in:
@@ -1195,7 +1195,23 @@ class ActivityStarter {
|
||||
}
|
||||
}
|
||||
|
||||
mService.onStartActivitySetDidAppSwitch();
|
||||
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,
|
||||
@@ -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 =
|
||||
@@ -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 = "
|
||||
@@ -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
|
||||
@@ -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");
|
||||
@@ -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()
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
@@ -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;
|
||||
/**
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -4666,7 +4706,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
|
||||
mLastStopAppSwitchesTime = SystemClock.uptimeMillis();
|
||||
mDidAppSwitch = false;
|
||||
getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
|
||||
// If BAL app switching enabled, app switches are blocked not delayed.
|
||||
if (!getBalAppSwitchesProtectionEnabled()) {
|
||||
getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -516,29 +516,33 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
|
||||
}
|
||||
}
|
||||
|
||||
boolean areBackgroundActivityStartsAllowed() {
|
||||
// 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();
|
||||
if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
|
||||
|| now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
|
||||
// if activity is started and finished before stop app switch time, we should not
|
||||
// let app to be able to start background activity even it's in grace period.
|
||||
if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime()
|
||||
|| mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) {
|
||||
if (DEBUG_ACTIVITY_STARTS) {
|
||||
Slog.d(TAG, "[WindowProcessController(" + mPid
|
||||
+ ")] Activity start allowed: within "
|
||||
+ ACTIVITY_BG_START_GRACE_PERIOD_MS + "ms grace period");
|
||||
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();
|
||||
if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
|
||||
|| now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
|
||||
// if activity is started and finished before stop app switch time, we should not
|
||||
// let app to be able to start background activity even it's in grace period.
|
||||
if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime()
|
||||
|| mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) {
|
||||
if (DEBUG_ACTIVITY_STARTS) {
|
||||
Slog.d(TAG, "[WindowProcessController(" + mPid
|
||||
+ ")] Activity start allowed: within "
|
||||
+ ACTIVITY_BG_START_GRACE_PERIOD_MS + "ms grace period");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (DEBUG_ACTIVITY_STARTS) {
|
||||
Slog.d(TAG, "[WindowProcessController(" + mPid + ")] Activity start within "
|
||||
+ ACTIVITY_BG_START_GRACE_PERIOD_MS
|
||||
+ "ms grace period but also within stop app switch window");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (DEBUG_ACTIVITY_STARTS) {
|
||||
Slog.d(TAG, "[WindowProcessController(" + mPid + ")] Activity start within "
|
||||
+ ACTIVITY_BG_START_GRACE_PERIOD_MS
|
||||
+ "ms grace period but also within stop app switch window");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// allow if the proc is instrumenting with background activity starts privs
|
||||
if (mInstrumentingWithBackgroundActivityStartPrivileges) {
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user