Loading services/core/java/com/android/server/wm/AppWindowContainerController.java +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading services/core/java/com/android/server/wm/AppWindowToken.java +20 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading services/core/java/com/android/server/wm/WindowSurfacePlacer.java +2 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java +29 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -175,6 +172,33 @@ public class AppWindowContainerControllerTests extends WindowTestsBase { assertHasStartingWindow(controller2.getAppWindowToken(mDisplayContent)); } @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 = Loading Loading
services/core/java/com/android/server/wm/AppWindowContainerController.java +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
services/core/java/com/android/server/wm/AppWindowToken.java +20 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading
services/core/java/com/android/server/wm/WindowSurfacePlacer.java +2 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading
services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java +29 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -175,6 +172,33 @@ public class AppWindowContainerControllerTests extends WindowTestsBase { assertHasStartingWindow(controller2.getAppWindowToken(mDisplayContent)); } @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 = Loading