Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +12 −16 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,7 @@ import com.android.wm.shell.common.InteractionJankMonitorUtils; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.function.Consumer; /** /** * Records and handles layout of splits. Helps to calculate proper bounds when configuration or * Records and handles layout of splits. Helps to calculate proper bounds when configuration or Loading Loading @@ -599,7 +600,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange /** Swich both surface position with animation. */ /** Swich both surface position with animation. */ public void splitSwitching(SurfaceControl.Transaction t, SurfaceControl leash1, public void splitSwitching(SurfaceControl.Transaction t, SurfaceControl leash1, SurfaceControl leash2, Runnable finishCallback) { SurfaceControl leash2, Consumer<Rect> finishCallback) { final boolean isLandscape = isLandscape(); final boolean isLandscape = isLandscape(); final Rect insets = getDisplayInsets(mContext); final Rect insets = getDisplayInsets(mContext); insets.set(isLandscape ? insets.left : 0, isLandscape ? 0 : insets.top, insets.set(isLandscape ? insets.left : 0, isLandscape ? 0 : insets.top, Loading @@ -617,18 +618,13 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange distBounds1.offset(-mRootBounds.left, -mRootBounds.top); distBounds1.offset(-mRootBounds.left, -mRootBounds.top); distBounds2.offset(-mRootBounds.left, -mRootBounds.top); distBounds2.offset(-mRootBounds.left, -mRootBounds.top); distDividerBounds.offset(-mRootBounds.left, -mRootBounds.top); distDividerBounds.offset(-mRootBounds.left, -mRootBounds.top); // DO NOT move to insets area for smooth animation. distBounds1.set(distBounds1.left, distBounds1.top, distBounds1.right - insets.right, distBounds1.bottom - insets.bottom); distBounds2.set(distBounds2.left + insets.left, distBounds2.top + insets.top, distBounds2.right, distBounds2.bottom); ValueAnimator animator1 = moveSurface(t, leash1, getRefBounds1(), distBounds1, ValueAnimator animator1 = moveSurface(t, leash1, getRefBounds1(), distBounds1, false /* alignStart */); -insets.left, -insets.top); ValueAnimator animator2 = moveSurface(t, leash2, getRefBounds2(), distBounds2, ValueAnimator animator2 = moveSurface(t, leash2, getRefBounds2(), distBounds2, true /* alignStart */); insets.left, insets.top); ValueAnimator animator3 = moveSurface(t, getDividerLeash(), getRefDividerBounds(), ValueAnimator animator3 = moveSurface(t, getDividerLeash(), getRefDividerBounds(), distDividerBounds, true /* alignStart */); distDividerBounds, 0 /* offsetX */, 0 /* offsetY */); AnimatorSet set = new AnimatorSet(); AnimatorSet set = new AnimatorSet(); set.playTogether(animator1, animator2, animator3); set.playTogether(animator1, animator2, animator3); Loading @@ -638,14 +634,14 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) { mDividePosition = dividerPos; mDividePosition = dividerPos; updateBounds(mDividePosition); updateBounds(mDividePosition); finishCallback.run(); finishCallback.accept(insets); } } }); }); set.start(); set.start(); } } private ValueAnimator moveSurface(SurfaceControl.Transaction t, SurfaceControl leash, private ValueAnimator moveSurface(SurfaceControl.Transaction t, SurfaceControl leash, Rect start, Rect end, boolean alignStart) { Rect start, Rect end, float offsetX, float offsetY) { Rect tempStart = new Rect(start); Rect tempStart = new Rect(start); Rect tempEnd = new Rect(end); Rect tempEnd = new Rect(end); final float diffX = tempEnd.left - tempStart.left; final float diffX = tempEnd.left - tempStart.left; Loading @@ -661,15 +657,15 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange final float distY = tempStart.top + scale * diffY; final float distY = tempStart.top + scale * diffY; final int width = (int) (tempStart.width() + scale * diffWidth); final int width = (int) (tempStart.width() + scale * diffWidth); final int height = (int) (tempStart.height() + scale * diffHeight); final int height = (int) (tempStart.height() + scale * diffHeight); if (alignStart) { if (offsetX == 0 && offsetY == 0) { t.setPosition(leash, distX, distY); t.setPosition(leash, distX, distY); t.setWindowCrop(leash, width, height); t.setWindowCrop(leash, width, height); } else { } else { final int offsetX = width - tempStart.width(); final int diffOffsetX = (int) (scale * offsetX); final int offsetY = height - tempStart.height(); final int diffOffsetY = (int) (scale * offsetY); t.setPosition(leash, distX + offsetX, distY + offsetY); t.setPosition(leash, distX + diffOffsetX, distY + diffOffsetY); mTempRect.set(0, 0, width, height); mTempRect.set(0, 0, width, height); mTempRect.offsetTo(-offsetX, -offsetY); mTempRect.offsetTo(-diffOffsetX, -diffOffsetY); t.setCrop(leash, mTempRect); t.setCrop(leash, mTempRect); } } t.apply(); t.apply(); Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +34 −4 Original line number Original line Diff line number Diff line Loading @@ -115,6 +115,7 @@ import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ScreenshotUtils; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.common.TransactionPool; Loading Loading @@ -846,15 +847,44 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, void setSideStagePositionAnimated(@SplitPosition int sideStagePosition) { void setSideStagePositionAnimated(@SplitPosition int sideStagePosition) { if (mSideStagePosition == sideStagePosition) return; if (mSideStagePosition == sideStagePosition) return; SurfaceControl.Transaction t = mTransactionPool.acquire(); SurfaceControl.Transaction t = mTransactionPool.acquire(); mTempRect1.setEmpty(); final StageTaskListener topLeftStage = final StageTaskListener topLeftStage = mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage; mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage; final SurfaceControl topLeftScreenshot = ScreenshotUtils.takeScreenshot(t, topLeftStage.mRootLeash, mTempRect1, Integer.MAX_VALUE - 1); final StageTaskListener bottomRightStage = final StageTaskListener bottomRightStage = mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage; mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage; final SurfaceControl bottomRightScreenshot = ScreenshotUtils.takeScreenshot(t, bottomRightStage.mRootLeash, mTempRect1, Integer.MAX_VALUE - 1); mSplitLayout.splitSwitching(t, topLeftStage.mRootLeash, bottomRightStage.mRootLeash, mSplitLayout.splitSwitching(t, topLeftStage.mRootLeash, bottomRightStage.mRootLeash, () -> { insets -> { setSideStagePosition(SplitLayout.reversePosition(mSideStagePosition), WindowContainerTransaction wct = new WindowContainerTransaction(); null /* wct */); setSideStagePosition(SplitLayout.reversePosition(mSideStagePosition), wct); mSyncQueue.queue(wct); mSyncQueue.runInSync(st -> { updateSurfaceBounds(mSplitLayout, st, false /* applyResizingOffset */); st.setPosition(topLeftScreenshot, -insets.left, -insets.top); st.setPosition(bottomRightScreenshot, insets.left, insets.top); final ValueAnimator va = ValueAnimator.ofFloat(1, 0); va.addUpdateListener(valueAnimator-> { final float progress = (float) valueAnimator.getAnimatedValue(); t.setAlpha(topLeftScreenshot, progress); t.setAlpha(bottomRightScreenshot, progress); t.apply(); }); va.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd( @androidx.annotation.NonNull Animator animation) { t.remove(topLeftScreenshot); t.remove(bottomRightScreenshot); t.apply(); mTransactionPool.release(t); mTransactionPool.release(t); } }); va.start(); }); }); }); } } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +12 −16 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,7 @@ import com.android.wm.shell.common.InteractionJankMonitorUtils; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.function.Consumer; /** /** * Records and handles layout of splits. Helps to calculate proper bounds when configuration or * Records and handles layout of splits. Helps to calculate proper bounds when configuration or Loading Loading @@ -599,7 +600,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange /** Swich both surface position with animation. */ /** Swich both surface position with animation. */ public void splitSwitching(SurfaceControl.Transaction t, SurfaceControl leash1, public void splitSwitching(SurfaceControl.Transaction t, SurfaceControl leash1, SurfaceControl leash2, Runnable finishCallback) { SurfaceControl leash2, Consumer<Rect> finishCallback) { final boolean isLandscape = isLandscape(); final boolean isLandscape = isLandscape(); final Rect insets = getDisplayInsets(mContext); final Rect insets = getDisplayInsets(mContext); insets.set(isLandscape ? insets.left : 0, isLandscape ? 0 : insets.top, insets.set(isLandscape ? insets.left : 0, isLandscape ? 0 : insets.top, Loading @@ -617,18 +618,13 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange distBounds1.offset(-mRootBounds.left, -mRootBounds.top); distBounds1.offset(-mRootBounds.left, -mRootBounds.top); distBounds2.offset(-mRootBounds.left, -mRootBounds.top); distBounds2.offset(-mRootBounds.left, -mRootBounds.top); distDividerBounds.offset(-mRootBounds.left, -mRootBounds.top); distDividerBounds.offset(-mRootBounds.left, -mRootBounds.top); // DO NOT move to insets area for smooth animation. distBounds1.set(distBounds1.left, distBounds1.top, distBounds1.right - insets.right, distBounds1.bottom - insets.bottom); distBounds2.set(distBounds2.left + insets.left, distBounds2.top + insets.top, distBounds2.right, distBounds2.bottom); ValueAnimator animator1 = moveSurface(t, leash1, getRefBounds1(), distBounds1, ValueAnimator animator1 = moveSurface(t, leash1, getRefBounds1(), distBounds1, false /* alignStart */); -insets.left, -insets.top); ValueAnimator animator2 = moveSurface(t, leash2, getRefBounds2(), distBounds2, ValueAnimator animator2 = moveSurface(t, leash2, getRefBounds2(), distBounds2, true /* alignStart */); insets.left, insets.top); ValueAnimator animator3 = moveSurface(t, getDividerLeash(), getRefDividerBounds(), ValueAnimator animator3 = moveSurface(t, getDividerLeash(), getRefDividerBounds(), distDividerBounds, true /* alignStart */); distDividerBounds, 0 /* offsetX */, 0 /* offsetY */); AnimatorSet set = new AnimatorSet(); AnimatorSet set = new AnimatorSet(); set.playTogether(animator1, animator2, animator3); set.playTogether(animator1, animator2, animator3); Loading @@ -638,14 +634,14 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) { mDividePosition = dividerPos; mDividePosition = dividerPos; updateBounds(mDividePosition); updateBounds(mDividePosition); finishCallback.run(); finishCallback.accept(insets); } } }); }); set.start(); set.start(); } } private ValueAnimator moveSurface(SurfaceControl.Transaction t, SurfaceControl leash, private ValueAnimator moveSurface(SurfaceControl.Transaction t, SurfaceControl leash, Rect start, Rect end, boolean alignStart) { Rect start, Rect end, float offsetX, float offsetY) { Rect tempStart = new Rect(start); Rect tempStart = new Rect(start); Rect tempEnd = new Rect(end); Rect tempEnd = new Rect(end); final float diffX = tempEnd.left - tempStart.left; final float diffX = tempEnd.left - tempStart.left; Loading @@ -661,15 +657,15 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange final float distY = tempStart.top + scale * diffY; final float distY = tempStart.top + scale * diffY; final int width = (int) (tempStart.width() + scale * diffWidth); final int width = (int) (tempStart.width() + scale * diffWidth); final int height = (int) (tempStart.height() + scale * diffHeight); final int height = (int) (tempStart.height() + scale * diffHeight); if (alignStart) { if (offsetX == 0 && offsetY == 0) { t.setPosition(leash, distX, distY); t.setPosition(leash, distX, distY); t.setWindowCrop(leash, width, height); t.setWindowCrop(leash, width, height); } else { } else { final int offsetX = width - tempStart.width(); final int diffOffsetX = (int) (scale * offsetX); final int offsetY = height - tempStart.height(); final int diffOffsetY = (int) (scale * offsetY); t.setPosition(leash, distX + offsetX, distY + offsetY); t.setPosition(leash, distX + diffOffsetX, distY + diffOffsetY); mTempRect.set(0, 0, width, height); mTempRect.set(0, 0, width, height); mTempRect.offsetTo(-offsetX, -offsetY); mTempRect.offsetTo(-diffOffsetX, -diffOffsetY); t.setCrop(leash, mTempRect); t.setCrop(leash, mTempRect); } } t.apply(); t.apply(); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +34 −4 Original line number Original line Diff line number Diff line Loading @@ -115,6 +115,7 @@ import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ScreenshotUtils; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.common.TransactionPool; Loading Loading @@ -846,15 +847,44 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, void setSideStagePositionAnimated(@SplitPosition int sideStagePosition) { void setSideStagePositionAnimated(@SplitPosition int sideStagePosition) { if (mSideStagePosition == sideStagePosition) return; if (mSideStagePosition == sideStagePosition) return; SurfaceControl.Transaction t = mTransactionPool.acquire(); SurfaceControl.Transaction t = mTransactionPool.acquire(); mTempRect1.setEmpty(); final StageTaskListener topLeftStage = final StageTaskListener topLeftStage = mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage; mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage; final SurfaceControl topLeftScreenshot = ScreenshotUtils.takeScreenshot(t, topLeftStage.mRootLeash, mTempRect1, Integer.MAX_VALUE - 1); final StageTaskListener bottomRightStage = final StageTaskListener bottomRightStage = mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage; mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage; final SurfaceControl bottomRightScreenshot = ScreenshotUtils.takeScreenshot(t, bottomRightStage.mRootLeash, mTempRect1, Integer.MAX_VALUE - 1); mSplitLayout.splitSwitching(t, topLeftStage.mRootLeash, bottomRightStage.mRootLeash, mSplitLayout.splitSwitching(t, topLeftStage.mRootLeash, bottomRightStage.mRootLeash, () -> { insets -> { setSideStagePosition(SplitLayout.reversePosition(mSideStagePosition), WindowContainerTransaction wct = new WindowContainerTransaction(); null /* wct */); setSideStagePosition(SplitLayout.reversePosition(mSideStagePosition), wct); mSyncQueue.queue(wct); mSyncQueue.runInSync(st -> { updateSurfaceBounds(mSplitLayout, st, false /* applyResizingOffset */); st.setPosition(topLeftScreenshot, -insets.left, -insets.top); st.setPosition(bottomRightScreenshot, insets.left, insets.top); final ValueAnimator va = ValueAnimator.ofFloat(1, 0); va.addUpdateListener(valueAnimator-> { final float progress = (float) valueAnimator.getAnimatedValue(); t.setAlpha(topLeftScreenshot, progress); t.setAlpha(bottomRightScreenshot, progress); t.apply(); }); va.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd( @androidx.annotation.NonNull Animator animation) { t.remove(topLeftScreenshot); t.remove(bottomRightScreenshot); t.apply(); mTransactionPool.release(t); mTransactionPool.release(t); } }); va.start(); }); }); }); } } Loading