diff options
4 files changed, 53 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java index 40f772aaa529..1170148d6781 100644 --- a/services/core/java/com/android/server/wm/AppWindowContainerController.java +++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java @@ -379,6 +379,8 @@ public class AppWindowContainerController if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "No longer Stopped: " + wtoken); wtoken.mAppStopped = false; + + mContainer.transferStartingWindowFromHiddenAboveTokenIfNeeded(); } // If we are preparing an app transition, then delay changing diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 267233750f55..b2f153a74699 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -187,6 +187,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree StartingSurface startingSurface; boolean startingDisplayed; boolean startingMoved; + // True if the hidden state of this token was forced to false due to a transferred starting // window. private boolean mHiddenSetFromTransferredStartingWindow; @@ -1136,6 +1137,25 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree stopFreezingScreen(true, true); } + /** + * Tries to transfer the starting window from a token that's above ourselves in the task but + * not visible anymore. This is a common scenario apps use: Trampoline activity T start main + * activity M in the same task. Now, when reopening the task, T starts on top of M but then + * immediately finishes after, so we have to transfer T to M. + */ + void transferStartingWindowFromHiddenAboveTokenIfNeeded() { + final Task task = getTask(); + for (int i = task.mChildren.size() - 1; i >= 0; i--) { + final AppWindowToken fromToken = task.mChildren.get(i); + if (fromToken == this) { + return; + } + if (fromToken.hiddenRequested && transferStartingWindow(fromToken.token)) { + return; + } + } + } + boolean transferStartingWindow(IBinder transferFrom) { final AppWindowToken fromToken = getDisplayContent().getAppWindowToken(transferFrom); if (fromToken == null) { diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index 417959087de2..40ee55277302 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -559,7 +559,8 @@ class WindowSurfacePlacer { + wtoken.allDrawn + " startingDisplayed=" + wtoken.startingDisplayed + " startingMoved=" + wtoken.startingMoved + " isRelaunching()=" - + wtoken.isRelaunching()); + + wtoken.isRelaunching() + " startingWindow=" + + wtoken.startingWindow); final boolean allDrawn = wtoken.allDrawn && !wtoken.isRelaunching(); diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java index 76e4e895278e..e0645b1f4bfb 100644 --- a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java @@ -20,11 +20,9 @@ import android.support.test.filters.FlakyTest; import org.junit.Test; import android.platform.test.annotations.Presubmit; -import android.platform.test.annotations.SecurityTest; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; -import android.view.WindowManager; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -36,13 +34,12 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; -import java.util.function.Consumer; +import com.android.server.wm.WindowTestUtils.TestTaskWindowContainerController; /** * Test class for {@link AppWindowContainerController}. * - * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.wm.AppWindowContainerControllerTests + * atest FrameworksServicesTests:com.android.server.wm.AppWindowContainerControllerTests */ @SmallTest @Presubmit @@ -176,6 +173,33 @@ public class AppWindowContainerControllerTests extends WindowTestsBase { } @Test + public void testTryTransferStartingWindowFromHiddenAboveToken() throws Exception { + + // Add two tasks on top of each other. + TestTaskWindowContainerController taskController = + new WindowTestUtils.TestTaskWindowContainerController(this); + final WindowTestUtils.TestAppWindowContainerController controllerTop = + createAppWindowController(taskController); + final WindowTestUtils.TestAppWindowContainerController controllerBottom = + createAppWindowController(taskController); + + // Add a starting window. + controllerTop.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(), + android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true, + false, false); + waitUntilHandlersIdle(); + + // Make the top one invisible, and try transfering the starting window from the top to the + // bottom one. + controllerTop.setVisibility(false, false); + controllerBottom.mContainer.transferStartingWindowFromHiddenAboveTokenIfNeeded(); + + // Assert that the bottom window now has the starting window. + assertNoStartingWindow(controllerTop.getAppWindowToken(mDisplayContent)); + assertHasStartingWindow(controllerBottom.getAppWindowToken(mDisplayContent)); + } + + @Test public void testReparent() throws Exception { final StackWindowController stackController = createStackControllerOnDisplay(mDisplayContent); |