AppIdleHistory: Only write screen on durations during regular sync

Stop writing to disk every time the display goes off. Only write to
disk periodically.

Consequences

Previously, if the device rebooted after the screen duration was written
to disk, apps would appear more stale than they actually were.

Now apps will always look fresher, which is a better scenario.

Bug:30807864
Change-Id: Ia69a2e51fc9e397789215b449fae56fa3e29c74a
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java b/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java
index 9ccb1a6..0bd014c 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java
@@ -67,7 +67,7 @@
         // Screen on time should not keep progressing with screen is off
         assertEquals(aih.getScreenOnTimeLocked(7000), 3000);
         assertEquals(aih.getScreenOnTimeLocked(8000), 3000);
-        aih.writeElapsedTimeLocked();
+        aih.writeAppIdleDurationsLocked();
 
         // Check if the screen on time is persisted across instantiations
         AppIdleHistory aih2 = new AppIdleHistory(mStorageDir, 0);
diff --git a/services/usage/java/com/android/server/usage/AppIdleHistory.java b/services/usage/java/com/android/server/usage/AppIdleHistory.java
index a3313c9..f69dae4 100644
--- a/services/usage/java/com/android/server/usage/AppIdleHistory.java
+++ b/services/usage/java/com/android/server/usage/AppIdleHistory.java
@@ -118,7 +118,6 @@
         } else {
             mScreenOnDuration += elapsedRealtime - mScreenOnSnapshot;
             mElapsedDuration += elapsedRealtime - mElapsedSnapshot;
-            writeScreenOnTimeLocked();
             mElapsedSnapshot = elapsedRealtime;
         }
     }
@@ -167,7 +166,7 @@
     /**
      * To be called periodically to keep track of elapsed time when app idle times are written
      */
-    public void writeElapsedTimeLocked() {
+    public void writeAppIdleDurationsLocked() {
         final long elapsedRealtime = SystemClock.elapsedRealtime();
         // Only bump up and snapshot the elapsed time. Don't change screen on duration.
         mElapsedDuration += elapsedRealtime - mElapsedSnapshot;
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 69cf1a2..8284773 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -304,9 +304,9 @@
 
         @Override public void onDisplayChanged(int displayId) {
             if (displayId == Display.DEFAULT_DISPLAY) {
+                final boolean displayOn = isDisplayOn();
                 synchronized (UsageStatsService.this.mLock) {
-                    mAppIdleHistory.updateDisplayLocked(isDisplayOn(),
-                            SystemClock.elapsedRealtime());
+                    mAppIdleHistory.updateDisplayLocked(displayOn, SystemClock.elapsedRealtime());
                 }
             }
         }
@@ -1005,9 +1005,9 @@
             service.persistActiveStats();
             mAppIdleHistory.writeAppIdleTimesLocked(mUserState.keyAt(i));
         }
-        // Persist elapsed time periodically, in case screen doesn't get toggled
-        // until the next boot
-        mAppIdleHistory.writeElapsedTimeLocked();
+        // Persist elapsed and screen on time. If this fails for whatever reason, the apps will be
+        // considered not-idle, which is the safest outcome in such an event.
+        mAppIdleHistory.writeAppIdleDurationsLocked();
         mHandler.removeMessages(MSG_FLUSH_TO_DISK);
     }