Beta specific hotseat opt in behavior

https://docs.google.com/document/d/1CKK-3vTl-SPGxx3Cwty7r69jk_vaDs9MlanbhpH85cY/edit

Bug: 142753423
Test: Manual
Change-Id: I51e949fa9962bc8e9d0cdb66d07fbe9e344fb35d
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 a7fb6e1..c03d2c4 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
@@ -62,6 +62,7 @@
             "android.settings.ACTION_CONTENT_SUGGESTIONS_SETTINGS";
 
     private final Launcher mLauncher;
+    private final Hotseat mHotseat;
     private final NotificationManager mNotificationManager;
     private final Notification mNotification;
     private List<WorkspaceItemInfo> mPredictedApps;
@@ -70,7 +71,6 @@
     private ArrayList<ItemInfo> mNewItems = new ArrayList<>();
     private IntArray mNewScreens = null;
     private Runnable mOnOnboardingComplete;
-    private Hotseat mHotseat;
 
     HotseatEduController(Launcher launcher, Runnable runnable) {
         mLauncher = launcher;
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 322ec5d..8944088 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
@@ -163,6 +163,7 @@
         target.rank = MIGRATION_EXPERIMENT_IDENTIFIER;
         // encoding migration type on pageIndex
         target.pageIndex = pageIndex;
+        target.cardinality = HotseatPredictionController.MAX_ITEMS_FOR_MIGRATION;
         LauncherLogProto.LauncherEvent event = newLauncherEvent(action, target);
         UserEventDispatcher.newInstance(getContext()).dispatchUserEvent(event, null);
     }
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 7eb82a9..d3bb4f9 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
@@ -16,6 +16,9 @@
 package com.android.launcher3.hybridhotseat;
 
 import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.logging.LoggerUtils.newAction;
+import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
 
 import android.animation.Animator;
 import android.animation.AnimatorSet;
@@ -28,6 +31,7 @@
 import android.app.prediction.AppTargetId;
 import android.content.ComponentName;
 import android.os.Bundle;
+import android.provider.DeviceConfig;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -59,9 +63,11 @@
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.logging.FileLog;
+import com.android.launcher3.logging.UserEventDispatcher;
 import com.android.launcher3.popup.SystemShortcut;
 import com.android.launcher3.shortcuts.ShortcutKey;
 import com.android.launcher3.touch.ItemLongClickListener;
+import com.android.launcher3.uioverrides.DeviceFlag;
 import com.android.launcher3.uioverrides.PredictedAppIcon;
 import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
@@ -85,6 +91,9 @@
     private static final String TAG = "PredictiveHotseat";
     private static final boolean DEBUG = false;
 
+    public static final int MAX_ITEMS_FOR_MIGRATION = DeviceConfig.getInt(
+            DeviceFlag.NAMESPACE_LAUNCHER, "max_homepage_items_for_migration", 5);
+
     //TODO: replace this with AppTargetEvent.ACTION_UNPIN (b/144119543)
     private static final int APPTARGET_ACTION_UNPIN = 4;
 
@@ -113,8 +122,8 @@
 
     private HotseatEduController mHotseatEduController;
 
-    private List<PredictedAppIcon.PredictedIconOutlineDrawing> mOutlineDrawings = new ArrayList<>();
 
+    private List<PredictedAppIcon.PredictedIconOutlineDrawing> mOutlineDrawings = new ArrayList<>();
 
     private final View.OnLongClickListener mPredictionLongClickListener = v -> {
         if (!ItemLongClickListener.canStartDrag(mLauncher)) return false;
@@ -278,7 +287,7 @@
         mAppPredictor.registerPredictionUpdates(mLauncher.getMainExecutor(),
                 this::setPredictedApps);
         setPauseUIUpdate(false);
-
+        performBetaCheck();
         if (!isReady()) {
             mHotseatEduController = new HotseatEduController(mLauncher, this::createPredictor);
         }
@@ -590,6 +599,39 @@
         }
     }
 
+    private void performBetaCheck() {
+        if (isReady()) return;
+        int hotseatItemsCount = mHotseat.getShortcutsAndWidgets().getChildCount();
+
+        // -1 to exclude smart space
+        int workspaceItemCount = mLauncher.getWorkspace().getScreenWithId(
+                Workspace.FIRST_SCREEN_ID).getShortcutsAndWidgets().getChildCount() - 1;
+
+        // opt user into the feature without onboarding tip or migration if they don't have any
+        // open spots in their hotseat and have more than maxItems in their hotseat + workspace
+
+        if (hotseatItemsCount == mHotSeatItemsCount && workspaceItemCount + hotseatItemsCount
+                > MAX_ITEMS_FOR_MIGRATION) {
+            mLauncher.getSharedPrefs().edit().putBoolean(HotseatEduController.KEY_HOTSEAT_EDU_SEEN,
+                    true).apply();
+
+            LauncherLogProto.Action action = newAction(LauncherLogProto.Action.Type.TOUCH);
+            LauncherLogProto.Target target = newContainerTarget(LauncherLogProto.ContainerType.TIP);
+            action.touch = LauncherLogProto.Action.Touch.TAP;
+            target.tipType = LauncherLogProto.TipType.HYBRID_HOTSEAT;
+            target.controlType = LauncherLogProto.ControlType.HYBRID_HOTSEAT_CANCELED;
+
+            // temporarily encode details in log target (go/hotseat_migration)
+            target.rank = 2;
+            target.cardinality = MAX_ITEMS_FOR_MIGRATION;
+            target.pageIndex = (workspaceItemCount * 1000) + hotseatItemsCount;
+            LauncherLogProto.LauncherEvent event = newLauncherEvent(action, target);
+            UserEventDispatcher.newInstance(mLauncher).dispatchUserEvent(event, null);
+
+
+        }
+    }
+
     /**
      * Fill in predicted_rank field based on app prediction.
      * Only applicable when {@link ItemInfo#itemType} is PREDICTED_HOTSEAT
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 31a9bdf..ab34f47 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -83,15 +83,15 @@
     <!-- 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 -->
+    <!-- action shown to turn off 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>
+    <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 some 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] -->