From 8b3d987b59d6811b301d97101f57ecfcd4e18a43 Mon Sep 17 00:00:00 2001
From: helen cheuk <helencheuk@google.com>
Date: Thu, 24 Aug 2023 10:58:17 +0000
Subject: [PATCH] Update the last active time to be in-sync with recency when
 device restarts

Found an issue that the last active time of tasks are random and not in-sync with their recent order. But it is needed with implementing pruning by last active time in ag/24058375. So the fix is to update the last active time before returning the task list

Fix: 271570416
Test: RecentTasksTest
Change-Id: Ied43f88fc3d87ee22b7292078afddfc52b29a087
---
 .../com/android/server/wm/RecentTasks.java    | 11 +++++++
 .../android/server/wm/RecentTasksTest.java    | 33 +++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index f33ecaa90531..10405ec7cd88 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -64,6 +64,7 @@ import android.graphics.Bitmap;
 import android.os.Environment;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.text.TextUtils;
@@ -503,6 +504,16 @@ class RecentTasks {
 
         Slog.i(TAG, "Loading recents for user " + userId + " into memory.");
         List<Task> tasks = mTaskPersister.restoreTasksForUserLocked(userId, preaddedTasks);
+
+        // Tasks are ordered from most recent to least recent. Update the last active time to be
+        // in sync with task recency when device reboots, so the most recent task has the
+        // highest last active time
+        long currentElapsedTime = SystemClock.elapsedRealtime();
+        for (int i = 0; i < tasks.size(); i++) {
+            Task task = tasks.get(i);
+            task.lastActiveTime = currentElapsedTime - i;
+        }
+
         mTasks.addAll(tasks);
         cleanupLocked(userId);
         mUsersWithRecentsLoaded.put(userId, true);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 25619b9ec5e8..4c25a4bf1455 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -91,6 +91,7 @@ import java.util.List;
 import java.util.Random;
 import java.util.Set;
 import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * Build/Install/Run:
@@ -562,6 +563,38 @@ public class RecentTasksTest extends WindowTestsBase {
                 .doesNotContain(TEST_USER_1_ID);
     }
 
+    @Test
+    public void testTasksWithCorrectOrderOfLastActiveTime() {
+        mRecentTasks.setOnlyTestVisibleRange();
+        mRecentTasks.unloadUserDataFromMemoryLocked(TEST_USER_0_ID);
+
+        // Setup some tasks for the user
+        mTaskPersister.mUserTaskIdsOverride = new SparseBooleanArray();
+        mTaskPersister.mUserTaskIdsOverride.put(1, true);
+        mTaskPersister.mUserTaskIdsOverride.put(2, true);
+        mTaskPersister.mUserTaskIdsOverride.put(3, true);
+        mTaskPersister.mUserTasksOverride = new ArrayList<>();
+        mTaskPersister.mUserTasksOverride.add(createTaskBuilder(".UserTask1").build());
+        mTaskPersister.mUserTasksOverride.add(createTaskBuilder(".UserTask2").build());
+        mTaskPersister.mUserTasksOverride.add(createTaskBuilder(".UserTask3").build());
+
+        // Assert no user tasks are initially loaded
+        assertThat(mRecentTasks.usersWithRecentsLoadedLocked()).hasLength(0);
+
+        // Load tasks
+        mRecentTasks.loadUserRecentsLocked(TEST_USER_0_ID);
+        assertThat(mRecentTasks.usersWithRecentsLoadedLocked()).asList().contains(TEST_USER_0_ID);
+
+        // Sort the time descendingly so the order should be in-sync with task recency (most
+        // recent to least recent)
+        List<Task> tasksSortedByTime = mRecentTasks.getRawTasks().stream()
+                .sorted((o1, o2) -> Long.compare(o2.lastActiveTime, o1.lastActiveTime))
+                .collect(Collectors.toList());
+
+        assertTrue("Task order is not in sync with its recency",
+                mRecentTasks.getRawTasks().equals(tasksSortedByTime));
+    }
+
     @Test
     public void testOrderedIteration() {
         mRecentTasks.setOnlyTestVisibleRange();
-- 
GitLab