diff options
| author | 2023-08-29 23:54:29 +0000 | |
|---|---|---|
| committer | 2023-08-29 23:54:29 +0000 | |
| commit | 3f6427fc0a250c0a164ca46af1da157b40e2215c (patch) | |
| tree | 66d43d45f06c995da6b26f81d8d3db45fdd0e47a | |
| parent | 071a9f92251c56ce865f153c288784b7d2e4db20 (diff) | |
| parent | 51d61fb4e0db918539099fd549bf75564aef27fd (diff) | |
Merge "Track frozen duration in procstats." into udc-qpr-dev
5 files changed, 120 insertions, 17 deletions
diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java index fff778c616ee..755113b22088 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_BOUND_TOP; 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 @@ public final class ProcessState { 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 @@ public final class ProcessState { } /** + * 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 @@ public final class ProcessState { 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 @@ public final class ProcessState { 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 @@ public final class ProcessState { } 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 @@ public final class ProcessState { } 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 @@ public final class ProcessState { 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 61899143b9c5..fe30d81a24b9 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 @@ public class ProcessStatsTest extends TestCase { 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 @@ public class ProcessStatsTest extends TestCase { } @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 be514c5630f0..db933239874f 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 @@ public final class CachedAppOptimizer { 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 @@ public final class CachedAppOptimizer { 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 @@ public final class CachedAppOptimizer { } } - 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 5ad49a47a012..db74f1aed422 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 @@ final class ProcessProfileRecord { 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 f6acc41e4df3..99ba098e4534 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 @@ class ProcessRecord implements WindowProcessListener { return false; } + void onProcessFrozen() { + mProfile.onProcessFrozen(); + } + + void onProcessUnfrozen() { + mProfile.onProcessUnfrozen(); + } + + /* * Delete all packages from list except the package indicated in info */ |