Merge "Implement initial transient Taskbar EDU tooltips." into tm-qpr-dev am: 654f714718 am: 4d7e4c4a8e
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/20795522
Change-Id: I70307a411262909945f44e7e3b58ff721ccc10d2
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/quickstep/res/drawable/bg_taskbar_edu_tooltip.xml b/quickstep/res/drawable/bg_taskbar_edu_tooltip.xml
new file mode 100644
index 0000000..a20f7da
--- /dev/null
+++ b/quickstep/res/drawable/bg_taskbar_edu_tooltip.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:shape="rectangle">
+
+ <corners android:radius="@dimen/dialogCornerRadius" />
+ <solid android:color="?androidprv:attr/colorSurface" />
+</shape>
\ No newline at end of file
diff --git a/quickstep/res/layout/taskbar_edu_features.xml b/quickstep/res/layout/taskbar_edu_features.xml
new file mode 100644
index 0000000..72517b1
--- /dev/null
+++ b/quickstep/res/layout/taskbar_edu_features.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <TextView
+ android:id="@+id/title"
+ style="@style/TextAppearance.TaskbarEduTooltip.Title"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/taskbar_edu_features"
+ app:layout_constraintEnd_toEndOf="@id/suggestions_animation"
+ app:layout_constraintStart_toStartOf="@id/splitscreen_animation"
+ app:layout_constraintTop_toTopOf="parent" />
+
+ <com.airbnb.lottie.LottieAnimationView
+ android:id="@+id/splitscreen_animation"
+ android:layout_width="@dimen/taskbar_edu_features_lottie_width"
+ android:layout_height="@dimen/taskbar_edu_features_lottie_height"
+ android:layout_marginTop="@dimen/taskbar_edu_tooltip_vertical_margin"
+ android:scaleType="centerCrop"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/title"
+ app:lottie_autoPlay="true"
+ app:lottie_loop="true"
+ app:lottie_rawRes="@raw/taskbar_edu_splitscreen_transient" />
+
+ <TextView
+ android:id="@+id/splitscreen_text"
+ style="@style/TextAppearance.TaskbarEduTooltip.Subtext"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/taskbar_edu_splitscreen"
+ app:layout_constraintEnd_toEndOf="@id/splitscreen_animation"
+ app:layout_constraintStart_toStartOf="@id/splitscreen_animation"
+ app:layout_constraintTop_toBottomOf="@id/splitscreen_animation" />
+
+ <com.airbnb.lottie.LottieAnimationView
+ android:id="@+id/suggestions_animation"
+ android:layout_width="@dimen/taskbar_edu_features_lottie_width"
+ android:layout_height="@dimen/taskbar_edu_features_lottie_height"
+ android:layout_marginStart="@dimen/taskbar_edu_features_horizontal_spacing"
+ android:layout_marginTop="@dimen/taskbar_edu_tooltip_vertical_margin"
+ android:scaleType="centerCrop"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@id/splitscreen_animation"
+ app:layout_constraintTop_toBottomOf="@id/title"
+ app:lottie_autoPlay="true"
+ app:lottie_loop="true"
+ app:lottie_rawRes="@raw/taskbar_edu_suggestions_transient" />
+
+ <TextView
+ android:id="@+id/suggestions_text"
+ style="@style/TextAppearance.TaskbarEduTooltip.Subtext"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/taskbar_edu_suggestions"
+ app:layout_constraintEnd_toEndOf="@id/suggestions_animation"
+ app:layout_constraintStart_toStartOf="@id/suggestions_animation"
+ app:layout_constraintTop_toBottomOf="@id/suggestions_animation" />
+
+ <Button
+ android:id="@+id/done_button"
+ style="@style/TaskbarEdu.Button.Next"
+ android:layout_width="wrap_content"
+ android:layout_height="36dp"
+ android:layout_marginTop="32dp"
+ android:text="@string/taskbar_edu_done"
+ android:textColor="?androidprv:attr/textColorOnAccent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/suggestions_text" />
+</merge>
\ No newline at end of file
diff --git a/quickstep/res/layout/taskbar_edu_swipe.xml b/quickstep/res/layout/taskbar_edu_swipe.xml
new file mode 100644
index 0000000..36a6e28
--- /dev/null
+++ b/quickstep/res/layout/taskbar_edu_swipe.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <TextView
+ android:id="@+id/title"
+ style="@style/TextAppearance.TaskbarEduTooltip.Title"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/taskbar_edu_stashing"
+ app:layout_constraintEnd_toEndOf="@id/animation"
+ app:layout_constraintStart_toStartOf="@id/animation"
+ app:layout_constraintTop_toTopOf="parent" />
+
+ <com.airbnb.lottie.LottieAnimationView
+ android:id="@+id/animation"
+ android:layout_width="@dimen/taskbar_edu_swipe_lottie_width"
+ android:layout_height="@dimen/taskbar_edu_swipe_lottie_height"
+ android:layout_marginTop="@dimen/taskbar_edu_tooltip_vertical_margin"
+ android:scaleType="centerCrop"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/title"
+ app:lottie_autoPlay="true"
+ app:lottie_loop="true"
+ app:lottie_rawRes="@raw/taskbar_edu_stashing_transient" />
+
+</merge>
\ No newline at end of file
diff --git a/quickstep/res/layout/taskbar_edu_tooltip.xml b/quickstep/res/layout/taskbar_edu_tooltip.xml
new file mode 100644
index 0000000..29f4956
--- /dev/null
+++ b/quickstep/res/layout/taskbar_edu_tooltip.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<com.android.launcher3.taskbar.TaskbarEduTooltip xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|center"
+ android:layout_marginBottom="16dp"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:fitsSystemWindows="true"
+ android:gravity="center"
+ android:orientation="vertical">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/content"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@drawable/bg_taskbar_edu_tooltip"
+ android:elevation="@dimen/taskbar_edu_tooltip_elevation"
+ android:paddingHorizontal="@dimen/taskbar_edu_tooltip_horizontal_margin"
+ android:paddingVertical="@dimen/taskbar_edu_tooltip_vertical_margin" />
+
+ <View
+ android:id="@+id/arrow"
+ android:layout_width="@dimen/popup_arrow_width"
+ android:layout_height="@dimen/popup_arrow_height"
+ android:elevation="@dimen/taskbar_edu_tooltip_elevation" />
+</com.android.launcher3.taskbar.TaskbarEduTooltip>
\ No newline at end of file
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 2eb4abc..d97e435 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -309,6 +309,18 @@
<dimen name="taskbar_button_margin_6_5">75dp</dimen>
<dimen name="taskbar_button_margin_default">48dp</dimen>
+ <!-- Taskbar education tooltip -->
+ <dimen name="taskbar_edu_tooltip_elevation">14dp</dimen>
+ <dimen name="taskbar_edu_tooltip_horizontal_margin">32dp</dimen>
+ <dimen name="taskbar_edu_tooltip_vertical_margin">24dp</dimen>
+ <dimen name="taskbar_edu_tooltip_enter_y_delta">20dp</dimen>
+ <dimen name="taskbar_edu_tooltip_exit_y_delta">-10dp</dimen>
+ <dimen name="taskbar_edu_swipe_lottie_width">348dp</dimen>
+ <dimen name="taskbar_edu_swipe_lottie_height">217dp</dimen>
+ <dimen name="taskbar_edu_features_lottie_width">170dp</dimen>
+ <dimen name="taskbar_edu_features_lottie_height">106dp</dimen>
+ <dimen name="taskbar_edu_features_horizontal_spacing">24dp</dimen>
+
<!-- Recents overview -->
<dimen name="recents_filter_icon_size">30dp</dimen>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index e691522..761934e 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -238,11 +238,13 @@
<!-- Accessibility text spoken when the taskbar education panel disappears [CHAR_LIMIT=NONE] -->
<string name="taskbar_edu_closed">Taskbar education closed</string>
<!-- Text in dialog that lets a user know how they can use the taskbar to use multiple apps at once on their device. [CHAR_LIMIT=60] -->
- <string name="taskbar_edu_splitscreen">Drag to the side to use 2 apps at once</string>
+ <string name="taskbar_edu_splitscreen">Drag an app to the side to use 2 apps at once</string>
<!-- Text in dialog that lets a user know how they can show the taskbar on their device. [CHAR_LIMIT=60] -->
<string name="taskbar_edu_stashing">Short swipe up to show the taskbar</string>
<!-- Text in dialog that lets a user know how the taskbar suggests apps based on their usage. [CHAR_LIMIT=60] -->
- <string name="taskbar_edu_suggestions">The taskbar suggests apps based on your routine</string>
+ <string name="taskbar_edu_suggestions">Get app suggestions based on your routine</string>
+ <!-- Title in dialog that shows a user what they can do with the taskbar. [CHAR_LIMIT=60] -->
+ <string name="taskbar_edu_features">Do more with the taskbar</string>
<!-- Text on button to go to the next screen of a tutorial [CHAR_LIMIT=16] -->
<string name="taskbar_edu_next">Next</string>
<!-- Text on button to go to the previous screen of a tutorial [CHAR_LIMIT=16] -->
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index eb75084..5256e29 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -186,4 +186,16 @@
<item name="android:textSize">24sp</item>
<item name="android:lines">2</item>
</style>
+
+ <style name="TextAppearance.TaskbarEduTooltip.Title" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle">
+ <item name="android:gravity">center_horizontal</item>
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:textSize">24sp</item>
+ </style>
+
+ <style name="TextAppearance.TaskbarEduTooltip.Subtext" parent="android:TextAppearance.Material.Body1">
+ <item name="android:layout_marginTop">16dp</item>
+ <item name="android:fontFamily">google-sans-text</item>
+ <item name="android:textSize">14sp</item>
+ </style>
</resources>
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 2521208..258e2bc 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -700,7 +700,7 @@
@Override
public void onAnimationStart(Animator animation) {
LauncherTaskbarUIController taskbarController = mLauncher.getTaskbarUIController();
- if (taskbarController != null && taskbarController.shouldShowEdu()) {
+ if (taskbarController != null && taskbarController.shouldShowEduOnAppLaunch()) {
// LAUNCHER_TASKBAR_EDUCATION_SHOWING is set to true here, when the education
// flow is about to start, to avoid a race condition with other components
// that would show something else to the user as soon as the app is opened.
@@ -716,7 +716,7 @@
}
LauncherTaskbarUIController taskbarController = mLauncher.getTaskbarUIController();
if (taskbarController != null) {
- taskbarController.showEdu();
+ taskbarController.showEduOnAppLaunch();
}
openingTargets.release();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java b/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
index 82d1830..48352a2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
@@ -20,6 +20,8 @@
import android.view.LayoutInflater;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
+import com.android.launcher3.LauncherPrefs;
+import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
@@ -32,10 +34,12 @@
protected final LayoutInflater mLayoutInflater;
private final List<OnDeviceProfileChangeListener> mDPChangeListeners = new ArrayList<>();
+ private final OnboardingPrefs<BaseTaskbarContext> mOnboardingPrefs;
public BaseTaskbarContext(Context windowContext) {
super(windowContext, Themes.getActivityThemeRes(windowContext));
mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
+ mOnboardingPrefs = new OnboardingPrefs<>(this, LauncherPrefs.getPrefs(this));
}
@Override
@@ -48,6 +52,11 @@
return mDPChangeListeners;
}
+ @Override
+ public OnboardingPrefs<BaseTaskbarContext> getOnboardingPrefs() {
+ return mOnboardingPrefs;
+ }
+
/** Callback invoked when a drag is initiated within this context. */
public abstract void onDragStart();
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 237661e..335482c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -18,6 +18,8 @@
import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
import static com.android.launcher3.QuickstepTransitionManager.TRANSIENT_TASKBAR_TRANSITION_DURATION;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_EDU_TOOLTIP;
+import static com.android.launcher3.taskbar.TaskbarEduTooltipControllerKt.TOOLTIP_STEP_FEATURES;
import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_RESUMED;
import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
@@ -259,23 +261,51 @@
}
/**
- * Starts the taskbar education flow, if the user hasn't seen it yet.
+ * Starts a Taskbar EDU flow, if the user should see one upon launching an application.
*/
- public void showEdu() {
- if (!shouldShowEdu()) {
+ public void showEduOnAppLaunch() {
+ if (!shouldShowEduOnAppLaunch()) {
return;
}
- mLauncher.getOnboardingPrefs().markChecked(OnboardingPrefs.TASKBAR_EDU_SEEN);
- mControllers.taskbarEduController.showEdu();
+ // Transient and persistent bottom sheet.
+ if (!ENABLE_TASKBAR_EDU_TOOLTIP.get()) {
+ mLauncher.getOnboardingPrefs().markChecked(OnboardingPrefs.TASKBAR_EDU_SEEN);
+ mControllers.taskbarEduController.showEdu();
+ return;
+ }
+
+ // Persistent features EDU tooltip.
+ if (!DisplayController.isTransientTaskbar(mLauncher)) {
+ mControllers.taskbarEduTooltipController.maybeShowFeaturesEdu();
+ return;
+ }
+
+ // Transient swipe EDU tooltip.
+ mControllers.taskbarEduTooltipController.maybeShowSwipeEdu();
}
/**
- * Whether the taskbar education should be shown.
+ * Returns {@code true} if a Taskbar education should be shown on application launch.
*/
- public boolean shouldShowEdu() {
- return !Utilities.IS_RUNNING_IN_TEST_HARNESS
- && !mLauncher.getOnboardingPrefs().getBoolean(OnboardingPrefs.TASKBAR_EDU_SEEN);
+ public boolean shouldShowEduOnAppLaunch() {
+ if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ return false;
+ }
+
+ // Transient and persistent bottom sheet.
+ if (!ENABLE_TASKBAR_EDU_TOOLTIP.get()) {
+ return !mLauncher.getOnboardingPrefs().getBoolean(OnboardingPrefs.TASKBAR_EDU_SEEN);
+ }
+
+ // Persistent features EDU tooltip.
+ if (!DisplayController.isTransientTaskbar(mLauncher)) {
+ return !mLauncher.getOnboardingPrefs().hasReachedMaxCount(
+ OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP);
+ }
+
+ // Transient swipe EDU tooltip.
+ return mControllers.taskbarEduTooltipController.getTooltipStep() < TOOLTIP_STEP_FEATURES;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 2d464d6..c01e670 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -234,7 +234,8 @@
new TaskbarTranslationController(this),
isDesktopMode
? new DesktopTaskbarRecentAppsController(this)
- : TaskbarRecentAppsController.DEFAULT);
+ : TaskbarRecentAppsController.DEFAULT,
+ new TaskbarEduTooltipController(this));
}
public void init(@NonNull TaskbarSharedState sharedState) {
@@ -916,6 +917,7 @@
*/
public void onSwipeToUnstashTaskbar() {
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(false);
+ mControllers.taskbarEduTooltipController.hide();
}
/** Returns {@code true} if taskbar All Apps is open. */
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendController.java
index 4350e9c..2bfc7dd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendController.java
@@ -39,11 +39,14 @@
public static final int FLAG_AUTOHIDE_SUSPEND_DRAGGING = 1 << 1;
// User has touched down but has not lifted finger.
public static final int FLAG_AUTOHIDE_SUSPEND_TOUCHING = 1 << 2;
+ // Taskbar EDU overlay is open above the Taskbar. */
+ public static final int FLAG_AUTOHIDE_SUSPEND_EDU_OPEN = 1 << 3;
@IntDef(flag = true, value = {
FLAG_AUTOHIDE_SUSPEND_FULLSCREEN,
FLAG_AUTOHIDE_SUSPEND_DRAGGING,
FLAG_AUTOHIDE_SUSPEND_TOUCHING,
+ FLAG_AUTOHIDE_SUSPEND_EDU_OPEN,
})
@Retention(RetentionPolicy.SOURCE)
public @interface AutohideSuspendFlag {}
@@ -102,6 +105,7 @@
"FLAG_AUTOHIDE_SUSPEND_FULLSCREEN");
appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_DRAGGING, "FLAG_AUTOHIDE_SUSPEND_DRAGGING");
appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_TOUCHING, "FLAG_AUTOHIDE_SUSPEND_TOUCHING");
+ appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_EDU_OPEN, "FLAG_AUTOHIDE_SUSPEND_EDU_OPEN");
return str.toString();
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index 260876b..ea70de4 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -58,6 +58,7 @@
public final TaskbarRecentAppsController taskbarRecentAppsController;
public final TaskbarTranslationController taskbarTranslationController;
public final TaskbarOverlayController taskbarOverlayController;
+ public final TaskbarEduTooltipController taskbarEduTooltipController;
@Nullable private LoggableTaskbarController[] mControllersToLog = null;
@Nullable private BackgroundRendererController[] mBackgroundRendererControllers = null;
@@ -101,7 +102,8 @@
TaskbarInsetsController taskbarInsetsController,
VoiceInteractionWindowController voiceInteractionWindowController,
TaskbarTranslationController taskbarTranslationController,
- TaskbarRecentAppsController taskbarRecentAppsController) {
+ TaskbarRecentAppsController taskbarRecentAppsController,
+ TaskbarEduTooltipController taskbarEduTooltipController) {
this.taskbarActivityContext = taskbarActivityContext;
this.taskbarDragController = taskbarDragController;
this.navButtonController = navButtonController;
@@ -124,6 +126,7 @@
this.voiceInteractionWindowController = voiceInteractionWindowController;
this.taskbarTranslationController = taskbarTranslationController;
this.taskbarRecentAppsController = taskbarRecentAppsController;
+ this.taskbarEduTooltipController = taskbarEduTooltipController;
}
/**
@@ -155,6 +158,7 @@
voiceInteractionWindowController.init(this);
taskbarRecentAppsController.init(this);
taskbarTranslationController.init(this);
+ taskbarEduTooltipController.init(this);
mControllersToLog = new LoggableTaskbarController[] {
taskbarDragController, navButtonController, navbarButtonsViewController,
@@ -162,7 +166,8 @@
taskbarUnfoldAnimationController, taskbarKeyguardController,
stashedHandleViewController, taskbarStashController, taskbarEduController,
taskbarAutohideSuspendController, taskbarPopupController, taskbarInsetsController,
- voiceInteractionWindowController, taskbarTranslationController
+ voiceInteractionWindowController, taskbarTranslationController,
+ taskbarEduTooltipController
};
mBackgroundRendererControllers = new BackgroundRendererController[] {
taskbarDragLayerController, taskbarScrimViewController,
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltip.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltip.kt
new file mode 100644
index 0000000..7dda73f
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltip.kt
@@ -0,0 +1,187 @@
+/*
+ * 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 android.animation.AnimatorSet
+import android.animation.ValueAnimator
+import android.content.Context
+import android.provider.Settings
+import android.provider.Settings.Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.View
+import android.view.ViewGroup
+import android.view.animation.Interpolator
+import com.android.launcher3.AbstractFloatingView
+import com.android.launcher3.R
+import com.android.launcher3.anim.AnimatorListeners
+import com.android.launcher3.popup.RoundedArrowDrawable
+import com.android.launcher3.util.Themes
+import com.android.launcher3.views.ActivityContext
+import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.systemui.animation.Interpolators.EMPHASIZED_DECELERATE
+import com.android.systemui.animation.Interpolators.STANDARD
+
+private const val ENTER_DURATION_MS = 300L
+private const val EXIT_DURATION_MS = 150L
+
+/** Floating tooltip for Taskbar education. */
+class TaskbarEduTooltip
+@JvmOverloads
+constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0,
+) : AbstractFloatingView(context, attrs, defStyleAttr) {
+
+ private val activityContext: ActivityContext = ActivityContext.lookupContext(context)
+
+ private val backgroundColor =
+ Themes.getAttrColor(context, com.android.internal.R.attr.colorSurface)
+
+ private val tooltipCornerRadius = Themes.getDialogCornerRadius(context)
+ private val arrowWidth = resources.getDimension(R.dimen.popup_arrow_width)
+ private val arrowHeight = resources.getDimension(R.dimen.popup_arrow_height)
+ private val arrowPointRadius = resources.getDimension(R.dimen.popup_arrow_corner_radius)
+
+ private val enterYDelta = resources.getDimension(R.dimen.taskbar_edu_tooltip_enter_y_delta)
+ private val exitYDelta = resources.getDimension(R.dimen.taskbar_edu_tooltip_exit_y_delta)
+
+ /** Container where the tooltip's body should be inflated. */
+ lateinit var content: ViewGroup
+ private set
+ private lateinit var arrow: View
+
+ /** Callback invoked when the tooltip is being closed. */
+ var onCloseCallback: () -> Unit = {}
+ private var openCloseAnimator: AnimatorSet? = null
+
+ /** Animates the tooltip into view. */
+ fun show() {
+ if (isOpen) {
+ return
+ }
+ mIsOpen = true
+ activityContext.dragLayer.addView(this)
+ openCloseAnimator = createOpenCloseAnimator(isOpening = true).apply { start() }
+ }
+
+ override fun onFinishInflate() {
+ super.onFinishInflate()
+
+ content = findViewById(R.id.content)
+ arrow = findViewById(R.id.arrow)
+ arrow.background =
+ RoundedArrowDrawable(
+ arrowWidth,
+ arrowHeight,
+ arrowPointRadius,
+ tooltipCornerRadius,
+ measuredWidth.toFloat(),
+ measuredHeight.toFloat(),
+ (measuredWidth - arrowWidth) / 2, // arrowOffsetX
+ 0f, // arrowOffsetY
+ false, // isPointingUp
+ true, // leftAligned
+ backgroundColor,
+ )
+ }
+
+ override fun handleClose(animate: Boolean) {
+ if (!isOpen) {
+ return
+ }
+
+ onCloseCallback()
+ if (!animate) {
+ return closeComplete()
+ }
+
+ openCloseAnimator?.cancel()
+ openCloseAnimator = createOpenCloseAnimator(isOpening = false)
+ openCloseAnimator?.addListener(AnimatorListeners.forEndCallback(this::closeComplete))
+ openCloseAnimator?.start()
+ }
+
+ override fun isOfType(type: Int): Boolean = type and TYPE_TASKBAR_EDUCATION_DIALOG != 0
+
+ override fun onControllerInterceptTouchEvent(ev: MotionEvent?): Boolean {
+ if (ev?.action == ACTION_DOWN && !activityContext.dragLayer.isEventOverView(this, ev)) {
+ close(true)
+ }
+ return false
+ }
+
+ override fun onDetachedFromWindow() {
+ super.onDetachedFromWindow()
+ Settings.Secure.putInt(mContext.contentResolver, LAUNCHER_TASKBAR_EDUCATION_SHOWING, 0)
+ }
+
+ private fun closeComplete() {
+ openCloseAnimator?.cancel()
+ openCloseAnimator = null
+ mIsOpen = false
+ activityContext.dragLayer.removeView(this)
+ }
+
+ private fun createOpenCloseAnimator(isOpening: Boolean): AnimatorSet {
+ val duration: Long
+ val alphaValues: FloatArray
+ val translateYValues: FloatArray
+ val fadeInterpolator: Interpolator
+ val translateYInterpolator: Interpolator
+
+ if (isOpening) {
+ duration = ENTER_DURATION_MS
+ alphaValues = floatArrayOf(0f, 1f)
+ translateYValues = floatArrayOf(enterYDelta, 0f)
+ fadeInterpolator = STANDARD
+ translateYInterpolator = EMPHASIZED_DECELERATE
+ } else {
+ duration = EXIT_DURATION_MS
+ alphaValues = floatArrayOf(1f, 0f)
+ translateYValues = floatArrayOf(0f, exitYDelta)
+ fadeInterpolator = EMPHASIZED_ACCELERATE
+ translateYInterpolator = EMPHASIZED_ACCELERATE
+ }
+
+ val fade =
+ ValueAnimator.ofFloat(*alphaValues).apply {
+ interpolator = fadeInterpolator
+ addUpdateListener {
+ val alpha = it.animatedValue as Float
+ content.alpha = alpha
+ arrow.alpha = alpha
+ }
+ }
+
+ val translateY =
+ ValueAnimator.ofFloat(*translateYValues).apply {
+ interpolator = translateYInterpolator
+ addUpdateListener {
+ val translationY = it.animatedValue as Float
+ content.translationY = translationY
+ arrow.translationY = translationY
+ }
+ }
+
+ return AnimatorSet().apply {
+ this.duration = duration
+ playTogether(fade, translateY)
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
new file mode 100644
index 0000000..817f67d
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
@@ -0,0 +1,147 @@
+/*
+ * 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 android.view.View
+import android.view.ViewGroup
+import androidx.annotation.IntDef
+import androidx.annotation.LayoutRes
+import com.android.launcher3.R
+import com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS
+import com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_EDU_TOOLTIP
+import com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_EDU_OPEN
+import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
+import com.android.launcher3.util.DisplayController
+import com.android.launcher3.util.OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP
+import java.io.PrintWriter
+
+/** First EDU step for swiping up to show transient Taskbar. */
+const val TOOLTIP_STEP_SWIPE = 0
+/** Second EDU step for explaining Taskbar functionality when unstashed. */
+const val TOOLTIP_STEP_FEATURES = 1
+/**
+ * EDU is completed.
+ *
+ * This value should match the maximum count for [TASKBAR_EDU_TOOLTIP_STEP].
+ */
+const val TOOLTIP_STEP_NONE = 2
+
+/** Current step in the tooltip EDU flow. */
+@Retention(AnnotationRetention.SOURCE)
+@IntDef(TOOLTIP_STEP_SWIPE, TOOLTIP_STEP_FEATURES, TOOLTIP_STEP_NONE)
+annotation class TaskbarEduTooltipStep
+
+/** Controls stepping through the Taskbar tooltip EDU. */
+class TaskbarEduTooltipController(val activityContext: TaskbarActivityContext) :
+ LoggableTaskbarController {
+
+ private val isTooltipEnabled = !IS_RUNNING_IN_TEST_HARNESS && ENABLE_TASKBAR_EDU_TOOLTIP.get()
+ private val isOpen: Boolean
+ get() = tooltip?.isOpen ?: false
+
+ private lateinit var controllers: TaskbarControllers
+
+ @TaskbarEduTooltipStep
+ var tooltipStep: Int
+ get() {
+ return activityContext.onboardingPrefs?.getCount(TASKBAR_EDU_TOOLTIP_STEP)
+ ?: TOOLTIP_STEP_NONE
+ }
+ private set(step) {
+ activityContext.onboardingPrefs?.setEventCount(step, TASKBAR_EDU_TOOLTIP_STEP)
+ }
+
+ private var tooltip: TaskbarEduTooltip? = null
+
+ fun init(controllers: TaskbarControllers) {
+ this.controllers = controllers
+ }
+
+ /** Shows swipe EDU tooltip if it is the current [tooltipStep]. */
+ fun maybeShowSwipeEdu() {
+ if (
+ !isTooltipEnabled ||
+ !DisplayController.isTransientTaskbar(activityContext) ||
+ tooltipStep > TOOLTIP_STEP_SWIPE
+ ) {
+ return
+ }
+
+ tooltipStep = TOOLTIP_STEP_FEATURES
+ inflateTooltip(R.layout.taskbar_edu_swipe)
+ tooltip?.show()
+ }
+
+ /**
+ * Shows feature EDU tooltip if this step has not been seen.
+ *
+ * If [TOOLTIP_STEP_SWIPE] has not been seen at this point, the first step is skipped because a
+ * swipe up is necessary to show this step.
+ */
+ fun maybeShowFeaturesEdu() {
+ if (!isTooltipEnabled || tooltipStep > TOOLTIP_STEP_FEATURES) {
+ return
+ }
+
+ tooltipStep = TOOLTIP_STEP_NONE
+ inflateTooltip(R.layout.taskbar_edu_features)
+ tooltip?.apply {
+ findViewById<View>(R.id.done_button)?.setOnClickListener { hide() }
+ if (DisplayController.isTransientTaskbar(activityContext)) {
+ (layoutParams as ViewGroup.MarginLayoutParams).bottomMargin +=
+ activityContext.deviceProfile.taskbarSize
+ }
+ show()
+ }
+ }
+
+ /** Closes the current [tooltip]. */
+ fun hide() = tooltip?.close(true)
+
+ /** Initializes [tooltip] with content from [contentResId]. */
+ private fun inflateTooltip(@LayoutRes contentResId: Int) {
+ val overlayContext = controllers.taskbarOverlayController.requestWindow()
+ val tooltip =
+ overlayContext.layoutInflater.inflate(
+ R.layout.taskbar_edu_tooltip,
+ overlayContext.dragLayer,
+ false
+ ) as TaskbarEduTooltip
+
+ controllers.taskbarAutohideSuspendController.updateFlag(
+ FLAG_AUTOHIDE_SUSPEND_EDU_OPEN,
+ true
+ )
+ tooltip.onCloseCallback = {
+ this.tooltip = null
+ controllers.taskbarAutohideSuspendController.updateFlag(
+ FLAG_AUTOHIDE_SUSPEND_EDU_OPEN,
+ false
+ )
+ controllers.taskbarStashController.updateAndAnimateTransientTaskbar(true)
+ }
+
+ overlayContext.layoutInflater.inflate(contentResId, tooltip.content, true)
+ this.tooltip = tooltip
+ }
+
+ override fun dumpLogs(prefix: String?, pw: PrintWriter?) {
+ pw?.println("$(prefix)TaskbarEduController:")
+ pw?.println("$prefix\tisTooltipEnabled=$isTooltipEnabled")
+ pw?.println("$prefix\tisOpen=$isOpen")
+ pw?.println("$prefix\ttooltipStep=$tooltipStep")
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 61d169f..ef79b8e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -426,6 +426,11 @@
return;
}
+ if (stash && mControllers.taskbarAutohideSuspendController.isSuspended()) {
+ // Avoid stashing if autohide is currently suspended.
+ return;
+ }
+
if (hasAnyFlag(FLAG_STASHED_IN_APP_AUTO) != stash) {
updateStateForFlag(FLAG_STASHED_IN_APP_AUTO, stash);
applyState();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java
index 5dba444..586115d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java
@@ -109,8 +109,12 @@
.setStiffness(SpringForce.STIFFNESS_LOW)
.build(mTranslationYForSwipe, VALUE);
mSpringBounce.addListener(forEndCallback(() -> {
- if (mGestureEnded) {
- reset();
+ if (!mGestureEnded) {
+ return;
+ }
+ reset();
+ if (mControllers.taskbarStashController.isInAppAndNotStashed()) {
+ mControllers.taskbarEduTooltipController.maybeShowFeaturesEdu();
}
}));
mSpringBounce.start();
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
index 38b6dfd..d7a0b03 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
@@ -19,7 +19,6 @@
import android.view.View;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.model.data.ItemInfo;
@@ -30,7 +29,6 @@
import com.android.launcher3.taskbar.TaskbarDragController;
import com.android.launcher3.taskbar.TaskbarStashController;
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsContainerView;
-import com.android.launcher3.util.OnboardingPrefs;
/**
* Window context for the taskbar overlays such as All Apps and EDU.
@@ -40,7 +38,6 @@
*/
public class TaskbarOverlayContext extends BaseTaskbarContext {
private final TaskbarActivityContext mTaskbarContext;
- private final OnboardingPrefs<TaskbarOverlayContext> mOnboardingPrefs;
private final TaskbarOverlayController mOverlayController;
private final TaskbarDragController mDragController;
@@ -59,7 +56,6 @@
mOverlayController = controllers.taskbarOverlayController;
mDragController = new TaskbarDragController(this);
mDragController.init(controllers);
- mOnboardingPrefs = new OnboardingPrefs<>(this, LauncherPrefs.getPrefs(this));
mDragLayer = new TaskbarOverlayDragLayer(this);
TaskbarStashController taskbarStashController = controllers.taskbarStashController;
@@ -100,11 +96,6 @@
}
@Override
- public OnboardingPrefs<TaskbarOverlayContext> getOnboardingPrefs() {
- return mOnboardingPrefs;
- }
-
- @Override
public boolean isBindingItems() {
return mTaskbarContext.isBindingItems();
}
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
index e8a575e..8a78d8c 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
@@ -23,55 +23,35 @@
import org.mockito.MockitoAnnotations
/**
- * Helper class to extend to get access to all controllers.
- * Gotta be careful of your relationship with this class though, it can be quite... controlling.
+ * Helper class to extend to get access to all controllers. Gotta be careful of your relationship
+ * with this class though, it can be quite... controlling.
*/
abstract class TaskbarBaseTestCase {
- @Mock
- lateinit var taskbarActivityContext: TaskbarActivityContext
- @Mock
- lateinit var taskbarDragController: TaskbarDragController
- @Mock
- lateinit var navButtonController: TaskbarNavButtonController
- @Mock
- lateinit var navbarButtonsViewController: NavbarButtonsViewController
- @Mock
- lateinit var rotationButtonController: RotationButtonController
- @Mock
- lateinit var taskbarDragLayerController: TaskbarDragLayerController
- @Mock
- lateinit var taskbarScrimViewController: TaskbarScrimViewController
- @Mock
- lateinit var taskbarViewController: TaskbarViewController
- @Mock
- lateinit var taskbarUnfoldAnimationController: TaskbarUnfoldAnimationController
- @Mock
- lateinit var taskbarKeyguardController: TaskbarKeyguardController
- @Mock
- lateinit var stashedHandleViewController: StashedHandleViewController
- @Mock
- lateinit var taskbarStashController: TaskbarStashController
- @Mock
- lateinit var taskbarEduController: TaskbarEduController
- @Mock
- lateinit var taskbarAutohideSuspendController: TaskbarAutohideSuspendController
- @Mock
- lateinit var taskbarPopupController: TaskbarPopupController
+ @Mock lateinit var taskbarActivityContext: TaskbarActivityContext
+ @Mock lateinit var taskbarDragController: TaskbarDragController
+ @Mock lateinit var navButtonController: TaskbarNavButtonController
+ @Mock lateinit var navbarButtonsViewController: NavbarButtonsViewController
+ @Mock lateinit var rotationButtonController: RotationButtonController
+ @Mock lateinit var taskbarDragLayerController: TaskbarDragLayerController
+ @Mock lateinit var taskbarScrimViewController: TaskbarScrimViewController
+ @Mock lateinit var taskbarViewController: TaskbarViewController
+ @Mock lateinit var taskbarUnfoldAnimationController: TaskbarUnfoldAnimationController
+ @Mock lateinit var taskbarKeyguardController: TaskbarKeyguardController
+ @Mock lateinit var stashedHandleViewController: StashedHandleViewController
+ @Mock lateinit var taskbarStashController: TaskbarStashController
+ @Mock lateinit var taskbarEduController: TaskbarEduController
+ @Mock lateinit var taskbarAutohideSuspendController: TaskbarAutohideSuspendController
+ @Mock lateinit var taskbarPopupController: TaskbarPopupController
@Mock
lateinit var taskbarForceVisibleImmersiveController: TaskbarForceVisibleImmersiveController
- @Mock
- lateinit var taskbarAllAppsController: TaskbarAllAppsController
- @Mock
- lateinit var taskbarInsetsController: TaskbarInsetsController
- @Mock
- lateinit var voiceInteractionWindowController: VoiceInteractionWindowController
- @Mock
- lateinit var taskbarRecentAppsController: TaskbarRecentAppsController
- @Mock
- lateinit var taskbarTranslationController: TaskbarTranslationController
- @Mock
- lateinit var taskbarOverlayController: TaskbarOverlayController
+ @Mock lateinit var taskbarAllAppsController: TaskbarAllAppsController
+ @Mock lateinit var taskbarInsetsController: TaskbarInsetsController
+ @Mock lateinit var voiceInteractionWindowController: VoiceInteractionWindowController
+ @Mock lateinit var taskbarRecentAppsController: TaskbarRecentAppsController
+ @Mock lateinit var taskbarTranslationController: TaskbarTranslationController
+ @Mock lateinit var taskbarOverlayController: TaskbarOverlayController
+ @Mock lateinit var taskbarEduTooltipController: TaskbarEduTooltipController
lateinit var mTaskbarControllers: TaskbarControllers
@@ -85,16 +65,31 @@
* includes that method to allow mocking it.
*/
MockitoAnnotations.initMocks(this)
- mTaskbarControllers = TaskbarControllers(
- taskbarActivityContext, taskbarDragController, navButtonController,
- navbarButtonsViewController, rotationButtonController, taskbarDragLayerController,
- taskbarViewController, taskbarScrimViewController, taskbarUnfoldAnimationController,
- taskbarKeyguardController, stashedHandleViewController, taskbarStashController,
- taskbarEduController, taskbarAutohideSuspendController, taskbarPopupController,
- taskbarForceVisibleImmersiveController, taskbarOverlayController,
- taskbarAllAppsController, taskbarInsetsController,
- voiceInteractionWindowController, taskbarTranslationController,
- taskbarRecentAppsController
- )
+ mTaskbarControllers =
+ TaskbarControllers(
+ taskbarActivityContext,
+ taskbarDragController,
+ navButtonController,
+ navbarButtonsViewController,
+ rotationButtonController,
+ taskbarDragLayerController,
+ taskbarViewController,
+ taskbarScrimViewController,
+ taskbarUnfoldAnimationController,
+ taskbarKeyguardController,
+ stashedHandleViewController,
+ taskbarStashController,
+ taskbarEduController,
+ taskbarAutohideSuspendController,
+ taskbarPopupController,
+ taskbarForceVisibleImmersiveController,
+ taskbarOverlayController,
+ taskbarAllAppsController,
+ taskbarInsetsController,
+ voiceInteractionWindowController,
+ taskbarTranslationController,
+ taskbarRecentAppsController,
+ taskbarEduTooltipController,
+ )
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/launcher3/util/OnboardingPrefs.java b/src/com/android/launcher3/util/OnboardingPrefs.java
index f4893c7..c146216 100644
--- a/src/com/android/launcher3/util/OnboardingPrefs.java
+++ b/src/com/android/launcher3/util/OnboardingPrefs.java
@@ -44,6 +44,7 @@
public static final String TASKBAR_EDU_SEEN = "launcher.taskbar_edu_seen2";
public static final String ALL_APPS_VISITED_COUNT = "launcher.all_apps_visited_count";
public static final String QSB_SEARCH_ONBOARDING_CARD_DISMISSED = "launcher.qsb_edu_dismiss";
+ public static final String TASKBAR_EDU_TOOLTIP_STEP = "launcher.taskbar_edu_tooltip_step";
// When adding a new key, add it here as well, to be able to reset it from Developer Options.
public static final Map<String, String[]> ALL_PREF_KEYS = Map.of(
"All Apps Bounce", new String[] { HOME_BOUNCE_SEEN, HOME_BOUNCE_COUNT },
@@ -51,7 +52,7 @@
HOTSEAT_LONGPRESS_TIP_SEEN },
"Search Education", new String[] { SEARCH_KEYBOARD_EDU_SEEN, SEARCH_SNACKBAR_COUNT,
SEARCH_ONBOARDING_COUNT, QSB_SEARCH_ONBOARDING_CARD_DISMISSED},
- "Taskbar Education", new String[] { TASKBAR_EDU_SEEN },
+ "Taskbar Education", new String[] { TASKBAR_EDU_SEEN, TASKBAR_EDU_TOOLTIP_STEP },
"All Apps Visited Count", new String[] {ALL_APPS_VISITED_COUNT}
);
@@ -76,7 +77,8 @@
HOTSEAT_DISCOVERY_TIP_COUNT,
SEARCH_SNACKBAR_COUNT,
SEARCH_ONBOARDING_COUNT,
- ALL_APPS_VISITED_COUNT
+ ALL_APPS_VISITED_COUNT,
+ TASKBAR_EDU_TOOLTIP_STEP,
})
@Retention(RetentionPolicy.SOURCE)
public @interface EventCountKey {}
@@ -91,6 +93,7 @@
// This is the sum of all onboarding cards. Currently there is only 1 card shown 3 times.
maxCounts.put(SEARCH_ONBOARDING_COUNT, 3);
maxCounts.put(ALL_APPS_VISITED_COUNT, 20);
+ maxCounts.put(TASKBAR_EDU_TOOLTIP_STEP, 2);
MAX_COUNTS = Collections.unmodifiableMap(maxCounts);
}