Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java +17 −9 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { private int mStartPos; private GestureDetector mDoubleTapDetector; private boolean mInteractive; private boolean mHideHandle; private boolean mSetTouchRegion = true; private int mLastDraggingPosition; private int mHandleRegionWidth; Loading Loading @@ -211,11 +212,8 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { } /** Sets up essential dependencies of the divider bar. */ public void setup( SplitLayout layout, SplitWindowManager splitWindowManager, SurfaceControlViewHost viewHost, InsetsState insetsState) { public void setup(SplitLayout layout, SplitWindowManager splitWindowManager, SurfaceControlViewHost viewHost, InsetsState insetsState) { mSplitLayout = layout; mSplitWindowManager = splitWindowManager; mViewHost = viewHost; Loading Loading @@ -277,6 +275,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { R.dimen.docked_stack_divider_lift_elevation); mDoubleTapDetector = new GestureDetector(getContext(), new DoubleTapListener()); mInteractive = true; mHideHandle = false; setOnTouchListener(this); mHandle.setAccessibilityDelegate(mHandleDelegate); setWillNotDraw(false); Loading Loading @@ -469,10 +468,11 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { void setInteractive(boolean interactive, boolean hideHandle, String from) { if (interactive == mInteractive) return; ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Set divider bar %s from %s", interactive ? "interactive" : "non-interactive", from); "Set divider bar %s hide handle=%b from %s", interactive ? "interactive" : "non-interactive", hideHandle, from); mInteractive = interactive; if (!mInteractive && hideHandle && mMoving) { mHideHandle = hideHandle; if (!mInteractive && mHideHandle && mMoving) { final int position = mSplitLayout.getDividePosition(); mSplitLayout.flingDividePosition( mLastDraggingPosition, Loading @@ -482,7 +482,15 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { mMoving = false; } releaseTouching(); mHandle.setVisibility(!mInteractive && hideHandle ? View.INVISIBLE : View.VISIBLE); mHandle.setVisibility(!mInteractive && mHideHandle ? View.INVISIBLE : View.VISIBLE); } boolean isInteractive() { return mInteractive; } boolean isHandleHidden() { return mHideHandle; } private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener { Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +20 −6 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import android.window.WindowContainerTransaction; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.animation.Interpolators; Loading @@ -70,6 +71,7 @@ import com.android.wm.shell.common.InteractionJankMonitorUtils; import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition; import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import com.android.wm.shell.protolog.ShellProtoLogGroup; import java.io.PrintWriter; import java.util.function.Consumer; Loading Loading @@ -420,7 +422,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange public void init() { if (mInitialized) return; mInitialized = true; mSplitWindowManager.init(this, mInsetsState); mSplitWindowManager.init(this, mInsetsState, false /* isRestoring */); mDisplayImeController.addPositionProcessor(mImePositionProcessor); } Loading @@ -442,14 +444,19 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange } /** Releases and re-inflates {@link DividerView} on the root surface. */ public void update(SurfaceControl.Transaction t) { public void update(SurfaceControl.Transaction t, boolean resetImePosition) { if (!mInitialized) { init(); return; } mSplitWindowManager.release(t); if (resetImePosition) { mImePositionProcessor.reset(); mSplitWindowManager.init(this, mInsetsState); } mSplitWindowManager.init(this, mInsetsState, true /* isRestoring */); // Update the surface positions again after recreating the divider in case nothing else // triggers it mSplitLayoutHandler.onLayoutPositionChanging(SplitLayout.this); } @Override Loading Loading @@ -868,6 +875,9 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange pw.println(prefix + TAG + ":"); pw.println(innerPrefix + "mAllowLeftRightSplitInPortrait=" + mAllowLeftRightSplitInPortrait); pw.println(innerPrefix + "mIsLeftRightSplit=" + mIsLeftRightSplit); pw.println(innerPrefix + "mFreezeDividerWindow=" + mFreezeDividerWindow); pw.println(innerPrefix + "mDimNonImeSide=" + mDimNonImeSide); pw.println(innerPrefix + "mDividerPosition=" + mDividerPosition); pw.println(innerPrefix + "bounds1=" + mBounds1.toShortString()); pw.println(innerPrefix + "dividerBounds=" + mDividerBounds.toShortString()); pw.println(innerPrefix + "bounds2=" + mBounds2.toShortString()); Loading Loading @@ -1151,14 +1161,16 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange mTargetYOffset = needOffset ? getTargetYOffset() : 0; if (mTargetYOffset != mLastYOffset) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Split IME animation starting, fromY=%d toY=%d", mLastYOffset, mTargetYOffset); // Freeze the configuration size with offset to prevent app get a configuration // changed or relaunch. This is required to make sure client apps will calculate // insets properly after layout shifted. if (mTargetYOffset == 0) { mSplitLayoutHandler.setLayoutOffsetTarget(0, 0, SplitLayout.this); } else { mSplitLayoutHandler.setLayoutOffsetTarget(0, mTargetYOffset - mLastYOffset, SplitLayout.this); mSplitLayoutHandler.setLayoutOffsetTarget(0, mTargetYOffset, SplitLayout.this); } } Loading @@ -1183,6 +1195,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange public void onImeEndPositioning(int displayId, boolean cancel, SurfaceControl.Transaction t) { if (displayId != mDisplayId || !mHasImeFocus || cancel) return; ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Split IME animation ending, canceled=%b", cancel); onProgress(1.0f); mSplitLayoutHandler.onLayoutPositionChanging(SplitLayout.this); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java +11 −1 Original line number Diff line number Diff line Loading @@ -62,6 +62,10 @@ public final class SplitWindowManager extends WindowlessWindowManager { // Used to "pass" a transaction to WWM.remove so that view removal can be synchronized. private SurfaceControl.Transaction mSyncTransaction = null; // For saving/restoring state private boolean mLastDividerInteractive = true; private boolean mLastDividerHandleHidden; public interface ParentContainerCallbacks { void attachToParentSurface(SurfaceControl.Builder b); void onLeashReady(SurfaceControl leash); Loading Loading @@ -107,7 +111,7 @@ public final class SplitWindowManager extends WindowlessWindowManager { } /** Inflates {@link DividerView} on to the root surface. */ void init(SplitLayout splitLayout, InsetsState insetsState) { void init(SplitLayout splitLayout, InsetsState insetsState, boolean isRestoring) { if (mDividerView != null || mViewHost != null) { throw new UnsupportedOperationException( "Try to inflate divider view again without release first"); Loading @@ -130,6 +134,10 @@ public final class SplitWindowManager extends WindowlessWindowManager { lp.accessibilityTitle = mContext.getResources().getString(R.string.accessibility_divider); mViewHost.setView(mDividerView, lp); mDividerView.setup(splitLayout, this, mViewHost, insetsState); if (isRestoring) { mDividerView.setInteractive(mLastDividerInteractive, mLastDividerHandleHidden, "restore_setup"); } } /** Loading @@ -138,6 +146,8 @@ public final class SplitWindowManager extends WindowlessWindowManager { */ void release(@Nullable SurfaceControl.Transaction t) { if (mDividerView != null) { mLastDividerInteractive = mDividerView.isInteractive(); mLastDividerHandleHidden = mDividerView.isHandleHidden(); mDividerView = null; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +9 −6 Original line number Diff line number Diff line Loading @@ -1666,7 +1666,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } void finishEnterSplitScreen(SurfaceControl.Transaction finishT) { mSplitLayout.update(finishT); mSplitLayout.update(finishT, true /* resetImePosition */); mMainStage.getSplitDecorManager().inflate(mContext, mMainStage.mRootLeash, getMainStageBounds()); mSideStage.getSplitDecorManager().inflate(mContext, mSideStage.mRootLeash, Loading Loading @@ -1860,9 +1860,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, && mSplitLayout.updateConfiguration(mRootTaskInfo.configuration) && mMainStage.isActive()) { // Clear the divider remote animating flag as the divider will be re-rendered to apply // the new rotation config. // the new rotation config. Don't reset the IME state since those updates are not in // sync with task info changes. mIsDividerRemoteAnimating = false; mSplitLayout.update(null /* t */); mSplitLayout.update(null /* t */, false /* resetImePosition */); onLayoutSizeChanged(mSplitLayout); } } Loading Loading @@ -2325,7 +2326,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, */ public void updateSurfaces(SurfaceControl.Transaction transaction) { updateSurfaceBounds(mSplitLayout, transaction, /* applyResizingOffset */ false); mSplitLayout.update(transaction); mSplitLayout.update(transaction, true /* resetImePosition */); } private void onDisplayChange(int displayId, int fromRotation, int toRotation, Loading Loading @@ -2598,7 +2599,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, final TransitionInfo.Change change = info.getChanges().get(iC); if (change.getMode() == TRANSIT_CHANGE && (change.getFlags() & FLAG_IS_DISPLAY) != 0) { mSplitLayout.update(startTransaction); // Don't reset the IME state since those updates are not in sync with the // display change transition mSplitLayout.update(startTransaction, false /* resetImePosition */); } if (mMixedHandler.isEnteringPip(change, transitType)) { Loading Loading @@ -2699,7 +2702,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, startTransaction, finishTransaction, finishCallback)) { if (mSplitTransitions.isPendingResize(transition)) { // Only need to update in resize because divider exist before transition. mSplitLayout.update(startTransaction); mSplitLayout.update(startTransaction, true /* resetImePosition */); startTransaction.apply(); } return true; Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -69,7 +69,7 @@ public class DividerViewTest extends ShellTestCase { SplitWindowManager splitWindowManager = new SplitWindowManager("TestSplitWindowManager", mContext, configuration, mCallbacks); splitWindowManager.init(mSplitLayout, new InsetsState()); splitWindowManager.init(mSplitLayout, new InsetsState(), false /* isRestoring */); mDividerView = spy((DividerView) splitWindowManager.getDividerView()); } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java +17 −9 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { private int mStartPos; private GestureDetector mDoubleTapDetector; private boolean mInteractive; private boolean mHideHandle; private boolean mSetTouchRegion = true; private int mLastDraggingPosition; private int mHandleRegionWidth; Loading Loading @@ -211,11 +212,8 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { } /** Sets up essential dependencies of the divider bar. */ public void setup( SplitLayout layout, SplitWindowManager splitWindowManager, SurfaceControlViewHost viewHost, InsetsState insetsState) { public void setup(SplitLayout layout, SplitWindowManager splitWindowManager, SurfaceControlViewHost viewHost, InsetsState insetsState) { mSplitLayout = layout; mSplitWindowManager = splitWindowManager; mViewHost = viewHost; Loading Loading @@ -277,6 +275,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { R.dimen.docked_stack_divider_lift_elevation); mDoubleTapDetector = new GestureDetector(getContext(), new DoubleTapListener()); mInteractive = true; mHideHandle = false; setOnTouchListener(this); mHandle.setAccessibilityDelegate(mHandleDelegate); setWillNotDraw(false); Loading Loading @@ -469,10 +468,11 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { void setInteractive(boolean interactive, boolean hideHandle, String from) { if (interactive == mInteractive) return; ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Set divider bar %s from %s", interactive ? "interactive" : "non-interactive", from); "Set divider bar %s hide handle=%b from %s", interactive ? "interactive" : "non-interactive", hideHandle, from); mInteractive = interactive; if (!mInteractive && hideHandle && mMoving) { mHideHandle = hideHandle; if (!mInteractive && mHideHandle && mMoving) { final int position = mSplitLayout.getDividePosition(); mSplitLayout.flingDividePosition( mLastDraggingPosition, Loading @@ -482,7 +482,15 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { mMoving = false; } releaseTouching(); mHandle.setVisibility(!mInteractive && hideHandle ? View.INVISIBLE : View.VISIBLE); mHandle.setVisibility(!mInteractive && mHideHandle ? View.INVISIBLE : View.VISIBLE); } boolean isInteractive() { return mInteractive; } boolean isHandleHidden() { return mHideHandle; } private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +20 −6 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import android.window.WindowContainerTransaction; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.animation.Interpolators; Loading @@ -70,6 +71,7 @@ import com.android.wm.shell.common.InteractionJankMonitorUtils; import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition; import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import com.android.wm.shell.protolog.ShellProtoLogGroup; import java.io.PrintWriter; import java.util.function.Consumer; Loading Loading @@ -420,7 +422,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange public void init() { if (mInitialized) return; mInitialized = true; mSplitWindowManager.init(this, mInsetsState); mSplitWindowManager.init(this, mInsetsState, false /* isRestoring */); mDisplayImeController.addPositionProcessor(mImePositionProcessor); } Loading @@ -442,14 +444,19 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange } /** Releases and re-inflates {@link DividerView} on the root surface. */ public void update(SurfaceControl.Transaction t) { public void update(SurfaceControl.Transaction t, boolean resetImePosition) { if (!mInitialized) { init(); return; } mSplitWindowManager.release(t); if (resetImePosition) { mImePositionProcessor.reset(); mSplitWindowManager.init(this, mInsetsState); } mSplitWindowManager.init(this, mInsetsState, true /* isRestoring */); // Update the surface positions again after recreating the divider in case nothing else // triggers it mSplitLayoutHandler.onLayoutPositionChanging(SplitLayout.this); } @Override Loading Loading @@ -868,6 +875,9 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange pw.println(prefix + TAG + ":"); pw.println(innerPrefix + "mAllowLeftRightSplitInPortrait=" + mAllowLeftRightSplitInPortrait); pw.println(innerPrefix + "mIsLeftRightSplit=" + mIsLeftRightSplit); pw.println(innerPrefix + "mFreezeDividerWindow=" + mFreezeDividerWindow); pw.println(innerPrefix + "mDimNonImeSide=" + mDimNonImeSide); pw.println(innerPrefix + "mDividerPosition=" + mDividerPosition); pw.println(innerPrefix + "bounds1=" + mBounds1.toShortString()); pw.println(innerPrefix + "dividerBounds=" + mDividerBounds.toShortString()); pw.println(innerPrefix + "bounds2=" + mBounds2.toShortString()); Loading Loading @@ -1151,14 +1161,16 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange mTargetYOffset = needOffset ? getTargetYOffset() : 0; if (mTargetYOffset != mLastYOffset) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Split IME animation starting, fromY=%d toY=%d", mLastYOffset, mTargetYOffset); // Freeze the configuration size with offset to prevent app get a configuration // changed or relaunch. This is required to make sure client apps will calculate // insets properly after layout shifted. if (mTargetYOffset == 0) { mSplitLayoutHandler.setLayoutOffsetTarget(0, 0, SplitLayout.this); } else { mSplitLayoutHandler.setLayoutOffsetTarget(0, mTargetYOffset - mLastYOffset, SplitLayout.this); mSplitLayoutHandler.setLayoutOffsetTarget(0, mTargetYOffset, SplitLayout.this); } } Loading @@ -1183,6 +1195,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange public void onImeEndPositioning(int displayId, boolean cancel, SurfaceControl.Transaction t) { if (displayId != mDisplayId || !mHasImeFocus || cancel) return; ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Split IME animation ending, canceled=%b", cancel); onProgress(1.0f); mSplitLayoutHandler.onLayoutPositionChanging(SplitLayout.this); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java +11 −1 Original line number Diff line number Diff line Loading @@ -62,6 +62,10 @@ public final class SplitWindowManager extends WindowlessWindowManager { // Used to "pass" a transaction to WWM.remove so that view removal can be synchronized. private SurfaceControl.Transaction mSyncTransaction = null; // For saving/restoring state private boolean mLastDividerInteractive = true; private boolean mLastDividerHandleHidden; public interface ParentContainerCallbacks { void attachToParentSurface(SurfaceControl.Builder b); void onLeashReady(SurfaceControl leash); Loading Loading @@ -107,7 +111,7 @@ public final class SplitWindowManager extends WindowlessWindowManager { } /** Inflates {@link DividerView} on to the root surface. */ void init(SplitLayout splitLayout, InsetsState insetsState) { void init(SplitLayout splitLayout, InsetsState insetsState, boolean isRestoring) { if (mDividerView != null || mViewHost != null) { throw new UnsupportedOperationException( "Try to inflate divider view again without release first"); Loading @@ -130,6 +134,10 @@ public final class SplitWindowManager extends WindowlessWindowManager { lp.accessibilityTitle = mContext.getResources().getString(R.string.accessibility_divider); mViewHost.setView(mDividerView, lp); mDividerView.setup(splitLayout, this, mViewHost, insetsState); if (isRestoring) { mDividerView.setInteractive(mLastDividerInteractive, mLastDividerHandleHidden, "restore_setup"); } } /** Loading @@ -138,6 +146,8 @@ public final class SplitWindowManager extends WindowlessWindowManager { */ void release(@Nullable SurfaceControl.Transaction t) { if (mDividerView != null) { mLastDividerInteractive = mDividerView.isInteractive(); mLastDividerHandleHidden = mDividerView.isHandleHidden(); mDividerView = null; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +9 −6 Original line number Diff line number Diff line Loading @@ -1666,7 +1666,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } void finishEnterSplitScreen(SurfaceControl.Transaction finishT) { mSplitLayout.update(finishT); mSplitLayout.update(finishT, true /* resetImePosition */); mMainStage.getSplitDecorManager().inflate(mContext, mMainStage.mRootLeash, getMainStageBounds()); mSideStage.getSplitDecorManager().inflate(mContext, mSideStage.mRootLeash, Loading Loading @@ -1860,9 +1860,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, && mSplitLayout.updateConfiguration(mRootTaskInfo.configuration) && mMainStage.isActive()) { // Clear the divider remote animating flag as the divider will be re-rendered to apply // the new rotation config. // the new rotation config. Don't reset the IME state since those updates are not in // sync with task info changes. mIsDividerRemoteAnimating = false; mSplitLayout.update(null /* t */); mSplitLayout.update(null /* t */, false /* resetImePosition */); onLayoutSizeChanged(mSplitLayout); } } Loading Loading @@ -2325,7 +2326,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, */ public void updateSurfaces(SurfaceControl.Transaction transaction) { updateSurfaceBounds(mSplitLayout, transaction, /* applyResizingOffset */ false); mSplitLayout.update(transaction); mSplitLayout.update(transaction, true /* resetImePosition */); } private void onDisplayChange(int displayId, int fromRotation, int toRotation, Loading Loading @@ -2598,7 +2599,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, final TransitionInfo.Change change = info.getChanges().get(iC); if (change.getMode() == TRANSIT_CHANGE && (change.getFlags() & FLAG_IS_DISPLAY) != 0) { mSplitLayout.update(startTransaction); // Don't reset the IME state since those updates are not in sync with the // display change transition mSplitLayout.update(startTransaction, false /* resetImePosition */); } if (mMixedHandler.isEnteringPip(change, transitType)) { Loading Loading @@ -2699,7 +2702,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, startTransaction, finishTransaction, finishCallback)) { if (mSplitTransitions.isPendingResize(transition)) { // Only need to update in resize because divider exist before transition. mSplitLayout.update(startTransaction); mSplitLayout.update(startTransaction, true /* resetImePosition */); startTransaction.apply(); } return true; Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -69,7 +69,7 @@ public class DividerViewTest extends ShellTestCase { SplitWindowManager splitWindowManager = new SplitWindowManager("TestSplitWindowManager", mContext, configuration, mCallbacks); splitWindowManager.init(mSplitLayout, new InsetsState()); splitWindowManager.init(mSplitLayout, new InsetsState(), false /* isRestoring */); mDividerView = spy((DividerView) splitWindowManager.getDividerView()); } Loading