From 2c8ea7b0217ecd50a70c52b3fbd3fa7697d297d7 Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Fri, 4 Dec 2020 16:11:15 +0800 Subject: Fix showing black background when resizing the divider bar. Reports resizing state to WM core so that app client could apply bigger visible bounds while resizing splits. Also moves DividerHandleView to more generic package. Fix: 172704238 Test: manul check divider behavior Test: atest WMShellUnitTests Change-Id: I1656c86de9a0b5dfe5e6da57ccc9d5f6e467843a --- .../Shell/res/layout/docked_stack_divider.xml | 4 +- .../Shell/res/layout/split_divider.xml | 6 + .../src/com/android/wm/shell/apppairs/AppPair.java | 28 ++-- .../wm/shell/common/split/DividerHandleView.java | 150 +++++++++++++++++++++ .../android/wm/shell/common/split/DividerView.java | 76 ++++++++--- .../android/wm/shell/common/split/SplitLayout.java | 4 + .../wm/shell/common/split/SplitWindowManager.java | 19 ++- .../shell/legacysplitscreen/DividerHandleView.java | 146 -------------------- .../wm/shell/legacysplitscreen/DividerView.java | 7 +- .../wm/shell/common/split/SplitLayoutTests.java | 15 ++- .../java/com/android/server/wm/WindowState.java | 3 +- 11 files changed, 258 insertions(+), 200 deletions(-) create mode 100644 libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java delete mode 100644 libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerHandleView.java diff --git a/libs/WindowManager/Shell/res/layout/docked_stack_divider.xml b/libs/WindowManager/Shell/res/layout/docked_stack_divider.xml index ea21eb97df57..ed5d2e1b49f5 100644 --- a/libs/WindowManager/Shell/res/layout/docked_stack_divider.xml +++ b/libs/WindowManager/Shell/res/layout/docked_stack_divider.xml @@ -27,9 +27,9 @@ "> + android:alpha="0"/> - + + diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java index 9754f5165a1c..563de06fe40c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java @@ -96,7 +96,8 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan mTaskInfo2 = task2; mSplitLayout = new SplitLayout( mDisplayController.getDisplayContext(mRootTaskInfo.displayId), - mRootTaskInfo.configuration, this, b -> b.setParent(mRootTaskLeash)); + mRootTaskInfo.configuration, this /* layoutChangeListener */, + b -> b.setParent(mRootTaskLeash)); final WindowContainerToken token1 = task1.token; final WindowContainerToken token2 = task2.token; @@ -191,22 +192,7 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan if (mSplitLayout != null && mSplitLayout.updateConfiguration(mRootTaskInfo.configuration)) { - // Update bounds when root bounds or its orientation changed. - final WindowContainerTransaction wct = new WindowContainerTransaction(); - final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash(); - final Rect dividerBounds = mSplitLayout.getDividerBounds(); - final Rect bounds1 = mSplitLayout.getBounds1(); - final Rect bounds2 = mSplitLayout.getBounds2(); - - wct.setBounds(mTaskInfo1.token, bounds1) - .setBounds(mTaskInfo2.token, bounds2); - mController.getTaskOrganizer().applyTransaction(wct); - mSyncQueue.runInSync(t -> t - .setPosition(mTaskLeash1, bounds1.left, bounds1.top) - .setPosition(mTaskLeash2, bounds2.left, bounds2.top) - .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top) - // Resets layer to divider bar to make sure it is always on top. - .setLayer(dividerLeash, Integer.MAX_VALUE)); + onBoundsChanged(mSplitLayout); } } else if (taskInfo.taskId == getTaskId1()) { mTaskInfo1 = taskInfo; @@ -262,6 +248,10 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan final Rect bounds1 = layout.getBounds1(); final Rect bounds2 = layout.getBounds2(); mSyncQueue.runInSync(t -> t + // Ignores the original surface bounds so that the app could fill up the gap + // between each surface with corresponding background while resizing. + .setWindowCrop(mTaskLeash1, bounds1.width(), bounds1.height()) + .setWindowCrop(mTaskLeash2, bounds2.width(), bounds2.height()) .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top) .setPosition(mTaskLeash1, bounds1.left, bounds1.top) .setPosition(mTaskLeash2, bounds2.left, bounds2.top)); @@ -279,6 +269,10 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan .setBounds(mTaskInfo2.token, bounds2); mController.getTaskOrganizer().applyTransaction(wct); mSyncQueue.runInSync(t -> t + // Resets layer of divider bar to make sure it is always on top. + .setLayer(dividerLeash, Integer.MAX_VALUE) + .setWindowCrop(mTaskLeash1, bounds1.width(), bounds1.height()) + .setWindowCrop(mTaskLeash2, bounds2.width(), bounds2.height()) .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top) .setPosition(mTaskLeash1, bounds1.left, bounds1.top) .setPosition(mTaskLeash2, bounds2.left, bounds2.top)); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java new file mode 100644 index 000000000000..218bf47e24aa --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.common.split; + +import static com.android.wm.shell.common.split.DividerView.TOUCH_ANIMATION_DURATION; +import static com.android.wm.shell.common.split.DividerView.TOUCH_RELEASE_ANIMATION_DURATION; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.annotation.Nullable; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.util.AttributeSet; +import android.util.Property; +import android.view.View; + +import com.android.wm.shell.R; +import com.android.wm.shell.animation.Interpolators; + +/** + * View for the handle in the docked stack divider. + */ +public class DividerHandleView extends View { + + private static final Property WIDTH_PROPERTY = + new Property(Integer.class, "width") { + @Override + public Integer get(DividerHandleView object) { + return object.mCurrentWidth; + } + + @Override + public void set(DividerHandleView object, Integer value) { + object.mCurrentWidth = value; + object.invalidate(); + } + }; + + private static final Property HEIGHT_PROPERTY = + new Property(Integer.class, "height") { + @Override + public Integer get(DividerHandleView object) { + return object.mCurrentHeight; + } + + @Override + public void set(DividerHandleView object, Integer value) { + object.mCurrentHeight = value; + object.invalidate(); + } + }; + + private final Paint mPaint = new Paint(); + private final int mWidth; + private final int mHeight; + private final int mCircleDiameter; + private int mCurrentWidth; + private int mCurrentHeight; + private AnimatorSet mAnimator; + private boolean mTouching; + + public DividerHandleView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + mPaint.setColor(getResources().getColor(R.color.docked_divider_handle, null)); + mPaint.setAntiAlias(true); + mWidth = getResources().getDimensionPixelSize(R.dimen.docked_divider_handle_width); + mHeight = getResources().getDimensionPixelSize(R.dimen.docked_divider_handle_height); + mCurrentWidth = mWidth; + mCurrentHeight = mHeight; + mCircleDiameter = (mWidth + mHeight) / 3; + } + + /** Sets touching state for this handle view. */ + public void setTouching(boolean touching, boolean animate) { + if (touching == mTouching) { + return; + } + if (mAnimator != null) { + mAnimator.cancel(); + mAnimator = null; + } + if (!animate) { + if (touching) { + mCurrentWidth = mCircleDiameter; + mCurrentHeight = mCircleDiameter; + } else { + mCurrentWidth = mWidth; + mCurrentHeight = mHeight; + } + invalidate(); + } else { + animateToTarget(touching ? mCircleDiameter : mWidth, + touching ? mCircleDiameter : mHeight, touching); + } + mTouching = touching; + } + + private void animateToTarget(int targetWidth, int targetHeight, boolean touching) { + ObjectAnimator widthAnimator = ObjectAnimator.ofInt(this, WIDTH_PROPERTY, + mCurrentWidth, targetWidth); + ObjectAnimator heightAnimator = ObjectAnimator.ofInt(this, HEIGHT_PROPERTY, + mCurrentHeight, targetHeight); + mAnimator = new AnimatorSet(); + mAnimator.playTogether(widthAnimator, heightAnimator); + mAnimator.setDuration(touching + ? TOUCH_ANIMATION_DURATION + : TOUCH_RELEASE_ANIMATION_DURATION); + mAnimator.setInterpolator(touching + ? Interpolators.TOUCH_RESPONSE + : Interpolators.FAST_OUT_SLOW_IN); + mAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mAnimator = null; + } + }); + mAnimator.start(); + } + + @Override + protected void onDraw(Canvas canvas) { + int left = getWidth() / 2 - mCurrentWidth / 2; + int top = getHeight() / 2 - mCurrentHeight / 2; + int radius = Math.min(mCurrentWidth, mCurrentHeight) / 2; + canvas.drawRoundRect(left, top, left + mCurrentWidth, top + mCurrentHeight, + radius, radius, mPaint); + } + + @Override + public boolean hasOverlappingRendering() { + return false; + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java index e97fe0a9111c..707747b3889b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java @@ -33,17 +33,23 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.policy.DividerSnapAlgorithm; +import com.android.wm.shell.R; +import com.android.wm.shell.animation.Interpolators; /** * Stack divider for app pair. */ -// TODO(b/172704238): add handle view to indicate touching status. public class DividerView extends FrameLayout implements View.OnTouchListener { + public static final long TOUCH_ANIMATION_DURATION = 150; + public static final long TOUCH_RELEASE_ANIMATION_DURATION = 200; + private final int mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); private SplitLayout mSplitLayout; private SurfaceControlViewHost mViewHost; - private DragListener mDragListener; + private DividerHandleView mHandle; + private View mBackground; + private int mTouchElevation; private VelocityTracker mVelocityTracker; private boolean mMoving; @@ -70,16 +76,18 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { /** Sets up essential dependencies of the divider bar. */ public void setup( SplitLayout layout, - SurfaceControlViewHost viewHost, - @Nullable DragListener dragListener) { + SurfaceControlViewHost viewHost) { mSplitLayout = layout; mViewHost = viewHost; - mDragListener = dragListener; } @Override protected void onFinishInflate() { super.onFinishInflate(); + mHandle = findViewById(R.id.docked_divider_handle); + mBackground = findViewById(R.id.docked_divider_background); + mTouchElevation = getResources().getDimensionPixelSize( + R.dimen.docked_stack_divider_lift_elevation); setOnTouchListener(this); } @@ -97,7 +105,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { case MotionEvent.ACTION_DOWN: mVelocityTracker = VelocityTracker.obtain(); mVelocityTracker.addMovement(event); - setSlippery(false); + setTouching(); mStartPos = touchPos; mMoving = false; break; @@ -106,9 +114,6 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { if (!mMoving && Math.abs(touchPos - mStartPos) > mTouchSlop) { mStartPos = touchPos; mMoving = true; - if (mDragListener != null) { - mDragListener.onDragStart(); - } } if (mMoving) { final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos; @@ -122,11 +127,8 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { final float velocity = isLandscape ? mVelocityTracker.getXVelocity() : mVelocityTracker.getYVelocity(); - setSlippery(true); + releaseTouching(); mMoving = false; - if (mDragListener != null) { - mDragListener.onDragEnd(); - } final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos; final DividerSnapAlgorithm.SnapTarget snapTarget = @@ -137,6 +139,45 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { return true; } + private void setTouching() { + setSlippery(false); + mHandle.setTouching(true, true); + if (isLandscape()) { + mBackground.animate().scaleX(1.4f); + } else { + mBackground.animate().scaleY(1.4f); + } + mBackground.animate() + .setInterpolator(Interpolators.TOUCH_RESPONSE) + .setDuration(TOUCH_ANIMATION_DURATION) + .translationZ(mTouchElevation) + .start(); + // Lift handle as well so it doesn't get behind the background, even though it doesn't + // cast shadow. + mHandle.animate() + .setInterpolator(Interpolators.TOUCH_RESPONSE) + .setDuration(TOUCH_ANIMATION_DURATION) + .translationZ(mTouchElevation) + .start(); + } + + private void releaseTouching() { + setSlippery(true); + mHandle.setTouching(false, true); + mBackground.animate() + .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) + .setDuration(TOUCH_RELEASE_ANIMATION_DURATION) + .translationZ(0) + .scaleX(1f) + .scaleY(1f) + .start(); + mHandle.animate() + .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) + .setDuration(TOUCH_RELEASE_ANIMATION_DURATION) + .translationZ(0) + .start(); + } + private void setSlippery(boolean slippery) { if (mViewHost == null) { return; @@ -159,13 +200,4 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { private boolean isLandscape() { return getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE; } - - /** Monitors dragging action of the divider bar. */ - // TODO(b/172704238): add listeners to deal with resizing state of the app windows. - public interface DragListener { - /** Called when start dragging. */ - void onDragStart(); - /** Called when stop dragging. */ - void onDragEnd(); - } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index 6b9bf2d44261..291e9bdad69b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -156,12 +156,14 @@ public class SplitLayout { void updateDivideBounds(int position) { updateBounds(position); mLayoutChangeListener.onBoundsChanging(this); + mSplitWindowManager.setResizingSplits(true); } void setDividePosition(int position) { mDividePosition = position; updateBounds(mDividePosition); mLayoutChangeListener.onBoundsChanged(this); + mSplitWindowManager.setResizingSplits(false); } /** @@ -172,9 +174,11 @@ public class SplitLayout { switch (snapTarget.flag) { case FLAG_DISMISS_START: mLayoutChangeListener.onSnappedToDismiss(false /* snappedToEnd */); + mSplitWindowManager.setResizingSplits(false); break; case FLAG_DISMISS_END: mLayoutChangeListener.onSnappedToDismiss(true /* snappedToEnd */); + mSplitWindowManager.setResizingSplits(false); break; default: flingDividePosition(currentPosition, snapTarget.position); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java index 238caef27547..29116bd6f956 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java @@ -25,6 +25,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMA import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; +import android.app.ActivityTaskManager; import android.content.Context; import android.content.res.Configuration; import android.graphics.PixelFormat; @@ -32,6 +33,8 @@ import android.graphics.Rect; import android.graphics.Region; import android.os.Binder; import android.os.IBinder; +import android.os.RemoteException; +import android.util.Slog; import android.view.IWindow; import android.view.LayoutInflater; import android.view.SurfaceControl; @@ -47,11 +50,13 @@ import com.android.wm.shell.R; * Holds view hierarchy of a root surface and helps to inflate {@link DividerView} for a split. */ public final class SplitWindowManager extends WindowlessWindowManager { + private static final String TAG = SplitWindowManager.class.getSimpleName(); private static final String DIVIDER_WINDOW_TITLE = "SplitDivider"; + private final ParentContainerCallbacks mParentContainerCallbacks; private Context mContext; private SurfaceControlViewHost mViewHost; - final private ParentContainerCallbacks mParentContainerCallbacks; + private boolean mResizingSplits; public interface ParentContainerCallbacks { void attachToParentSurface(SurfaceControl.Builder b); @@ -104,7 +109,7 @@ public final class SplitWindowManager extends WindowlessWindowManager { lp.setTitle(DIVIDER_WINDOW_TITLE); lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY; mViewHost.setView(dividerView, lp); - dividerView.setup(splitLayout, mViewHost, null /* dragListener */); + dividerView.setup(splitLayout, mViewHost); } /** @@ -117,6 +122,16 @@ public final class SplitWindowManager extends WindowlessWindowManager { mViewHost = null; } + void setResizingSplits(boolean resizing) { + if (resizing == mResizingSplits) return; + try { + ActivityTaskManager.getService().setSplitScreenResizing(resizing); + mResizingSplits = resizing; + } catch (RemoteException e) { + Slog.w(TAG, "Error calling setSplitScreenResizing", e); + } + } + /** * Gets {@link SurfaceControl} of the surface holding divider view. @return {@code null} if not * feasible. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerHandleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerHandleView.java deleted file mode 100644 index 17ca110285bf..000000000000 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerHandleView.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.legacysplitscreen; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; -import android.annotation.Nullable; -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.util.AttributeSet; -import android.util.Property; -import android.view.View; - -import com.android.wm.shell.R; -import com.android.wm.shell.animation.Interpolators; - -/** - * View for the handle in the docked stack divider. - */ -public class DividerHandleView extends View { - - private static final Property WIDTH_PROPERTY = - new Property(Integer.class, "width") { - @Override - public Integer get(DividerHandleView object) { - return object.mCurrentWidth; - } - - @Override - public void set(DividerHandleView object, Integer value) { - object.mCurrentWidth = value; - object.invalidate(); - } - }; - - private static final Property HEIGHT_PROPERTY = - new Property(Integer.class, "height") { - @Override - public Integer get(DividerHandleView object) { - return object.mCurrentHeight; - } - - @Override - public void set(DividerHandleView object, Integer value) { - object.mCurrentHeight = value; - object.invalidate(); - } - }; - - private final Paint mPaint = new Paint(); - private final int mWidth; - private final int mHeight; - private final int mCircleDiameter; - private int mCurrentWidth; - private int mCurrentHeight; - private AnimatorSet mAnimator; - private boolean mTouching; - - public DividerHandleView(Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - mPaint.setColor(getResources().getColor(R.color.docked_divider_handle, null)); - mPaint.setAntiAlias(true); - mWidth = getResources().getDimensionPixelSize(R.dimen.docked_divider_handle_width); - mHeight = getResources().getDimensionPixelSize(R.dimen.docked_divider_handle_height); - mCurrentWidth = mWidth; - mCurrentHeight = mHeight; - mCircleDiameter = (mWidth + mHeight) / 3; - } - - void setTouching(boolean touching, boolean animate) { - if (touching == mTouching) { - return; - } - if (mAnimator != null) { - mAnimator.cancel(); - mAnimator = null; - } - if (!animate) { - if (touching) { - mCurrentWidth = mCircleDiameter; - mCurrentHeight = mCircleDiameter; - } else { - mCurrentWidth = mWidth; - mCurrentHeight = mHeight; - } - invalidate(); - } else { - animateToTarget(touching ? mCircleDiameter : mWidth, - touching ? mCircleDiameter : mHeight, touching); - } - mTouching = touching; - } - - private void animateToTarget(int targetWidth, int targetHeight, boolean touching) { - ObjectAnimator widthAnimator = ObjectAnimator.ofInt(this, WIDTH_PROPERTY, - mCurrentWidth, targetWidth); - ObjectAnimator heightAnimator = ObjectAnimator.ofInt(this, HEIGHT_PROPERTY, - mCurrentHeight, targetHeight); - mAnimator = new AnimatorSet(); - mAnimator.playTogether(widthAnimator, heightAnimator); - mAnimator.setDuration(touching - ? DividerView.TOUCH_ANIMATION_DURATION - : DividerView.TOUCH_RELEASE_ANIMATION_DURATION); - mAnimator.setInterpolator(touching - ? Interpolators.TOUCH_RESPONSE - : Interpolators.FAST_OUT_SLOW_IN); - mAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mAnimator = null; - } - }); - mAnimator.start(); - } - - @Override - protected void onDraw(Canvas canvas) { - int left = getWidth() / 2 - mCurrentWidth / 2; - int top = getHeight() / 2 - mCurrentHeight / 2; - int radius = Math.min(mCurrentWidth, mCurrentHeight) / 2; - canvas.drawRoundRect(left, top, left + mCurrentWidth, top + mCurrentHeight, - radius, radius, mPaint); - } - - @Override - public boolean hasOverlappingRendering() { - return false; - } -} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java index 16c966fccbf4..c1b6c4fec792 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java @@ -20,6 +20,9 @@ import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW; import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW; import static android.view.WindowManager.DOCKED_RIGHT; +import static com.android.wm.shell.common.split.DividerView.TOUCH_ANIMATION_DURATION; +import static com.android.wm.shell.common.split.DividerView.TOUCH_RELEASE_ANIMATION_DURATION; + import android.animation.AnimationHandler; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -66,6 +69,7 @@ import com.android.internal.policy.DockedDividerUtils; import com.android.wm.shell.R; import com.android.wm.shell.animation.FlingAnimationUtils; import com.android.wm.shell.animation.Interpolators; +import com.android.wm.shell.common.split.DividerHandleView; import java.util.function.Consumer; @@ -82,9 +86,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, void onDraggingEnd(); } - static final long TOUCH_ANIMATION_DURATION = 150; - static final long TOUCH_RELEASE_ANIMATION_DURATION = 200; - public static final int INVALID_RECENTS_GROW_TARGET = -1; private static final int LOG_VALUE_RESIZE_50_50 = 0; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java index 708a6c56a3f5..cd468167e372 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java @@ -75,15 +75,16 @@ public class SplitLayoutTests extends ShellTestCase { } @Test - @UiThreadTest - public void testSnapToTarget() { - DividerSnapAlgorithm.SnapTarget snapTarget = getSnapTarget(0 /* position */, - DividerSnapAlgorithm.SnapTarget.FLAG_NONE); - mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget); - verify(mLayoutChangeListener).onBoundsChanging(any(SplitLayout.class)); + public void testSetDividePosition() { + mSplitLayout.setDividePosition(anyInt()); + verify(mLayoutChangeListener).onBoundsChanged(any(SplitLayout.class)); + } + @Test + @UiThreadTest + public void testSnapToDismissTarget() { // verify it callbacks properly when the snap target indicates dismissing split. - snapTarget = getSnapTarget(0 /* position */, + DividerSnapAlgorithm.SnapTarget snapTarget = getSnapTarget(0 /* position */, DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_START); mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget); verify(mLayoutChangeListener).onSnappedToDismiss(eq(false)); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 32b84a8d0a2c..d3102600092f 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3843,7 +3843,8 @@ class WindowState extends WindowContainer implements WindowManagerP if (task == null) { return false; } - if (!inSplitScreenWindowingMode() && !inFreeformWindowingMode()) { + if (!inSplitScreenWindowingMode() && !inFreeformWindowingMode() + && !task.getRootTask().mCreatedByOrganizer) { return false; } // TODO(157912944): formalize drag-resizing so that exceptions aren't hardcoded like this -- cgit v1.2.3-59-g8ed1b