From 3d119a904a1f507834c1a8c87235c03b7dc75e5b Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Mon, 22 Apr 2019 10:45:37 +0800 Subject: [PATCH] Set activity state to PAUSED when making visible from STOPPING/STOPPED MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An invisible activity state was STOPPED and was not updated while making it visible. Once the activity became invisible again, the activity won’t have to reenter the STOPPED state. But the window surface was not destroyed and the window was in the surface destroy list (WindowState.mDestroying was true). In that case, when resuming the activity by finishing current top activity (such as pressing back key), a transition animation was set, but failed to play and had to wait until timeout. Bug: 118349021 Bug: 132811175 Bug: 134986295 Test: ActivityRecordTests Test: ActivityVisibilityTests Test: ActivityLifecycleTests Change-Id: I887740312de8f8580c58cde36e0f5137365b607c --- .../com/android/server/wm/ActivityRecord.java | 7 +++++++ .../android/server/wm/ActivityRecordTests.java | 15 +++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 1344727ab36da..0faea61b9d604 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2039,6 +2039,13 @@ final class ActivityRecord extends ConfigurationContainer { mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken, WindowVisibilityItem.obtain(true /* showWindow */)); makeActiveIfNeeded(null /* activeActivity*/); + if (isState(STOPPING, STOPPED) && isFocusable()) { + // #shouldMakeActive() only evaluates the topmost activities in task, so + // activities that are not the topmost in task are not being resumed or paused. + // For activities that are still in STOPPING or STOPPED state, updates the state + // to PAUSE at least when making it visible. + setState(PAUSED, "makeClientVisible"); + } } catch (Exception e) { Slog.w(TAG, "Exception thrown sending visibility update: " + intent.getComponent(), e); } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 11a177a71a10a..8fbb7f53e668a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -31,6 +31,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING; +import static com.android.server.wm.ActivityStack.ActivityState.PAUSED; import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; @@ -56,7 +57,6 @@ import android.app.servertransaction.PauseActivityItem; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Rect; -import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.util.MergedConfiguration; import android.util.MutableBoolean; @@ -163,12 +163,10 @@ public class ActivityRecordTests extends ActivityTestsBase { // Make sure the state does not change if we are not the current top activity. mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped behind"); - // Make sure that the state does not change when we have an activity becoming translucent final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build(); mStack.mTranslucentActivityWaiting = topActivity; mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */); - - assertTrue(mActivity.isState(STOPPED)); + assertTrue(mActivity.isState(PAUSED)); } private void ensureActivityConfiguration() { @@ -438,6 +436,15 @@ public class ActivityRecordTests extends ActivityTestsBase { } } + @Test + public void testShouldPauseWhenMakeClientVisible() { + ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build(); + topActivity.changeWindowTranslucency(false); + mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing"); + mActivity.makeClientVisible(); + assertEquals(PAUSED, mActivity.getState()); + } + @Test public void testSizeCompatMode_FixedAspectRatioBoundsWithDecor() { setupDisplayContentForCompatDisplayInsets();