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

Commit c55b43cf authored by Bill Lin's avatar Bill Lin Committed by Automerger Merge Worker
Browse files

Merge "Refactor OHM to use (float)offset for translating windows" into sc-dev...

Merge "Refactor OHM to use (float)offset for translating windows" into sc-dev am: 214bff10 am: 96b0d847

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14206624

Change-Id: Ib2b3492f3112f668cf61984684694d8eb57b01b2
parents c2b4a3be 96b0d847
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -44,8 +44,9 @@ public interface OneHandedAnimationCallback {
    }

    /**
     * Called when OneHanded animator is updating offset
     * Called when OneHanded animator is updating position
     */
    default void onTutorialAnimationUpdate(int offset) {}
    default void onAnimationUpdate(float xPos, float yPos) {
    }

}
+49 −43
Original line number Diff line number Diff line
@@ -25,8 +25,10 @@ import android.view.SurfaceControl;
import android.view.animation.BaseInterpolator;
import android.window.WindowContainerToken;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -37,6 +39,7 @@ import java.util.List;
 * Controller class of OneHanded animations (both from and to OneHanded mode).
 */
public class OneHandedAnimationController {
    private static final String TAG = "OneHandedAnimationController";
    private static final float FRACTION_START = 0f;
    private static final float FRACTION_END = 1f;

@@ -68,17 +71,19 @@ public class OneHandedAnimationController {

    @SuppressWarnings("unchecked")
    OneHandedTransitionAnimator getAnimator(WindowContainerToken token, SurfaceControl leash,
            Rect startBounds, Rect endBounds) {
            float startPos, float endPos, Rect displayBounds) {
        final OneHandedTransitionAnimator animator = mAnimatorMap.get(token);
        if (animator == null) {
            mAnimatorMap.put(token, setupOneHandedTransitionAnimator(
                    OneHandedTransitionAnimator.ofBounds(token, leash, startBounds, endBounds)));
                    OneHandedTransitionAnimator.ofYOffset(token, leash, startPos, endPos,
                            displayBounds)));
        } else if (animator.isRunning()) {
            animator.updateEndValue(endBounds);
            animator.updateEndValue(endPos);
        } else {
            animator.cancel();
            mAnimatorMap.put(token, setupOneHandedTransitionAnimator(
                    OneHandedTransitionAnimator.ofBounds(token, leash, startBounds, endBounds)));
                    OneHandedTransitionAnimator.ofYOffset(token, leash, startPos, endPos,
                            displayBounds)));
        }
        return mAnimatorMap.get(token);
    }
@@ -147,9 +152,7 @@ public class OneHandedAnimationController {
        public void onAnimationStart(Animator animation) {
            mCurrentValue = mStartValue;
            mOneHandedAnimationCallbacks.forEach(
                    (callback) -> {
                        callback.onOneHandedAnimationStart(this);
                    }
                    (callback) -> callback.onOneHandedAnimationStart(this)
            );
        }

@@ -159,9 +162,7 @@ public class OneHandedAnimationController {
            final SurfaceControl.Transaction tx = newSurfaceControlTransaction();
            onEndTransaction(mLeash, tx);
            mOneHandedAnimationCallbacks.forEach(
                    (callback) -> {
                        callback.onOneHandedAnimationEnd(tx, this);
                    }
                    (callback) -> callback.onOneHandedAnimationEnd(tx, this)
            );
        }

@@ -169,9 +170,7 @@ public class OneHandedAnimationController {
        public void onAnimationCancel(Animator animation) {
            mCurrentValue = mEndValue;
            mOneHandedAnimationCallbacks.forEach(
                    (callback) -> {
                        callback.onOneHandedAnimationCancel(this);
                    }
                    (callback) -> callback.onOneHandedAnimationCancel(this)
            );
        }

@@ -181,12 +180,10 @@ public class OneHandedAnimationController {

        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            applySurfaceControlTransaction(mLeash, newSurfaceControlTransaction(),
                    animation.getAnimatedFraction());
            final SurfaceControl.Transaction tx = newSurfaceControlTransaction();
            applySurfaceControlTransaction(mLeash, tx, animation.getAnimatedFraction());
            mOneHandedAnimationCallbacks.forEach(
                    (callback) -> {
                        callback.onTutorialAnimationUpdate(((Rect) mCurrentValue).top);
                    }
                    (callback) -> callback.onAnimationUpdate(0f, (float) mCurrentValue)
            );
        }

@@ -217,12 +214,8 @@ public class OneHandedAnimationController {
            return mToken;
        }

        Rect getDestinationBounds() {
            return (Rect) mEndValue;
        }

        int getDestinationOffset() {
            return ((Rect) mEndValue).top - ((Rect) mStartValue).top;
        float getDestinationOffset() {
            return ((float) mEndValue - (float) mStartValue);
        }

        @TransitionDirection
@@ -259,40 +252,42 @@ public class OneHandedAnimationController {
        }

        @VisibleForTesting
        static OneHandedTransitionAnimator<Rect> ofBounds(WindowContainerToken token,
                SurfaceControl leash, Rect startValue, Rect endValue) {
        static OneHandedTransitionAnimator<Float> ofYOffset(WindowContainerToken token,
                SurfaceControl leash, float startValue, float endValue, Rect displayBounds) {

            return new OneHandedTransitionAnimator<Rect>(token, leash, new Rect(startValue),
                    new Rect(endValue)) {
            return new OneHandedTransitionAnimator<Float>(token, leash, startValue, endValue) {

                private final Rect mTmpRect = new Rect();
                private final Rect mTmpRect = new Rect(displayBounds);

                private int getCastedFractionValue(float start, float end, float fraction) {
                    return (int) (start * (1 - fraction) + end * fraction + .5f);
                private float getCastedFractionValue(float start, float end, float fraction) {
                    return (start * (1 - fraction) + end * fraction + .5f);
                }

                @Override
                void applySurfaceControlTransaction(SurfaceControl leash,
                        SurfaceControl.Transaction tx, float fraction) {
                    final Rect start = getStartValue();
                    final Rect end = getEndValue();
                    final float start = getStartValue();
                    final float end = getEndValue();
                    final float currentValue = getCastedFractionValue(start, end, fraction);
                    mTmpRect.set(
                            getCastedFractionValue(start.left, end.left, fraction),
                            getCastedFractionValue(start.top, end.top, fraction),
                            getCastedFractionValue(start.right, end.right, fraction),
                            getCastedFractionValue(start.bottom, end.bottom, fraction));
                    setCurrentValue(mTmpRect);
                    getSurfaceTransactionHelper().crop(tx, leash, mTmpRect)
                            .round(tx, leash);
                            mTmpRect.left,
                            mTmpRect.top + Math.round(currentValue),
                            mTmpRect.right,
                            mTmpRect.bottom + Math.round(currentValue));
                    setCurrentValue(currentValue);
                    getSurfaceTransactionHelper()
                            .crop(tx, leash, mTmpRect)
                            .round(tx, leash)
                            .translate(tx, leash, currentValue);
                    tx.apply();
                }

                @Override
                void onStartTransaction(SurfaceControl leash, SurfaceControl.Transaction tx) {
                    getSurfaceTransactionHelper()
                            .alpha(tx, leash, 1f)
                            .translate(tx, leash, getEndValue().top - getStartValue().top)
                            .round(tx, leash);
                            .crop(tx, leash, mTmpRect)
                            .round(tx, leash)
                            .translate(tx, leash, getStartValue());
                    tx.apply();
                }
            };
@@ -309,4 +304,15 @@ public class OneHandedAnimationController {
                    * (2.0f * Math.PI) / 4.0f) + 1);
        }
    }

    void dump(@NonNull PrintWriter pw) {
        final String innerPrefix = "  ";
        pw.println(TAG + "states: ");
        pw.print(innerPrefix + "mAnimatorMap=");
        pw.println(mAnimatorMap);

        if (mSurfaceTransactionHelper != null) {
            mSurfaceTransactionHelper.dump(pw);
        }
    }
}
+34 −46
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {

    private DisplayLayout mDisplayLayout = new DisplayLayout();

    private float mLastVisualOffset = 0;
    private final Rect mLastVisualDisplayBounds = new Rect();
    private final Rect mDefaultDisplayBounds = new Rect();
    private final OneHandedSettingsUtil mOneHandedSettingsUtil;
@@ -96,8 +97,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
                        OneHandedAnimationController.OneHandedTransitionAnimator animator) {
                    mAnimationController.removeAnimator(animator.getToken());
                    if (mAnimationController.isAnimatorsConsumed()) {
                        resetWindowsOffsetInternal(animator.getTransitionDirection());
                        finishOffset(animator.getDestinationOffset(),
                        finishOffset((int) animator.getDestinationOffset(),
                                animator.getTransitionDirection());
                    }
                }
@@ -107,8 +107,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
                        OneHandedAnimationController.OneHandedTransitionAnimator animator) {
                    mAnimationController.removeAnimator(animator.getToken());
                    if (mAnimationController.isAnimatorsConsumed()) {
                        resetWindowsOffsetInternal(animator.getTransitionDirection());
                        finishOffset(animator.getDestinationOffset(),
                        finishOffset((int) animator.getDestinationOffset(),
                                animator.getTransitionDirection());
                    }
                }
@@ -165,7 +164,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
    @Override
    public void unregisterOrganizer() {
        super.unregisterOrganizer();
        resetWindowsOffset(null);
        resetWindowsOffset();
    }

    /**
@@ -186,7 +185,6 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
            return;
        }
        mDisplayLayout.rotateTo(context.getResources(), toRotation);
        resetWindowsOffset(wct);
        updateDisplayBounds();
        finishOffset(0, TRANSITION_DIRECTION_EXIT);
    }
@@ -196,38 +194,20 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
     * Directly perform manipulation/offset on the leash.
     */
    public void scheduleOffset(int xOffset, int yOffset) {
        final Rect toBounds = new Rect(mDefaultDisplayBounds.left,
                mDefaultDisplayBounds.top + yOffset,
                mDefaultDisplayBounds.right,
                mDefaultDisplayBounds.bottom + yOffset);
        final Rect fromBounds = getLastVisualDisplayBounds();
        final float fromPos = mLastVisualOffset;
        final int direction = yOffset > 0
                ? TRANSITION_DIRECTION_TRIGGER
                : TRANSITION_DIRECTION_EXIT;

        final WindowContainerTransaction wct = new WindowContainerTransaction();
        mDisplayAreaTokenMap.forEach(
                (token, leash) -> {
                    animateWindows(token, leash, fromBounds, toBounds, direction,
                    animateWindows(token, leash, fromPos, yOffset, direction,
                            mEnterExitAnimationDurationMs);
                    wct.setBounds(token, toBounds);
                    wct.setAppBounds(token, toBounds);
                });
        applyTransaction(wct);
    }

    private void resetWindowsOffsetInternal(
            @OneHandedAnimationController.TransitionDirection int td) {
        if (td == TRANSITION_DIRECTION_TRIGGER) {
            return;
        }
        final WindowContainerTransaction wct = new WindowContainerTransaction();
        resetWindowsOffset(wct);
        applyTransaction(wct);
        mLastVisualOffset = yOffset;
    }

    @VisibleForTesting
    void resetWindowsOffset(WindowContainerTransaction wct) {
    void resetWindowsOffset() {
        final SurfaceControl.Transaction tx =
                mSurfaceControlTransactionFactory.getTransaction();
        mDisplayAreaTokenMap.forEach(
@@ -238,21 +218,20 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
                        animator.cancel();
                    }
                    tx.setPosition(leash, 0, 0)
                            .setWindowCrop(leash, -1/* reset */, -1/* reset */);
                    // DisplayRotationController will applyTransaction() after finish rotating
                    if (wct != null) {
                        wct.setBounds(token, null/* reset */);
                        wct.setAppBounds(token, null/* reset */);
                    }
                            .setWindowCrop(leash, -1, -1)
                            .setCornerRadius(leash, -1);
                });
        tx.apply();
        mLastVisualOffset = 0;
        mLastVisualDisplayBounds.offsetTo(0, 0);
    }

    private void animateWindows(WindowContainerToken token, SurfaceControl leash, Rect fromBounds,
            Rect toBounds, @OneHandedAnimationController.TransitionDirection int direction,
    private void animateWindows(WindowContainerToken token, SurfaceControl leash, float fromPos,
            float toPos, @OneHandedAnimationController.TransitionDirection int direction,
            int durationMs) {
        final OneHandedAnimationController.OneHandedTransitionAnimator animator =
                mAnimationController.getAnimator(token, leash, fromBounds, toBounds);
                mAnimationController.getAnimator(token, leash, fromPos, toPos,
                        mLastVisualDisplayBounds);
        if (animator != null) {
            animator.setTransitionDirection(direction)
                    .addOneHandedAnimationCallback(mOneHandedAnimationCallback)
@@ -265,10 +244,13 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
    }

    @VisibleForTesting
    void finishOffset(int offset,
            @OneHandedAnimationController.TransitionDirection int direction) {
        mLastVisualDisplayBounds.offsetTo(0,
                direction == TRANSITION_DIRECTION_TRIGGER ? offset : 0);
    void finishOffset(int offset, @OneHandedAnimationController.TransitionDirection int direction) {
        if (direction == TRANSITION_DIRECTION_EXIT) {
            // We must do this to ensure reset property for leash when exit one handed mode
            resetWindowsOffset();
        }
        mLastVisualOffset = direction == TRANSITION_DIRECTION_TRIGGER ? offset : 0;
        mLastVisualDisplayBounds.offsetTo(0, Math.round(mLastVisualOffset));
        for (int i = mTransitionCallbacks.size() - 1; i >= 0; i--) {
            final OneHandedTransitionCallback cb = mTransitionCallbacks.get(i);
            cb.onStartTransition(false /* isTransitioning */);
@@ -285,7 +267,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
     *
     * @return Rect latest finish_offset
     */
    public Rect getLastVisualDisplayBounds() {
    private Rect getLastVisualDisplayBounds() {
        return mLastVisualDisplayBounds;
    }

@@ -332,5 +314,11 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
        pw.println(mDefaultDisplayBounds);
        pw.print(innerPrefix + "mLastVisualDisplayBounds=");
        pw.println(mLastVisualDisplayBounds);
        pw.print(innerPrefix + "mLastVisualOffset=");
        pw.println(mLastVisualOffset);

        if (mAnimationController != null) {
            mAnimationController.dump(pw);
        }
    }
}
+23 −14
Original line number Diff line number Diff line
@@ -21,18 +21,28 @@ import android.content.res.Resources;
import android.graphics.Rect;
import android.view.SurfaceControl;

import androidx.annotation.NonNull;

import com.android.wm.shell.R;

import java.io.PrintWriter;

/**
 * Abstracts the common operations on {@link SurfaceControl.Transaction} for OneHanded transition.
 */
public class OneHandedSurfaceTransactionHelper {
    private static final String TAG = "OneHandedSurfaceTransactionHelper";

    private final boolean mEnableCornerRadius;
    private final float mCornerRadius;
    private final float mCornerRadiusAdjustment;

    public OneHandedSurfaceTransactionHelper(Context context) {
        final Resources res = context.getResources();
        mCornerRadius = res.getDimension(com.android.internal.R.dimen.rounded_corner_radius);
        mCornerRadiusAdjustment = res.getDimension(
                com.android.internal.R.dimen.rounded_corner_radius_adjustment);
        mCornerRadius = res.getDimension(com.android.internal.R.dimen.rounded_corner_radius)
                - mCornerRadiusAdjustment;
        mEnableCornerRadius = res.getBoolean(R.bool.config_one_handed_enable_round_corner);
    }

@@ -47,17 +57,6 @@ public class OneHandedSurfaceTransactionHelper {
        return this;
    }

    /**
     * Operates the alpha on a given transaction and leash
     *
     * @return same {@link OneHandedSurfaceTransactionHelper} instance for method chaining
     */
    OneHandedSurfaceTransactionHelper alpha(SurfaceControl.Transaction tx, SurfaceControl leash,
            float alpha) {
        tx.setAlpha(leash, alpha);
        return this;
    }

    /**
     * Operates the crop (setMatrix) on a given transaction and leash
     *
@@ -65,8 +64,7 @@ public class OneHandedSurfaceTransactionHelper {
     */
    OneHandedSurfaceTransactionHelper crop(SurfaceControl.Transaction tx, SurfaceControl leash,
            Rect destinationBounds) {
        tx.setWindowCrop(leash, destinationBounds.width(), destinationBounds.height())
                .setPosition(leash, destinationBounds.left, destinationBounds.top);
        tx.setWindowCrop(leash, destinationBounds.width(), destinationBounds.height());
        return this;
    }

@@ -85,4 +83,15 @@ public class OneHandedSurfaceTransactionHelper {
    interface SurfaceControlTransactionFactory {
        SurfaceControl.Transaction getTransaction();
    }

    void dump(@NonNull PrintWriter pw) {
        final String innerPrefix = "  ";
        pw.println(TAG + "states: ");
        pw.print(innerPrefix + "mEnableCornerRadius=");
        pw.println(mEnableCornerRadius);
        pw.print(innerPrefix + "mCornerRadiusAdjustment=");
        pw.println(mCornerRadiusAdjustment);
        pw.print(innerPrefix + "mCornerRadius=");
        pw.println(mCornerRadius);
    }
}
+9 −13
Original line number Diff line number Diff line
@@ -78,16 +78,21 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback {

    private final OneHandedAnimationCallback mAnimationCallback = new OneHandedAnimationCallback() {
        @Override
        public void onTutorialAnimationUpdate(int offset) {
            onAnimationUpdate(offset);
        public void onAnimationUpdate(float xPos, float yPos) {
            if (!canShowTutorial()) {
                return;
            }
            mTargetViewContainer.setVisibility(View.VISIBLE);
            mTargetViewContainer.setTransitionGroup(true);
            mTargetViewContainer.setTranslationY(yPos - mTargetViewContainer.getHeight());
        }

        @Override
        public void onOneHandedAnimationStart(
                OneHandedAnimationController.OneHandedTransitionAnimator animator) {
            final Rect startValue = (Rect) animator.getStartValue();
            final float startValue = (float) animator.getStartValue();
            if (mTriggerState == ONE_HANDED_TRIGGER_STATE.UNSET) {
                mTriggerState = (startValue.top == 0)
                mTriggerState = (startValue == 0f)
                        ? ONE_HANDED_TRIGGER_STATE.ENTERING : ONE_HANDED_TRIGGER_STATE.EXITING;
                if (mCanShowTutorial && mTriggerState == ONE_HANDED_TRIGGER_STATE.ENTERING) {
                    attachTurtorialTarget();
@@ -239,15 +244,6 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback {
        return true;
    }

    private void onAnimationUpdate(float value) {
        if (!canShowTutorial()) {
            return;
        }
        mTargetViewContainer.setVisibility(View.VISIBLE);
        mTargetViewContainer.setTransitionGroup(true);
        mTargetViewContainer.setTranslationY(value - mTargetViewContainer.getHeight());
    }

    /**
     * onConfigurationChanged events for updating tutorial text.
     * @param newConfig
Loading