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

Commit 04088ebe authored by mpodolian's avatar mpodolian
Browse files

Update placement of the nav bar in persistent taskbar for 3 button nav

Implemented nav bar placement update to be located opposite to the
bubble bar.
When bubble bar is moved to the other side of the bar, 3 button nav will
swap sides (without animation).
If taskbar has to be repositioned it does that with the animation.

Test: TaskbarViewControllerTest
Bug: 346381754
Flag: com.android.wm.shell.enable_bubble_bar
Change-Id: Id031706183c60cbd9c67537b01530acb43bae614
parent 9074e19d
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
@@ -690,6 +690,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);

@@ -226,6 +241,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.
     */
@@ -459,6 +522,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.
     */
@@ -1017,4 +1091,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