Merge "3 button nav is laid out correctly." into main
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index 895535e..d1725bc 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -406,6 +406,12 @@
             }
         };
         mSeparateWindowParent.recreateControllers();
+        if (BubbleBarController.isBubbleBarEnabled()) {
+            mNavButtonsView.addOnLayoutChangeListener(
+                    (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+                            onLayoutsUpdated()
+            );
+        }
     }
 
     private void initButtons(ViewGroup navContainer, ViewGroup endContainer,
@@ -1180,15 +1186,20 @@
     /** Adjusts navigation buttons layout accordingly to the bubble bar position. */
     @Override
     public void onBubbleBarLocationUpdated(BubbleBarLocation location) {
-        cancelExistingNavBarAnimation();
-        mBubbleBarTargetLocation = location;
+        boolean locationUpdated = location != mBubbleBarTargetLocation;
+        if (locationUpdated) {
+            cancelExistingNavBarAnimation();
+        } else {
+            endExistingAnimation();
+        }
         mNavButtonContainer.setTranslationX(getNavBarTranslationX(location));
-        mNavButtonContainer.setAlpha(1);
+        mBubbleBarTargetLocation = location;
     }
 
     /** Animates navigation buttons accordingly to the bubble bar position. */
     @Override
     public void onBubbleBarLocationAnimated(BubbleBarLocation location) {
+        if (location == mBubbleBarTargetLocation) return;
         cancelExistingNavBarAnimation();
         mBubbleBarTargetLocation = location;
         int finalX = getNavBarTranslationX(location);
@@ -1199,6 +1210,13 @@
         mNavBarLocationAnimator.start();
     }
 
+    private void endExistingAnimation() {
+        if (mNavBarLocationAnimator != null) {
+            mNavBarLocationAnimator.end();
+            mNavBarLocationAnimator = null;
+        }
+    }
+
     private void cancelExistingNavBarAnimation() {
         if (mNavBarLocationAnimator != null) {
             mNavBarLocationAnimator.cancel();
@@ -1240,12 +1258,18 @@
     }
 
     /** Adjusts the navigation buttons layout position according to the bubble bar location. */
-    public void onTaskbarLayoutChanged() {
-        if (mControllers.taskbarViewController.getIconLayoutBounds().isEmpty()) return;
+    public void onLayoutsUpdated() {
+        // no need to do anything if on phone, or if taskbar or navbar views were not placed on
+        // screen.
+        if (mContext.getDeviceProfile().isPhone
+                || mControllers.taskbarViewController.getIconLayoutBounds().isEmpty()
+                || mNavButtonsView.getWidth() == 0) {
+            return;
+        }
         if (enableBubbleBarInPersistentTaskBar()
                 && mControllers.bubbleControllers.isPresent()) {
             if (mBubbleBarTargetLocation == null) {
-                // only set bubble bar location if it was not set before, e.g. at device boot
+                // only set bubble bar location if it was not set before
                 mBubbleBarTargetLocation = mControllers.bubbleControllers.get()
                         .bubbleBarViewController.getBubbleBarLocation();
             }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index a59445b..46d063b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -278,7 +278,10 @@
         // If Bubble bar is present, TaskbarControllers depends on it so build it first.
         Optional<BubbleControllers> bubbleControllersOptional = Optional.empty();
         BubbleBarController.onTaskbarRecreated();
-        if (BubbleBarController.isBubbleBarEnabled() && bubbleBarView != null) {
+        if (BubbleBarController.isBubbleBarEnabled()
+                && !mDeviceProfile.isPhone
+                && bubbleBarView != null
+        ) {
             Optional<BubbleStashedHandleViewController> bubbleHandleController = Optional.empty();
             Optional<BubbleBarSwipeController> bubbleBarSwipeController = Optional.empty();
             if (isTransientTaskbar) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index 5974675..219a24a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -220,11 +220,12 @@
         uiController = newUiController;
         uiController.init(this);
         uiController.updateStateForSysuiFlags(mSharedState.sysuiStateFlags);
-        bubbleControllers.ifPresent(bubbleControllers -> {
+        // if bubble controllers are present take bubble bar location, else set it to null
+        bubbleControllers.ifPresentOrElse(bubbleControllers -> {
             BubbleBarLocation location =
                     bubbleControllers.bubbleBarViewController.getBubbleBarLocation();
             uiController.onBubbleBarLocationUpdated(location);
-        });
+        }, () -> uiController.onBubbleBarLocationUpdated(null));
         // Notify that the ui controller has changed
         navbarButtonsViewController.onUiControllerChanged();
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 8f722f4..8a1d71a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -866,43 +866,49 @@
     }
 
     /** Updates launcher home screen appearance accordingly to the bubble bar location. */
-    public void onBubbleBarLocationChanged(BubbleBarLocation location, boolean animate) {
-        DeviceProfile deviceProfile = mLauncher.getDeviceProfile();
-        if (mBubbleBarLocation == location) return;
+    public void onBubbleBarLocationChanged(@Nullable BubbleBarLocation location, boolean animate) {
         mBubbleBarLocation = location;
+        if (location == null) {
+            // bubble bar is not present, hence no location, resetting the hotseat
+            updateHotseatAndQsbTranslationX(0, animate);
+            mBubbleBarLocation = null;
+            return;
+        }
+        DeviceProfile deviceProfile = mLauncher.getDeviceProfile();
         if (!deviceProfile.shouldAdjustHotseatOnBubblesLocationUpdate(
                 mControllers.taskbarActivityContext)) {
             return;
         }
-        int targetX = 0;
-        if (mBubbleBarLocation != null) {
-            boolean isBubblesOnLeft = location.isOnLeft(isRtl(mLauncher.getResources()));
-            targetX = deviceProfile.getHotseatTranslationXForBubbleBar(/* isNavbarOnRight= */
-                    isBubblesOnLeft);
-        }
+        boolean isBubblesOnLeft = location.isOnLeft(isRtl(mLauncher.getResources()));
+        int targetX = deviceProfile
+                .getHotseatTranslationXForBubbleBar(/* isNavbarOnRight= */ isBubblesOnLeft);
         updateHotseatAndQsbTranslationX(targetX, animate);
     }
 
+    /** Used to translate hotseat and QSB to make room for bubbles. */
     private void updateHotseatAndQsbTranslationX(float targetValue, boolean animate) {
         // cancel existing animation
         if (mHotseatTranslationXAnimation != null) {
             mHotseatTranslationXAnimation.cancel();
+            mHotseatTranslationXAnimation = null;
         }
-        Runnable alignTaskbar = new Runnable() {
+        Runnable postAnimationAction = new Runnable() {
             @Override
             public void run() {
+                mHotseatTranslationXAnimation = null;
                 // We only need to align the task bar when on launcher home screen
                 if (mControllers.taskbarStashController.isOnHome()) {
-                    DeviceProfile dp = mLauncher.getDeviceProfile();
-                    mControllers.taskbarViewController
-                            .setLauncherIconAlignment(/* alignmentRatio = */ 1, dp);
+                    mControllers.taskbarViewController.setLauncherIconAlignment(
+                            /* alignmentRatio = */ 1,
+                            mLauncher.getDeviceProfile()
+                    );
                 }
             }
         };
         Hotseat hotseat = mLauncher.getHotseat();
         AnimatorSet translationXAnimation = new AnimatorSet();
-        MultiProperty iconsTranslationX = hotseat.getIconsTranslationX(
-                Hotseat.ICONS_TRANSLATION_X_NAV_BAR_ALIGNMENT);
+        MultiProperty iconsTranslationX = mLauncher.getHotseat()
+                .getIconsTranslationX(Hotseat.ICONS_TRANSLATION_X_NAV_BAR_ALIGNMENT);
         if (animate) {
             translationXAnimation.playTogether(iconsTranslationX.animateToValue(targetValue));
         } else {
@@ -921,18 +927,17 @@
             }
         }
         if (!animate) {
-            alignTaskbar.run();
+            postAnimationAction.run();
             return;
         }
         mHotseatTranslationXAnimation = translationXAnimation;
         translationXAnimation.setStartDelay(FADE_OUT_ANIM_POSITION_DURATION_MS);
         translationXAnimation.setDuration(FADE_IN_ANIM_ALPHA_DURATION_MS);
         translationXAnimation.setInterpolator(Interpolators.EMPHASIZED);
-        translationXAnimation.addListener(AnimatorListeners.forEndCallback(alignTaskbar));
+        translationXAnimation.addListener(AnimatorListeners.forEndCallback(postAnimationAction));
         translationXAnimation.start();
     }
 
-
     private final class TaskBarRecentsAnimationListener implements
             RecentsAnimationCallbacks.RecentsAnimationListener {
         private final RecentsAnimationCallbacks mCallbacks;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index e522035..21d0cda 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -159,7 +159,9 @@
     private final View.OnLayoutChangeListener mTaskbarViewLayoutChangeListener =
             (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
                 updateTaskbarIconTranslationXForPinning();
-                mControllers.navbarButtonsViewController.onTaskbarLayoutChanged();
+                if (BubbleBarController.isBubbleBarEnabled()) {
+                    mControllers.navbarButtonsViewController.onLayoutsUpdated();
+                }
             };
 
     // Animation to align icons with Launcher, created lazily. This allows the controller to be