Transfer starting windows more aggressively
We currently transfer starting windows when starting another activity on top of the previous one. However, that's not enough: Sometimes we also need to transfer back in case the one on top finishes itself/gets hidden for other reasons. This fixes an issue where some animations are aborted in the middle of the animation because the trampoline activity contained the starting window but then the trampoline activity was finished. Test: go/wm-smoke Test: Open Drive, Reopen Drive 100x Test: Open Hangouts, Receive notification, open it, reopen hangouts from launcher 100x Test: AppWindowContainerControllerTests Bug: 72301120 Change-Id: I6711ce0bc35de430aac03f7b8b39ceac26e595e7
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user