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

Commit 56cda496 authored by Mykola Podolian's avatar Mykola Podolian Committed by Android (Google) Code Review
Browse files

Merge "Update placement of the nav bar in persistent taskbar for 3 button nav" into main

parents 9c749aaf 04088ebe
Loading
Loading
Loading
Loading
+56 −1
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AlphaUpdateListener;
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarButton;
import com.android.launcher3.taskbar.bubbles.BubbleBarController;
import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory;
import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter;
import com.android.launcher3.taskbar.navbutton.NearestTouchFrame;
@@ -106,6 +107,7 @@ import com.android.systemui.shared.rotation.RotationButton;
import com.android.systemui.shared.statusbar.phone.BarTransitions;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;

import java.io.PrintWriter;
import java.util.ArrayList;
@@ -115,7 +117,8 @@ import java.util.function.IntPredicate;
/**
 * Controller for managing nav bar buttons in taskbar
 */
public class NavbarButtonsViewController implements TaskbarControllers.LoggableTaskbarController {
public class NavbarButtonsViewController implements TaskbarControllers.LoggableTaskbarController,
        BubbleBarController.BubbleBarLocationListener {

    private final Rect mTempRect = new Rect();

@@ -397,6 +400,12 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT
            }
        };
        mSeparateWindowParent.recreateControllers();
        if (com.android.wm.shell.Flags.enableBubbleBarInPersistentTaskBar()
                && mControllers.bubbleControllers.isPresent()) {
            BubbleBarLocation bubblesLocation = mControllers.bubbleControllers.get()
                    .bubbleBarViewController.getBubbleBarLocation();
            onBubbleBarLocationUpdated(bubblesLocation);
        }
    }

    private void initButtons(ViewGroup navContainer, ViewGroup endContainer,
@@ -1168,6 +1177,52 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT
        mHitboxExtender.onAnimationProgressToOverview(alignment);
    }

    /** Adjusts navigation buttons layout accordingly to the bubble bar position. */
    @Override
    public void onBubbleBarLocationUpdated(BubbleBarLocation location) {
        mNavButtonContainer.setTranslationX(getNavBarTranslationX(location));
    }

    /** Animates navigation buttons accordingly to the bubble bar position. */
    @Override
    public void onBubbleBarLocationAnimated(BubbleBarLocation location) {
        // TODO(b/346381754) add the teleport animation similarly to the bubble bar
        mNavButtonContainer.setTranslationX(getNavBarTranslationX(location));
    }

    private int getNavBarTranslationX(BubbleBarLocation location) {
        boolean isNavbarOnRight = location.isOnLeft(mNavButtonsView.isLayoutRtl());
        DeviceProfile dp = mContext.getDeviceProfile();
        float navBarTargetStartX;
        if (mContext.shouldStartAlignTaskbar()) {
            int navBarSpacing = dp.inlineNavButtonsEndSpacingPx;
            // If the taskbar is start aligned the navigation bar is aligned to the start or end of
            // the container, depending on the bubble bar location
            if (isNavbarOnRight) {
                navBarTargetStartX = dp.widthPx - navBarSpacing - mNavButtonContainer.getWidth();
            } else {
                navBarTargetStartX = navBarSpacing;
            }
        } else {
            // If the task bar is not start aligned, the navigation bar is located in the center
            // between the taskbar and screen edges, depending on the bubble bar location.
            float navbarWidth = mNavButtonContainer.getWidth();
            Rect taskbarBounds = mControllers.taskbarViewController.getIconLayoutBounds();
            if (isNavbarOnRight) {
                if (mNavButtonsView.isLayoutRtl()) {
                    float taskBarEnd = taskbarBounds.right;
                    navBarTargetStartX = (dp.widthPx + taskBarEnd - navbarWidth) / 2;
                } else {
                    navBarTargetStartX = mNavButtonContainer.getLeft();
                }
            } else {
                float taskBarStart = taskbarBounds.left;
                navBarTargetStartX = (taskBarStart - navbarWidth) / 2;
            }
        }
        return (int) navBarTargetStartX - mNavButtonContainer.getLeft();
    }

    private class RotationButtonListener implements RotationButton.RotationButtonUpdatesCallback {
        @Override
        public void onVisibilityChanged(boolean isVisible) {
+5 −0
Original line number Diff line number Diff line
@@ -688,6 +688,11 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
        return mNavMode == NavigationMode.THREE_BUTTONS;
    }

    /** Returns whether taskbar should start align. */
    public boolean shouldStartAlignTaskbar() {
        return isThreeButtonNav() && mDeviceProfile.startAlignTaskbar;
    }

    public boolean isGestureNav() {
        return mNavMode == NavigationMode.NO_BUTTON;
    }
+64 −26
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
    private final boolean mIsRtl;

    private final TaskbarActivityContext mActivityContext;
    @Nullable private BubbleBarLocation mBubbleBarLocation = null;

    // Initialized in init.
    private TaskbarViewCallbacks mControllerCallbacks;
@@ -197,7 +198,7 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar

    @Override
    public void onDeviceProfileChanged(DeviceProfile dp) {
        mShouldTryStartAlign = mActivityContext.isThreeButtonNav() && dp.startAlignTaskbar;
        mShouldTryStartAlign = mActivityContext.shouldStartAlignTaskbar();
    }

    @Override
@@ -494,29 +495,49 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
        icon.setOnHoverListener(mControllerCallbacks.getIconOnHoverListener(icon));
    }

    /** Updates taskbar icons accordingly to the new bubble bar location. */
    public void onBubbleBarLocationUpdated(BubbleBarLocation location) {
        if (mBubbleBarLocation == location) return;
        mBubbleBarLocation = location;
        requestLayout();
    }

    /**
     * Returns translation X for the taskbar icons for provided {@link BubbleBarLocation}. If the
     * bubble bar is not enabled, or location of the bubble bar is the same, or taskbar is not start
     * aligned - returns 0.
     */
    public float getTranslationXForBubbleBarPosition(BubbleBarLocation location) {
        if (!mControllerCallbacks.isBubbleBarEnabledInPersistentTaskbar()
                || location == mBubbleBarLocation
                || !mActivityContext.shouldStartAlignTaskbar()
        ) {
            return 0;
        }
        Rect iconsBounds = getIconLayoutBounds();
        return getTaskBarIconsEndForBubbleBarLocation(location) - iconsBounds.right;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        int count = getChildCount();
        DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
        int spaceNeeded = getIconLayoutWidth();
        int navSpaceNeeded = deviceProfile.hotseatBarEndOffset;
        boolean layoutRtl = isLayoutRtl();
        int centerAlignIconEnd = right - (right - left - spaceNeeded) / 2;
        int iconEnd;

        DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
        int navSpaceNeeded = deviceProfile.hotseatBarEndOffset;
        int centerAlignIconEnd = (right + left + spaceNeeded) / 2;
        int iconEnd = centerAlignIconEnd;
        if (mShouldTryStartAlign) {
            // Taskbar is aligned to the start
            int startSpacingPx = deviceProfile.inlineNavButtonsEndSpacingPx;

            if (mControllerCallbacks.isBubbleBarEnabledInPersistentTaskbar()
                    && mBubbleBarLocation != null
                    && mActivityContext.shouldStartAlignTaskbar()) {
                iconEnd = (int) getTaskBarIconsEndForBubbleBarLocation(mBubbleBarLocation);
            } else {
                if (layoutRtl) {
                    iconEnd = right - startSpacingPx;
                } else {
                    iconEnd = startSpacingPx + spaceNeeded;
                }
        } else {
            iconEnd = centerAlignIconEnd;
        }

                boolean needMoreSpaceForNav = layoutRtl
                        ? navSpaceNeeded > (iconEnd - spaceNeeded)
                        : iconEnd > (right - navSpaceNeeded);
@@ -525,9 +546,10 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
                    int offset = layoutRtl
                            ? navSpaceNeeded - (centerAlignIconEnd - spaceNeeded)
                            : (right - navSpaceNeeded) - centerAlignIconEnd;

                    iconEnd = centerAlignIconEnd + offset;
                }
            }
        }

        // Currently, we support only one device with display cutout and we only are concern about
        // it when the bottom rect is present and non empty
@@ -558,6 +580,7 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
        mIconLayoutBounds.right = iconEnd;
        mIconLayoutBounds.top = (bottom - top - mIconTouchSize) / 2;
        mIconLayoutBounds.bottom = mIconLayoutBounds.top + mIconTouchSize;
        int count = getChildCount();
        for (int i = count; i > 0; i--) {
            View child = getChildAt(i - 1);
            if (child == mQsb) {
@@ -770,4 +793,19 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
        }
        return mAllAppsButtonContainer;
    }

    /**
     * This method only works for bubble bar enabled in persistent task bar and the taskbar is start
     * aligned.
     */
    private float getTaskBarIconsEndForBubbleBarLocation(BubbleBarLocation location) {
        DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
        boolean navbarOnRight = location.isOnLeft(isLayoutRtl());
        int navSpaceNeeded = deviceProfile.hotseatBarEndOffset;
        if (navbarOnRight) {
            return getWidth() - navSpaceNeeded;
        } else {
            return navSpaceNeeded + getIconLayoutWidth();
        }
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import androidx.annotation.Nullable;
import com.android.internal.jank.Cuj;
import com.android.launcher3.taskbar.bubbles.BubbleBarViewController;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.wm.shell.Flags;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;

/**
@@ -127,4 +128,10 @@ public class TaskbarViewCallbacks {
        }
        return null;
    }

    /** Returns true if bubble bar controllers present and enabled in persistent taskbar. */
    public boolean isBubbleBarEnabledInPersistentTaskbar() {
        return Flags.enableBubbleBarInPersistentTaskBar()
                && mControllers.bubbleControllers.isPresent();
    }
}
+83 −1
Original line number Diff line number Diff line
@@ -29,7 +29,10 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NAVBAR_UN
import static com.android.launcher3.config.FeatureFlags.enableTaskbarPinning;
import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_PERSISTENT;
import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_TRANSIENT;
import static com.android.launcher3.taskbar.bubbles.BubbleBarView.FADE_IN_ANIM_ALPHA_DURATION_MS;
import static com.android.launcher3.taskbar.bubbles.BubbleBarView.FADE_OUT_ANIM_POSITION_DURATION_MS;
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_NAV_BAR_ANIM;
import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_ALIGNMENT_ANIM;
import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_PINNING_ANIM;
import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_REVEAL_ANIM;
@@ -66,6 +69,7 @@ import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.TaskItemInfo;
import com.android.launcher3.taskbar.bubbles.BubbleBarController;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.LauncherBindableItemsContainer;
@@ -74,6 +78,8 @@ import com.android.launcher3.util.MultiTranslateDelegate;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.quickstep.util.GroupTask;
import com.android.systemui.shared.recents.model.Task;
import com.android.wm.shell.Flags;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;

import java.io.PrintWriter;
import java.util.Set;
@@ -82,7 +88,8 @@ import java.util.function.Predicate;
/**
 * Handles properties/data collection, then passes the results to TaskbarView to render.
 */
public class TaskbarViewController implements TaskbarControllers.LoggableTaskbarController {
public class TaskbarViewController implements TaskbarControllers.LoggableTaskbarController,
        BubbleBarController.BubbleBarLocationListener {

    private static final String TAG = "TaskbarViewController";

@@ -122,6 +129,14 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
    private final AnimatedFloat mTaskbarIconTranslationXForPinning = new AnimatedFloat(
            this::updateTaskbarIconTranslationXForPinning);

    private final AnimatedFloat mIconsTranslationXForNavbar = new AnimatedFloat(
            this::updateTranslationXForNavBar);

    @Nullable
    private Animator mTaskbarShiftXAnim;
    @Nullable
    private BubbleBarLocation mCurrentBubbleBarLocation;

    private final AnimatedFloat mTaskbarIconTranslationYForPinning = new AnimatedFloat(
            this::updateTranslationY);

@@ -227,6 +242,54 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
        }
    }

    /** Adjusts start aligned taskbar layout accordingly to the bubble bar position. */
    @Override
    public void onBubbleBarLocationUpdated(BubbleBarLocation location) {
        updateCurrentBubbleBarLocation(location);
        if (!shouldMoveTaskbarOnBubbleBarLocationUpdate()) return;
        cancelTaskbarShiftAnimation();
        // reset translation x, taskbar will position icons with the updated location
        mIconsTranslationXForNavbar.updateValue(0);
        mTaskbarView.onBubbleBarLocationUpdated(location);
    }

    /** Animates start aligned taskbar accordingly to the bubble bar position. */
    @Override
    public void onBubbleBarLocationAnimated(BubbleBarLocation location) {
        if (!updateCurrentBubbleBarLocation(location)
                || !shouldMoveTaskbarOnBubbleBarLocationUpdate()) {
            return;
        }
        cancelTaskbarShiftAnimation();
        float translationX = mTaskbarView.getTranslationXForBubbleBarPosition(location);
        mTaskbarShiftXAnim = createTaskbarIconsShiftAnimator(translationX);
        mTaskbarShiftXAnim.start();
    }

    /** Updates the mCurrentBubbleBarLocation, returns {@code} true if location is updated. */
    private boolean updateCurrentBubbleBarLocation(BubbleBarLocation location) {
        if (mCurrentBubbleBarLocation == location || location == null) {
            return false;
        } else {
            mCurrentBubbleBarLocation = location;
            return true;
        }
    }

    /** Returns whether taskbar should be moved on the bubble bar location update. */
    private boolean shouldMoveTaskbarOnBubbleBarLocationUpdate() {
        return Flags.enableBubbleBarInPersistentTaskBar()
                && mControllers.bubbleControllers.isPresent()
                && mActivity.shouldStartAlignTaskbar()
                && mActivity.isThreeButtonNav();
    }

    private void cancelTaskbarShiftAnimation() {
        if (mTaskbarShiftXAnim != null) {
            mTaskbarShiftXAnim.cancel();
        }
    }

    /**
     * Announcement for Accessibility when Taskbar stashes/unstashes.
     */
@@ -460,6 +523,17 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
                + mTaskbarIconTranslationYForSpringOnStash);
    }

    private void updateTranslationXForNavBar() {
        View[] iconViews = mTaskbarView.getIconViews();
        float translationX = mIconsTranslationXForNavbar.value;
        for (int iconIndex = 0; iconIndex < iconViews.length; iconIndex++) {
            View iconView = iconViews[iconIndex];
            MultiTranslateDelegate translateDelegate =
                    ((Reorderable) iconView).getTranslateDelegate();
            translateDelegate.getTranslationX(INDEX_NAV_BAR_ANIM).setValue(translationX);
        }
    }

    /**
     * Computes translation y for taskbar pinning.
     */
@@ -1018,4 +1092,12 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
    public static void enableModelLoadingForTests(boolean enable) {
        sEnableModelLoadingForTests = enable;
    }

    private ObjectAnimator createTaskbarIconsShiftAnimator(float translationX) {
        ObjectAnimator animator = mIconsTranslationXForNavbar.animateToValue(translationX);
        animator.setStartDelay(FADE_OUT_ANIM_POSITION_DURATION_MS);
        animator.setDuration(FADE_IN_ANIM_ALPHA_DURATION_MS);
        animator.setInterpolator(Interpolators.EMPHASIZED);
        return animator;
    }
}
Loading