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

Commit ad456e85 authored by Shawn Lin's avatar Shawn Lin Committed by Android (Google) Code Review
Browse files

Merge "Move assist handles from ScreenDecorations to navigation bar"

parents f82d3672 87af538d
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -24,6 +24,21 @@
    android:layout_width="match_parent"
    android:background="@drawable/system_bar_background">

    <com.android.systemui.CornerHandleView
        android:id="@+id/assist_hint_left"
        android:layout_width="36dp"
        android:layout_height="36dp"
        android:layout_gravity="left|bottom"
        android:rotation="270"
        android:visibility="gone"/>
    <com.android.systemui.CornerHandleView
        android:id="@+id/assist_hint_right"
        android:layout_width="36dp"
        android:layout_height="36dp"
        android:layout_gravity="right|bottom"
        android:rotation="180"
        android:visibility="gone"/>

    <com.android.systemui.statusbar.phone.NavigationBarInflaterView
        android:id="@+id/navigation_inflater"
        android:layout_width="match_parent"
+0 −12
Original line number Diff line number Diff line
@@ -18,18 +18,6 @@
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.android.systemui.CornerHandleView
        android:id="@+id/assist_hint_left"
        android:layout_width="36dp"
        android:layout_height="36dp"
        android:layout_gravity="left|top"
        android:visibility="gone"/>
    <com.android.systemui.CornerHandleView
        android:id="@+id/assist_hint_right"
        android:layout_width="36dp"
        android:layout_height="36dp"
        android:layout_gravity="right|bottom"
        android:visibility="gone"/>
    <ImageView
        android:id="@+id/left"
        android:layout_width="12dp"
+3 −260
Original line number Diff line number Diff line
@@ -25,9 +25,6 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M
import static com.android.systemui.tuner.TunablePadding.FLAG_END;
import static com.android.systemui.tuner.TunablePadding.FLAG_START;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.Dimension;
import android.app.ActivityManager;
import android.app.Fragment;
@@ -52,7 +49,6 @@ import android.os.SystemProperties;
import android.provider.Settings.Secure;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.MathUtils;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.Gravity;
@@ -64,9 +60,6 @@ import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;

@@ -78,10 +71,7 @@ import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.SecureSetting;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.NavigationBarTransitions;
import com.android.systemui.statusbar.phone.NavigationModeController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.tuner.TunablePadding;
import com.android.systemui.tuner.TunerService;
@@ -95,8 +85,7 @@ import java.util.List;
 * An overlay that draws screen decorations in software (e.g for rounded corners or display cutout)
 * for antialiasing and emulation purposes.
 */
public class ScreenDecorations extends SystemUI implements Tunable,
        NavigationBarTransitions.DarkIntensityListener {
public class ScreenDecorations extends SystemUI implements Tunable {
    private static final boolean DEBUG = false;
    private static final String TAG = "ScreenDecorations";

@@ -120,15 +109,11 @@ public class ScreenDecorations extends SystemUI implements Tunable,
    private float mDensity;
    private WindowManager mWindowManager;
    private int mRotation;
    private boolean mAssistHintVisible;
    private DisplayCutoutView mCutoutTop;
    private DisplayCutoutView mCutoutBottom;
    private SecureSetting mColorInversionSetting;
    private boolean mPendingRotationChange;
    private Handler mHandler;
    private boolean mAssistHintBlocked = false;
    private boolean mIsReceivingNavBarColor = false;
    private boolean mInGesturalMode;

    /**
     * Converts a set of {@link Rect}s into a {@link Region}
@@ -153,160 +138,6 @@ public class ScreenDecorations extends SystemUI implements Tunable,
        mHandler.post(this::startOnScreenDecorationsThread);
        setupStatusBarPaddingIfNeeded();
        putComponent(ScreenDecorations.class, this);
        mInGesturalMode = QuickStepContract.isGesturalMode(
                Dependency.get(NavigationModeController.class)
                        .addListener(this::handleNavigationModeChange));
    }

    @VisibleForTesting
    void handleNavigationModeChange(int navigationMode) {
        if (!mHandler.getLooper().isCurrentThread()) {
            mHandler.post(() -> handleNavigationModeChange(navigationMode));
            return;
        }
        boolean inGesturalMode = QuickStepContract.isGesturalMode(navigationMode);
        if (mInGesturalMode != inGesturalMode) {
            mInGesturalMode = inGesturalMode;

            if (mInGesturalMode && mOverlay == null) {
                setupDecorations();
                if (mOverlay != null) {
                    updateLayoutParams();
                }
            }
        }
    }

    /**
     * Returns an animator that animates the given view from start to end over durationMs. Start and
     * end represent total animation progress: 0 is the start, 1 is the end, 1.1 would be an
     * overshoot.
     */
    Animator getHandleAnimator(View view, float start, float end, boolean isLeft, long durationMs,
            Interpolator interpolator) {
        // Note that lerp does allow overshoot, in cases where start and end are outside of [0,1].
        float scaleStart = MathUtils.lerp(2f, 1f, start);
        float scaleEnd = MathUtils.lerp(2f, 1f, end);
        Animator scaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, scaleStart, scaleEnd);
        Animator scaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, scaleStart, scaleEnd);
        float translationStart = MathUtils.lerp(0.2f, 0f, start);
        float translationEnd = MathUtils.lerp(0.2f, 0f, end);
        int xDirection = isLeft ? -1 : 1;
        Animator translateX = ObjectAnimator.ofFloat(view, View.TRANSLATION_X,
                xDirection * translationStart * view.getWidth(),
                xDirection * translationEnd * view.getWidth());
        Animator translateY = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y,
                translationStart * view.getHeight(), translationEnd * view.getHeight());

        AnimatorSet set = new AnimatorSet();
        set.play(scaleX).with(scaleY);
        set.play(scaleX).with(translateX);
        set.play(scaleX).with(translateY);
        set.setDuration(durationMs);
        set.setInterpolator(interpolator);
        return set;
    }

    private void fade(View view, boolean fadeIn, boolean isLeft) {
        if (fadeIn) {
            view.animate().cancel();
            view.setAlpha(1f);
            view.setVisibility(View.VISIBLE);

            // A piecewise spring-like interpolation.
            // End value in one animator call must match the start value in the next, otherwise
            // there will be a discontinuity.
            AnimatorSet anim = new AnimatorSet();
            Animator first = getHandleAnimator(view, 0, 1.1f, isLeft, 750,
                    new PathInterpolator(0, 0.45f, .67f, 1f));
            Interpolator secondInterpolator = new PathInterpolator(0.33f, 0, 0.67f, 1f);
            Animator second = getHandleAnimator(view, 1.1f, 0.97f, isLeft, 400,
                    secondInterpolator);
            Animator third = getHandleAnimator(view, 0.97f, 1.02f, isLeft, 400,
                    secondInterpolator);
            Animator fourth = getHandleAnimator(view, 1.02f, 1f, isLeft, 400,
                    secondInterpolator);
            anim.play(first).before(second);
            anim.play(second).before(third);
            anim.play(third).before(fourth);
            anim.start();
        } else {
            view.animate().cancel();
            view.animate()
                    .setInterpolator(new AccelerateInterpolator(1.5f))
                    .setDuration(250)
                    .alpha(0f);
        }

    }

    /**
     * Controls the visibility of the assist gesture handles.
     *
     * @param visible whether the handles should be shown
     */
    public void setAssistHintVisible(boolean visible) {
        if (!mHandler.getLooper().isCurrentThread()) {
            mHandler.post(() -> setAssistHintVisible(visible));
            return;
        }

        if (mAssistHintBlocked && visible) {
            if (VERBOSE) {
                Log.v(TAG, "Assist hint blocked, cannot make it visible");
            }
            return;
        }

        if (mOverlay == null || mBottomOverlay == null) {
            return;
        }

        if (mAssistHintVisible != visible) {
            mAssistHintVisible = visible;

            CornerHandleView assistHintTopLeft = mOverlay.findViewById(R.id.assist_hint_left);
            CornerHandleView assistHintTopRight = mOverlay.findViewById(R.id.assist_hint_right);
            CornerHandleView assistHintBottomLeft = mBottomOverlay.findViewById(
                    R.id.assist_hint_left);
            CornerHandleView assistHintBottomRight = mBottomOverlay.findViewById(
                    R.id.assist_hint_right);

            switch (mRotation) {
                case RotationUtils.ROTATION_NONE:
                    fade(assistHintBottomLeft, mAssistHintVisible, /* isLeft = */ true);
                    fade(assistHintBottomRight, mAssistHintVisible, /* isLeft = */ false);
                    break;
                case RotationUtils.ROTATION_LANDSCAPE:
                    fade(assistHintTopRight, mAssistHintVisible, /* isLeft = */ true);
                    fade(assistHintBottomRight, mAssistHintVisible, /* isLeft = */ false);
                    break;
                case RotationUtils.ROTATION_SEASCAPE:
                    fade(assistHintTopLeft, mAssistHintVisible, /* isLeft = */ false);
                    fade(assistHintBottomLeft, mAssistHintVisible,  /* isLeft = */ true);
                    break;
                case RotationUtils.ROTATION_UPSIDE_DOWN:
                    fade(assistHintTopLeft, mAssistHintVisible, /* isLeft = */ false);
                    fade(assistHintTopRight, mAssistHintVisible, /* isLeft = */ true);
                    break;
            }
        }
        updateWindowVisibilities();
    }

    /**
     * Prevents the assist hint from becoming visible even if `mAssistHintVisible` is true.
     */
    public void setAssistHintBlocked(boolean blocked) {
        if (!mHandler.getLooper().isCurrentThread()) {
            mHandler.post(() -> setAssistHintBlocked(blocked));
            return;
        }

        mAssistHintBlocked = blocked;
        if (mAssistHintVisible && mAssistHintBlocked) {
            hideAssistHandles();
        }
    }

    @VisibleForTesting
@@ -316,15 +147,11 @@ public class ScreenDecorations extends SystemUI implements Tunable,
        return thread.getThreadHandler();
    }

    private boolean shouldHostHandles() {
        return mInGesturalMode;
    }

    private void startOnScreenDecorationsThread() {
        mRotation = RotationUtils.getExactRotation(mContext);
        mWindowManager = mContext.getSystemService(WindowManager.class);
        updateRoundedCornerRadii();
        if (hasRoundedCorners() || shouldDrawCutout() || shouldHostHandles()) {
        if (hasRoundedCorners() || shouldDrawCutout()) {
            setupDecorations();
        }

@@ -501,26 +328,10 @@ public class ScreenDecorations extends SystemUI implements Tunable,
            if (mOverlay != null) {
                updateLayoutParams();
                updateViews();
                if (mAssistHintVisible) {
                    // If assist handles are visible, hide them without animation and then make them
                    // show once again (with corrected rotation).
                    hideAssistHandles();
                    setAssistHintVisible(true);
                }
            }
        }
    }

    private void hideAssistHandles() {
        if (mOverlay != null && mBottomOverlay != null) {
            mOverlay.findViewById(R.id.assist_hint_left).setVisibility(View.GONE);
            mOverlay.findViewById(R.id.assist_hint_right).setVisibility(View.GONE);
            mBottomOverlay.findViewById(R.id.assist_hint_left).setVisibility(View.GONE);
            mBottomOverlay.findViewById(R.id.assist_hint_right).setVisibility(View.GONE);
            mAssistHintVisible = false;
        }
    }

    private void updateRoundedCornerRadii() {
        final int newRoundedDefault = mContext.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.rounded_corner_radius);
@@ -569,52 +380,12 @@ public class ScreenDecorations extends SystemUI implements Tunable,
            updateView(bottomRight, Gravity.TOP | Gravity.LEFT, 0);
        }

        updateAssistantHandleViews();
        mCutoutTop.setRotation(mRotation);
        mCutoutBottom.setRotation(mRotation);

        updateWindowVisibilities();
    }

    private void updateAssistantHandleViews() {
        View assistHintTopLeft = mOverlay.findViewById(R.id.assist_hint_left);
        View assistHintTopRight = mOverlay.findViewById(R.id.assist_hint_right);
        View assistHintBottomLeft = mBottomOverlay.findViewById(R.id.assist_hint_left);
        View assistHintBottomRight = mBottomOverlay.findViewById(R.id.assist_hint_right);

        final int assistHintVisibility = mAssistHintVisible ? View.VISIBLE : View.INVISIBLE;

        if (mRotation == RotationUtils.ROTATION_NONE) {
            assistHintTopLeft.setVisibility(View.GONE);
            assistHintTopRight.setVisibility(View.GONE);
            assistHintBottomLeft.setVisibility(assistHintVisibility);
            assistHintBottomRight.setVisibility(assistHintVisibility);
            updateView(assistHintBottomLeft, Gravity.BOTTOM | Gravity.LEFT, 270);
            updateView(assistHintBottomRight, Gravity.BOTTOM | Gravity.RIGHT, 180);
        } else if (mRotation == RotationUtils.ROTATION_LANDSCAPE) {
            assistHintTopLeft.setVisibility(View.GONE);
            assistHintTopRight.setVisibility(assistHintVisibility);
            assistHintBottomLeft.setVisibility(View.GONE);
            assistHintBottomRight.setVisibility(assistHintVisibility);
            updateView(assistHintTopRight, Gravity.BOTTOM | Gravity.LEFT, 270);
            updateView(assistHintBottomRight, Gravity.BOTTOM | Gravity.RIGHT, 180);
        } else if (mRotation == RotationUtils.ROTATION_UPSIDE_DOWN) {
            assistHintTopLeft.setVisibility(assistHintVisibility);
            assistHintTopRight.setVisibility(assistHintVisibility);
            assistHintBottomLeft.setVisibility(View.GONE);
            assistHintBottomRight.setVisibility(View.GONE);
            updateView(assistHintTopLeft, Gravity.BOTTOM | Gravity.LEFT, 270);
            updateView(assistHintTopRight, Gravity.BOTTOM | Gravity.RIGHT, 180);
        } else if (mRotation == RotationUtils.ROTATION_SEASCAPE) {
            assistHintTopLeft.setVisibility(assistHintVisibility);
            assistHintTopRight.setVisibility(View.GONE);
            assistHintBottomLeft.setVisibility(assistHintVisibility);
            assistHintBottomRight.setVisibility(View.GONE);
            updateView(assistHintTopLeft, Gravity.BOTTOM | Gravity.RIGHT, 180);
            updateView(assistHintBottomLeft, Gravity.BOTTOM | Gravity.LEFT, 270);
        }
    }

    private void updateView(View v, int gravity, int rotation) {
        ((FrameLayout.LayoutParams) v.getLayoutParams()).gravity = gravity;
        v.setRotation(rotation);
@@ -629,10 +400,7 @@ public class ScreenDecorations extends SystemUI implements Tunable,
        boolean visibleForCutout = shouldDrawCutout()
                && overlay.findViewById(R.id.display_cutout).getVisibility() == View.VISIBLE;
        boolean visibleForRoundedCorners = hasRoundedCorners();
        boolean visibleForHandles = overlay.findViewById(R.id.assist_hint_left).getVisibility()
                == View.VISIBLE || overlay.findViewById(R.id.assist_hint_right).getVisibility()
                == View.VISIBLE;
        overlay.setVisibility(visibleForCutout || visibleForRoundedCorners || visibleForHandles
        overlay.setVisibility(visibleForCutout || visibleForRoundedCorners
                ? View.VISIBLE : View.GONE);
    }

@@ -766,31 +534,6 @@ public class ScreenDecorations extends SystemUI implements Tunable,
        view.setLayoutParams(params);
    }

    @Override
    public void onDarkIntensity(float darkIntensity) {
        if (!mHandler.getLooper().isCurrentThread()) {
            mHandler.post(() -> onDarkIntensity(darkIntensity));
            return;
        }
        if (mOverlay != null) {
            CornerHandleView assistHintTopLeft = mOverlay.findViewById(R.id.assist_hint_left);
            CornerHandleView assistHintTopRight = mOverlay.findViewById(R.id.assist_hint_right);

            assistHintTopLeft.updateDarkness(darkIntensity);
            assistHintTopRight.updateDarkness(darkIntensity);
        }

        if (mBottomOverlay != null) {
            CornerHandleView assistHintBottomLeft = mBottomOverlay.findViewById(
                    R.id.assist_hint_left);
            CornerHandleView assistHintBottomRight = mBottomOverlay.findViewById(
                    R.id.assist_hint_right);

            assistHintBottomLeft.updateDarkness(darkIntensity);
            assistHintBottomRight.updateDarkness(darkIntensity);
        }
    }

    @VisibleForTesting
    static class TunablePaddingTagListener implements FragmentListener {

+16 −15
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.DumpController;
import com.android.systemui.Dumpable;
import com.android.systemui.ScreenDecorations;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.phone.NavigationModeController;

@@ -71,7 +70,7 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
    private final Handler mHandler;
    private final Runnable mHideHandles = this::hideHandles;
    private final Runnable mShowAndGo = this::showAndGoInternal;
    private final Provider<ScreenDecorations> mScreenDecorations;
    private final Provider<AssistHandleViewController> mAssistHandleViewController;
    private final PhenotypeHelper mPhenotypeHelper;
    private final Map<AssistHandleBehavior, BehaviorController> mBehaviorMap;

@@ -90,7 +89,7 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
            Context context,
            AssistUtils assistUtils,
            @Named(ASSIST_HANDLE_THREAD_NAME) Handler handler,
            Provider<ScreenDecorations> screenDecorations,
            Provider<AssistHandleViewController> assistHandleViewController,
            PhenotypeHelper phenotypeHelper,
            Map<AssistHandleBehavior, BehaviorController> behaviorMap,
            NavigationModeController navigationModeController,
@@ -98,7 +97,7 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
        mContext = context;
        mAssistUtils = assistUtils;
        mHandler = handler;
        mScreenDecorations = screenDecorations;
        mAssistHandleViewController = assistHandleViewController;
        mPhenotypeHelper = phenotypeHelper;
        mBehaviorMap = behaviorMap;

@@ -229,12 +228,13 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
        }

        if (handlesUnblocked(ignoreThreshold)) {
            ScreenDecorations screenDecorations = mScreenDecorations.get();
            if (screenDecorations == null) {
                Log.w(TAG, "Couldn't show handles, ScreenDecorations unavailable");
            } else {
            mHandlesShowing = true;
                screenDecorations.setAssistHintVisible(true);
            AssistHandleViewController assistHandleViewController =
                    mAssistHandleViewController.get();
            if (assistHandleViewController == null) {
                Log.w(TAG, "Couldn't show handles, AssistHandleViewController unavailable");
            } else {
                assistHandleViewController.setAssistHintVisible(true);
            }
        }
    }
@@ -244,13 +244,14 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
            return;
        }

        ScreenDecorations screenDecorations = mScreenDecorations.get();
        if (screenDecorations == null) {
            Log.w(TAG, "Couldn't hide handles, ScreenDecorations unavailable");
        } else {
        mHandlesShowing = false;
        mHandlesLastHiddenAt = SystemClock.elapsedRealtime();
            screenDecorations.setAssistHintVisible(false);
        AssistHandleViewController assistHandleViewController =
                mAssistHandleViewController.get();
        if (assistHandleViewController == null) {
            Log.w(TAG, "Couldn't show handles, AssistHandleViewController unavailable");
        } else {
            assistHandleViewController.setAssistHintVisible(false);
        }
    }

+172 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading