Remove activity from stopping activities once resumed.
Previously we were waiting for the activity to become visible before
removing from this list. This can lead to a race condition where the
activity is resumed and the stopping activities are cleaned up. If
the activity has not become visible, the resumed activity will be
stopped.
This CL addresses the issue by removing the activity from the
stopping activities list once resume has completed.
Change-Id: Ic33906327e538920961e60064a6ae976864509be
Fixes: 63804822
Test: bit FrameworksServicesTests:com.android.server.am.ActivityStackSupervisorTests#testStoppingActivityRemovedWhenResumed
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 1c18954..a985be5 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -3297,6 +3297,9 @@
}
boolean reportResumedActivityLocked(ActivityRecord r) {
+ // A resumed activity cannot be stopping. remove from list
+ mStoppingActivities.remove(r);
+
final ActivityStack stack = r.getStack();
if (isFocusedStack(stack)) {
mService.updateUsageStats(r, true);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
index fc9ab96..661dd4f 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
import android.content.ComponentName;
import android.graphics.Rect;
@@ -117,4 +118,21 @@
assertTrue(stackTasks.contains(task));
}
}
+
+ /**
+ * Ensures that an activity is removed from the stopping activities list once it is resumed.
+ */
+ @Test
+ public void testStoppingActivityRemovedWhenResumed() throws Exception {
+ final ActivityManagerService service = createActivityManagerService();
+ final TaskRecord firstTask = createTask(service, testActivityComponent,
+ FULLSCREEN_WORKSPACE_STACK_ID);
+ final ActivityRecord firstActivity = createActivity(service, testActivityComponent,
+ firstTask);
+ service.mStackSupervisor.mStoppingActivities.add(firstActivity);
+
+ firstActivity.completeResumeLocked();
+
+ assertFalse(service.mStackSupervisor.mStoppingActivities.contains(firstActivity));
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 4ad92c7..c03a957 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -145,6 +145,10 @@
protected ActivityStackSupervisor createStackSupervisor() {
return new TestActivityStackSupervisor(this, mHandlerThread.getLooper());
}
+
+ @Override
+ void updateUsageStats(ActivityRecord component, boolean resumed) {
+ }
}
/**