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

Commit 47abd6c2 authored by Jason Chang's avatar Jason Chang Committed by Automerger Merge Worker
Browse files

Merge "Fix tutorial background color not up-to-date occasionally" into sc-dev am: 3ebd024a

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

Change-Id: I1cba57040d1b3d78a096f8336359fd0e3d64e52f
parents dd14d693 3ebd024a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ public interface OneHandedAnimationCallback {
    /**
     * Called when OneHanded animator is updating position
     */
    default void onAnimationUpdate(float xPos, float yPos) {
    default void onAnimationUpdate(SurfaceControl.Transaction tx, float xPos, float yPos) {
    }

}
+2 −2
Original line number Diff line number Diff line
@@ -182,10 +182,10 @@ public class OneHandedAnimationController {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            final SurfaceControl.Transaction tx = newSurfaceControlTransaction();
            applySurfaceControlTransaction(mLeash, tx, animation.getAnimatedFraction());
            mOneHandedAnimationCallbacks.forEach(
                    (callback) -> callback.onAnimationUpdate(0f, mCurrentValue)
                    (callback) -> callback.onAnimationUpdate(tx, 0f, mCurrentValue)
            );
            applySurfaceControlTransaction(mLeash, tx, animation.getAnimatedFraction());
        }

        void onStartTransaction(SurfaceControl leash, SurfaceControl.Transaction tx) {
+144 −124
Original line number Diff line number Diff line
@@ -16,12 +16,14 @@

package com.android.wm.shell.onehanded;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.animation.LinearInterpolator;
import android.window.DisplayAreaAppearedInfo;
import android.window.DisplayAreaInfo;
import android.window.DisplayAreaOrganizer;
@@ -29,8 +31,8 @@ import android.window.DisplayAreaOrganizer;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.view.ContextThemeWrapper;

import com.android.internal.annotations.GuardedBy;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayLayout;

@@ -44,83 +46,51 @@ import java.util.concurrent.Executor;
 * the screen has entered one handed mode.
 */
public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
        implements OneHandedTransitionCallback {
        implements OneHandedAnimationCallback {
    private static final String TAG = "OneHandedBackgroundPanelOrganizer";
    private static final int THEME_COLOR_OFFSET = 10;
    private static final int ALPHA_ANIMATION_DURATION = 200;

    private final Context mContext;
    private final Object mLock = new Object();
    private final SurfaceSession mSurfaceSession = new SurfaceSession();
    private final Executor mMainExecutor;
    private final OneHandedSurfaceTransactionHelper.SurfaceControlTransactionFactory
            mSurfaceControlTransactionFactory;
            mTransactionFactory;

    private float[] mDefaultColor;
    private ValueAnimator mAlphaAnimator;

    private float mTranslationFraction;
    private float[] mThemeColor;

    /**
     * The background to distinguish the boundary of translated windows and empty region when
     * one handed mode triggered.
     */
    private Rect mBkgBounds;
    @VisibleForTesting
    @GuardedBy("mLock")
    boolean mIsShowing;
    private Rect mStableInsets;

    @Nullable
    @GuardedBy("mLock")
    private SurfaceControl mBackgroundSurface;
    @VisibleForTesting
    SurfaceControl mBackgroundSurface;
    @Nullable
    @GuardedBy("mLock")
    private SurfaceControl mParentLeash;

    private final OneHandedAnimationCallback mOneHandedAnimationCallback =
            new OneHandedAnimationCallback() {
                @Override
                public void onOneHandedAnimationStart(
                        OneHandedAnimationController.OneHandedTransitionAnimator animator) {
                    mMainExecutor.execute(() -> showBackgroundPanelLayer());
                }
            };

    @Override
    public void onStopFinished(Rect bounds) {
        mMainExecutor.execute(() -> removeBackgroundPanelLayer());
    }

    public OneHandedBackgroundPanelOrganizer(Context context, DisplayLayout displayLayout,
            Executor executor) {
            OneHandedSettingsUtil settingsUtil, Executor executor) {
        super(executor);
        mContext = context;
        // Ensure the mBkgBounds is portrait, due to OHM only support on portrait
        if (displayLayout.height() > displayLayout.width()) {
            mBkgBounds = new Rect(0, 0, displayLayout.width(), displayLayout.height());
        } else {
            mBkgBounds = new Rect(0, 0, displayLayout.height(), displayLayout.width());
        }
        mTranslationFraction = settingsUtil.getTranslationFraction(context);
        mTransactionFactory = SurfaceControl.Transaction::new;
        updateThemeColors();
        mMainExecutor = executor;
        mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
    }

    @Override
    public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo,
            @NonNull SurfaceControl leash) {
        synchronized (mLock) {
            if (mParentLeash == null) {
        mParentLeash = leash;
            } else {
                throw new RuntimeException("There should be only one DisplayArea for "
                        + "the one-handed mode background panel");
            }
        }
    }

    OneHandedAnimationCallback getOneHandedAnimationCallback() {
        return mOneHandedAnimationCallback;
    }

    @Override
    public List<DisplayAreaAppearedInfo> registerOrganizer(int displayAreaFeature) {
        synchronized (mLock) {
        final List<DisplayAreaAppearedInfo> displayAreaInfos;
        displayAreaInfos = super.registerOrganizer(displayAreaFeature);
        for (int i = 0; i < displayAreaInfos.size(); i++) {
@@ -129,27 +99,28 @@ public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
        }
        return displayAreaInfos;
    }
    }

    @Override
    public void unregisterOrganizer() {
        synchronized (mLock) {
        super.unregisterOrganizer();
        removeBackgroundPanelLayer();
        mParentLeash = null;
    }

    @Override
    public void onAnimationUpdate(SurfaceControl.Transaction tx, float xPos, float yPos) {
        final int yTopPos = (mStableInsets.top - mBkgBounds.height()) + Math.round(yPos);
        tx.setPosition(mBackgroundSurface, 0, yTopPos);
    }

    @Nullable
    @VisibleForTesting
    SurfaceControl getBackgroundSurface() {
        synchronized (mLock) {
            if (mParentLeash == null) {
                return null;
    boolean isRegistered() {
        return mParentLeash != null;
    }

            if (mBackgroundSurface == null) {
    void createBackgroundSurface() {
        mBackgroundSurface = new SurfaceControl.Builder(mSurfaceSession)
                        .setParent(mParentLeash)
                .setBufferSize(mBkgBounds.width(), mBkgBounds.height())
                .setColorLayer()
                .setFormat(PixelFormat.RGB_888)
@@ -157,81 +128,130 @@ public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
                .setName("one-handed-background-panel")
                .setCallsite("OneHandedBackgroundPanelOrganizer")
                .build();

        // TODO(185890335) Avoid Dimming for mid-range luminance wallpapers flash.
        mAlphaAnimator = ValueAnimator.ofFloat(1.0f, 0.0f);
        mAlphaAnimator.setInterpolator(new LinearInterpolator());
        mAlphaAnimator.setDuration(ALPHA_ANIMATION_DURATION);
        mAlphaAnimator.addUpdateListener(
                animator -> detachBackgroundFromParent(animator));
    }

    void detachBackgroundFromParent(ValueAnimator animator) {
        if (mBackgroundSurface == null || mParentLeash == null) {
            return;
        }
        // TODO(185890335) Avoid Dimming for mid-range luminance wallpapers flash.
        final float currentValue = (float) animator.getAnimatedValue();
        final SurfaceControl.Transaction tx = mTransactionFactory.getTransaction();
        if (currentValue == 0.0f) {
            tx.reparent(mBackgroundSurface, null).apply();
        } else {
            tx.setAlpha(mBackgroundSurface, (float) animator.getAnimatedValue()).apply();
        }
            return mBackgroundSurface;
    }

    /**
     * Called when onDisplayAdded() or onDisplayRemoved() callback.
     *
     * @param displayLayout The latest {@link DisplayLayout} representing current displayId
     */
    public void onDisplayChanged(DisplayLayout displayLayout) {
        mStableInsets = displayLayout.stableInsets();
        // Ensure the mBkgBounds is portrait, due to OHM only support on portrait
        if (displayLayout.height() > displayLayout.width()) {
            mBkgBounds = new Rect(0, 0, displayLayout.width(),
                    Math.round(displayLayout.height() * mTranslationFraction) + mStableInsets.top);
        } else {
            mBkgBounds = new Rect(0, 0, displayLayout.height(),
                    Math.round(displayLayout.width() * mTranslationFraction) + mStableInsets.top);
        }
    }

    @VisibleForTesting
    void onStart() {
        if (mBackgroundSurface == null) {
            createBackgroundSurface();
        }
        showBackgroundPanelLayer();
    }

    /**
     * Called when transition finished.
     */
    public void onStopFinished() {
        mAlphaAnimator.start();
    }

    @VisibleForTesting
    void showBackgroundPanelLayer() {
        synchronized (mLock) {
            if (mIsShowing) {
        if (mParentLeash == null) {
            return;
        }

            if (getBackgroundSurface() == null) {
                return;
        if (mBackgroundSurface == null) {
            createBackgroundSurface();
        }

        // TODO(185890335) Avoid Dimming for mid-range luminance wallpapers flash.
        if (mAlphaAnimator.isRunning()) {
            mAlphaAnimator.end();
        }

            SurfaceControl.Transaction transaction =
                    mSurfaceControlTransactionFactory.getTransaction();
            transaction.setLayer(mBackgroundSurface, -1 /* at bottom-most layer */)
                    .setColor(mBackgroundSurface, mDefaultColor)
        mTransactionFactory.getTransaction()
                .reparent(mBackgroundSurface, mParentLeash)
                .setAlpha(mBackgroundSurface, 1.0f)
                .setLayer(mBackgroundSurface, -1 /* at bottom-most layer */)
                .setColor(mBackgroundSurface, mThemeColor)
                .show(mBackgroundSurface)
                .apply();
            transaction.close();
            mIsShowing = true;
        }
    }

    @VisibleForTesting
    void removeBackgroundPanelLayer() {
        synchronized (mLock) {
        if (mBackgroundSurface == null) {
            return;
        }

            SurfaceControl.Transaction transaction =
                    mSurfaceControlTransactionFactory.getTransaction();
            transaction.remove(mBackgroundSurface).apply();
            transaction.close();
        mTransactionFactory.getTransaction()
                .remove(mBackgroundSurface)
                .apply();
        mBackgroundSurface = null;
            mIsShowing = false;
        }
    }

    /**
     * onConfigurationChanged events for updating tutorial text.
     */
    public void onConfigurationChanged() {
        synchronized (mLock) {
            if (mBackgroundSurface == null) {
                getBackgroundSurface();
            } else {
                removeBackgroundPanelLayer();
            }
        updateThemeColors();
        showBackgroundPanelLayer();
    }
    }

    private void updateThemeColors() {
        synchronized (mLock) {
            final int themeColor = mContext.getColor(R.color.one_handed_tutorial_background_color);
            mDefaultColor = new float[]{(Color.red(themeColor) - THEME_COLOR_OFFSET) / 255.0f,
                    (Color.green(themeColor) - THEME_COLOR_OFFSET) / 255.0f,
                    (Color.blue(themeColor) - THEME_COLOR_OFFSET) / 255.0f};
        final Context themedContext = new ContextThemeWrapper(mContext,
                com.android.internal.R.style.Theme_DeviceDefault_DayNight);
        final int themeColor = themedContext.getColor(
                R.color.one_handed_tutorial_background_color);
        mThemeColor = new float[]{
                adjustColor(Color.red(themeColor)),
                adjustColor(Color.green(themeColor)),
                adjustColor(Color.blue(themeColor))};
    }

    private float adjustColor(int origColor) {
        return Math.max(origColor - THEME_COLOR_OFFSET, 0) / 255.0f;
    }

    void dump(@NonNull PrintWriter pw) {
        final String innerPrefix = "  ";
        pw.println(TAG);
        pw.print(innerPrefix + "mIsShowing=");
        pw.println(mIsShowing);
        pw.print(innerPrefix + "mBackgroundSurface=");
        pw.println(mBackgroundSurface);
        pw.print(innerPrefix + "mBkgBounds=");
        pw.println(mBkgBounds);
        pw.print(innerPrefix + "mDefaultColor=");
        pw.println(mDefaultColor);
        pw.print(innerPrefix + "mThemeColor=");
        pw.println(mThemeColor);
        pw.print(innerPrefix + "mTranslationFraction=");
        pw.println(mTranslationFraction);
    }
}
+7 −4
Original line number Diff line number Diff line
@@ -180,6 +180,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
                public void onStopFinished(Rect bounds) {
                    mState.setState(STATE_NONE);
                    notifyShortcutStateChanged(STATE_NONE);
                    mBackgroundPanelOrganizer.onStopFinished();
                }
            };

@@ -223,13 +224,14 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
        OneHandedTimeoutHandler timeoutHandler = new OneHandedTimeoutHandler(mainExecutor);
        OneHandedState transitionState = new OneHandedState();
        OneHandedTutorialHandler tutorialHandler = new OneHandedTutorialHandler(context,
                windowManager);
                settingsUtil, windowManager);
        OneHandedAnimationController animationController =
                new OneHandedAnimationController(context);
        OneHandedTouchHandler touchHandler = new OneHandedTouchHandler(timeoutHandler,
                mainExecutor);
        OneHandedBackgroundPanelOrganizer oneHandedBackgroundPanelOrganizer =
                new OneHandedBackgroundPanelOrganizer(context, displayLayout, mainExecutor);
                new OneHandedBackgroundPanelOrganizer(context, displayLayout, settingsUtil,
                        mainExecutor);
        OneHandedDisplayAreaOrganizer organizer = new OneHandedDisplayAreaOrganizer(
                context, displayLayout, settingsUtil, animationController, tutorialHandler,
                oneHandedBackgroundPanelOrganizer, mainExecutor);
@@ -386,6 +388,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
                mDisplayAreaOrganizer.getDisplayLayout().height() * mOffSetFraction);
        mOneHandedAccessibilityUtil.announcementForScreenReader(
                mOneHandedAccessibilityUtil.getOneHandedStartDescription());
        mBackgroundPanelOrganizer.onStart();
        mDisplayAreaOrganizer.scheduleOffset(0, yOffSet);
        mTimeoutHandler.resetTimer();
        mOneHandedUiEventLogger.writeEvent(
@@ -423,7 +426,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
                stopOneHanded(OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_OVERSPACE_OUT));
        mDisplayAreaOrganizer.registerTransitionCallback(mTouchHandler);
        mDisplayAreaOrganizer.registerTransitionCallback(mTutorialHandler);
        mDisplayAreaOrganizer.registerTransitionCallback(mBackgroundPanelOrganizer);
        mDisplayAreaOrganizer.registerTransitionCallback(mTransitionCallBack);
        if (mTaskChangeToExit) {
            mTaskStackListener.addListener(mTaskStackListenerCallback);
@@ -469,6 +471,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
        final DisplayLayout newDisplayLayout = mDisplayController.getDisplayLayout(displayId);
        mDisplayAreaOrganizer.setDisplayLayout(newDisplayLayout);
        mTutorialHandler.onDisplayChanged(newDisplayLayout);
        mBackgroundPanelOrganizer.onDisplayChanged(newDisplayLayout);
    }

    private ContentObserver getObserver(Runnable onChangeRunnable) {
@@ -606,7 +609,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
                    OneHandedDisplayAreaOrganizer.FEATURE_ONE_HANDED);
        }

        if (mBackgroundPanelOrganizer.getBackgroundSurface() == null) {
        if (!mBackgroundPanelOrganizer.isRegistered()) {
            mBackgroundPanelOrganizer.registerOrganizer(
                    OneHandedBackgroundPanelOrganizer.FEATURE_ONE_HANDED_BACKGROUND_PANEL);
        }
+3 −5
Original line number Diff line number Diff line
@@ -135,8 +135,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
                SystemProperties.getInt(ONE_HANDED_MODE_TRANSLATE_ANIMATION_DURATION,
                        animationDurationConfig);
        mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
        mTutorialHandler = tutorialHandler;
        mBackgroundPanelOrganizer = oneHandedBackgroundGradientOrganizer;
        mTutorialHandler = tutorialHandler;
    }

    @Override
@@ -249,9 +249,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
        if (animator != null) {
            animator.setTransitionDirection(direction)
                    .addOneHandedAnimationCallback(mOneHandedAnimationCallback)
                    .addOneHandedAnimationCallback(mTutorialHandler.getAnimationCallback())
                    .addOneHandedAnimationCallback(
                            mBackgroundPanelOrganizer.getOneHandedAnimationCallback())
                    .addOneHandedAnimationCallback(mTutorialHandler)
                    .addOneHandedAnimationCallback(mBackgroundPanelOrganizer)
                    .setDuration(durationMs)
                    .start();
        }
@@ -267,7 +266,6 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
        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 */);
            if (direction == TRANSITION_DIRECTION_TRIGGER) {
                cb.onStartFinished(getLastVisualDisplayBounds());
            } else {
Loading