Merge "Allow FGS start within a grace period after its activity going to BG" into sc-dev
This commit is contained in:
@@ -174,6 +174,8 @@ public class PowerExemptionManager {
|
||||
public static final int REASON_ALLOWLISTED_PACKAGE = 65;
|
||||
/** @hide */
|
||||
public static final int REASON_APPOP = 66;
|
||||
/** @hide */
|
||||
public static final int REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD = 67;
|
||||
|
||||
/* BG-FGS-launch is allowed by temp-allow-list or system-allow-list.
|
||||
Reason code for temp and system allow list starts here.
|
||||
@@ -334,6 +336,7 @@ public class PowerExemptionManager {
|
||||
REASON_EXEMPTED_PACKAGE,
|
||||
REASON_ALLOWLISTED_PACKAGE,
|
||||
REASON_APPOP,
|
||||
REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD,
|
||||
// temp and system allow list reasons.
|
||||
REASON_GEOFENCING,
|
||||
REASON_PUSH_MESSAGING,
|
||||
@@ -585,6 +588,8 @@ public class PowerExemptionManager {
|
||||
return "ALLOWLISTED_PACKAGE";
|
||||
case REASON_APPOP:
|
||||
return "APPOP";
|
||||
case REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD:
|
||||
return "ACTIVITY_VISIBILITY_GRACE_PERIOD";
|
||||
case REASON_GEOFENCING:
|
||||
return "GEOFENCING";
|
||||
case REASON_PUSH_MESSAGING:
|
||||
|
||||
@@ -24,6 +24,7 @@ import static android.app.ActivityManager.PROCESS_STATE_RECEIVER;
|
||||
import static android.app.ActivityManager.PROCESS_STATE_TOP;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST;
|
||||
import static android.os.PowerExemptionManager.REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD;
|
||||
import static android.os.PowerWhitelistManager.REASON_ACTIVITY_STARTER;
|
||||
import static android.os.PowerWhitelistManager.REASON_ALLOWLISTED_PACKAGE;
|
||||
import static android.os.PowerWhitelistManager.REASON_BACKGROUND_ACTIVITY_PERMISSION;
|
||||
@@ -5597,6 +5598,14 @@ public final class ActiveServices {
|
||||
&& instr.mHasBackgroundForegroundServiceStartsPermission) {
|
||||
return REASON_INSTR_BACKGROUND_FGS_PERMISSION;
|
||||
}
|
||||
final long lastInvisibleTime = app.mState.getLastInvisibleTime();
|
||||
if (lastInvisibleTime > 0 && lastInvisibleTime < Long.MAX_VALUE) {
|
||||
final long sinceLastInvisible = SystemClock.elapsedRealtime()
|
||||
- lastInvisibleTime;
|
||||
if (sinceLastInvisible < mAm.mConstants.mFgToBgFgsGraceDuration) {
|
||||
return REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -95,6 +95,7 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
"process_crash_count_reset_interval";
|
||||
static final String KEY_PROCESS_CRASH_COUNT_LIMIT = "process_crash_count_limit";
|
||||
static final String KEY_BOOT_TIME_TEMP_ALLOWLIST_DURATION = "boot_time_temp_allowlist_duration";
|
||||
static final String KEY_FG_TO_BG_FGS_GRACE_DURATION = "fg_to_bg_fgs_grace_duration";
|
||||
|
||||
private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
|
||||
private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000;
|
||||
@@ -133,6 +134,7 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
private static final int DEFAULT_PROCESS_CRASH_COUNT_RESET_INTERVAL = 12 * 60 * 60 * 1000;
|
||||
private static final int DEFAULT_PROCESS_CRASH_COUNT_LIMIT = 12;
|
||||
private static final int DEFAULT_BOOT_TIME_TEMP_ALLOWLIST_DURATION = 10 * 1000;
|
||||
private static final long DEFAULT_FG_TO_BG_FGS_GRACE_DURATION = 5 * 1000;
|
||||
|
||||
|
||||
// Flag stored in the DeviceConfig API.
|
||||
@@ -388,6 +390,12 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
*/
|
||||
volatile long mBootTimeTempAllowlistDuration = DEFAULT_BOOT_TIME_TEMP_ALLOWLIST_DURATION;
|
||||
|
||||
/**
|
||||
* The grace period in milliseconds to allow a process to start FGS from background after
|
||||
* switching from foreground to background; currently it's only applicable to its activities.
|
||||
*/
|
||||
volatile long mFgToBgFgsGraceDuration = DEFAULT_FG_TO_BG_FGS_GRACE_DURATION;
|
||||
|
||||
private final ActivityManagerService mService;
|
||||
private ContentResolver mResolver;
|
||||
private final KeyValueListParser mParser = new KeyValueListParser(',');
|
||||
@@ -575,6 +583,9 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
case KEY_BOOT_TIME_TEMP_ALLOWLIST_DURATION:
|
||||
updateBootTimeTempAllowListDuration();
|
||||
break;
|
||||
case KEY_FG_TO_BG_FGS_GRACE_DURATION:
|
||||
updateFgToBgFgsGraceDuration();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -851,6 +862,13 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
DEFAULT_BOOT_TIME_TEMP_ALLOWLIST_DURATION);
|
||||
}
|
||||
|
||||
private void updateFgToBgFgsGraceDuration() {
|
||||
mFgToBgFgsGraceDuration = DeviceConfig.getLong(
|
||||
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
|
||||
KEY_FG_TO_BG_FGS_GRACE_DURATION,
|
||||
DEFAULT_FG_TO_BG_FGS_GRACE_DURATION);
|
||||
}
|
||||
|
||||
private void updateImperceptibleKillExemptions() {
|
||||
IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.clear();
|
||||
IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.addAll(mDefaultImperceptibleKillExemptPackages);
|
||||
@@ -1051,6 +1069,8 @@ final class ActivityManagerConstants extends ContentObserver {
|
||||
pw.println(MAX_PHANTOM_PROCESSES);
|
||||
pw.print(" "); pw.print(KEY_BOOT_TIME_TEMP_ALLOWLIST_DURATION); pw.print("=");
|
||||
pw.println(mBootTimeTempAllowlistDuration);
|
||||
pw.print(" "); pw.print(KEY_FG_TO_BG_FGS_GRACE_DURATION); pw.print("=");
|
||||
pw.println(mFgToBgFgsGraceDuration);
|
||||
|
||||
pw.println();
|
||||
if (mOverrideMaxCachedProcesses >= 0) {
|
||||
|
||||
@@ -1367,6 +1367,7 @@ public final class OomAdjuster {
|
||||
ProcessRecord app;
|
||||
int adj;
|
||||
boolean foregroundActivities;
|
||||
boolean mHasVisibleActivities;
|
||||
int procState;
|
||||
int schedGroup;
|
||||
int appUid;
|
||||
@@ -1375,10 +1376,12 @@ public final class OomAdjuster {
|
||||
ProcessStateRecord mState;
|
||||
|
||||
void initialize(ProcessRecord app, int adj, boolean foregroundActivities,
|
||||
int procState, int schedGroup, int appUid, int logUid, int processStateCurTop) {
|
||||
boolean hasVisibleActivities, int procState, int schedGroup, int appUid,
|
||||
int logUid, int processStateCurTop) {
|
||||
this.app = app;
|
||||
this.adj = adj;
|
||||
this.foregroundActivities = foregroundActivities;
|
||||
this.mHasVisibleActivities = hasVisibleActivities;
|
||||
this.procState = procState;
|
||||
this.schedGroup = schedGroup;
|
||||
this.appUid = appUid;
|
||||
@@ -1411,6 +1414,7 @@ public final class OomAdjuster {
|
||||
mState.setCached(false);
|
||||
mState.setEmpty(false);
|
||||
foregroundActivities = true;
|
||||
mHasVisibleActivities = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1436,6 +1440,7 @@ public final class OomAdjuster {
|
||||
mState.setCached(false);
|
||||
mState.setEmpty(false);
|
||||
foregroundActivities = true;
|
||||
mHasVisibleActivities = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1468,6 +1473,7 @@ public final class OomAdjuster {
|
||||
mState.setCached(false);
|
||||
mState.setEmpty(false);
|
||||
foregroundActivities = true;
|
||||
mHasVisibleActivities = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1480,6 +1486,7 @@ public final class OomAdjuster {
|
||||
"Raise procstate to cached activity: " + app);
|
||||
}
|
||||
}
|
||||
mHasVisibleActivities = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1591,12 +1598,14 @@ public final class OomAdjuster {
|
||||
int capability = 0;
|
||||
|
||||
boolean foregroundActivities = false;
|
||||
boolean hasVisibleActivities = false;
|
||||
if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == topApp) {
|
||||
// The last app on the list is the foreground app.
|
||||
adj = ProcessList.FOREGROUND_APP_ADJ;
|
||||
schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
|
||||
state.setAdjType("top-activity");
|
||||
foregroundActivities = true;
|
||||
hasVisibleActivities = true;
|
||||
procState = PROCESS_STATE_CUR_TOP;
|
||||
state.bumpAllowStartFgsState(PROCESS_STATE_TOP);
|
||||
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
|
||||
@@ -1672,11 +1681,12 @@ public final class OomAdjuster {
|
||||
// Examine all activities if not already foreground.
|
||||
if (!foregroundActivities && state.getCachedHasActivities()) {
|
||||
state.computeOomAdjFromActivitiesIfNecessary(mTmpComputeOomAdjWindowCallback,
|
||||
adj, foregroundActivities, procState, schedGroup, appUid, logUid,
|
||||
PROCESS_STATE_CUR_TOP);
|
||||
adj, foregroundActivities, hasVisibleActivities, procState, schedGroup,
|
||||
appUid, logUid, PROCESS_STATE_CUR_TOP);
|
||||
|
||||
adj = state.getCachedAdj();
|
||||
foregroundActivities = state.getCachedForegroundActivities();
|
||||
hasVisibleActivities = state.getCachedHasVisibleActivities();
|
||||
procState = state.getCachedProcState();
|
||||
schedGroup = state.getCachedSchedGroup();
|
||||
}
|
||||
@@ -2450,6 +2460,7 @@ public final class OomAdjuster {
|
||||
state.setCurrentSchedulingGroup(schedGroup);
|
||||
state.setCurProcState(procState);
|
||||
state.setCurRawProcState(procState);
|
||||
state.updateLastInvisibleTime(hasVisibleActivities);
|
||||
state.setHasForegroundActivities(foregroundActivities);
|
||||
state.setCompletedAdjSeq(mAdjSeq);
|
||||
state.setAllowStartFgs();
|
||||
|
||||
@@ -43,6 +43,7 @@ import static android.os.Process.SYSTEM_UID;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
|
||||
import static com.android.server.am.ProcessRecord.TAG;
|
||||
|
||||
import android.annotation.ElapsedRealtimeLong;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ComponentName;
|
||||
import android.os.Binder;
|
||||
@@ -386,6 +387,16 @@ final class ProcessStateRecord {
|
||||
@GuardedBy("mService")
|
||||
private boolean mReachable;
|
||||
|
||||
/**
|
||||
* The most recent time when the last visible activity within this process became invisible.
|
||||
*
|
||||
* <p> It'll be set to 0 if there is never a visible activity, or Long.MAX_VALUE if there is
|
||||
* any visible activities within this process at this moment.</p>
|
||||
*/
|
||||
@GuardedBy("mService")
|
||||
@ElapsedRealtimeLong
|
||||
private long mLastInvisibleTime;
|
||||
|
||||
// Below are the cached task info for OomAdjuster only
|
||||
private static final int VALUE_INVALID = -1;
|
||||
private static final int VALUE_FALSE = 0;
|
||||
@@ -1040,18 +1051,19 @@ final class ProcessStateRecord {
|
||||
|
||||
@GuardedBy("mService")
|
||||
void computeOomAdjFromActivitiesIfNecessary(OomAdjuster.ComputeOomAdjWindowCallback callback,
|
||||
int adj, boolean foregroundActivities, int procState, int schedGroup, int appUid,
|
||||
int logUid, int processCurTop) {
|
||||
int adj, boolean foregroundActivities, boolean hasVisibleActivities, int procState,
|
||||
int schedGroup, int appUid, int logUid, int processCurTop) {
|
||||
if (mCachedAdj != ProcessList.INVALID_ADJ) {
|
||||
return;
|
||||
}
|
||||
callback.initialize(mApp, adj, foregroundActivities, procState, schedGroup, appUid, logUid,
|
||||
processCurTop);
|
||||
callback.initialize(mApp, adj, foregroundActivities, hasVisibleActivities, procState,
|
||||
schedGroup, appUid, logUid, processCurTop);
|
||||
final int minLayer = Math.min(ProcessList.VISIBLE_APP_LAYER_MAX,
|
||||
mApp.getWindowProcessController().computeOomAdjFromActivities(callback));
|
||||
|
||||
mCachedAdj = callback.adj;
|
||||
mCachedForegroundActivities = callback.foregroundActivities;
|
||||
mCachedHasVisibleActivities = callback.mHasVisibleActivities ? VALUE_TRUE : VALUE_FALSE;
|
||||
mCachedProcState = callback.procState;
|
||||
mCachedSchedGroup = callback.schedGroup;
|
||||
|
||||
@@ -1263,6 +1275,21 @@ final class ProcessStateRecord {
|
||||
return mAllowStartFgs;
|
||||
}
|
||||
|
||||
@GuardedBy("mService")
|
||||
void updateLastInvisibleTime(boolean hasVisibleActivities) {
|
||||
if (hasVisibleActivities) {
|
||||
mLastInvisibleTime = Long.MAX_VALUE;
|
||||
} else if (mLastInvisibleTime == Long.MAX_VALUE) {
|
||||
mLastInvisibleTime = SystemClock.elapsedRealtime();
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mService")
|
||||
@ElapsedRealtimeLong
|
||||
long getLastInvisibleTime() {
|
||||
return mLastInvisibleTime;
|
||||
}
|
||||
|
||||
@GuardedBy({"mService", "mProcLock"})
|
||||
void dump(PrintWriter pw, String prefix, long nowUptime) {
|
||||
if (mReportedInteraction || mFgInteractionTime != 0) {
|
||||
@@ -1340,6 +1367,15 @@ final class ProcessStateRecord {
|
||||
TimeUtils.formatDuration(mLastTopTime, nowUptime, pw);
|
||||
pw.println();
|
||||
}
|
||||
if (mLastInvisibleTime > 0 && mLastInvisibleTime < Long.MAX_VALUE) {
|
||||
pw.print(prefix); pw.print("lastInvisibleTime=");
|
||||
final long elapsedRealtimeNow = SystemClock.elapsedRealtime();
|
||||
final long currentTimeNow = System.currentTimeMillis();
|
||||
final long lastInvisibleCurrentTime =
|
||||
currentTimeNow - elapsedRealtimeNow + mLastInvisibleTime;
|
||||
TimeUtils.dumpTimeWithDelta(pw, lastInvisibleCurrentTime, currentTimeNow);
|
||||
pw.println();
|
||||
}
|
||||
if (mHasStartedServices) {
|
||||
pw.print(prefix); pw.print("hasStartedServices="); pw.println(mHasStartedServices);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user