Prevent extra work on the same timestamp

AttentionDetector gets called a lot, and there is no reason to do
any work, unless it is called with a new timestamp.

Bug: 111939367
Test: verified by doing FSOP + atest AttentionDetectorTest
Change-Id: If427bd3358e0ea35279fb5d235c2fd137df036ac
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index 7605ccb..e148468 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -270,7 +270,7 @@
                 return;
             }
             if (!userState.mCurrentAttentionCheck.mCallbackInternal.equals(callbackInternal)) {
-                Slog.e(LOG_TAG, "Cannot cancel a non-current request");
+                Slog.w(LOG_TAG, "Cannot cancel a non-current request");
                 return;
             }
             cancel(userState);
diff --git a/services/core/java/com/android/server/power/AttentionDetector.java b/services/core/java/com/android/server/power/AttentionDetector.java
index 3262eb6..14f1196 100644
--- a/services/core/java/com/android/server/power/AttentionDetector.java
+++ b/services/core/java/com/android/server/power/AttentionDetector.java
@@ -75,6 +75,8 @@
      */
     private final AtomicBoolean mRequested;
 
+    private long mLastActedOnNextScreenDimming;
+
     /**
      * Monotonously increasing ID for the requests sent.
      */
@@ -150,6 +152,9 @@
     }
 
     public long updateUserActivity(long nextScreenDimming) {
+        if (nextScreenDimming == mLastActedOnNextScreenDimming) {
+            return nextScreenDimming;
+        }
         if (!mIsSettingEnabled) {
             return nextScreenDimming;
         }
@@ -190,13 +195,14 @@
         // afterwards if AttentionManager couldn't deliver it.
         mRequested.set(true);
         mRequestId++;
+        mLastActedOnNextScreenDimming = nextScreenDimming;
         mCallback = new AttentionCallbackInternalImpl(mRequestId);
+        Slog.v(TAG, "Checking user attention, ID: " + mRequestId);
         final boolean sent = mAttentionManager.checkAttention(getAttentionTimeout(), mCallback);
         if (!sent) {
             mRequested.set(false);
         }
 
-        Slog.v(TAG, "Checking user attention, ID: " + mRequestId);
         return whenToCheck;
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
index c30a7dd..a63f49b 100644
--- a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
@@ -182,10 +183,22 @@
     }
 
     @Test
+    public void testOnUserActivity_ignoresIfAlreadyDoneForThatNextScreenDimming() {
+        long when = registerAttention();
+        verify(mAttentionManagerInternal).checkAttention(anyLong(), any());
+        assertThat(when).isLessThan(mNextDimming);
+        clearInvocations(mAttentionManagerInternal);
+
+        long redundantWhen = mAttentionDetector.updateUserActivity(mNextDimming);
+        assertThat(redundantWhen).isEqualTo(mNextDimming);
+        verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
+    }
+
+    @Test
     public void testOnUserActivity_skipsIfAlreadyScheduled() {
         registerAttention();
         reset(mAttentionManagerInternal);
-        long when = mAttentionDetector.updateUserActivity(mNextDimming);
+        long when = mAttentionDetector.updateUserActivity(mNextDimming + 1);
         verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
         assertThat(when).isLessThan(mNextDimming);
     }