Merge "Allow FGS start within a grace period after its activity going to BG" into sc-dev

This commit is contained in:
Jing Ji
2021-03-17 00:09:36 +00:00
committed by Android (Google) Code Review
5 changed files with 88 additions and 7 deletions

View File

@@ -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:

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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);
}