Only collect PSS one time after an app has been frozen.

Bug: 253913855
Test: print to console when we hit this condition
Change-Id: If1913e9d6b4d3bde3e2c751cd52ca85a6deeee09
Signed-off-by: Mark Fasheh <mfasheh@google.com>
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index b7de57f8..45b11e1 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -506,10 +506,14 @@
             }
             if (profile != null) {
                 long startTime = SystemClock.currentThreadTimeMillis();
-                // skip background PSS calculation of apps that are capturing
-                // camera imagery
-                final boolean usingCamera = mService.isCameraActiveForUid(profile.mApp.uid);
-                long pss = usingCamera ? 0 : Debug.getPss(pid, tmp, null);
+                // skip background PSS calculation under the following situations:
+                //  - app is capturing camera imagery
+                //  - app is frozen and we have already collected PSS once.
+                final boolean skipPSSCollection =
+                        (profile.mApp.mOptRecord != null
+                         && profile.mApp.mOptRecord.skipPSSCollectionBecauseFrozen())
+                        || mService.isCameraActiveForUid(profile.mApp.uid);
+                long pss = skipPSSCollection ? 0 : Debug.getPss(pid, tmp, null);
                 long endTime = SystemClock.currentThreadTimeMillis();
                 synchronized (mProfilerLock) {
                     if (pss != 0 && profile.getThread() != null
@@ -524,7 +528,7 @@
                         if (DEBUG_PSS) {
                             Slog.d(TAG_PSS, "Skipped pss collection of " + pid
                                     + ": " + (profile.getThread() == null ? "NO_THREAD " : "")
-                                    + (usingCamera ? "CAMERA " : "")
+                                    + (skipPSSCollection ? "SKIP_PSS_COLLECTION " : "")
                                     + (profile.getPid() != pid ? "PID_CHANGED " : "")
                                     + " initState=" + procState + " curState="
                                     + profile.getSetProcState() + " "
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index cbf0aae..a3b3238 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -1977,6 +1977,7 @@
 
                     opt.setFreezeUnfreezeTime(SystemClock.uptimeMillis());
                     opt.setFrozen(true);
+                    opt.setHasCollectedFrozenPSS(false);
                     mFrozenProcesses.put(pid, proc);
                 } catch (Exception e) {
                     Slog.w(TAG_AM, "Unable to freeze " + pid + " " + name);
diff --git a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
index fb41a39..24cc533 100644
--- a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
+++ b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
@@ -73,6 +73,12 @@
     private boolean mFrozen;
 
     /**
+     * Set to false after the process has been frozen.
+     * Set to true after we have collected PSS for the frozen process.
+     */
+    private boolean mHasCollectedFrozenPSS;
+
+    /**
      * An override on the freeze state is in progress.
      */
     @GuardedBy("mProcLock")
@@ -188,6 +194,25 @@
         mFrozen = frozen;
     }
 
+    boolean skipPSSCollectionBecauseFrozen() {
+        boolean collected = mHasCollectedFrozenPSS;
+
+        // This check is racy but it isn't critical to PSS collection that we have the most up to
+        // date idea of whether a task is frozen.
+        if (!mFrozen) {
+            // not frozen == always ask to collect PSS
+            return false;
+        }
+
+        // We don't want to count PSS for a frozen process more than once.
+        mHasCollectedFrozenPSS = true;
+        return collected;
+    }
+
+    void setHasCollectedFrozenPSS(boolean collected) {
+        mHasCollectedFrozenPSS = collected;
+    }
+
     @GuardedBy("mProcLock")
     boolean hasFreezerOverride() {
         return mFreezerOverride;