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

Commit 5dc07d78 authored by Jon Miranda's avatar Jon Miranda
Browse files

Add support for taskbar background to wrap around hotseat

Currently only enabled for app launch animation

Future work is planned:
- Overview to home
- App dismiss
- When QSB is drawn inline

Bug: 345768019
Test: Launch an app, taskbar background and stashed handle will
      first wrap around hotseat before transforming into the
      stashed handle.
      Verified by locally forcing taskbar background and
      stashed handle to always draw.
Flag: com.android.launcher3.enable_scaling_reveal_home_animation
Change-Id: I9ab1870f87247b6a1b53a352ac3eb0183b7a1a1d
parent 50a37b33
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static com.android.window.flags.Flags.enableDesktopWindowingWallpaperActi

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.graphics.Rect;
import android.window.RemoteTransition;

import androidx.annotation.NonNull;
@@ -179,6 +180,24 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
                placeholderDuration));
    }

    /**
     * Returns the bounds of launcher's hotseat.
     */
    public void getHotseatBounds(Rect hotseatBoundsOut) {
        DeviceProfile launcherDP = mLauncher.getDeviceProfile();
        if (launcherDP.isQsbInline) {
            // Not currently supported.
            hotseatBoundsOut.setEmpty();
            return;
        }
        int left = (launcherDP.widthPx - launcherDP.getHotseatWidthPx()
                - mLauncher.getHotseat().getUnusedHorizontalSpace()) / 2;
        int right = left + launcherDP.getHotseatWidthPx();
        int bottom = launcherDP.getHotseatLayoutPadding(mLauncher).bottom;
        int top = bottom - launcherDP.hotseatCellHeightPx;
        hotseatBoundsOut.set(left, top, right, bottom);
    }

    /**
     * Should be called from onResume() and onPause(), and animates the Taskbar accordingly.
     */
+11 −1
Original line number Diff line number Diff line
@@ -207,8 +207,11 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT
     * Creates and returns a {@link RevealOutlineAnimation} Animator that updates the stashed handle
     * shape and size. When stashed, the shape is a thin rounded pill. When unstashed, the shape
     * morphs into the size of where the taskbar icons will be.
     *
     * @param taskbarToHotseatOffsets A Rect of offsets used to transform the bounds of the
     *                                stashed handle to wrap around the hotseat items.
     */
    public Animator createRevealAnimToIsStashed(boolean isStashed) {
    public Animator createRevealAnimToIsStashed(boolean isStashed, Rect taskbarToHotseatOffsets) {
        Rect visualBounds = new Rect(mControllers.taskbarViewController.getIconLayoutBounds());
        float startRadius = mStashedHandleRadius;

@@ -219,6 +222,13 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT
            visualBounds.bottom += heightDiff;

            startRadius = visualBounds.height() / 2f;

            // We use these offsets to create a larger stashed handle to wrap around the items
            // of the hotseat. This is only used for certain animations.
            visualBounds.top +=  taskbarToHotseatOffsets.top;
            visualBounds.bottom += taskbarToHotseatOffsets.bottom;
            visualBounds.left += taskbarToHotseatOffsets.left;
            visualBounds.right += taskbarToHotseatOffsets.right;
        }

        final RevealOutlineAnimation handleRevealProvider = new RoundedRectRevealOutlineProvider(
+44 −0
Original line number Diff line number Diff line
@@ -336,6 +336,38 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
        dispatchDeviceProfileChanged();
    }

    /**
     * Calculate the offsets needed to transform the transient taskbar bounds to the hotseat bounds.
     * @return The offsets will be stored in a Rect
     */
    public Rect calculateTaskbarToHotseatOffsets(Rect hotseatBounds) {
        Rect taskbar = getTransientTaskbarBounds();
        Rect offsets = new Rect();

        offsets.left = hotseatBounds.left - taskbar.left;
        offsets.right = hotseatBounds.right - taskbar.right;

        int heightDiff = hotseatBounds.height() - taskbar.height();
        offsets.top = (taskbar.height() - heightDiff) / 2;

        int gleanedTaskbarPadding = (mDeviceProfile.taskbarHeight
                - getTransientTaskbarBounds().height()) / 2;
        offsets.left -= gleanedTaskbarPadding;
        offsets.top -= gleanedTaskbarPadding;
        offsets.right += gleanedTaskbarPadding;

        // Bottom is relative to the bottom of layout, so we can calculate it with padding included.
        offsets.bottom = (hotseatBounds.height() - taskbar.height()) / 2;

        // Update bounds in taskbar background
        if (hotseatBounds.isEmpty()) {
            mDragLayer.getTaskbarToHotseatOffsetRect().setEmpty();
        } else {
            mDragLayer.getTaskbarToHotseatOffsetRect().set(offsets);
        }
        return offsets;
    }

    /**
     * Copy the original DeviceProfile, match the number of hotseat icons and qsb width and update
     * the icon size
@@ -1517,6 +1549,18 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
        return AnimatorPlaybackController.wrap(fullAnimation, duration);
    }

    /**
     * Returns the bounds of launcher's hotseat (if exists).
     */
    public void getHotseatBounds(Rect hotseatBoundsOut) {
        TaskbarUIController uiController = mControllers.uiController;
        if (uiController instanceof LauncherTaskbarUIController launcherController) {
            launcherController.getHotseatBounds(hotseatBoundsOut);
        } else {
            hotseatBoundsOut.setEmpty();
        }
    }

    /**
     * Called when we determine the touchable region.
     *
+14 −4
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Rect
import android.graphics.RectF
import com.android.app.animation.Interpolators
import com.android.launcher3.R
@@ -59,6 +60,9 @@ class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {
    var translationYForSwipe = 0f
    var translationYForStash = 0f

    // When not empty, we can use this to transform transient taskbar background to hotseat bounds.
    val taskbarToHotseatOffsetRect = Rect()

    private val transientBackgroundBounds = context.transientTaskbarBounds

    private val shadowAlpha: Float
@@ -215,6 +219,12 @@ class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {
        val radius = newBackgroundHeight / 2f
        val bottomMarginProgress = bottomMargin * ((1f - progress) / 2f)

        // Used to transform the background so that it wraps around the items on the hotseat.
        val hotseatOffsetLeft = taskbarToHotseatOffsetRect.left * progress
        val hotseatOffsetTop = taskbarToHotseatOffsetRect.top * progress
        val hotseatOffsetRight = taskbarToHotseatOffsetRect.right * progress
        val hotseatOffsetBottom = taskbarToHotseatOffsetRect.bottom * progress

        // Aligns the bottom with the bottom of the stashed handle.
        val bottom =
            canvas.height - bottomMargin +
@@ -238,10 +248,10 @@ class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {
        )

        lastDrawnTransientRect.set(
            transientBackgroundBounds.left + halfWidthDelta,
            bottom - newBackgroundHeight,
            transientBackgroundBounds.right - halfWidthDelta,
            bottom
            transientBackgroundBounds.left + halfWidthDelta + hotseatOffsetLeft,
            bottom - newBackgroundHeight + hotseatOffsetTop,
            transientBackgroundBounds.right - halfWidthDelta + hotseatOffsetRight,
            bottom + hotseatOffsetBottom
        )
        val horizontalInset = fullWidth * widthInsetPercentage
        lastDrawnTransientRect.inset(horizontalInset, 0f)
+6 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NAVBAR_UN

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.permission.SafeCloseable;
import android.util.AttributeSet;
@@ -260,6 +261,11 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
        return mBackgroundRenderer.getLastDrawnTransientRect();
    }

    /** Returns the rect used to transform transient taskbar to the hotseat */
    public Rect getTaskbarToHotseatOffsetRect() {
        return mBackgroundRenderer.getTaskbarToHotseatOffsetRect();
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        TestLogging.recordMotionEvent(TestProtocol.SEQUENCE_MAIN, "Touch event", ev);
Loading