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

Commit 24231d99 authored by Jagrut Desai's avatar Jagrut Desai Committed by Android (Google) Code Review
Browse files

Merge "Taskbar pinning animation with no recreate" into main

parents 821bc0d0 631b2848
Loading
Loading
Loading
Loading
+45 −9
Original line number Diff line number Diff line
@@ -174,13 +174,16 @@ public class TaskbarActivityContext extends BaseTaskbarContext {

    private final TaskbarShortcutMenuAccessibilityDelegate mAccessibilityDelegate;

    private DeviceProfile mTransientTaskbarDeviceProfile;

    private DeviceProfile mPersistentTaskbarDeviceProfile;

    public TaskbarActivityContext(Context windowContext, DeviceProfile launcherDp,
            TaskbarNavButtonController buttonController, ScopedUnfoldTransitionProgressProvider
            unfoldTransitionProgressProvider) {
        super(windowContext);

        applyDeviceProfile(launcherDp);

        final Resources resources = getResources();

        mImeDrawsImeNavBar = getBoolByName(IME_DRAWS_IME_NAV_BAR_RES_NAME, resources, false);
@@ -275,7 +278,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
                        : TaskbarRecentAppsController.DEFAULT,
                new TaskbarEduTooltipController(this),
                new KeyboardQuickSwitchController(),
                new TaskbarDividerPopupController(this),
                new TaskbarPinningController(this),
                bubbleControllersOptional);
    }

@@ -307,6 +310,30 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
                    deviceProfile.iconSizePx = deviceProfile.taskbarIconSize;
                    deviceProfile.updateIconSize(1f, getResources());
                }).build();

        if (DisplayController.isTransientTaskbar(this)) {
            mTransientTaskbarDeviceProfile = mDeviceProfile;
            mPersistentTaskbarDeviceProfile = mDeviceProfile
                    .toBuilder(this)
                    .withDimensionsOverride(deviceProfile -> {
                        // Update icon size
                        deviceProfile.iconSizePx = deviceProfile.taskbarIconSize;
                        deviceProfile.updateIconSize(1f, getResources());
                    })
                    .setIsTransientTaskbar(false)
                    .build();
        } else {
            mPersistentTaskbarDeviceProfile = mDeviceProfile;
            mTransientTaskbarDeviceProfile = mDeviceProfile
                    .toBuilder(this)
                    .withDimensionsOverride(deviceProfile -> {
                        // Update icon size
                        deviceProfile.iconSizePx = deviceProfile.taskbarIconSize;
                        deviceProfile.updateIconSize(1f, getResources());
                    })
                    .setIsTransientTaskbar(true)
                    .build();
        }
        mNavMode = DisplayController.getNavigationMode(this);
    }

@@ -392,6 +419,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext {

    /**
     * Creates LayoutParams for adding a view directly to WindowManager as a new window.
     *
     * @param type  The window type to pass to the created WindowManager.LayoutParams.
     * @param title The window title to pass to the created WindowManager.LayoutParams.
     */
@@ -880,6 +908,14 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
        return getResources().getDimensionPixelSize(R.dimen.taskbar_suw_frame);
    }

    public DeviceProfile getTransientTaskbarDeviceProfile() {
        return mTransientTaskbarDeviceProfile;
    }

    public DeviceProfile getPersistentTaskbarDeviceProfile() {
        return mPersistentTaskbarDeviceProfile;
    }

    /**
     * Either adds or removes {@link WindowManager.LayoutParams#FLAG_NOT_FOCUSABLE} on the taskbar
     * window.
+131 −66
Original line number Diff line number Diff line
@@ -29,26 +29,38 @@ import com.android.launcher3.Utilities
import com.android.launcher3.Utilities.mapRange
import com.android.launcher3.Utilities.mapToRange
import com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound
import com.android.launcher3.taskbar.TaskbarPinningController.Companion.PINNING_PERSISTENT
import com.android.launcher3.taskbar.TaskbarPinningController.Companion.PINNING_TRANSIENT
import com.android.launcher3.util.DisplayController

/** Helps draw the taskbar background, made up of a rectangle plus two inverted rounded corners. */
class TaskbarBackgroundRenderer(context: TaskbarActivityContext) {
class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {

    private val isInSetup: Boolean = !context.isUserSetupComplete
    private val DARK_THEME_SHADOW_ALPHA = 51f
    private val LIGHT_THEME_SHADOW_ALPHA = 25f

    private val maxTransientTaskbarHeight =
        context.transientTaskbarDeviceProfile.taskbarHeight.toFloat()
    private val maxPersistentTaskbarHeight =
        context.persistentTaskbarDeviceProfile.taskbarHeight.toFloat()
    var backgroundProgress =
        if (DisplayController.isTransientTaskbar(context)) {
            PINNING_TRANSIENT
        } else {
            PINNING_PERSISTENT
        }

    var isAnimatingPinning = false

    val paint = Paint()
    val lastDrawnTransientRect = RectF()
    var backgroundHeight = context.deviceProfile.taskbarHeight.toFloat()
    var translationYForSwipe = 0f
    var translationYForStash = 0f

    private var maxBackgroundHeight = context.deviceProfile.taskbarHeight.toFloat()
    private val transientBackgroundBounds = context.transientTaskbarBounds

    private val isTransientTaskbar = DisplayController.isTransientTaskbar(context)

    private val shadowAlpha: Float
    private var shadowBlur = 0f
    private var keyShadowDistance = 0f
@@ -75,13 +87,6 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) {
        paint.flags = Paint.ANTI_ALIAS_FLAG
        paint.style = Paint.Style.FILL

        if (isTransientTaskbar) {
            val res = context.resources
            bottomMargin = res.getDimensionPixelSize(R.dimen.transient_taskbar_bottom_margin)
            shadowBlur = res.getDimension(R.dimen.transient_taskbar_shadow_blur)
            keyShadowDistance = res.getDimension(R.dimen.transient_taskbar_key_shadow_distance)
        }

        shadowAlpha =
            if (Utilities.isDarkTheme(context)) DARK_THEME_SHADOW_ALPHA
            else LIGHT_THEME_SHADOW_ALPHA
@@ -90,7 +95,8 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) {
    }

    fun updateStashedHandleWidth(dp: DeviceProfile, res: Resources) {
        stashedHandleWidth = res.getDimensionPixelSize(
        stashedHandleWidth =
            res.getDimensionPixelSize(
                if (TaskbarManager.isPhoneMode(dp)) R.dimen.taskbar_stashed_small_screen
                else R.dimen.taskbar_stashed_handle_width
            )
@@ -102,7 +108,7 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) {
     * @param cornerRoundness 0 has no round corner, 1 has complete round corner.
     */
    fun setCornerRoundness(cornerRoundness: Float) {
        if (isTransientTaskbar && !transientBackgroundBounds.isEmpty) {
        if (DisplayController.isTransientTaskbar(context) && !transientBackgroundBounds.isEmpty) {
            return
        }

@@ -126,11 +132,31 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) {

    /** Draws the background with the given paint and height, on the provided canvas. */
    fun draw(canvas: Canvas) {
        if (isInSetup) return
        val isTransientTaskbar = backgroundProgress == 0f
        canvas.save()
        if (!isTransientTaskbar || transientBackgroundBounds.isEmpty) {
            canvas.translate(0f, canvas.height - backgroundHeight - bottomMargin)
        if (!isTransientTaskbar || transientBackgroundBounds.isEmpty || isAnimatingPinning) {
            drawPersistentBackground(canvas)
        }
        canvas.restore()
        canvas.save()
        if (isAnimatingPinning || isTransientTaskbar) {
            drawTransientBackground(canvas)
        }
        canvas.restore()
    }

    private fun drawPersistentBackground(canvas: Canvas) {
        if (isAnimatingPinning) {
            val persistentTaskbarHeight = maxPersistentTaskbarHeight * backgroundProgress
            canvas.translate(0f, canvas.height - persistentTaskbarHeight)
            // Draw the background behind taskbar content.
            canvas.drawRect(0f, 0f, canvas.width.toFloat(), persistentTaskbarHeight, paint)
        } else {
            canvas.translate(0f, canvas.height - maxPersistentTaskbarHeight)
            // Draw the background behind taskbar content.
            canvas.drawRect(0f, 0f, canvas.width.toFloat(), backgroundHeight, paint)
            canvas.drawRect(0f, 0f, canvas.width.toFloat(), maxPersistentTaskbarHeight, paint)
        }

        // Draw the inverted rounded corners above the taskbar.
        canvas.translate(0f, -leftCornerRadius)
@@ -138,17 +164,54 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) {
        canvas.translate(0f, leftCornerRadius)
        canvas.translate(canvas.width - rightCornerRadius, -rightCornerRadius)
        canvas.drawPath(invertedRightCornerPath, paint)
        } else if (!isInSetup) {
            // backgroundHeight is a value from [0...maxBackgroundHeight], so we can use it as a
            // proxy to figure out the animation progress of the stash/unstash animation.
            val progress = backgroundHeight / maxBackgroundHeight
    }

    private fun drawTransientBackground(canvas: Canvas) {
        val res = context.resources
        val transientTaskbarHeight = maxTransientTaskbarHeight * (1f - backgroundProgress)
        val heightProgressWhileAnimating =
            if (isAnimatingPinning) transientTaskbarHeight else backgroundHeight

        var progress = heightProgressWhileAnimating / maxTransientTaskbarHeight
        progress = Math.round(progress * 100f) / 100f
        if (isAnimatingPinning) {
            var scale = transientTaskbarHeight / maxTransientTaskbarHeight
            scale = Math.round(scale * 100f) / 100f
            bottomMargin =
                mapRange(
                        scale,
                        0f,
                        res.getDimensionPixelSize(R.dimen.transient_taskbar_bottom_margin).toFloat()
                    )
                    .toInt()
            shadowBlur =
                mapRange(scale, 0f, res.getDimension(R.dimen.transient_taskbar_shadow_blur))
            keyShadowDistance =
                mapRange(scale, 0f, res.getDimension(R.dimen.transient_taskbar_key_shadow_distance))
        } else {
            bottomMargin = res.getDimensionPixelSize(R.dimen.transient_taskbar_bottom_margin)
            shadowBlur = res.getDimension(R.dimen.transient_taskbar_shadow_blur)
            keyShadowDistance = res.getDimension(R.dimen.transient_taskbar_key_shadow_distance)
        }

        // At progress 0, we draw the background as the stashed handle.
        // At progress 1, we draw the background as the full taskbar.
        // Min height capped to max persistent taskbar height for animation
        val backgroundHeightWhileAnimating =
            if (isAnimatingPinning) maxPersistentTaskbarHeight else stashedHandleHeight.toFloat()
        val newBackgroundHeight =
                mapRange(progress, stashedHandleHeight.toFloat(), maxBackgroundHeight)
            mapRange(progress, backgroundHeightWhileAnimating, maxTransientTaskbarHeight)
        val fullWidth = transientBackgroundBounds.width()
            val newWidth = mapRange(progress, stashedHandleWidth.toFloat(), fullWidth.toFloat())

        // .9f is here to restrict min width of the background while animating, so transient
        // background keeps it pill shape until animation end.
        val animationWidth =
            if (DisplayController.isTransientTaskbar(context)) fullWidth.toFloat() * .9f
            else fullWidth.toFloat()
        val backgroundWidthWhileAnimating =
            if (isAnimatingPinning) animationWidth else stashedHandleWidth.toFloat()

        val newWidth = mapRange(progress, backgroundWidthWhileAnimating, fullWidth.toFloat())
        val halfWidthDelta = (fullWidth - newWidth) / 2f
        val radius = newBackgroundHeight / 2f
        val bottomMarginProgress = bottomMargin * ((1f - progress) / 2f)
@@ -159,7 +222,11 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) {
                bottomMarginProgress +
                translationYForSwipe +
                translationYForStash +
                    -mapRange(1f - progress, 0f, stashedHandleHeight / 2f)
                -mapRange(
                    1f - progress,
                    0f,
                    if (isAnimatingPinning) 0f else stashedHandleHeight / 2f
                )

        // Draw shadow.
        val newShadowAlpha =
@@ -182,8 +249,6 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) {

        canvas.drawRoundRect(lastDrawnTransientRect, radius, radius, paint)
    }
        canvas.restore()
    }

    /**
     * Sets the width percentage to inset the transient taskbar's background from the left and from
+3 −3
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ public class TaskbarControllers {
    public final TaskbarOverlayController taskbarOverlayController;
    public final TaskbarEduTooltipController taskbarEduTooltipController;
    public final KeyboardQuickSwitchController keyboardQuickSwitchController;
    public final TaskbarDividerPopupController taskbarPinningController;
    public final TaskbarPinningController taskbarPinningController;
    public final Optional<BubbleControllers> bubbleControllers;

    @Nullable private LoggableTaskbarController[] mControllersToLog = null;
@@ -110,7 +110,7 @@ public class TaskbarControllers {
            TaskbarRecentAppsController taskbarRecentAppsController,
            TaskbarEduTooltipController taskbarEduTooltipController,
            KeyboardQuickSwitchController keyboardQuickSwitchController,
            TaskbarDividerPopupController taskbarPinningController,
            TaskbarPinningController taskbarPinningController,
            Optional<BubbleControllers> bubbleControllers) {
        this.taskbarActivityContext = taskbarActivityContext;
        this.taskbarDragController = taskbarDragController;
@@ -171,7 +171,7 @@ public class TaskbarControllers {
        taskbarTranslationController.init(this);
        taskbarEduTooltipController.init(this);
        keyboardQuickSwitchController.init(this);
        taskbarPinningController.init(this);
        taskbarPinningController.init(this, mSharedState);
        bubbleControllers.ifPresent(controllers -> controllers.init(this));

        mControllersToLog = new LoggableTaskbarController[] {
+0 −8
Original line number Diff line number Diff line
@@ -75,12 +75,6 @@ constructor(
    /** Callback invoked when the pinning popup view is closing. */
    var onCloseCallback: (preferenceChanged: Boolean) -> Unit = {}

    /**
     * Callback invoked when the user preference changes in popup view. Preference change will be
     * based upon current value stored in [LauncherPrefs] for `TASKBAR_PINNING`
     */
    var changePreference: () -> Unit = {}

    init {
        // This synchronizes the arrow and menu to open at the same time
        mOpenChildFadeStartDelay = mOpenFadeStartDelay
@@ -185,8 +179,6 @@ constructor(

    private fun onClickAlwaysShowTaskbarSwitchOption() {
        didPreferenceChange = true
        changePreference()
        changePreference = {}
        // Allow switch animation to finish and then close the popup.
        postDelayed(DIVIDER_POPUP_CLOSING_DELAY) {
            if (isOpen) {
+20 −0
Original line number Diff line number Diff line
@@ -73,6 +73,8 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
    private SafeCloseable mViewCaptureCloseable;

    private float mTaskbarBackgroundOffset;
    private float mTaskbarBackgroundProgress;
    private boolean mIsAnimatingTaskbarPinning = false;

    private final MultiPropertyFactory<TaskbarDragLayer> mTaskbarBackgroundAlpha;

@@ -162,10 +164,19 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
        float backgroundHeight = mControllerCallbacks.getTaskbarBackgroundHeight()
                * (1f - mTaskbarBackgroundOffset);
        mBackgroundRenderer.setBackgroundHeight(backgroundHeight);
        mBackgroundRenderer.setBackgroundProgress(mTaskbarBackgroundProgress);
        mBackgroundRenderer.draw(canvas);
        super.dispatchDraw(canvas);
    }

    /**
     * Sets animation boolean when taskbar pinning animation starts or stops.
     */
    public void setAnimatingTaskbarPinning(boolean animatingTaskbarPinning) {
        mIsAnimatingTaskbarPinning = animatingTaskbarPinning;
        mBackgroundRenderer.setAnimatingPinning(mIsAnimatingTaskbarPinning);
    }

    protected MultiProperty getBackgroundRendererAlpha() {
        return mTaskbarBackgroundAlpha.get(INDEX_ALL_OTHER_STATES);
    }
@@ -174,6 +185,15 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
        return mTaskbarBackgroundAlpha.get(INDEX_STASH_ANIM);
    }

    /**
     * Sets the value for taskbar background switching between persistent and transient backgrounds.
     * @param progress 0 is transient background, 1 is persistent background.
     */
    protected void setTaskbarBackgroundProgress(float progress) {
        mTaskbarBackgroundProgress = progress;
        invalidate();
    }

    /**
     * Sets the translation of the background color behind all the Taskbar contents.
     * @param offset 0 is fully onscreen, 1 is fully offscreen.
Loading