Merge "Track frozen duration in procstats." into udc-qpr-dev
diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java
index fff778c..755113b 100644
--- a/core/java/com/android/internal/app/procstats/ProcessState.java
+++ b/core/java/com/android/internal/app/procstats/ProcessState.java
@@ -33,6 +33,7 @@
import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED;
import static com.android.internal.app.procstats.ProcessStats.STATE_COUNT;
import static com.android.internal.app.procstats.ProcessStats.STATE_FGS;
+import static com.android.internal.app.procstats.ProcessStats.STATE_FROZEN;
import static com.android.internal.app.procstats.ProcessStats.STATE_HEAVY_WEIGHT;
import static com.android.internal.app.procstats.ProcessStats.STATE_HOME;
import static com.android.internal.app.procstats.ProcessStats.STATE_IMPORTANT_BACKGROUND;
@@ -142,6 +143,7 @@
private ProcessState mCommonProcess;
private int mCurCombinedState = STATE_NOTHING;
private long mStartTime;
+ private int mStateBeforeFrozen = STATE_NOTHING;
private int mLastPssState = STATE_NOTHING;
private long mLastPssTime;
@@ -423,6 +425,27 @@
}
/**
+ * Used to notify that this process was frozen.
+ */
+ public void onProcessFrozen(long now,
+ ArrayMap<String, ProcessStateHolder> pkgList) {
+ mStateBeforeFrozen = mCurCombinedState % STATE_COUNT;
+ int currentMemFactor = mCurCombinedState / STATE_COUNT;
+ int combinedState = STATE_FROZEN + (currentMemFactor * STATE_COUNT);
+ setCombinedState(combinedState, now, pkgList);
+ }
+
+ /**
+ * Used to notify that this process was unfrozen.
+ */
+ public void onProcessUnfrozen(long now,
+ ArrayMap<String, ProcessStateHolder> pkgList) {
+ int currentMemFactor = mCurCombinedState / STATE_COUNT;
+ int combinedState = mStateBeforeFrozen + (currentMemFactor * STATE_COUNT);
+ setCombinedState(combinedState, now, pkgList);
+ }
+
+ /**
* Update the current state of the given list of processes.
*
* @param state Current ActivityManager.PROCESS_STATE_*
@@ -434,13 +457,20 @@
ArrayMap<String, ProcessStateHolder> pkgList) {
if (state < 0) {
state = mNumStartedServices > 0
- ? (STATE_SERVICE_RESTARTING+(memFactor*STATE_COUNT)) : STATE_NOTHING;
+ ? (STATE_SERVICE_RESTARTING + (memFactor * STATE_COUNT)) : STATE_NOTHING;
} else {
- state = PROCESS_STATE_TO_STATE[state] + (memFactor*STATE_COUNT);
+ state = PROCESS_STATE_TO_STATE[state] + (memFactor * STATE_COUNT);
}
+ setCombinedState(state, now, pkgList);
+ }
+ /**
+ * Sets combined state on the corresponding ProcessState objects.
+ */
+ void setCombinedState(int state, long now,
+ ArrayMap<String, ProcessStateHolder> pkgList) {
// First update the common process.
- mCommonProcess.setCombinedState(state, now);
+ mCommonProcess.setCombinedStateIdv(state, now);
// If the common process is not multi-package, there is nothing else to do.
if (!mCommonProcess.mMultiPackage) {
@@ -449,12 +479,15 @@
if (pkgList != null) {
for (int ip=pkgList.size()-1; ip>=0; ip--) {
- pullFixedProc(pkgList, ip).setCombinedState(state, now);
+ pullFixedProc(pkgList, ip).setCombinedStateIdv(state, now);
}
}
}
- public void setCombinedState(int state, long now) {
+ /**
+ * Sets the combined state for this individual ProcessState object.
+ */
+ void setCombinedStateIdv(int state, long now) {
ensureNotDead();
if (!mDead && (mCurCombinedState != state)) {
//Slog.i(TAG, "Setting state in " + mName + "/" + mPackage + ": " + state);
@@ -545,7 +578,7 @@
}
mNumStartedServices++;
if (mNumStartedServices == 1 && mCurCombinedState == STATE_NOTHING) {
- setCombinedState(STATE_SERVICE_RESTARTING + (memFactor*STATE_COUNT), now);
+ setCombinedStateIdv(STATE_SERVICE_RESTARTING + (memFactor * STATE_COUNT), now);
}
}
@@ -561,7 +594,7 @@
}
mNumStartedServices--;
if (mNumStartedServices == 0 && (mCurCombinedState %STATE_COUNT) == STATE_SERVICE_RESTARTING) {
- setCombinedState(STATE_NOTHING, now);
+ setCombinedStateIdv(STATE_NOTHING, now);
} else if (mNumStartedServices < 0) {
Slog.wtfStack(TAG, "Proc started services underrun: pkg="
+ mPackage + " uid=" + mUid + " name=" + mName);
@@ -1588,7 +1621,9 @@
case STATE_CACHED:
cachedMs += duration;
break;
- // TODO (b/261910877) Add support for tracking frozenMs.
+ case STATE_FROZEN:
+ frozenMs += duration;
+ break;
}
}
statsEventOutput.write(
diff --git a/core/tests/coretests/src/com/android/internal/app/procstats/ProcessStatsTest.java b/core/tests/coretests/src/com/android/internal/app/procstats/ProcessStatsTest.java
index 6189914..fe30d81 100644
--- a/core/tests/coretests/src/com/android/internal/app/procstats/ProcessStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/procstats/ProcessStatsTest.java
@@ -16,8 +16,6 @@
package com.android.internal.app.procstats;
-import static com.android.internal.app.procstats.ProcessStats.STATE_TOP;
-
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
@@ -108,7 +106,8 @@
ProcessState processState =
processStats.getProcessStateLocked(
APP_1_PACKAGE_NAME, APP_1_UID, APP_1_VERSION, APP_1_PROCESS_NAME);
- processState.setCombinedState(STATE_TOP, NOW_MS);
+ processState.setState(ActivityManager.PROCESS_STATE_TOP, ProcessStats.ADJ_MEM_FACTOR_NORMAL,
+ NOW_MS, /* pkgList */ null);
processState.commitStateTime(NOW_MS + TimeUnit.SECONDS.toMillis(DURATION_SECS));
processStats.dumpProcessState(FrameworkStatsLog.PROCESS_STATE, mStatsEventOutput);
verify(mStatsEventOutput)
@@ -158,6 +157,38 @@
}
@SmallTest
+ public void testDumpFrozenDuration() throws Exception {
+ ProcessStats processStats = new ProcessStats();
+ ProcessState processState =
+ processStats.getProcessStateLocked(
+ APP_1_PACKAGE_NAME, APP_1_UID, APP_1_VERSION, APP_1_PROCESS_NAME);
+ processState.setState(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE,
+ ProcessStats.ADJ_MEM_FACTOR_NORMAL, NOW_MS, /* pkgList */ null);
+ processState.onProcessFrozen(NOW_MS + 1 * TimeUnit.SECONDS.toMillis(DURATION_SECS),
+ /* pkgList */ null);
+ processState.onProcessUnfrozen(NOW_MS + 2 * TimeUnit.SECONDS.toMillis(DURATION_SECS),
+ /* pkgList */ null);
+ processState.commitStateTime(NOW_MS + 3 * TimeUnit.SECONDS.toMillis(DURATION_SECS));
+ processStats.dumpProcessState(FrameworkStatsLog.PROCESS_STATE, mStatsEventOutput);
+ verify(mStatsEventOutput)
+ .write(
+ eq(FrameworkStatsLog.PROCESS_STATE),
+ eq(APP_1_UID),
+ eq(APP_1_PROCESS_NAME),
+ anyInt(),
+ anyInt(),
+ eq(0),
+ eq(0),
+ eq(0),
+ eq(0),
+ eq(2 * DURATION_SECS), // bound_fgs
+ eq(0),
+ eq(0),
+ eq(DURATION_SECS), // frozen
+ eq(0));
+ }
+
+ @SmallTest
public void testDumpProcessAssociation() throws Exception {
ProcessStats processStats = new ProcessStats();
AssociationState associationState =
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index be514c5..db93323 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -1513,7 +1513,7 @@
mFreezeHandler.obtainMessage(REPORT_UNFREEZE_MSG,
pid,
(int) Math.min(opt.getFreezeUnfreezeTime() - freezeTime, Integer.MAX_VALUE),
- new Pair<String, Integer>(app.processName, reason)));
+ new Pair<ProcessRecord, Integer>(app, reason)));
}
}
@@ -2151,11 +2151,12 @@
case REPORT_UNFREEZE_MSG: {
int pid = msg.arg1;
int frozenDuration = msg.arg2;
- Pair<String, Integer> obj = (Pair<String, Integer>) msg.obj;
- String processName = obj.first;
+ Pair<ProcessRecord, Integer> obj = (Pair<ProcessRecord, Integer>) msg.obj;
+ ProcessRecord app = obj.first;
+ String processName = app.processName;
int reason = obj.second;
- reportUnfreeze(pid, frozenDuration, processName, reason);
+ reportUnfreeze(app, pid, frozenDuration, processName, reason);
} break;
case UID_FROZEN_STATE_CHANGED_MSG: {
final boolean frozen = (msg.arg1 == 1);
@@ -2350,10 +2351,11 @@
}
}
- private void reportUnfreeze(int pid, int frozenDuration, String processName,
- @UnfreezeReason int reason) {
+ private void reportUnfreeze(ProcessRecord app, int pid, int frozenDuration,
+ String processName, @UnfreezeReason int reason) {
EventLog.writeEvent(EventLogTags.AM_UNFREEZE, pid, processName, reason);
+ app.onProcessUnfrozen();
// See above for why we're not taking mPhenotypeFlagLock here
if (mRandom.nextFloat() < mFreezerStatsdSampleRate) {
diff --git a/services/core/java/com/android/server/am/ProcessProfileRecord.java b/services/core/java/com/android/server/am/ProcessProfileRecord.java
index 5ad49a4..db74f1a 100644
--- a/services/core/java/com/android/server/am/ProcessProfileRecord.java
+++ b/services/core/java/com/android/server/am/ProcessProfileRecord.java
@@ -225,6 +225,32 @@
mBaseProcessTracker = baseProcessTracker;
}
+ void onProcessFrozen() {
+ synchronized (mService.mProcessStats.mLock) {
+ final ProcessState tracker = mBaseProcessTracker;
+ if (tracker != null) {
+ final PackageList pkgList = mApp.getPkgList();
+ final long now = SystemClock.uptimeMillis();
+ synchronized (pkgList) {
+ tracker.onProcessFrozen(now, pkgList.getPackageListLocked());
+ }
+ }
+ }
+ }
+
+ void onProcessUnfrozen() {
+ synchronized (mService.mProcessStats.mLock) {
+ final ProcessState tracker = mBaseProcessTracker;
+ if (tracker != null) {
+ final PackageList pkgList = mApp.getPkgList();
+ final long now = SystemClock.uptimeMillis();
+ synchronized (pkgList) {
+ tracker.onProcessUnfrozen(now, pkgList.getPackageListLocked());
+ }
+ }
+ }
+ }
+
void onProcessActive(IApplicationThread thread, ProcessStatsService tracker) {
if (mThread == null) {
synchronized (mProfilerLock) {
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index f6acc41..99ba098 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -1354,6 +1354,15 @@
return false;
}
+ void onProcessFrozen() {
+ mProfile.onProcessFrozen();
+ }
+
+ void onProcessUnfrozen() {
+ mProfile.onProcessUnfrozen();
+ }
+
+
/*
* Delete all packages from list except the package indicated in info
*/