Merge "Update placement of the hotseat according to the bubble bar location." into main
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index a64936d..4b43bd2 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -1353,8 +1353,13 @@
? null
: mLauncher.getTaskbarUIController().findMatchingView(launcherView),
true /* hideOriginal */, targetRect, false /* isOpening */);
- isInHotseat = launcherView.getTag() instanceof ItemInfo
- && ((ItemInfo) launcherView.getTag()).isInHotseat();
+ if (launcherView.getTag() instanceof ItemInfo itemInfo) {
+ isInHotseat = itemInfo.isInHotseat();
+ if (isInHotseat) {
+ int dx = mLauncher.getHotseatItemTranslationX(itemInfo);
+ targetRect.offset(dx, 0);
+ }
+ }
} else {
targetRect.set(getDefaultWindowTargetRect());
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 477f90c..10ff9ac 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -50,6 +50,7 @@
import com.android.quickstep.util.TISBindHelper;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import java.io.PrintWriter;
@@ -469,6 +470,18 @@
}
@Override
+ public void onBubbleBarLocationAnimated(BubbleBarLocation location) {
+ mTaskbarLauncherStateController.onBubbleBarLocationChanged(location, /* animate = */ true);
+ mLauncher.setBubbleBarLocation(location);
+ }
+
+ @Override
+ public void onBubbleBarLocationUpdated(BubbleBarLocation location) {
+ mTaskbarLauncherStateController.onBubbleBarLocationChanged(location, /* animate = */ false);
+ mLauncher.setBubbleBarLocation(location);
+ }
+
+ @Override
public void onSwipeToUnstashTaskbar() {
// Once taskbar is unstashed, the user cannot return back to the overlay. We can
// clear it here to set the expected state once the user goes home.
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index 2ac5793..a4a93f7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -201,6 +201,8 @@
private final Rect mFloatingRotationButtonBounds = new Rect();
+ private @Nullable BubbleBarLocation mBubbleBarLocation;
+
// Initialized in init.
private TaskbarControllers mControllers;
private boolean mIsImeRenderingNavButtons;
@@ -1174,6 +1176,7 @@
/** Adjusts navigation buttons layout accordingly to the bubble bar position. */
@Override
public void onBubbleBarLocationUpdated(BubbleBarLocation location) {
+ mBubbleBarLocation = location;
mNavButtonContainer.setTranslationX(getNavBarTranslationX(location));
}
@@ -1181,6 +1184,7 @@
@Override
public void onBubbleBarLocationAnimated(BubbleBarLocation location) {
// TODO(b/346381754) add the teleport animation similarly to the bubble bar
+ mBubbleBarLocation = location;
mNavButtonContainer.setTranslationX(getNavBarTranslationX(location));
}
@@ -1221,9 +1225,12 @@
public void onTaskbarLayoutChange() {
if (com.android.wm.shell.Flags.enableBubbleBarInPersistentTaskBar()
&& mControllers.bubbleControllers.isPresent()) {
- BubbleBarLocation bubblesLocation = mControllers.bubbleControllers.get()
- .bubbleBarViewController.getBubbleBarLocation();
- onBubbleBarLocationUpdated(bubblesLocation);
+ if (mBubbleBarLocation == null) {
+ // only set bubble bar location if it was not set before, e.g. at device boot
+ mBubbleBarLocation = mControllers.bubbleControllers.get()
+ .bubbleBarViewController.getBubbleBarLocation();
+ }
+ onBubbleBarLocationUpdated(mBubbleBarLocation);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index 56fd2bb..5974675 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -26,6 +26,7 @@
import com.android.launcher3.taskbar.bubbles.BubbleControllers;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayController;
import com.android.systemui.shared.rotation.RotationButtonController;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -219,7 +220,11 @@
uiController = newUiController;
uiController.init(this);
uiController.updateStateForSysuiFlags(mSharedState.sysuiStateFlags);
-
+ bubbleControllers.ifPresent(bubbleControllers -> {
+ BubbleBarLocation location =
+ bubbleControllers.bubbleBarViewController.getBubbleBarLocation();
+ uiController.onBubbleBarLocationUpdated(location);
+ });
// 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 876221b..065646a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -19,11 +19,14 @@
import static com.android.launcher3.Hotseat.ALPHA_CHANNEL_TASKBAR_ALIGNMENT;
import static com.android.launcher3.Hotseat.ALPHA_CHANNEL_TASKBAR_STASH;
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
+import static com.android.launcher3.Utilities.isRtl;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_OVERVIEW;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_STASHED_LAUNCHER_STATE;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_FOR_BUBBLES;
import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_HOME;
+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.FlagDebugUtils.appendFlag;
import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_AWAKE;
@@ -42,8 +45,10 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.app.animation.Interpolators;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Hotseat;
import com.android.launcher3.Hotseat.HotseatQsbAlphaId;
import com.android.launcher3.LauncherState;
import com.android.launcher3.QuickstepTransitionManager;
@@ -62,6 +67,7 @@
import com.android.systemui.animation.ViewRootSync;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import java.io.PrintWriter;
import java.util.HashMap;
@@ -151,6 +157,7 @@
private AnimatedFloat mTaskbarAlpha;
private AnimatedFloat mTaskbarCornerRoundness;
private MultiProperty mTaskbarAlphaForHome;
+ private @Nullable Animator mHotseatTranslationXAnimation;
private QuickstepLauncher mLauncher;
private boolean mIsDestroyed = false;
@@ -168,6 +175,8 @@
private boolean mShouldDelayLauncherStateAnim;
+ private @Nullable BubbleBarLocation mBubbleBarLocation;
+
// We skip any view synchronizations during init/destroy.
private boolean mCanSyncViews;
@@ -185,6 +194,8 @@
mIsQsbInline = dp.isQsbInline;
TaskbarLauncherStateController.this.updateIconAlphaForHome(
mTaskbarAlphaForHome.getValue(), ALPHA_CHANNEL_TASKBAR_ALIGNMENT);
+ TaskbarLauncherStateController.this.onBubbleBarLocationChanged(
+ mBubbleBarLocation, /* animate = */ false);
}
};
@@ -833,6 +844,74 @@
}
}
+ /** 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;
+ mBubbleBarLocation = location;
+ if (!deviceProfile.shouldAdjustHotseatOnBubblesLocationUpdate(
+ mControllers.taskbarActivityContext)) {
+ return;
+ }
+ int targetX = 0;
+ if (mBubbleBarLocation != null) {
+ boolean isBubblesOnLeft = location.isOnLeft(isRtl(mLauncher.getResources()));
+ targetX = deviceProfile.getHotseatTranslationXForBubbleBar(/* isNavbarOnRight= */
+ isBubblesOnLeft);
+ }
+ updateHotseatAndQsbTranslationX(targetX, animate);
+ }
+
+ private void updateHotseatAndQsbTranslationX(float targetValue, boolean animate) {
+ // cancel existing animation
+ if (mHotseatTranslationXAnimation != null) {
+ mHotseatTranslationXAnimation.cancel();
+ }
+ Runnable alignTaskbar = new Runnable() {
+ @Override
+ public void run() {
+ // 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);
+ }
+ }
+ };
+ Hotseat hotseat = mLauncher.getHotseat();
+ AnimatorSet translationXAnimation = new AnimatorSet();
+ MultiProperty iconsTranslationX = hotseat.getIconsTranslationX(
+ Hotseat.ICONS_TRANSLATION_X_NAV_BAR_ALIGNMENT);
+ if (animate) {
+ translationXAnimation.playTogether(iconsTranslationX.animateToValue(targetValue));
+ } else {
+ iconsTranslationX.setValue(targetValue);
+ }
+ float qsbTargetX = 0;
+ if (mIsQsbInline) {
+ qsbTargetX = targetValue;
+ }
+ MultiProperty qsbTranslationX = hotseat.getQsbTranslationX();
+ if (qsbTranslationX != null) {
+ if (animate) {
+ translationXAnimation.playTogether(qsbTranslationX.animateToValue(qsbTargetX));
+ } else {
+ qsbTranslationX.setValue(qsbTargetX);
+ }
+ }
+ if (!animate) {
+ alignTaskbar.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.start();
+ }
+
+
private final class TaskBarRecentsAnimationListener implements
RecentsAnimationCallbacks.RecentsAnimationListener {
private final RecentsAnimationCallbacks mCallbacks;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index e39e904..6222e53 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -450,6 +450,11 @@
return hasAnyFlag(FLAG_IN_OVERVIEW);
}
+ /** Returns whether the taskbar is currently on launcher home screen. */
+ public boolean isOnHome() {
+ return !isInOverview() && !isInApp();
+ }
+
/** Returns whether taskbar is hidden for bubbles. */
public boolean isHiddenForBubbles() {
return hasAnyFlag(FLAG_STASHED_FOR_BUBBLES);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 9c8c2a9..b80aaf8 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -36,6 +36,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.popup.SystemShortcut;
+import com.android.launcher3.taskbar.bubbles.BubbleBarController;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.quickstep.OverviewCommandHelper;
@@ -47,6 +48,7 @@
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import java.io.PrintWriter;
import java.util.Collections;
@@ -55,7 +57,7 @@
/**
* Base class for providing different taskbar UI
*/
-public class TaskbarUIController {
+public class TaskbarUIController implements BubbleBarController.BubbleBarLocationListener {
public static final TaskbarUIController DEFAULT = new TaskbarUIController();
// Initialized in init.
@@ -433,6 +435,14 @@
public void stashHotseat(boolean stash) {
}
+ @Override
+ public void onBubbleBarLocationAnimated(BubbleBarLocation location) {
+ }
+
+ @Override
+ public void onBubbleBarLocationUpdated(BubbleBarLocation location) {
+ }
+
/** Un-stash the hotseat instantly */
public void unStashHotseatInstantly() {
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 83527ab..0fa9e60 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -834,6 +834,14 @@
: mPersistentTaskbarDp.taskbarBottomMargin;
int firstRecentTaskIndex = -1;
+ int hotseatNavBarTranslationX = 0;
+ if (mCurrentBubbleBarLocation != null
+ && taskbarDp.shouldAdjustHotseatOnBubblesLocationUpdate(mActivity)) {
+ boolean isBubblesOnLeft = mCurrentBubbleBarLocation.isOnLeft(
+ mTaskbarView.isLayoutRtl());
+ hotseatNavBarTranslationX = taskbarDp
+ .getHotseatTranslationXForBubbleBar(/* isNavbarOnRight = */ isBubblesOnLeft);
+ }
for (int i = 0; i < mTaskbarView.getChildCount(); i++) {
View child = mTaskbarView.getChildAt(i);
boolean isAllAppsButton = child == mTaskbarView.getAllAppsButtonContainer();
@@ -869,16 +877,20 @@
: Interpolators.clampToProgress(LINEAR, 0.72f, 0.84f));
}
}
-
if (child == mTaskbarView.getQsb()) {
boolean isRtl = Utilities.isRtl(child.getResources());
float hotseatIconCenter = isRtl
? launcherDp.widthPx - hotseatPadding.right + borderSpacing
+ launcherDp.hotseatQsbWidth / 2f
: hotseatPadding.left - borderSpacing - launcherDp.hotseatQsbWidth / 2f;
+ if (taskbarDp.isQsbInline) {
+ hotseatIconCenter += hotseatNavBarTranslationX;
+ }
float childCenter = (child.getLeft() + child.getRight()) / 2f;
- childCenter += ((Reorderable) child).getTranslateDelegate().getTranslationX(
- INDEX_TASKBAR_PINNING_ANIM).getValue();
+ if (child instanceof Reorderable reorderableChild) {
+ childCenter += reorderableChild.getTranslateDelegate().getTranslationX(
+ INDEX_TASKBAR_PINNING_ANIM).getValue();
+ }
float halfQsbIconWidthDiff =
(launcherDp.hotseatQsbWidth - taskbarDp.taskbarIconSize) / 2f;
float scale = ((float) taskbarDp.taskbarIconSize)
@@ -887,8 +899,8 @@
float fromX = isRtl ? -halfQsbIconWidthDiff : halfQsbIconWidthDiff;
float toX = hotseatIconCenter - childCenter;
- if (child instanceof Reorderable) {
- MultiTranslateDelegate mtd = ((Reorderable) child).getTranslateDelegate();
+ if (child instanceof Reorderable reorderableChild) {
+ MultiTranslateDelegate mtd = reorderableChild.getTranslateDelegate();
setter.addFloat(mtd.getTranslationX(INDEX_TASKBAR_ALIGNMENT_ANIM),
MULTI_PROPERTY_VALUE, fromX, toX, interpolator);
@@ -935,6 +947,7 @@
+ (hotseatCellSize + borderSpacing) * positionInHotseat
+ hotseatCellSize / 2f;
}
+ hotseatIconCenter += hotseatNavBarTranslationX;
float childCenter = (child.getLeft() + child.getRight()) / 2f;
childCenter += ((Reorderable) child).getTranslateDelegate().getTranslationX(
INDEX_TASKBAR_PINNING_ANIM).getValue();
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
index 6860004..51e09ab 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
@@ -196,7 +196,8 @@
mBubbleBarViewController.setUpdateSelectedBubbleAfterCollapse(
key -> setSelectedBubbleInternal(mBubbles.get(key)));
mBubbleBarViewController.setBoundsChangeListener(this::onBubbleBarBoundsChanged);
-
+ mBubbleBarLocationListener.onBubbleBarLocationUpdated(
+ mBubbleBarViewController.getBubbleBarLocation());
if (sBubbleBarEnabled) {
mSystemUiProxy.setBubblesListener(this);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java
index 8230f42..b5d94bd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java
@@ -22,6 +22,7 @@
import com.android.launcher3.taskbar.TaskbarControllers;
import com.android.launcher3.taskbar.bubbles.BubbleBarViewController.TaskbarViewPropertiesProvider;
+import com.android.launcher3.taskbar.bubbles.stashing.BubbleBarLocationOnDemandListener;
import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.RunnableList;
@@ -79,11 +80,11 @@
* in constructors for now, as some controllers may still be waiting for init().
*/
public void init(TaskbarControllers taskbarControllers) {
- // TODO(b/346381754) add TaskbarLauncherStateController implementation to adjust the hotseat
BubbleBarLocationCompositeListener bubbleBarLocationListeners =
new BubbleBarLocationCompositeListener(
taskbarControllers.navbarButtonsViewController,
- taskbarControllers.taskbarViewController
+ taskbarControllers.taskbarViewController,
+ new BubbleBarLocationOnDemandListener(() -> taskbarControllers.uiController)
);
bubbleBarController.init(this,
bubbleBarLocationListeners,
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleBarLocationOnDemandListener.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleBarLocationOnDemandListener.kt
new file mode 100644
index 0000000..ffe7c44
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleBarLocationOnDemandListener.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.taskbar.bubbles.stashing
+
+import com.android.launcher3.taskbar.bubbles.BubbleBarController.BubbleBarLocationListener
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation
+
+/** On demand implementation of [BubbleBarLocationListener]. */
+class BubbleBarLocationOnDemandListener(
+ private val listenerProvider: () -> BubbleBarLocationListener
+) : BubbleBarLocationListener {
+
+ override fun onBubbleBarLocationAnimated(location: BubbleBarLocation) {
+ listenerProvider().onBubbleBarLocationAnimated(location)
+ }
+
+ override fun onBubbleBarLocationUpdated(location: BubbleBarLocation) {
+ listenerProvider().onBubbleBarLocationUpdated(location)
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 9d9f096..6997f25 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -37,6 +37,7 @@
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
+import static com.android.launcher3.Utilities.isRtl;
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
import static com.android.launcher3.config.FeatureFlags.enableSplitContextually;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
@@ -63,6 +64,8 @@
import static com.android.quickstep.util.AnimUtils.completeRunnableListCallback;
import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
+import static com.android.wm.shell.Flags.enableBubbleAnything;
+import static com.android.wm.shell.Flags.enableBubbleBarInPersistentTaskBar;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_50_50;
import android.animation.Animator;
@@ -196,6 +199,7 @@
import com.android.systemui.unfold.dagger.UnfoldMain;
import com.android.systemui.unfold.progress.RemoteUnfoldTransitionReceiver;
import com.android.systemui.unfold.updates.RotationChangeProvider;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import java.io.FileDescriptor;
@@ -237,6 +241,7 @@
private SplitSelectStateController mSplitSelectStateController;
private SplitWithKeyboardShortcutController mSplitWithKeyboardShortcutController;
private SplitToWorkspaceController mSplitToWorkspaceController;
+ private BubbleBarLocation mBubbleBarLocation;
/**
* If Launcher restarted while in the middle of an Overview split select, it needs this data to
@@ -461,7 +466,7 @@
if (Flags.enablePrivateSpace()) {
shortcuts.add(UNINSTALL_APP);
}
- if (com.android.wm.shell.Flags.enableBubbleAnything()) {
+ if (enableBubbleAnything()) {
shortcuts.add(BUBBLE_SHORTCUT);
}
return shortcuts.stream();
@@ -1092,6 +1097,29 @@
return mTaskbarUIController;
}
+ /** Provides the translation X for the hotseat item. */
+ public int getHotseatItemTranslationX(ItemInfo itemInfo) {
+ int translationX = 0;
+ if (isBubbleBarEnabled()
+ && enableBubbleBarInPersistentTaskBar()
+ && mBubbleBarLocation != null) {
+ boolean isBubblesOnLeft = mBubbleBarLocation.isOnLeft(isRtl(getResources()));
+ translationX += mDeviceProfile
+ .getHotseatTranslationXForBubbleBar(/* isNavbarOnRight = */ isBubblesOnLeft);
+ }
+ if (isBubbleBarEnabled() && hasBubbles()) {
+ // TODO(368379159) : create a class to reuse computation logic
+ float adjustedBorderSpace =
+ mDeviceProfile.getHotseatAdjustedBorderSpaceForBubbleBar(this);
+ if (Float.compare(adjustedBorderSpace, 0f) != 0) {
+ float borderSpaceDelta = adjustedBorderSpace - mDeviceProfile.hotseatBorderSpace;
+ translationX +=
+ (int) (mDeviceProfile.iconSizePx + itemInfo.cellX * borderSpaceDelta);
+ }
+ }
+ return translationX;
+ }
+
public SplitToWorkspaceController getSplitToWorkspaceController() {
return mSplitToWorkspaceController;
}
@@ -1397,6 +1425,11 @@
SystemUiProxy.INSTANCE.get(this).showAppBubble(intent);
}
+ /** Sets the location of the bubble bar */
+ public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
+ mBubbleBarLocation = bubbleBarLocation;
+ }
+
private static final class LauncherTaskViewController extends
TaskViewTouchController<QuickstepLauncher> {
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 483f5f8..abecc58 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -31,6 +31,8 @@
import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE;
import static com.android.launcher3.testing.shared.ResourceUtils.pxFromDp;
import static com.android.launcher3.testing.shared.ResourceUtils.roundPxValueFromFloat;
+import static com.android.wm.shell.Flags.enableBubbleBar;
+import static com.android.wm.shell.Flags.enableBubbleBarInPersistentTaskBar;
import static com.android.wm.shell.Flags.enableTinyTaskbar;
import android.annotation.SuppressLint;
@@ -64,8 +66,10 @@
import com.android.launcher3.responsive.ResponsiveSpec.DimensionType;
import com.android.launcher3.responsive.ResponsiveSpecsProvider;
import com.android.launcher3.util.CellContentDimensions;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.IconSizeSteps;
+import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.ResourceHelper;
import com.android.launcher3.util.WindowBounds;
import com.android.launcher3.util.window.WindowManagerProxy;
@@ -219,6 +223,8 @@
public int hotseatBarBottomSpacePx;
public int hotseatBarEndOffset;
public int hotseatQsbSpace;
+ public int inlineNavButtonsEndSpacingPx;
+ public int navButtonsLayoutWidthPx;
public int springLoadedHotseatBarTopMarginPx;
// These 2 values are only used for isVerticalBar
// Padding between edge of screen and hotseat
@@ -233,7 +239,6 @@
private final int mMinHotseatIconSpacePx;
private final int mMinHotseatQsbWidthPx;
private final int mMaxHotseatIconSpacePx;
- public final int inlineNavButtonsEndSpacingPx;
// Space required for the bubble bar between the hotseat and the edge of the screen. If there's
// not enough space, the hotseat will adjust itself for the bubble bar.
private final int mBubbleBarSpaceThresholdPx;
@@ -692,17 +697,12 @@
if (areNavButtonsInline && !isPhone) {
inlineNavButtonsEndSpacingPx =
res.getDimensionPixelSize(inv.inlineNavButtonsEndSpacing);
- /*
- * 3 nav buttons +
- * Spacing between nav buttons +
- * Space at the end for contextual buttons
- */
- hotseatBarEndOffset = 3 * res.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size)
- + 2 * res.getDimensionPixelSize(R.dimen.taskbar_button_space_inbetween)
- + inlineNavButtonsEndSpacingPx;
- } else {
- inlineNavButtonsEndSpacingPx = 0;
- hotseatBarEndOffset = 0;
+ /* 3 nav buttons + Spacing between nav buttons */
+ navButtonsLayoutWidthPx = 3 * res.getDimensionPixelSize(
+ R.dimen.taskbar_nav_buttons_size)
+ + 2 * res.getDimensionPixelSize(R.dimen.taskbar_button_space_inbetween);
+ /* nav buttons layout width + Space at the end for contextual buttons */
+ hotseatBarEndOffset = navButtonsLayoutWidthPx + inlineNavButtonsEndSpacingPx;
}
mBubbleBarSpaceThresholdPx =
@@ -2328,6 +2328,25 @@
}
/**
+ * Returns whether Taskbar and Hotseat should adjust horizontally on bubble bar location update.
+ */
+ public boolean shouldAdjustHotseatOnBubblesLocationUpdate(Context context) {
+ return enableBubbleBar()
+ && enableBubbleBarInPersistentTaskBar()
+ && DisplayController.getNavigationMode(context)
+ == NavigationMode.THREE_BUTTONS;
+ }
+
+ /** Returns hotseat translation X for the bubble bar position. */
+ public int getHotseatTranslationXForBubbleBar(boolean isNavbarOnRight) {
+ if (isNavbarOnRight) {
+ return 0;
+ } else {
+ return navButtonsLayoutWidthPx;
+ }
+ }
+
+ /**
* Callback when a component changes the DeviceProfile associated with it, as a result of
* configuration change
*/
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 024dde4..ae4c122 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -34,8 +34,10 @@
import android.widget.FrameLayout;
import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
import com.android.launcher3.util.HorizontalInsettableView;
+import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
import com.android.launcher3.util.MultiTranslateDelegate;
import com.android.launcher3.util.MultiValueAlpha;
@@ -61,6 +63,14 @@
public @interface HotseatQsbAlphaId {
}
+ public static final int ICONS_TRANSLATION_X_NAV_BAR_ALIGNMENT = 0;
+ public static final int ICONS_TRANSLATION_X_CHANNELS_COUNT = 1;
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @IntDef({ICONS_TRANSLATION_X_NAV_BAR_ALIGNMENT})
+ public @interface IconsTranslationX {
+ }
+
// Ratio of empty space, qsb should take up to appear visually centered.
public static final float QSB_CENTER_FACTOR = .325f;
private static final int BUBBLE_BAR_ADJUSTMENT_ANIMATION_DURATION_MS = 250;
@@ -72,6 +82,10 @@
private final MultiValueAlpha mIconsAlphaChannels;
private final MultiValueAlpha mQsbAlphaChannels;
+ private @Nullable MultiProperty mQsbTranslationX;
+
+ private final MultiPropertyFactory mIconsTranslationXFactory;
+
private final View mQsb;
public Hotseat(Context context) {
@@ -88,9 +102,26 @@
addView(mQsb);
mIconsAlphaChannels = new MultiValueAlpha(getShortcutsAndWidgets(),
ALPHA_CHANNEL_CHANNELS_COUNT);
+ if (mQsb instanceof Reorderable qsbReorderable) {
+ mQsbTranslationX = qsbReorderable.getTranslateDelegate()
+ .getTranslationX(MultiTranslateDelegate.INDEX_NAV_BAR_ANIM);
+ }
+ mIconsTranslationXFactory = new MultiPropertyFactory<>(getShortcutsAndWidgets(),
+ VIEW_TRANSLATE_X, ICONS_TRANSLATION_X_CHANNELS_COUNT, Float::sum);
mQsbAlphaChannels = new MultiValueAlpha(mQsb, ALPHA_CHANNEL_CHANNELS_COUNT);
}
+ /** Provides translation X for hotseat icons for the channel. */
+ public MultiProperty getIconsTranslationX(@IconsTranslationX int channelId) {
+ return mIconsTranslationXFactory.get(channelId);
+ }
+
+ /** Provides translation X for hotseat Qsb. */
+ @Nullable
+ public MultiProperty getQsbTranslationX() {
+ return mQsbTranslationX;
+ }
+
/**
* Returns orientation specific cell X given invariant order in the hotseat
*/