Merge "Remove BubbleBarViewAnimatorTest from deviceless suite." into main
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 517bd6d..1bce9b3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -59,6 +59,7 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.SHOW_WORK_APPS" />
+ <action android:name="android.intent.action.ALL_APPS" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
diff --git a/go/AndroidManifest-launcher.xml b/go/AndroidManifest-launcher.xml
index 2223036..bef7180 100644
--- a/go/AndroidManifest-launcher.xml
+++ b/go/AndroidManifest-launcher.xml
@@ -57,6 +57,7 @@
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
+ <action android:name="android.intent.action.ALL_APPS" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
diff --git a/quickstep/AndroidManifest-launcher.xml b/quickstep/AndroidManifest-launcher.xml
index 80d8154..d6aa886 100644
--- a/quickstep/AndroidManifest-launcher.xml
+++ b/quickstep/AndroidManifest-launcher.xml
@@ -57,6 +57,7 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.SHOW_WORK_APPS" />
+ <action android:name="android.intent.action.ALL_APPS" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index e9b4956..66887d0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -696,8 +696,7 @@
*/
public WindowManager.LayoutParams createDefaultWindowLayoutParams(int type, String title) {
int windowFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_SLIPPERY
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
+ | WindowManager.LayoutParams.FLAG_SLIPPERY;
boolean watchOutside = isTransientTaskbar() || isThreeButtonNav();
if (watchOutside && !isRunningInTestHarness()) {
windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java
index b7000db..76489e0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java
@@ -19,6 +19,7 @@
import static android.view.MotionEvent.ACTION_HOVER_EXIT;
import static android.view.View.ALPHA;
+import static com.android.launcher3.AbstractFloatingView.TYPE_ACTION_POPUP;
import static com.android.launcher3.AbstractFloatingView.TYPE_FOLDER;
import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS;
@@ -98,20 +99,18 @@
@Override
public boolean onHover(View v, MotionEvent event) {
- boolean isFolderOpen = AbstractFloatingView.hasOpenView(mActivity, TYPE_FOLDER);
// If hover leaves a taskbar icon animate the tooltip closed.
if (event.getAction() == ACTION_HOVER_EXIT) {
mHoverToolTipView.close(/* animate= */ false);
mActivity.setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS, false);
- } else if (!isFolderOpen && event.getAction() == ACTION_HOVER_ENTER) {
- // Do not reveal if any floating views such as folders or edu pop-ups are open.
- revealHoverToolTip();
+ } else if (event.getAction() == ACTION_HOVER_ENTER) {
+ maybeRevealHoverToolTip();
mActivity.setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS, true);
}
return false;
}
- private void revealHoverToolTip() {
+ private void maybeRevealHoverToolTip() {
if (mHoverView == null || mToolTipText == null) {
return;
}
@@ -122,6 +121,12 @@
if (mHoverView instanceof FolderIcon && !((FolderIcon) mHoverView).getIconVisible()) {
return;
}
+ // Do not reveal if floating views such as folders or app pop-ups are open,
+ // as these views will overlap and not look great.
+ if (AbstractFloatingView.hasOpenView(mActivity, TYPE_FOLDER | TYPE_ACTION_POPUP)) {
+ return;
+ }
+
Rect iconViewBounds = Utilities.getViewBounds(mHoverView);
mHoverToolTipView.showAtLocation(mToolTipText, iconViewBounds.centerX(),
mTaskbarView.getTop() - mYOffset, /* shouldAutoClose= */ false);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
index 1a6cd60..7f240bd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
@@ -83,7 +83,7 @@
// Initialized in init.
private TaskbarControllers mControllers;
private boolean mAllowInitialSplitSelection;
- private AppInfo[] mAppInfosList;
+ private AppInfo[] mAppInfosList = AppInfo.EMPTY_ARRAY;
// Saves the ItemInfos in the hotseat without the predicted items.
private SparseArray<ItemInfo> mHotseatInfosList;
private ManageWindowsTaskbarShortcut<BaseTaskbarContext> mManageWindowsTaskbarShortcut;
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
index 675d55b..de20f77 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
@@ -200,7 +200,7 @@
private LayoutParams createLayoutParams() {
LayoutParams layoutParams = new LayoutParams(
TYPE_APPLICATION_OVERLAY,
- LayoutParams.FLAG_SPLIT_TOUCH,
+ /* flags = */ 0,
PixelFormat.TRANSLUCENT);
layoutParams.setTitle(WINDOW_TITLE);
layoutParams.gravity = Gravity.BOTTOM;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
index 9970a7d..c7eedb0 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
@@ -30,7 +30,6 @@
import androidx.annotation.AnyThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.SafeCloseable;
@@ -167,7 +166,7 @@
};
QuickstepWidgetHolderListener holderListener = getHolderListener(appWidgetId);
holderListener.addHolder(handler);
- return () -> holderListener.mListeningHolders.remove(handler);
+ return () -> holderListener.removeHolder(handler);
}
/**
@@ -211,7 +210,7 @@
public void clearViews() {
mViews.clear();
for (int i = sListeners.size() - 1; i >= 0; i--) {
- sListeners.valueAt(i).mListeningHolders.remove(mUpdateHandler);
+ sListeners.valueAt(i).removeHolder(mUpdateHandler);
}
}
@@ -238,13 +237,15 @@
mWidgetId = widgetId;
}
- @UiThread
- @Nullable
public RemoteViews addHolder(@NonNull UpdateHandler holder) {
- mListeningHolders.add(holder);
+ MAIN_EXECUTOR.execute(() -> mListeningHolders.add(holder));
return mRemoteViews;
}
+ public void removeHolder(@NonNull UpdateHandler holder) {
+ MAIN_EXECUTOR.execute(() -> mListeningHolders.remove(holder));
+ }
+
@Override
@AnyThread
public void onUpdateProviderInfo(@Nullable AppWidgetProviderInfo info) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewDismissTouchController.kt b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewDismissTouchController.kt
index 454a307..76eb138 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewDismissTouchController.kt
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewDismissTouchController.kt
@@ -63,6 +63,7 @@
private var hasDismissThresholdHapticRun = false
private var initialDisplacement: Float = 0f
private var recentsScaleAnimation: SpringAnimation? = null
+ private var isBlockedDuringDismissal = false
private fun canInterceptTouch(ev: MotionEvent): Boolean =
when {
@@ -137,6 +138,7 @@
}
override fun onDragStart(start: Boolean, startDisplacement: Float) {
+ if (isBlockedDuringDismissal) return
val taskBeingDragged = taskBeingDragged ?: return
initialDisplacement =
@@ -149,6 +151,7 @@
}
override fun onDrag(displacement: Float): Boolean {
+ if (isBlockedDuringDismissal) return true
val taskBeingDragged = taskBeingDragged ?: return false
val currentDisplacement = displacement + initialDisplacement
val boundedDisplacement =
@@ -204,6 +207,7 @@
}
override fun onDragEnd(velocity: Float) {
+ if (isBlockedDuringDismissal) return
val taskBeingDragged = taskBeingDragged ?: return
val currentDisplacement =
@@ -234,6 +238,7 @@
if (isDismissing) (dismissLength * verticalFactor).toFloat() else 0f
)
}
+ isBlockedDuringDismissal = true
recentsScaleAnimation =
recentsView.animateRecentsScale(RECENTS_SCALE_DEFAULT).addEndListener { _, _, _, _ ->
recentsScaleAnimation = null
@@ -246,6 +251,7 @@
taskBeingDragged?.translationZ = 0f
taskBeingDragged = null
springAnimation = null
+ isBlockedDuringDismissal = false
}
private fun getRecentsScale(dismissFraction: Float): Float {
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 4f00381..cf0a3d5 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -59,6 +59,7 @@
import java.io.PrintWriter;
import java.util.HashMap;
+import java.util.Locale;
public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener {
public static final boolean SHELL_TRANSITIONS_ROTATION =
@@ -132,6 +133,17 @@
public RecentsAnimationCallbacks startRecentsAnimation(@NonNull GestureState gestureState,
Intent intent, RecentsAnimationCallbacks.RecentsAnimationListener listener) {
ActiveGestureProtoLogProxy.logStartRecentsAnimation();
+ // Check displayId
+ if (mDisplayId != gestureState.getDisplayId()) {
+ String msg = String.format(Locale.ENGLISH,
+ "Constructor displayId %d does not equal gestureState display id %d",
+ mDisplayId, gestureState.getDisplayId());
+ if (FeatureFlags.IS_STUDIO_BUILD) {
+ throw new IllegalArgumentException(msg);
+ } else {
+ Log.e("TaskAnimationManager", msg, new Exception());
+ }
+ }
// Notify if recents animation is still running
if (mController != null) {
String msg = "New recents animation started before old animation completed";
@@ -239,11 +251,11 @@
RemoteAnimationTarget appearedTaskTarget = appearedTaskTargets[0];
BaseContainerInterface containerInterface =
mLastGestureState.getContainerInterface();
-
for (RemoteAnimationTarget compat : appearedTaskTargets) {
if (compat.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME
&& containerInterface.getCreatedContainer() instanceof RecentsActivity
- && DisplayController.getNavigationMode(mCtx) != NO_BUTTON) {
+ && DisplayController.INSTANCE.get(mCtx).getInfoForDisplay(
+ mDisplayId).getNavigationMode() != NO_BUTTON) {
// The only time we get onTasksAppeared() in button navigation with a
// 3p launcher is if the user goes to overview first, and in this case we
// can immediately finish the transition
diff --git a/quickstep/src/com/android/quickstep/views/IconAppChipView.kt b/quickstep/src/com/android/quickstep/views/IconAppChipView.kt
index 7683a15..46ed29b 100644
--- a/quickstep/src/com/android/quickstep/views/IconAppChipView.kt
+++ b/quickstep/src/com/android/quickstep/views/IconAppChipView.kt
@@ -122,7 +122,7 @@
field = max(value, minMaxWidth)
}
- var isExpanded: Boolean = false
+ var status: AppChipStatus = AppChipStatus.Collapsed
private set
override fun onFinishInflate() {
@@ -358,8 +358,8 @@
ObjectAnimator.ofFloat(iconArrowView, TRANSLATION_X, arrowTranslationWithRtl),
ObjectAnimator.ofFloat(iconArrowView, SCALE_Y, -1f),
)
- animator!!.setDuration(MENU_BACKGROUND_REVEAL_DURATION.toLong())
- isExpanded = true
+ animator!!.duration = MENU_BACKGROUND_REVEAL_DURATION.toLong()
+ status = AppChipStatus.Expanded
} else {
// Clip expanded text with reveal animation so it doesn't go beyond the edge of the menu
val expandedTextClipAnim =
@@ -393,8 +393,8 @@
ObjectAnimator.ofFloat(iconArrowView, TRANSLATION_X, 0f),
ObjectAnimator.ofFloat(iconArrowView, SCALE_Y, 1f),
)
- animator!!.setDuration(MENU_BACKGROUND_HIDE_DURATION.toLong())
- isExpanded = false
+ animator!!.duration = MENU_BACKGROUND_HIDE_DURATION.toLong()
+ status = AppChipStatus.Collapsed
}
if (!animated) animator!!.duration = 0
@@ -434,6 +434,11 @@
override fun asView(): View = this
+ enum class AppChipStatus {
+ Expanded,
+ Collapsed,
+ }
+
private companion object {
private val SUM_AGGREGATOR = FloatBiFunction { a: Float, b: Float -> a + b }
diff --git a/quickstep/src/com/android/quickstep/views/RecentsDismissUtils.kt b/quickstep/src/com/android/quickstep/views/RecentsDismissUtils.kt
index d39b528..db18394 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsDismissUtils.kt
+++ b/quickstep/src/com/android/quickstep/views/RecentsDismissUtils.kt
@@ -82,6 +82,7 @@
runTaskGridReflowSpringAnimation(
draggedTaskView,
getDismissedTaskGapForReflow(draggedTaskView),
+ onEndRunnable,
)
} else {
recentsView.dismissTaskView(
@@ -89,11 +90,12 @@
/* animateTaskView = */ false,
/* removeTask = */ true,
)
+ onEndRunnable()
}
} else {
recentsView.onDismissAnimationEnds()
+ onEndRunnable()
}
- onEndRunnable()
}
if (!isDismissing) {
addNeighborSettlingSpringAnimations(
@@ -295,7 +297,7 @@
val maxDismissSettlingVelocity =
recentsView.pagedOrientationHandler.getSecondaryDimension(recentsView)
MSDLPlayerWrapper.INSTANCE.get(recentsView.context)
- .playToken(
+ ?.playToken(
MSDLToken.CANCEL,
InteractionProperties.DynamicVibrationScale(
boundToRange(abs(velocity) / maxDismissSettlingVelocity, 0f, 1f),
@@ -339,6 +341,7 @@
private fun runTaskGridReflowSpringAnimation(
dismissedTaskView: TaskView,
dismissedTaskGap: Float,
+ onEndRunnable: () -> Unit,
) {
// Empty spring animation exists for conditional start, and to drive neighboring springs.
val springAnimationDriver =
@@ -427,12 +430,17 @@
driverProgressThreshold = dismissedTaskGap,
isSpringDirectionVertical = false,
)
+ } else {
+ springAnimationDriver.addEndListener { _, _, _, _ ->
+ // Play the same haptic as when neighbors spring into place.
+ MSDLPlayerWrapper.INSTANCE.get(recentsView.context)?.playToken(MSDLToken.CANCEL)
+ }
}
// Start animations and remove the dismissed task at the end, dismiss immediately if no
// neighboring tasks exist.
val runGridEndAnimationAndRelayout = {
- recentsView.expressiveDismissTaskView(dismissedTaskView)
+ recentsView.expressiveDismissTaskView(dismissedTaskView, onEndRunnable)
}
springAnimationDriver?.apply {
addEndListener { _, _, _, _ -> runGridEndAnimationAndRelayout() }
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 37c75cd..4feeb95 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -3367,8 +3367,8 @@
int snappedPage = isKeyboardTaskFocusPending() ? mKeyboardTaskFocusIndex : getNextPage();
TaskView snappedTaskView = getTaskViewAt(snappedPage);
TaskView homeTaskView = getHomeTaskView();
- TaskView expectedCurrentTaskView = mUtils.getExpectedCurrentTask(getFocusedTaskView(),
- getRunningTaskView());
+ TaskView expectedCurrentTaskView = mUtils.getExpectedCurrentTask(getRunningTaskView(),
+ getFocusedTaskView());
TaskView nextFocusedTaskView = null;
// Don't clear the top row, if the user has dismissed a task, to maintain the task order.
@@ -3943,7 +3943,7 @@
newClearAllShortTotalWidthTranslation = expectedFirstTaskStart - firstTaskStart;
}
}
- if (lastGridTaskView != null && (lastGridTaskView.isVisibleToUser() || (
+ if (lastGridTaskView != null && (isTaskViewVisible(lastGridTaskView) || (
isExpressiveDismiss && lastGridTaskView == dismissedTaskView))) {
// After dismissal, animate translation of the remaining tasks to fill any gap left
// between the end of the grid and the clear all button. Only animate if the clear
@@ -4740,11 +4740,12 @@
runDismissAnimation(pa);
}
- protected void expressiveDismissTaskView(TaskView taskView) {
+ protected void expressiveDismissTaskView(TaskView taskView, Function0<Unit> onEndRunnable) {
PendingAnimation pa = new PendingAnimation(DISMISS_TASK_DURATION);
createTaskDismissAnimation(pa, taskView, false /* animateTaskView */, true /* removeTask */,
DISMISS_TASK_DURATION, false /* dismissingForSplitSelection*/,
true /* isExpressiveDismiss */);
+ pa.addEndListener((success) -> onEndRunnable.invoke());
runDismissAnimation(pa);
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.kt b/quickstep/src/com/android/quickstep/views/TaskMenuView.kt
index 696f934..4d4ce4e 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.kt
@@ -428,9 +428,7 @@
var additionalTranslationX = 0f
if (
- recentsViewContainer.deviceProfile.isLandscape &&
- taskContainer.stagePosition ==
- SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT
+ taskContainer.stagePosition == SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT
) {
// Animate menu and icon when split task would display off the side of the screen.
additionalTranslationX =
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt
index 3835e48..e6ef708 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskView.kt
@@ -99,6 +99,7 @@
import com.android.quickstep.util.TaskRemovedDuringLaunchListener
import com.android.quickstep.util.displayId
import com.android.quickstep.util.isExternalDisplay
+import com.android.quickstep.views.IconAppChipView.AppChipStatus
import com.android.quickstep.views.RecentsView.UNBOUND_TASK_VIEW_ID
import com.android.systemui.shared.recents.model.Task
import com.android.systemui.shared.recents.model.ThumbnailData
@@ -1551,7 +1552,7 @@
recentsView.setTaskBorderEnabled(false)
}
return if (enableOverviewIconMenu() && menuContainer.iconView is IconAppChipView) {
- if (menuContainer.iconView.isExpanded) {
+ if (menuContainer.iconView.status == AppChipStatus.Expanded) {
closeTaskMenu()
} else {
menuContainer.iconView.revealAnim(/* isRevealing= */ true)
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.kt
new file mode 100644
index 0000000..d2b9fcf
--- /dev/null
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.kt
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2025 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
+
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_HOVER_ENTER
+import android.view.MotionEvent.ACTION_HOVER_EXIT
+import com.android.launcher3.AbstractFloatingView
+import com.android.launcher3.BubbleTextView
+import com.android.launcher3.R
+import com.android.launcher3.apppairs.AppPairIcon
+import com.android.launcher3.folder.FolderIcon
+import com.android.launcher3.model.data.WorkspaceItemInfo
+import com.android.launcher3.taskbar.TaskbarControllerTestUtil.runOnMainSync
+import com.android.launcher3.taskbar.TaskbarViewTestUtil.createHotseatAppPairsItem
+import com.android.launcher3.taskbar.TaskbarViewTestUtil.createHotseatFolderItem
+import com.android.launcher3.taskbar.TaskbarViewTestUtil.createHotseatWorkspaceItem
+import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule
+import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.InjectController
+import com.android.launcher3.taskbar.rules.TaskbarWindowSandboxContext
+import com.android.launcher3.util.LauncherMultivalentJUnit
+import com.android.launcher3.util.LauncherMultivalentJUnit.EmulatedDevices
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(LauncherMultivalentJUnit::class)
+@EmulatedDevices(["pixelFoldable2023", "pixelTablet2023"])
+class TaskbarHoverToolTipControllerTest {
+
+ @get:Rule(order = 0) val context = TaskbarWindowSandboxContext.create()
+ @get:Rule(order = 1) val taskbarUnitTestRule = TaskbarUnitTestRule(this, context)
+
+ @InjectController lateinit var autohideSuspendController: TaskbarAutohideSuspendController
+ @InjectController lateinit var popupController: TaskbarPopupController
+
+ private val taskbarContext: TaskbarActivityContext by taskbarUnitTestRule::activityContext
+
+ private lateinit var taskbarView: TaskbarView
+ private lateinit var iconView: BubbleTextView
+ private lateinit var appPairIcon: AppPairIcon
+ private lateinit var folderIcon: FolderIcon
+
+ private val isHoverToolTipOpen: Boolean
+ get() {
+ // TaskbarHoverToolTip uses ArrowTipView which is type TYPE_ON_BOARD_POPUP.
+ return AbstractFloatingView.hasOpenView(
+ taskbarContext,
+ AbstractFloatingView.TYPE_ON_BOARD_POPUP,
+ )
+ }
+
+ @Before
+ fun setup() {
+ runOnMainSync { taskbarView = taskbarContext.dragLayer.findViewById(R.id.taskbar_view) }
+
+ val hotseatItems =
+ arrayOf(
+ createHotseatWorkspaceItem(),
+ createHotseatAppPairsItem(),
+ createHotseatFolderItem(),
+ )
+ runOnMainSync {
+ taskbarView.updateItems(hotseatItems, emptyList())
+ iconView =
+ taskbarView.iconViews.filterIsInstance<BubbleTextView>().first {
+ it.tag is WorkspaceItemInfo
+ }
+ appPairIcon = taskbarView.iconViews.filterIsInstance<AppPairIcon>().first()
+ folderIcon = taskbarView.iconViews.filterIsInstance<FolderIcon>().first()
+ }
+ }
+
+ @Test
+ fun onHover_hoverEnterIcon_revealToolTip_hoverExitIcon_closeToolTip() {
+ runOnMainSync { iconView.dispatchGenericMotionEvent(HOVER_ENTER) }
+ assertThat(isHoverToolTipOpen).isTrue()
+ assertThat(autohideSuspendController.isTransientTaskbarStashingSuspended).isTrue()
+ runOnMainSync { iconView.dispatchGenericMotionEvent(HOVER_EXIT) }
+ assertThat(isHoverToolTipOpen).isFalse()
+ assertThat(autohideSuspendController.isTransientTaskbarStashingSuspended).isFalse()
+ }
+
+ @Test
+ fun onHover_hoverEnterFolderIcon_revealToolTip_hoverExitFolderIcon_closeToolTip() {
+ runOnMainSync { folderIcon.dispatchGenericMotionEvent(HOVER_ENTER) }
+ assertThat(isHoverToolTipOpen).isTrue()
+ assertThat(autohideSuspendController.isTransientTaskbarStashingSuspended).isTrue()
+ runOnMainSync { folderIcon.dispatchGenericMotionEvent(HOVER_EXIT) }
+ assertThat(isHoverToolTipOpen).isFalse()
+ assertThat(autohideSuspendController.isTransientTaskbarStashingSuspended).isFalse()
+ }
+
+ @Test
+ fun onHover_hoverEnterAppPair_revealToolTip_hoverExitAppPair_closeToolTip() {
+ runOnMainSync { appPairIcon.dispatchGenericMotionEvent(HOVER_ENTER) }
+ assertThat(isHoverToolTipOpen).isTrue()
+ assertThat(autohideSuspendController.isTransientTaskbarStashingSuspended).isTrue()
+ runOnMainSync { appPairIcon.dispatchGenericMotionEvent(HOVER_EXIT) }
+ assertThat(isHoverToolTipOpen).isFalse()
+ assertThat(autohideSuspendController.isTransientTaskbarStashingSuspended).isFalse()
+ }
+
+ @Test
+ fun onHover_hoverEnterIconAlignedWithHotseat_noToolTip() {
+ taskbarContext.setUIController(
+ object : TaskbarUIController() {
+ override fun isIconAlignedWithHotseat(): Boolean = true
+ }
+ )
+
+ runOnMainSync { iconView.dispatchGenericMotionEvent(HOVER_ENTER) }
+ assertThat(isHoverToolTipOpen).isFalse()
+ }
+
+ @Test
+ fun onHover_hoverEnterFolderOpen_noToolTip() {
+ runOnMainSync {
+ folderIcon.folder.animateOpen()
+ iconView.dispatchGenericMotionEvent(HOVER_ENTER)
+ }
+ assertThat(isHoverToolTipOpen).isFalse()
+ }
+
+ @Test
+ fun onHover_hoverEnterPopupOpen_noToolTip() {
+ runOnMainSync {
+ popupController.showForIcon(iconView)
+ iconView.dispatchGenericMotionEvent(HOVER_ENTER)
+ }
+ assertThat(isHoverToolTipOpen).isFalse()
+ }
+
+ companion object {
+ private val HOVER_EXIT = MotionEvent.obtain(0, 0, ACTION_HOVER_EXIT, 0f, 0f, 0)
+ private val HOVER_ENTER = MotionEvent.obtain(0, 0, ACTION_HOVER_ENTER, 0f, 0f, 0)
+ }
+}
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarViewTestUtil.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarViewTestUtil.kt
index e52aacf..92abbba 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarViewTestUtil.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarViewTestUtil.kt
@@ -18,8 +18,13 @@
import android.content.ComponentName
import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.Bitmap.createBitmap
import android.os.Process
+import com.android.launcher3.icons.BitmapInfo
import com.android.launcher3.model.data.AppInfo
+import com.android.launcher3.model.data.AppPairInfo
+import com.android.launcher3.model.data.FolderInfo
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.WorkspaceItemInfo
import com.android.launcher3.taskbar.TaskbarIconType.ALL_APPS
@@ -53,7 +58,27 @@
return WorkspaceItemInfo(
AppInfo(TEST_COMPONENT, "Test App $id", Process.myUserHandle(), Intent())
)
- .apply { this.id = id }
+ .apply {
+ this.id = id
+ // Create a placeholder icon so that the test doesn't try to load a high-res icon.
+ this.bitmap = BitmapInfo.fromBitmap(createBitmap(1, 1, Bitmap.Config.ALPHA_8))
+ }
+ }
+
+ fun createHotseatAppPairsItem(): AppPairInfo {
+ return AppPairInfo().apply {
+ add(createHotseatWorkspaceItem(1))
+ add(createHotseatWorkspaceItem(2))
+ }
+ }
+
+ fun createHotseatFolderItem(): FolderInfo {
+ return FolderInfo().apply {
+ title = "Test Folder"
+ add(createHotseatWorkspaceItem(1))
+ add(createHotseatWorkspaceItem(2))
+ add(createHotseatWorkspaceItem(3))
+ }
}
/** Creates a list of fake recent tasks. */
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarUnitTestRule.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarUnitTestRule.kt
index 2dacf69..19c8824 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarUnitTestRule.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarUnitTestRule.kt
@@ -28,6 +28,7 @@
import com.android.launcher3.taskbar.TaskbarControllers
import com.android.launcher3.taskbar.TaskbarManager
import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarNavButtonCallbacks
+import com.android.launcher3.taskbar.TaskbarUIController
import com.android.launcher3.taskbar.bubbles.BubbleControllers
import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.InjectController
import com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR
@@ -117,6 +118,8 @@
super.recreateTaskbars()
if (currentActivityContext != null) {
injectControllers()
+ // TODO(b/346394875): we should test a non-default uiController.
+ activityContext.setUIController(TaskbarUIController.DEFAULT)
controllerInjectionCallback.invoke()
}
}
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java
deleted file mode 100644
index 3f7c85c..0000000
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2023 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;
-
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
-import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.Display;
-import android.view.MotionEvent;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.apppairs.AppPairIcon;
-import com.android.launcher3.folder.Folder;
-import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.model.data.FolderInfo;
-import com.android.launcher3.util.ActivityContextWrapper;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.stubbing.Answer;
-
-/**
- * Tests for TaskbarHoverToolTipController.
- */
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper(setAsMainLooper = true)
-public class TaskbarHoverToolTipControllerTest extends TaskbarBaseTestCase {
-
- private TaskbarHoverToolTipController mTaskbarHoverToolTipController;
- private TestableLooper mTestableLooper;
-
- @Mock private TaskbarView mTaskbarView;
- @Mock private MotionEvent mMotionEvent;
- @Mock private BubbleTextView mHoverBubbleTextView;
- @Mock private FolderIcon mHoverFolderIcon;
- @Mock private AppPairIcon mAppPairIcon;
- @Mock private Display mDisplay;
- @Mock private TaskbarDragLayer mTaskbarDragLayer;
- private Folder mSpyFolderView;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
-
- Context context = getApplicationContext();
-
- doAnswer((Answer<Object>) invocation -> context.getSystemService(
- (String) invocation.getArgument(0)))
- .when(taskbarActivityContext).getSystemService(anyString());
- when(taskbarActivityContext.getResources()).thenReturn(context.getResources());
- when(taskbarActivityContext.getApplicationInfo()).thenReturn(
- context.getApplicationInfo());
- when(taskbarActivityContext.getDragLayer()).thenReturn(mTaskbarDragLayer);
- when(taskbarActivityContext.getMainLooper()).thenReturn(context.getMainLooper());
- when(taskbarActivityContext.getDisplay()).thenReturn(mDisplay);
- when(taskbarActivityContext.isIconAlignedWithHotseat()).thenReturn(false);
-
- when(mTaskbarDragLayer.getChildCount()).thenReturn(1);
- mSpyFolderView = spy(new Folder(new ActivityContextWrapper(context), null));
- when(mTaskbarDragLayer.getChildAt(anyInt())).thenReturn(mSpyFolderView);
- doReturn(false).when(mSpyFolderView).isOpen();
-
- when(mHoverBubbleTextView.getText()).thenReturn("tooltip");
- doAnswer((Answer<Void>) invocation -> {
- Object[] args = invocation.getArguments();
- ((int[]) args[0])[0] = 0;
- ((int[]) args[0])[1] = 0;
- return null;
- }).when(mHoverBubbleTextView).getLocationOnScreen(any(int[].class));
- when(mHoverBubbleTextView.getWidth()).thenReturn(100);
- when(mHoverBubbleTextView.getHeight()).thenReturn(100);
-
- mHoverFolderIcon.mInfo = new FolderInfo();
- mHoverFolderIcon.mInfo.title = "tooltip";
- doAnswer((Answer<Void>) invocation -> {
- Object[] args = invocation.getArguments();
- ((int[]) args[0])[0] = 0;
- ((int[]) args[0])[1] = 0;
- return null;
- }).when(mHoverFolderIcon).getLocationOnScreen(any(int[].class));
- when(mHoverFolderIcon.getWidth()).thenReturn(100);
- when(mHoverFolderIcon.getHeight()).thenReturn(100);
-
- when(mTaskbarView.getTop()).thenReturn(200);
-
- mTaskbarHoverToolTipController = new TaskbarHoverToolTipController(
- taskbarActivityContext, mTaskbarView, mHoverBubbleTextView);
- mTestableLooper = TestableLooper.get(this);
- }
-
- @Test
- public void onHover_hoverEnterIcon_revealToolTip() {
- when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
- when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
-
- boolean hoverConsumed =
- mTaskbarHoverToolTipController.onHover(mHoverBubbleTextView, mMotionEvent);
- waitForIdleSync();
-
- assertThat(hoverConsumed).isFalse();
- verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
- true);
- }
-
- @Test
- public void onHover_hoverExitIcon_closeToolTip() {
- when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
- when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
-
- boolean hoverConsumed =
- mTaskbarHoverToolTipController.onHover(mHoverBubbleTextView, mMotionEvent);
- waitForIdleSync();
-
- assertThat(hoverConsumed).isFalse();
- verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
- false);
- }
-
- @Test
- public void onHover_hoverEnterFolderIcon_revealToolTip() {
- when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
- when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
-
- boolean hoverConsumed =
- mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent);
- waitForIdleSync();
-
- assertThat(hoverConsumed).isFalse();
- verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
- true);
- }
-
- @Test
- public void onHover_hoverExitFolderIcon_closeToolTip() {
- when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
- when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
-
- boolean hoverConsumed =
- mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent);
- waitForIdleSync();
-
- assertThat(hoverConsumed).isFalse();
- verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
- false);
- }
-
- @Test
- public void onHover_hoverExitFolderOpen_closeToolTip() {
- when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
- when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
- doReturn(true).when(mSpyFolderView).isOpen();
-
- boolean hoverConsumed =
- mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent);
- waitForIdleSync();
-
- assertThat(hoverConsumed).isFalse();
- verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
- false);
- }
-
- @Test
- public void onHover_hoverEnterFolderOpen_noToolTip() {
- when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
- when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
- doReturn(true).when(mSpyFolderView).isOpen();
-
- boolean hoverConsumed =
- mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent);
-
- assertThat(hoverConsumed).isFalse();
- }
-
- @Test
- public void onHover_hoverMove_noUpdate() {
- when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_MOVE);
- when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_MOVE);
-
- boolean hoverConsumed =
- mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent);
-
- assertThat(hoverConsumed).isFalse();
- }
-
- @Test
- public void onHover_hoverEnterAppPair_revealToolTip() {
- when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
- when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
-
- boolean hoverConsumed =
- mTaskbarHoverToolTipController.onHover(mAppPairIcon, mMotionEvent);
- waitForIdleSync();
-
- assertThat(hoverConsumed).isFalse();
- verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
- true);
- }
-
- @Test
- public void onHover_hoverExitAppPair_closeToolTip() {
- when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
- when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
-
- boolean hoverConsumed =
- mTaskbarHoverToolTipController.onHover(mAppPairIcon, mMotionEvent);
- waitForIdleSync();
-
- assertThat(hoverConsumed).isFalse();
- verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
- false);
- }
-
- @Test
- public void onHover_hoverEnterIconAlignedWithHotseat_noReveal() {
- when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
- when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
- when(taskbarActivityContext.isIconAlignedWithHotseat()).thenReturn(true);
-
- boolean hoverConsumed =
- mTaskbarHoverToolTipController.onHover(mHoverBubbleTextView, mMotionEvent);
- waitForIdleSync();
-
- assertThat(hoverConsumed).isFalse();
- verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
- true);
- }
-
- private void waitForIdleSync() {
- mTestableLooper.processAllMessages();
- }
-}
diff --git a/res/values-sw600dp/styles.xml b/res/values-sw600dp/styles.xml
index 63bd46b..db49a3e 100644
--- a/res/values-sw600dp/styles.xml
+++ b/res/values-sw600dp/styles.xml
@@ -14,8 +14,11 @@
~ limitations under the License.
-->
-<resources>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="CellStyleDefault">
<item name="iconDrawablePadding">7dp</item>
</style>
+ <style name="DropTargetButton" parent="DropTargetButtonBase">
+ <item name="android:fontFamily" android:featureFlag="com.android.launcher3.gsf_res">variable-title-large</item>
+ </style>
</resources>
\ No newline at end of file
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 39206d3..cf6c560 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -373,7 +373,9 @@
<item name="android:background">@drawable/drop_target_background</item>
</style>
- <style name="DropTargetButton" parent="DropTargetButtonBase" />
+ <style name="DropTargetButton" parent="DropTargetButtonBase">
+ <item name="android:fontFamily" android:featureFlag="com.android.launcher3.gsf_res">variable-title-medium</item>
+ </style>
<style name="TextHeadline" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle" />
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 39f68bf..9a226df 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -24,7 +24,9 @@
import static com.android.launcher3.allapps.AlphabeticalAppsList.PRIVATE_SPACE_PACKAGE;
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_NOT_PINNABLE;
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
+import static com.android.launcher3.shortcuts.DeepShortcutTextView.GOOGLE_SANS_FLEX_LABEL_LARGE;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import static com.android.wm.shell.Flags.enableGsf;
import android.animation.AnimatorSet;
import android.animation.LayoutTransition;
@@ -32,6 +34,7 @@
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.graphics.Typeface;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
@@ -479,6 +482,10 @@
if (view instanceof DeepShortcutView) {
// System shortcut takes entire row with icon and text
final DeepShortcutView shortcutView = (DeepShortcutView) view;
+ if (enableGsf()) {
+ shortcutView.getBubbleText().setTypeface(
+ Typeface.create(GOOGLE_SANS_FLEX_LABEL_LARGE, Typeface.NORMAL));
+ }
info.setIconAndLabelFor(shortcutView.getIconView(), shortcutView.getBubbleText());
} else if (view instanceof ImageView) {
// System shortcut is just an icon
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutTextView.java b/src/com/android/launcher3/shortcuts/DeepShortcutTextView.java
index ded2cee..b1d095b 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutTextView.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutTextView.java
@@ -16,9 +16,12 @@
package com.android.launcher3.shortcuts;
+import static com.android.wm.shell.Flags.enableGsf;
+
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
+import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -31,6 +34,7 @@
* A {@link BubbleTextView} that has the shortcut icon on the left and drag handle on the right.
*/
public class DeepShortcutTextView extends BubbleTextView {
+ public static final String GOOGLE_SANS_FLEX_LABEL_LARGE = "variable-label-large";
private boolean mShowLoadingState;
private Drawable mLoadingStatePlaceholder;
@@ -47,6 +51,9 @@
public DeepShortcutTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
showLoadingState(true);
+ if (enableGsf()) {
+ setTypeface(Typeface.create(GOOGLE_SANS_FLEX_LABEL_LARGE, Typeface.NORMAL));
+ }
}
@Override