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] -->