Loading core/java/android/view/WindowlessWindowManager.java +5 −1 Original line number Diff line number Diff line Loading @@ -218,9 +218,13 @@ public class WindowlessWindowManager implements IWindowSession { throw new IllegalArgumentException( "Invalid window token (never added or removed already)"); } removeSurface(state.mSurfaceControl); } /** Separate from {@link #remove} so that subclasses can put removal on a sync transaction. */ protected void removeSurface(SurfaceControl sc) { try (SurfaceControl.Transaction t = new SurfaceControl.Transaction()) { t.remove(state.mSurfaceControl).apply(); t.remove(sc).apply(); } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +24 −7 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange private WindowContainerToken mWinToken2; private int mDividePosition; private boolean mInitialized = false; private boolean mFreezeDividerWindow = false; private int mOrientation; private int mRotation; Loading Loading @@ -225,11 +226,6 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds, null); initDividerPosition(mTempRect); if (mInitialized) { release(); init(); } return true; } Loading Loading @@ -298,20 +294,37 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange } /** Releases the surface holding the current {@link DividerView}. */ public void release() { public void release(SurfaceControl.Transaction t) { if (!mInitialized) return; mInitialized = false; mSplitWindowManager.release(); mSplitWindowManager.release(t); mDisplayImeController.removePositionProcessor(mImePositionProcessor); mImePositionProcessor.reset(); } public void release() { release(null /* t */); } /** Releases and re-inflates {@link DividerView} on the root surface. */ public void update(SurfaceControl.Transaction t) { if (!mInitialized) return; mSplitWindowManager.release(t); mImePositionProcessor.reset(); mSplitWindowManager.init(this, mInsetsState); } @Override public void insetsChanged(InsetsState insetsState) { mInsetsState.set(insetsState); if (!mInitialized) { return; } if (mFreezeDividerWindow) { // DO NOT change its layout before transition actually run because it might cause // flicker. return; } mSplitWindowManager.onInsetsChanged(insetsState); } Loading @@ -323,6 +336,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange } } public void setFreezeDividerWindow(boolean freezeDividerWindow) { mFreezeDividerWindow = freezeDividerWindow; } /** * Updates bounds with the passing position. Usually used to update recording bounds while * performing animation or dragging divider bar to resize the splits. Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java +21 −2 Original line number Diff line number Diff line Loading @@ -58,6 +58,9 @@ public final class SplitWindowManager extends WindowlessWindowManager { private SurfaceControl mLeash; private DividerView mDividerView; // Used to "pass" a transaction to WWM.remove so that view removal can be synchronized. private SurfaceControl.Transaction mSyncTransaction = null; public interface ParentContainerCallbacks { void attachToParentSurface(SurfaceControl.Builder b); void onLeashReady(SurfaceControl leash); Loading Loading @@ -130,22 +133,38 @@ public final class SplitWindowManager extends WindowlessWindowManager { * Releases the surface control of the current {@link DividerView} and tear down the view * hierarchy. */ void release() { void release(@Nullable SurfaceControl.Transaction t) { if (mDividerView != null) { mDividerView = null; } if (mViewHost != null){ mSyncTransaction = t; mViewHost.release(); mSyncTransaction = null; mViewHost = null; } if (mLeash != null) { if (t == null) { new SurfaceControl.Transaction().remove(mLeash).apply(); } else { t.remove(mLeash); } mLeash = null; } } @Override protected void removeSurface(SurfaceControl sc) { // This gets called via SurfaceControlViewHost.release() if (mSyncTransaction != null) { mSyncTransaction.remove(sc); } else { super.removeSurface(sc); } } void setInteractive(boolean interactive) { if (mDividerView == null) return; mDividerView.setInteractive(interactive); Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +18 −7 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.view.WindowManager.transitTypeToString; import static android.view.WindowManagerPolicyConstants.SPLIT_DIVIDER_LAYER; import static android.window.TransitionInfo.FLAG_IS_DISPLAY; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; Loading Loading @@ -1171,6 +1172,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, updateUnfoldBounds(); return; } mSplitLayout.update(null /* t */); onLayoutSizeChanged(mSplitLayout); } } Loading Loading @@ -1198,7 +1201,6 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, if (!ENABLE_SHELL_TRANSITIONS) return; final SurfaceControl.Transaction t = mTransactionPool.acquire(); setDividerVisibility(false, t); mDisplayLayout.rotateTo(mContext.getResources(), toRotation); mSplitLayout.rotateTo(toRotation, mDisplayLayout.stableInsets()); updateWindowBounds(mSplitLayout, wct); Loading Loading @@ -1255,8 +1257,15 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Nullable TransitionRequestInfo request) { final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask(); if (triggerTask == null) { if (mMainStage.isActive()) { if (request.getType() == TRANSIT_CHANGE && request.getDisplayChange() != null) { mSplitLayout.setFreezeDividerWindow(true); } // Still want to monitor everything while in split-screen, so return non-null. return mMainStage.isActive() ? new WindowContainerTransaction() : null; return new WindowContainerTransaction(); } else { return null; } } else if (triggerTask.displayId != mDisplayId) { // Skip handling task on the other display. return null; Loading Loading @@ -1352,8 +1361,14 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, // If we're not in split-mode, just abort so something else can handle it. if (!mMainStage.isActive()) return false; mSplitLayout.setFreezeDividerWindow(false); for (int iC = 0; iC < info.getChanges().size(); ++iC) { final TransitionInfo.Change change = info.getChanges().get(iC); if (change.getMode() == TRANSIT_CHANGE && (change.getFlags() & FLAG_IS_DISPLAY) != 0) { mSplitLayout.update(startTransaction); } final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); if (taskInfo == null || !taskInfo.hasParentTask()) continue; final StageTaskListener stage = getStageOfTask(taskInfo); Loading @@ -1368,10 +1383,6 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, Log.w(TAG, "Expected onTaskVanished on " + stage + " to have been called" + " with " + taskInfo.taskId + " before startAnimation()."); } } else if (info.getType() == TRANSIT_CHANGE && change.getStartRotation() != change.getEndRotation()) { // Show the divider after transition finished. setDividerVisibility(true, finishTransaction); } } if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) { Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitWindowManagerTests.java +1 −1 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ public class SplitWindowManagerTests extends ShellTestCase { public void testInitRelease() { mSplitWindowManager.init(mSplitLayout, new InsetsState()); assertThat(mSplitWindowManager.getSurfaceControl()).isNotNull(); mSplitWindowManager.release(); mSplitWindowManager.release(null /* t */); assertThat(mSplitWindowManager.getSurfaceControl()).isNull(); } } Loading
core/java/android/view/WindowlessWindowManager.java +5 −1 Original line number Diff line number Diff line Loading @@ -218,9 +218,13 @@ public class WindowlessWindowManager implements IWindowSession { throw new IllegalArgumentException( "Invalid window token (never added or removed already)"); } removeSurface(state.mSurfaceControl); } /** Separate from {@link #remove} so that subclasses can put removal on a sync transaction. */ protected void removeSurface(SurfaceControl sc) { try (SurfaceControl.Transaction t = new SurfaceControl.Transaction()) { t.remove(state.mSurfaceControl).apply(); t.remove(sc).apply(); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +24 −7 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange private WindowContainerToken mWinToken2; private int mDividePosition; private boolean mInitialized = false; private boolean mFreezeDividerWindow = false; private int mOrientation; private int mRotation; Loading Loading @@ -225,11 +226,6 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds, null); initDividerPosition(mTempRect); if (mInitialized) { release(); init(); } return true; } Loading Loading @@ -298,20 +294,37 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange } /** Releases the surface holding the current {@link DividerView}. */ public void release() { public void release(SurfaceControl.Transaction t) { if (!mInitialized) return; mInitialized = false; mSplitWindowManager.release(); mSplitWindowManager.release(t); mDisplayImeController.removePositionProcessor(mImePositionProcessor); mImePositionProcessor.reset(); } public void release() { release(null /* t */); } /** Releases and re-inflates {@link DividerView} on the root surface. */ public void update(SurfaceControl.Transaction t) { if (!mInitialized) return; mSplitWindowManager.release(t); mImePositionProcessor.reset(); mSplitWindowManager.init(this, mInsetsState); } @Override public void insetsChanged(InsetsState insetsState) { mInsetsState.set(insetsState); if (!mInitialized) { return; } if (mFreezeDividerWindow) { // DO NOT change its layout before transition actually run because it might cause // flicker. return; } mSplitWindowManager.onInsetsChanged(insetsState); } Loading @@ -323,6 +336,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange } } public void setFreezeDividerWindow(boolean freezeDividerWindow) { mFreezeDividerWindow = freezeDividerWindow; } /** * Updates bounds with the passing position. Usually used to update recording bounds while * performing animation or dragging divider bar to resize the splits. Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java +21 −2 Original line number Diff line number Diff line Loading @@ -58,6 +58,9 @@ public final class SplitWindowManager extends WindowlessWindowManager { private SurfaceControl mLeash; private DividerView mDividerView; // Used to "pass" a transaction to WWM.remove so that view removal can be synchronized. private SurfaceControl.Transaction mSyncTransaction = null; public interface ParentContainerCallbacks { void attachToParentSurface(SurfaceControl.Builder b); void onLeashReady(SurfaceControl leash); Loading Loading @@ -130,22 +133,38 @@ public final class SplitWindowManager extends WindowlessWindowManager { * Releases the surface control of the current {@link DividerView} and tear down the view * hierarchy. */ void release() { void release(@Nullable SurfaceControl.Transaction t) { if (mDividerView != null) { mDividerView = null; } if (mViewHost != null){ mSyncTransaction = t; mViewHost.release(); mSyncTransaction = null; mViewHost = null; } if (mLeash != null) { if (t == null) { new SurfaceControl.Transaction().remove(mLeash).apply(); } else { t.remove(mLeash); } mLeash = null; } } @Override protected void removeSurface(SurfaceControl sc) { // This gets called via SurfaceControlViewHost.release() if (mSyncTransaction != null) { mSyncTransaction.remove(sc); } else { super.removeSurface(sc); } } void setInteractive(boolean interactive) { if (mDividerView == null) return; mDividerView.setInteractive(interactive); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +18 −7 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.view.WindowManager.transitTypeToString; import static android.view.WindowManagerPolicyConstants.SPLIT_DIVIDER_LAYER; import static android.window.TransitionInfo.FLAG_IS_DISPLAY; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; Loading Loading @@ -1171,6 +1172,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, updateUnfoldBounds(); return; } mSplitLayout.update(null /* t */); onLayoutSizeChanged(mSplitLayout); } } Loading Loading @@ -1198,7 +1201,6 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, if (!ENABLE_SHELL_TRANSITIONS) return; final SurfaceControl.Transaction t = mTransactionPool.acquire(); setDividerVisibility(false, t); mDisplayLayout.rotateTo(mContext.getResources(), toRotation); mSplitLayout.rotateTo(toRotation, mDisplayLayout.stableInsets()); updateWindowBounds(mSplitLayout, wct); Loading Loading @@ -1255,8 +1257,15 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Nullable TransitionRequestInfo request) { final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask(); if (triggerTask == null) { if (mMainStage.isActive()) { if (request.getType() == TRANSIT_CHANGE && request.getDisplayChange() != null) { mSplitLayout.setFreezeDividerWindow(true); } // Still want to monitor everything while in split-screen, so return non-null. return mMainStage.isActive() ? new WindowContainerTransaction() : null; return new WindowContainerTransaction(); } else { return null; } } else if (triggerTask.displayId != mDisplayId) { // Skip handling task on the other display. return null; Loading Loading @@ -1352,8 +1361,14 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, // If we're not in split-mode, just abort so something else can handle it. if (!mMainStage.isActive()) return false; mSplitLayout.setFreezeDividerWindow(false); for (int iC = 0; iC < info.getChanges().size(); ++iC) { final TransitionInfo.Change change = info.getChanges().get(iC); if (change.getMode() == TRANSIT_CHANGE && (change.getFlags() & FLAG_IS_DISPLAY) != 0) { mSplitLayout.update(startTransaction); } final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); if (taskInfo == null || !taskInfo.hasParentTask()) continue; final StageTaskListener stage = getStageOfTask(taskInfo); Loading @@ -1368,10 +1383,6 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, Log.w(TAG, "Expected onTaskVanished on " + stage + " to have been called" + " with " + taskInfo.taskId + " before startAnimation()."); } } else if (info.getType() == TRANSIT_CHANGE && change.getStartRotation() != change.getEndRotation()) { // Show the divider after transition finished. setDividerVisibility(true, finishTransaction); } } if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) { Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitWindowManagerTests.java +1 −1 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ public class SplitWindowManagerTests extends ShellTestCase { public void testInitRelease() { mSplitWindowManager.init(mSplitLayout, new InsetsState()); assertThat(mSplitWindowManager.getSurfaceControl()).isNotNull(); mSplitWindowManager.release(); mSplitWindowManager.release(null /* t */); assertThat(mSplitWindowManager.getSurfaceControl()).isNull(); } }