Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 39a6d69a authored by Jerry Chang's avatar Jerry Chang Committed by Android (Google) Code Review
Browse files

Merge "Fix showing black background when resizing the divider bar."

parents 46bdad0b 2c8ea7b0
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -27,9 +27,9 @@
    <com.android.wm.shell.legacysplitscreen.MinimizedDockShadow
        style="@style/DockedDividerMinimizedShadow"
        android:id="@+id/minimized_dock_shadow"
        android:alpha="0"/>">
        android:alpha="0"/>

    <com.android.wm.shell.legacysplitscreen.DividerHandleView
    <com.android.wm.shell.common.split.DividerHandleView
        style="@style/DockedDividerHandle"
        android:id="@+id/docked_divider_handle"
        android:contentDescription="@string/accessibility_divider"
+6 −0
Original line number Diff line number Diff line
@@ -24,4 +24,10 @@
        android:id="@+id/docked_divider_background"
        android:background="@color/docked_divider_background"/>

    <com.android.wm.shell.common.split.DividerHandleView
        style="@style/DockedDividerHandle"
        android:id="@+id/docked_divider_handle"
        android:contentDescription="@string/accessibility_divider"
        android:background="@null"/>

</com.android.wm.shell.common.split.DividerView>
+11 −17
Original line number Diff line number Diff line
@@ -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));
+8 −4
Original line number Diff line number Diff line
@@ -14,7 +14,10 @@
 * limitations under the License.
 */

package com.android.wm.shell.legacysplitscreen;
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;
@@ -84,7 +87,8 @@ public class DividerHandleView extends View {
        mCircleDiameter = (mWidth + mHeight) / 3;
    }

    void setTouching(boolean touching, boolean animate) {
    /** Sets touching state for this handle view. */
    public void setTouching(boolean touching, boolean animate) {
        if (touching == mTouching) {
            return;
        }
@@ -116,8 +120,8 @@ public class DividerHandleView extends View {
        mAnimator = new AnimatorSet();
        mAnimator.playTogether(widthAnimator, heightAnimator);
        mAnimator.setDuration(touching
                ? DividerView.TOUCH_ANIMATION_DURATION
                : DividerView.TOUCH_RELEASE_ANIMATION_DURATION);
                ? TOUCH_ANIMATION_DURATION
                : TOUCH_RELEASE_ANIMATION_DURATION);
        mAnimator.setInterpolator(touching
                ? Interpolators.TOUCH_RESPONSE
                : Interpolators.FAST_OUT_SLOW_IN);
+54 −22
Original line number Diff line number Diff line
@@ -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();
    }
}
Loading