Loading services/core/java/com/android/server/wm/TaskFragment.java +34 −22 Original line number Diff line number Diff line Loading @@ -288,6 +288,12 @@ class TaskFragment extends WindowContainer<WindowContainer> { @Nullable private final IBinder mFragmentToken; /** * Whether to delay the call to {@link #updateOrganizedTaskFragmentSurface()} when there is a * configuration change. */ private boolean mDelayOrganizedTaskFragmentSurfaceUpdate; /** * Whether to delay the last activity of TaskFragment being immediately removed while finishing. * This should only be set on a embedded TaskFragment, where the organizer can have the Loading Loading @@ -2273,35 +2279,41 @@ class TaskFragment extends WindowContainer<WindowContainer> { @Override public void onConfigurationChanged(Configuration newParentConfig) { // Task will animate differently. super.onConfigurationChanged(newParentConfig); if (mTaskFragmentOrganizer != null) { mTmpPrevBounds.set(getBounds()); updateOrganizedTaskFragmentSurface(); } super.onConfigurationChanged(newParentConfig); sendTaskFragmentInfoChanged(); } final boolean shouldStartChangeTransition = shouldStartChangeTransition(mTmpPrevBounds); if (shouldStartChangeTransition) { initializeChangeTransition(mTmpPrevBounds); void deferOrganizedTaskFragmentSurfaceUpdate() { mDelayOrganizedTaskFragmentSurfaceUpdate = true; } void continueOrganizedTaskFragmentSurfaceUpdate() { mDelayOrganizedTaskFragmentSurfaceUpdate = false; updateOrganizedTaskFragmentSurface(); } private void updateOrganizedTaskFragmentSurface() { if (mDelayOrganizedTaskFragmentSurfaceUpdate) { return; } if (mTaskFragmentOrganizer != null) { if (mTransitionController.isShellTransitionsEnabled() && !mTransitionController.isCollecting(this)) { // TaskFragmentOrganizer doesn't have access to the surface for security reasons, so // update the surface here if it is not collected by Shell transition. updateOrganizedTaskFragmentSurface(); } else if (!mTransitionController.isShellTransitionsEnabled() && !shouldStartChangeTransition) { updateOrganizedTaskFragmentSurfaceUnchecked(); } else if (!mTransitionController.isShellTransitionsEnabled() && !isAnimating()) { // Update the surface here instead of in the organizer so that we can make sure // it can be synced with the surface freezer for legacy app transition. updateOrganizedTaskFragmentSurface(); } updateOrganizedTaskFragmentSurfaceUnchecked(); } sendTaskFragmentInfoChanged(); } private void updateOrganizedTaskFragmentSurface() { private void updateOrganizedTaskFragmentSurfaceUnchecked() { final SurfaceControl.Transaction t = getSyncTransaction(); updateSurfacePosition(t); updateOrganizedTaskFragmentSurfaceSize(t, false /* forceUpdate */); Loading Loading @@ -2355,7 +2367,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { } /** Whether we should prepare a transition for this {@link TaskFragment} bounds change. */ private boolean shouldStartChangeTransition(Rect startBounds) { boolean shouldStartChangeTransition(Rect startBounds) { if (mTaskFragmentOrganizer == null || !canStartChangeTransition()) { return false; } Loading @@ -2375,7 +2387,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { void setSurfaceControl(SurfaceControl sc) { super.setSurfaceControl(sc); if (mTaskFragmentOrganizer != null) { updateOrganizedTaskFragmentSurface(); updateOrganizedTaskFragmentSurfaceUnchecked(); // If the TaskFragmentOrganizer was set before we created the SurfaceControl, we need to // emit the callbacks now. sendTaskFragmentAppeared(); Loading services/core/java/com/android/server/wm/WindowOrganizerController.java +33 −14 Original line number Diff line number Diff line Loading @@ -147,6 +147,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub @VisibleForTesting final ArrayMap<IBinder, TaskFragment> mLaunchTaskFragments = new ArrayMap<>(); private final Rect mTmpBounds = new Rect(); WindowOrganizerController(ActivityTaskManagerService atm) { mService = atm; mGlobalLock = atm.mGlobalLock; Loading Loading @@ -711,7 +713,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } private int applyTaskChanges(Task tr, WindowContainerTransaction.Change c) { int effects = 0; int effects = applyChanges(tr, c, null /* errorCallbackToken */); final SurfaceControl.Transaction t = c.getBoundsChangeTransaction(); if ((c.getChangeMask() & WindowContainerTransaction.Change.CHANGE_HIDDEN) != 0) { Loading Loading @@ -772,6 +774,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub private int applyDisplayAreaChanges(DisplayArea displayArea, WindowContainerTransaction.Change c) { final int[] effects = new int[1]; effects[0] = applyChanges(displayArea, c, null /* errorCallbackToken */); if ((c.getChangeMask() & WindowContainerTransaction.Change.CHANGE_IGNORE_ORIENTATION_REQUEST) != 0) { Loading @@ -792,6 +795,27 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub return effects[0]; } private int applyTaskFragmentChanges(@NonNull TaskFragment taskFragment, @NonNull WindowContainerTransaction.Change c, @Nullable IBinder errorCallbackToken) { if (taskFragment.isEmbeddedTaskFragmentInPip()) { // No override from organizer for embedded TaskFragment in a PIP Task. return 0; } // When the TaskFragment is resized, we may want to create a change transition for it, for // which we want to defer the surface update until we determine whether or not to start // change transition. mTmpBounds.set(taskFragment.getBounds()); taskFragment.deferOrganizedTaskFragmentSurfaceUpdate(); final int effects = applyChanges(taskFragment, c, errorCallbackToken); if (taskFragment.shouldStartChangeTransition(mTmpBounds)) { taskFragment.initializeChangeTransition(mTmpBounds); } taskFragment.continueOrganizedTaskFragmentSurfaceUpdate(); mTmpBounds.set(0, 0, 0, 0); return effects; } private int applyHierarchyOp(WindowContainerTransaction.HierarchyOp hop, int effects, int syncId, @Nullable Transition transition, boolean isInLockTaskMode, @NonNull CallerInfo caller, @Nullable IBinder errorCallbackToken, Loading Loading @@ -1457,20 +1481,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub private int applyWindowContainerChange(WindowContainer wc, WindowContainerTransaction.Change c, @Nullable IBinder errorCallbackToken) { sanitizeWindowContainer(wc); if (wc.asTaskFragment() != null && wc.asTaskFragment().isEmbeddedTaskFragmentInPip()) { // No override from organizer for embedded TaskFragment in a PIP Task. return 0; } int effects = applyChanges(wc, c, errorCallbackToken); if (wc instanceof DisplayArea) { effects |= applyDisplayAreaChanges(wc.asDisplayArea(), c); } else if (wc instanceof Task) { effects |= applyTaskChanges(wc.asTask(), c); if (wc.asDisplayArea() != null) { return applyDisplayAreaChanges(wc.asDisplayArea(), c); } else if (wc.asTask() != null) { return applyTaskChanges(wc.asTask(), c); } else if (wc.asTaskFragment() != null) { return applyTaskFragmentChanges(wc.asTaskFragment(), c, errorCallbackToken); } else { return applyChanges(wc, c, errorCallbackToken); } return effects; } @Override Loading services/core/java/com/android/server/wm/WindowState.java +19 −4 Original line number Diff line number Diff line Loading @@ -1537,10 +1537,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mWmService.makeWindowFreezingScreenIfNeededLocked(this); // If the orientation is changing, or we're starting or ending a drag resizing action, // then we need to hold off on unfreezing the display until this window has been // redrawn; to do that, we need to go through the process of getting informed by the // application when it has finished drawing. if (getOrientationChanging() || dragResizingChanged) { // or we're resizing an embedded Activity, then we need to hold off on unfreezing the // display until this window has been redrawn; to do that, we need to go through the // process of getting informed by the application when it has finished drawing. if (getOrientationChanging() || dragResizingChanged || isEmbeddedActivityResizeChanged()) { if (dragResizingChanged) { ProtoLog.v(WM_DEBUG_RESIZE, "Resize start waiting for draw, " Loading Loading @@ -4147,6 +4148,20 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return mActivityRecord == null || mActivityRecord.isFullyTransparentBarAllowed(frame); } /** * Whether this window belongs to a resizing embedded activity. */ private boolean isEmbeddedActivityResizeChanged() { if (mActivityRecord == null || !isVisibleRequested()) { // No need to update if the window is in the background. return false; } final TaskFragment embeddedTaskFragment = mActivityRecord.getOrganizedTaskFragment(); return embeddedTaskFragment != null && mDisplayContent.mChangingContainers.contains(embeddedTaskFragment); } boolean isDragResizeChanged() { return mDragResizing != computeDragResizing(); } Loading services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java +5 −2 Original line number Diff line number Diff line Loading @@ -118,10 +118,13 @@ public class TaskFragmentTest extends WindowTestsBase { doReturn(true).when(mTaskFragment).isVisibleRequested(); clearInvocations(mTransaction); mTaskFragment.deferOrganizedTaskFragmentSurfaceUpdate(); mTaskFragment.setBounds(endBounds); assertTrue(mTaskFragment.shouldStartChangeTransition(startBounds)); mTaskFragment.initializeChangeTransition(startBounds); mTaskFragment.continueOrganizedTaskFragmentSurfaceUpdate(); // Surface reset when prepare transition. verify(mTaskFragment).initializeChangeTransition(startBounds); verify(mTransaction).setPosition(mLeash, 0, 0); verify(mTransaction).setWindowCrop(mLeash, 0, 0); Loading Loading @@ -166,7 +169,7 @@ public class TaskFragmentTest extends WindowTestsBase { mTaskFragment.setBounds(endBounds); verify(mTaskFragment, never()).initializeChangeTransition(any()); assertFalse(mTaskFragment.shouldStartChangeTransition(startBounds)); } /** Loading services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +35 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,8 @@ import android.view.InsetsState; import android.view.InsetsVisibilities; import android.view.SurfaceControl; import android.view.WindowManager; import android.window.ITaskFragmentOrganizer; import android.window.TaskFragmentOrganizer; import androidx.test.filters.SmallTest; Loading Loading @@ -797,6 +799,39 @@ public class WindowStateTests extends WindowTestsBase { assertThat(mWm.mResizingWindows).doesNotContain(win); } @Test public void testEmbeddedActivityResizing_clearAllDrawn() { final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); mAtm.mTaskFragmentOrganizerController.registerOrganizer( ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder())); final Task task = createTask(mDisplayContent); final TaskFragment embeddedTf = createTaskFragmentWithEmbeddedActivity(task, organizer); final ActivityRecord embeddedActivity = embeddedTf.getTopMostActivity(); final WindowState win = createWindow(null /* parent */, TYPE_APPLICATION, embeddedActivity, "App window"); doReturn(true).when(embeddedActivity).isVisible(); embeddedActivity.mVisibleRequested = true; makeWindowVisible(win); win.mLayoutSeq = win.getDisplayContent().mLayoutSeq; // Set the bounds twice: // 1. To make sure there is no orientation change after #reportResized, which can also cause // #clearAllDrawn. // 2. Make #isLastConfigReportedToClient to be false after #reportResized, so it can process // to check if we need redraw. embeddedTf.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); embeddedTf.setBounds(0, 0, 1000, 2000); win.reportResized(); embeddedTf.setBounds(500, 0, 1000, 2000); // Clear all drawn when the embedded TaskFragment is in mDisplayContent.mChangingContainers. win.updateResizingWindowIfNeeded(); verify(embeddedActivity, never()).clearAllDrawn(); mDisplayContent.mChangingContainers.add(embeddedTf); win.updateResizingWindowIfNeeded(); verify(embeddedActivity).clearAllDrawn(); } @Test public void testCantReceiveTouchWhenAppTokenHiddenRequested() { final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0"); Loading Loading
services/core/java/com/android/server/wm/TaskFragment.java +34 −22 Original line number Diff line number Diff line Loading @@ -288,6 +288,12 @@ class TaskFragment extends WindowContainer<WindowContainer> { @Nullable private final IBinder mFragmentToken; /** * Whether to delay the call to {@link #updateOrganizedTaskFragmentSurface()} when there is a * configuration change. */ private boolean mDelayOrganizedTaskFragmentSurfaceUpdate; /** * Whether to delay the last activity of TaskFragment being immediately removed while finishing. * This should only be set on a embedded TaskFragment, where the organizer can have the Loading Loading @@ -2273,35 +2279,41 @@ class TaskFragment extends WindowContainer<WindowContainer> { @Override public void onConfigurationChanged(Configuration newParentConfig) { // Task will animate differently. super.onConfigurationChanged(newParentConfig); if (mTaskFragmentOrganizer != null) { mTmpPrevBounds.set(getBounds()); updateOrganizedTaskFragmentSurface(); } super.onConfigurationChanged(newParentConfig); sendTaskFragmentInfoChanged(); } final boolean shouldStartChangeTransition = shouldStartChangeTransition(mTmpPrevBounds); if (shouldStartChangeTransition) { initializeChangeTransition(mTmpPrevBounds); void deferOrganizedTaskFragmentSurfaceUpdate() { mDelayOrganizedTaskFragmentSurfaceUpdate = true; } void continueOrganizedTaskFragmentSurfaceUpdate() { mDelayOrganizedTaskFragmentSurfaceUpdate = false; updateOrganizedTaskFragmentSurface(); } private void updateOrganizedTaskFragmentSurface() { if (mDelayOrganizedTaskFragmentSurfaceUpdate) { return; } if (mTaskFragmentOrganizer != null) { if (mTransitionController.isShellTransitionsEnabled() && !mTransitionController.isCollecting(this)) { // TaskFragmentOrganizer doesn't have access to the surface for security reasons, so // update the surface here if it is not collected by Shell transition. updateOrganizedTaskFragmentSurface(); } else if (!mTransitionController.isShellTransitionsEnabled() && !shouldStartChangeTransition) { updateOrganizedTaskFragmentSurfaceUnchecked(); } else if (!mTransitionController.isShellTransitionsEnabled() && !isAnimating()) { // Update the surface here instead of in the organizer so that we can make sure // it can be synced with the surface freezer for legacy app transition. updateOrganizedTaskFragmentSurface(); } updateOrganizedTaskFragmentSurfaceUnchecked(); } sendTaskFragmentInfoChanged(); } private void updateOrganizedTaskFragmentSurface() { private void updateOrganizedTaskFragmentSurfaceUnchecked() { final SurfaceControl.Transaction t = getSyncTransaction(); updateSurfacePosition(t); updateOrganizedTaskFragmentSurfaceSize(t, false /* forceUpdate */); Loading Loading @@ -2355,7 +2367,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { } /** Whether we should prepare a transition for this {@link TaskFragment} bounds change. */ private boolean shouldStartChangeTransition(Rect startBounds) { boolean shouldStartChangeTransition(Rect startBounds) { if (mTaskFragmentOrganizer == null || !canStartChangeTransition()) { return false; } Loading @@ -2375,7 +2387,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { void setSurfaceControl(SurfaceControl sc) { super.setSurfaceControl(sc); if (mTaskFragmentOrganizer != null) { updateOrganizedTaskFragmentSurface(); updateOrganizedTaskFragmentSurfaceUnchecked(); // If the TaskFragmentOrganizer was set before we created the SurfaceControl, we need to // emit the callbacks now. sendTaskFragmentAppeared(); Loading
services/core/java/com/android/server/wm/WindowOrganizerController.java +33 −14 Original line number Diff line number Diff line Loading @@ -147,6 +147,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub @VisibleForTesting final ArrayMap<IBinder, TaskFragment> mLaunchTaskFragments = new ArrayMap<>(); private final Rect mTmpBounds = new Rect(); WindowOrganizerController(ActivityTaskManagerService atm) { mService = atm; mGlobalLock = atm.mGlobalLock; Loading Loading @@ -711,7 +713,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } private int applyTaskChanges(Task tr, WindowContainerTransaction.Change c) { int effects = 0; int effects = applyChanges(tr, c, null /* errorCallbackToken */); final SurfaceControl.Transaction t = c.getBoundsChangeTransaction(); if ((c.getChangeMask() & WindowContainerTransaction.Change.CHANGE_HIDDEN) != 0) { Loading Loading @@ -772,6 +774,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub private int applyDisplayAreaChanges(DisplayArea displayArea, WindowContainerTransaction.Change c) { final int[] effects = new int[1]; effects[0] = applyChanges(displayArea, c, null /* errorCallbackToken */); if ((c.getChangeMask() & WindowContainerTransaction.Change.CHANGE_IGNORE_ORIENTATION_REQUEST) != 0) { Loading @@ -792,6 +795,27 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub return effects[0]; } private int applyTaskFragmentChanges(@NonNull TaskFragment taskFragment, @NonNull WindowContainerTransaction.Change c, @Nullable IBinder errorCallbackToken) { if (taskFragment.isEmbeddedTaskFragmentInPip()) { // No override from organizer for embedded TaskFragment in a PIP Task. return 0; } // When the TaskFragment is resized, we may want to create a change transition for it, for // which we want to defer the surface update until we determine whether or not to start // change transition. mTmpBounds.set(taskFragment.getBounds()); taskFragment.deferOrganizedTaskFragmentSurfaceUpdate(); final int effects = applyChanges(taskFragment, c, errorCallbackToken); if (taskFragment.shouldStartChangeTransition(mTmpBounds)) { taskFragment.initializeChangeTransition(mTmpBounds); } taskFragment.continueOrganizedTaskFragmentSurfaceUpdate(); mTmpBounds.set(0, 0, 0, 0); return effects; } private int applyHierarchyOp(WindowContainerTransaction.HierarchyOp hop, int effects, int syncId, @Nullable Transition transition, boolean isInLockTaskMode, @NonNull CallerInfo caller, @Nullable IBinder errorCallbackToken, Loading Loading @@ -1457,20 +1481,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub private int applyWindowContainerChange(WindowContainer wc, WindowContainerTransaction.Change c, @Nullable IBinder errorCallbackToken) { sanitizeWindowContainer(wc); if (wc.asTaskFragment() != null && wc.asTaskFragment().isEmbeddedTaskFragmentInPip()) { // No override from organizer for embedded TaskFragment in a PIP Task. return 0; } int effects = applyChanges(wc, c, errorCallbackToken); if (wc instanceof DisplayArea) { effects |= applyDisplayAreaChanges(wc.asDisplayArea(), c); } else if (wc instanceof Task) { effects |= applyTaskChanges(wc.asTask(), c); if (wc.asDisplayArea() != null) { return applyDisplayAreaChanges(wc.asDisplayArea(), c); } else if (wc.asTask() != null) { return applyTaskChanges(wc.asTask(), c); } else if (wc.asTaskFragment() != null) { return applyTaskFragmentChanges(wc.asTaskFragment(), c, errorCallbackToken); } else { return applyChanges(wc, c, errorCallbackToken); } return effects; } @Override Loading
services/core/java/com/android/server/wm/WindowState.java +19 −4 Original line number Diff line number Diff line Loading @@ -1537,10 +1537,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mWmService.makeWindowFreezingScreenIfNeededLocked(this); // If the orientation is changing, or we're starting or ending a drag resizing action, // then we need to hold off on unfreezing the display until this window has been // redrawn; to do that, we need to go through the process of getting informed by the // application when it has finished drawing. if (getOrientationChanging() || dragResizingChanged) { // or we're resizing an embedded Activity, then we need to hold off on unfreezing the // display until this window has been redrawn; to do that, we need to go through the // process of getting informed by the application when it has finished drawing. if (getOrientationChanging() || dragResizingChanged || isEmbeddedActivityResizeChanged()) { if (dragResizingChanged) { ProtoLog.v(WM_DEBUG_RESIZE, "Resize start waiting for draw, " Loading Loading @@ -4147,6 +4148,20 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return mActivityRecord == null || mActivityRecord.isFullyTransparentBarAllowed(frame); } /** * Whether this window belongs to a resizing embedded activity. */ private boolean isEmbeddedActivityResizeChanged() { if (mActivityRecord == null || !isVisibleRequested()) { // No need to update if the window is in the background. return false; } final TaskFragment embeddedTaskFragment = mActivityRecord.getOrganizedTaskFragment(); return embeddedTaskFragment != null && mDisplayContent.mChangingContainers.contains(embeddedTaskFragment); } boolean isDragResizeChanged() { return mDragResizing != computeDragResizing(); } Loading
services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java +5 −2 Original line number Diff line number Diff line Loading @@ -118,10 +118,13 @@ public class TaskFragmentTest extends WindowTestsBase { doReturn(true).when(mTaskFragment).isVisibleRequested(); clearInvocations(mTransaction); mTaskFragment.deferOrganizedTaskFragmentSurfaceUpdate(); mTaskFragment.setBounds(endBounds); assertTrue(mTaskFragment.shouldStartChangeTransition(startBounds)); mTaskFragment.initializeChangeTransition(startBounds); mTaskFragment.continueOrganizedTaskFragmentSurfaceUpdate(); // Surface reset when prepare transition. verify(mTaskFragment).initializeChangeTransition(startBounds); verify(mTransaction).setPosition(mLeash, 0, 0); verify(mTransaction).setWindowCrop(mLeash, 0, 0); Loading Loading @@ -166,7 +169,7 @@ public class TaskFragmentTest extends WindowTestsBase { mTaskFragment.setBounds(endBounds); verify(mTaskFragment, never()).initializeChangeTransition(any()); assertFalse(mTaskFragment.shouldStartChangeTransition(startBounds)); } /** Loading
services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +35 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,8 @@ import android.view.InsetsState; import android.view.InsetsVisibilities; import android.view.SurfaceControl; import android.view.WindowManager; import android.window.ITaskFragmentOrganizer; import android.window.TaskFragmentOrganizer; import androidx.test.filters.SmallTest; Loading Loading @@ -797,6 +799,39 @@ public class WindowStateTests extends WindowTestsBase { assertThat(mWm.mResizingWindows).doesNotContain(win); } @Test public void testEmbeddedActivityResizing_clearAllDrawn() { final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); mAtm.mTaskFragmentOrganizerController.registerOrganizer( ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder())); final Task task = createTask(mDisplayContent); final TaskFragment embeddedTf = createTaskFragmentWithEmbeddedActivity(task, organizer); final ActivityRecord embeddedActivity = embeddedTf.getTopMostActivity(); final WindowState win = createWindow(null /* parent */, TYPE_APPLICATION, embeddedActivity, "App window"); doReturn(true).when(embeddedActivity).isVisible(); embeddedActivity.mVisibleRequested = true; makeWindowVisible(win); win.mLayoutSeq = win.getDisplayContent().mLayoutSeq; // Set the bounds twice: // 1. To make sure there is no orientation change after #reportResized, which can also cause // #clearAllDrawn. // 2. Make #isLastConfigReportedToClient to be false after #reportResized, so it can process // to check if we need redraw. embeddedTf.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); embeddedTf.setBounds(0, 0, 1000, 2000); win.reportResized(); embeddedTf.setBounds(500, 0, 1000, 2000); // Clear all drawn when the embedded TaskFragment is in mDisplayContent.mChangingContainers. win.updateResizingWindowIfNeeded(); verify(embeddedActivity, never()).clearAllDrawn(); mDisplayContent.mChangingContainers.add(embeddedTf); win.updateResizingWindowIfNeeded(); verify(embeddedActivity).clearAllDrawn(); } @Test public void testCantReceiveTouchWhenAppTokenHiddenRequested() { final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0"); Loading