Personalize hotseat education

If a user has has 0 apps in the hotseat, jump directly to showing predications.
Otherwise show migration dialog as usual and if user rejects it, show different tips based on the number of available spots.

Bug: 142753423
Test: Manual
Change-Id: Ic5202caf074db2409f6468dd9373875571f3f3c1
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
index da58817..a7fb6e1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
@@ -26,6 +26,7 @@
 
 import androidx.core.app.NotificationCompat;
 
+import com.android.launcher3.ArrowTipView;
 import com.android.launcher3.CellLayout;
 import com.android.launcher3.FolderInfo;
 import com.android.launcher3.Hotseat;
@@ -42,6 +43,7 @@
 import com.android.launcher3.util.GridOccupancy;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.Themes;
+import com.android.launcher3.views.Snackbar;
 
 import java.util.ArrayDeque;
 import java.util.ArrayList;
@@ -56,6 +58,9 @@
     private static final String NOTIFICATION_CHANNEL_ID = "launcher_onboarding";
     private static final int ONBOARDING_NOTIFICATION_ID = 7641;
 
+    private static final String SETTINGS_ACTION =
+            "android.settings.ACTION_CONTENT_SUGGESTIONS_SETTINGS";
+
     private final Launcher mLauncher;
     private final NotificationManager mNotificationManager;
     private final Notification mNotification;
@@ -65,9 +70,11 @@
     private ArrayList<ItemInfo> mNewItems = new ArrayList<>();
     private IntArray mNewScreens = null;
     private Runnable mOnOnboardingComplete;
+    private Hotseat mHotseat;
 
     HotseatEduController(Launcher launcher, Runnable runnable) {
         mLauncher = launcher;
+        mHotseat = launcher.getHotseat();
         mOnOnboardingComplete = runnable;
         mNotificationManager = mLauncher.getSystemService(NotificationManager.class);
         createNotificationChannel();
@@ -98,7 +105,7 @@
 
         //separate folders and items that can get in folders
         for (int i = 0; i < mLauncher.getDeviceProfile().inv.numHotseatIcons; i++) {
-            View view = mLauncher.getHotseat().getChildAt(i, 0);
+            View view = mHotseat.getChildAt(i, 0);
             if (view == null) continue;
             ItemInfo info = (ItemInfo) view.getTag();
             if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
@@ -178,7 +185,6 @@
      */
     private int migrateHotseatWhole() {
         Workspace workspace = mLauncher.getWorkspace();
-        Hotseat hotseatVG = mLauncher.getHotseat();
 
         int pageId = -1;
         int toRow = 0;
@@ -196,7 +202,7 @@
                     .getInt(LauncherSettings.Settings.EXTRA_VALUE);
         }
         for (int i = 0; i < mLauncher.getDeviceProfile().inv.numHotseatIcons; i++) {
-            View child = hotseatVG.getChildAt(i, 0);
+            View child = mHotseat.getChildAt(i, 0);
             if (child == null || child.getTag() == null) continue;
             ItemInfo tag = (ItemInfo) child.getTag();
             mLauncher.getModelWriter().moveItemInDatabase(tag,
@@ -211,8 +217,8 @@
         mNotificationManager.cancel(ONBOARDING_NOTIFICATION_ID);
     }
 
-    void finishOnboarding() {
-        mLauncher.getHotseat().removeAllViewsInLayout();
+    void moveHotseatItems() {
+        mHotseat.removeAllViewsInLayout();
         if (!mNewItems.isEmpty()) {
             int lastPage = mNewItems.get(mNewItems.size() - 1).screenId;
             ArrayList<ItemInfo> animated = new ArrayList<>();
@@ -227,11 +233,25 @@
             }
             mLauncher.bindAppsAdded(mNewScreens, nonAnimated, animated);
         }
+    }
+
+    void finishOnboarding() {
         mOnOnboardingComplete.run();
         destroy();
         mLauncher.getSharedPrefs().edit().putBoolean(KEY_HOTSEAT_EDU_SEEN, true).apply();
     }
 
+    void showDimissTip() {
+        if (mHotseat.getShortcutsAndWidgets().getChildCount()
+                < mLauncher.getDeviceProfile().inv.numHotseatIcons) {
+            Snackbar.show(mLauncher, R.string.hotseat_tip_gaps_filled, R.string.hotseat_turn_off,
+                    null, () -> mLauncher.startActivity(new Intent(SETTINGS_ACTION)));
+        } else {
+            new ArrowTipView(mLauncher).show(
+                    mLauncher.getString(R.string.hotseat_tip_no_empty_slots), mHotseat.getTop());
+        }
+    }
+
     void setPredictedApps(List<WorkspaceItemInfo> predictedApps) {
         mPredictedApps = predictedApps;
         if (!mPredictedApps.isEmpty()
@@ -275,6 +295,17 @@
         }
     }
 
+    void showEdu() {
+        // hotseat is already empty and does not require migration. show edu tip
+        if (mHotseat.getShortcutsAndWidgets().getChildCount() == 0) {
+            new ArrowTipView(mLauncher).show(mLauncher.getString(R.string.hotseat_auto_enrolled),
+                    mHotseat.getTop());
+            finishOnboarding();
+        } else {
+            showDialog();
+        }
+    }
+
     void showDialog() {
         if (mPredictedApps == null || mPredictedApps.isEmpty()) {
             return;
@@ -291,7 +322,7 @@
             ActivityTracker.SchedulerCallback<QuickstepLauncher> {
         @Override
         public boolean init(QuickstepLauncher activity, boolean alreadyOnHome) {
-            activity.getHotseatPredictionController().showEduDialog();
+            activity.getHotseatPredictionController().showEdu();
             return true;
         }
     }
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
index bcce168..322ec5d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
@@ -16,7 +16,8 @@
 package com.android.launcher3.hybridhotseat;
 
 import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.HYBRID_HOTSEAT_CANCELED;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType
+        .HYBRID_HOTSEAT_CANCELED;
 
 import android.animation.PropertyValuesHolder;
 import android.content.Context;
@@ -27,9 +28,7 @@
 import android.view.View;
 import android.widget.Button;
 import android.widget.TextView;
-import android.widget.Toast;
 
-import com.android.launcher3.ArrowTipView;
 import com.android.launcher3.CellLayout;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Insettable;
@@ -109,18 +108,16 @@
     private void onAccept(View v) {
         mHotseatEduController.migrate();
         handleClose(true);
+
+        mHotseatEduController.moveHotseatItems();
         mHotseatEduController.finishOnboarding();
         //TODO: pass actual page index here.
         // Temporarily we're passing 1 for folder migration and 2 for page migration
         logUserAction(true, FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get() ? 1 : 2);
-        int toastStringRes = !FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get()
-                ? R.string.hotseat_items_migrated : R.string.hotseat_items_migrated_alt;
-        Toast.makeText(mLauncher, toastStringRes, Toast.LENGTH_LONG).show();
     }
 
     private void onDismiss(View v) {
-        int top = mLauncher.getHotseat().getTop();
-        new ArrowTipView(mLauncher).show(mLauncher.getString(R.string.hotseat_no_migration), top);
+        mHotseatEduController.showDimissTip();
         mHotseatEduController.finishOnboarding();
         logUserAction(false, -1);
         handleClose(true);
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 801408f..7eb82a9 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -147,12 +147,12 @@
     }
 
     /**
-     * Transitions to NORMAL workspace mode and shows edu dialog
+     * Transitions to NORMAL workspace mode and shows edu
      */
-    public void showEduDialog() {
+    public void showEdu() {
         if (mHotseatEduController == null) return;
         mLauncher.getStateManager().goToState(LauncherState.NORMAL, true,
-                () -> mHotseatEduController.showDialog());
+                () -> mHotseatEduController.showEdu());
     }
 
     @Override
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index b55b042..31a9bdf 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -78,16 +78,21 @@
     <string name="hotseat_edu_message_migrate">Easily access your most-used apps right on the Home screen. Suggestions will change based on your routines. Apps on the bottom row will move up to your Home screen. </string>
     <string name="hotseat_edu_message_migrate_alt">Easily access your most-used apps, right on the Home screen. Suggestions will change based on your routines. Apps on the bottom row will move to a new folder.</string>
 
-    <!-- Toast message user sees after opting into fully predicted hybrid hotseat -->
-    <string name="hotseat_items_migrated">Your hotseat items have been moved up to your homescreen</string>
-    <string name="hotseat_items_migrated_alt">Your hotseat items have been moved to a folder</string>
-    <!-- Toast message user sees after opting into fully predicted hybrid hotseat -->
-    <string name="hotseat_no_migration">Drag apps off the bottom row to see app suggestions</string>
     <!-- Button text to opt in for fully predicted hotseat -->
     <string name="hotseat_edu_accept">Get app suggestions</string>
     <!-- Button text to dismiss opt in for fully predicted hotseat -->
     <string name="hotseat_edu_dismiss">No thanks</string>
 
+    <!-- action shown to turn of predictions after onboarding -->
+    <string name="hotseat_turn_off">Settings</string>
+
+    <!-- tip shown if user has no items in hotseat to migrate -->
+    <string name="hotseat_auto_enrolled">Most-used apps appear here, and change based on routines</string>
+    <!-- tip shown if user declines migration and has some open spots for prediction -->
+    <string name="hotseat_tip_no_empty_slots">Drag apps off the bottom row to get app suggestions</string>
+    <!-- tip shown if user declines migration and has no open spots for prediction -->
+    <string name="hotseat_tip_gaps_filled">App suggestions added to empty space.</string>
+
 
     <!-- Title shown during interactive part of Back gesture tutorial for right edge. [CHAR LIMIT=30] -->
     <string name="back_gesture_tutorial_playground_title_swipe_inward_right_edge" translatable="false">Try the back gesture</string>