From 8e714d42aed4df42d2a4d90c74f28284cd172bdf Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Sun, 22 Mar 2020 13:11:29 -0700 Subject: [PATCH 1/7] Update launcher call to fetch recent tasks - Always just fetch the tasks that will end up in recents Bug: 152133859 Test: Manual, swipe up with pip/assistant and verify nothing changed Change-Id: I41719e111cba85da7e93f65681b7b50b4c5c4a46 --- .../quickstep/TouchInteractionService.java | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 25a307852d..fc1630c5b9 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -439,7 +439,7 @@ public class TouchInteractionService extends Service implements PluginListener mAM.getRunningTask(0))); + () -> mAM.getRunningTask(true /* filterOnlyVisibleRecents */))); if (mDeviceState.isInSwipeUpTouchRegion(event)) { mConsumer.onConsumerAboutToBeSwitched(); @@ -567,18 +567,10 @@ public class TouchInteractionService extends Service implements PluginListener mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT /* ignoreActivityType */))); - ComponentName homeComponent = mOverviewComponentObserver.getHomeIntent().getComponent(); - ComponentName runningComponent = - gestureState.getRunningTask().baseIntent.getComponent(); - forceOverviewInputConsumer = - runningComponent != null && runningComponent.equals(homeComponent); - } + RunningTaskInfo runningTask = gestureState.getRunningTask(); + ComponentName homeComponent = mOverviewComponentObserver.getHomeIntent().getComponent(); + boolean forceOverviewInputConsumer = runningTask != null + && runningTask.baseIntent.getComponent().equals(homeComponent); if (previousGestureState.getFinishingRecentsAnimationTaskId() > 0) { // If the finish animation was interrupted, then continue using the other activity input From 08c4d9923782acee8c450bb02d034d004b04cfc6 Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Wed, 25 Mar 2020 22:07:56 +0000 Subject: [PATCH 2/7] Revert "Default fixed_rotation to off" This reverts commit c0b289c93eee2ecf126acf561d6e72fabc7b354f. Reason for revert: fixed in ag/10826395 Bug: 151727009 Change-Id: I0c71d5d47a6825c2445bf8dc9d8a9a1ca23f9e64 --- src/com/android/launcher3/config/FeatureFlags.java | 2 +- src/com/android/launcher3/states/RotationHelper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 650b20a7f4..471a743ab4 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -156,7 +156,7 @@ public final class FeatureFlags { "Always use hardware optimization for folder animations."); public static final BooleanFlag ENABLE_FIXED_ROTATION_TRANSFORM = getDebugFlag( - FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, false, + FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, true, "Launch/close apps without rotation animation. Fix Launcher to portrait"); public static void initialize(Context context) { diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java index 8c8aa9b8e5..fae0fe2d81 100644 --- a/src/com/android/launcher3/states/RotationHelper.java +++ b/src/com/android/launcher3/states/RotationHelper.java @@ -134,7 +134,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { */ private void updateForcedRotation(boolean setValueFromPrefs) { boolean isForcedRotation = mFeatureFlagsPrefs - .getBoolean(FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, false) + .getBoolean(FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, true) && !getAllowRotationDefaultValue(); if (mForcedRotation == isForcedRotation) { return; From 210774dfaa0ff163f206e07d049892f4e63300b4 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Mon, 23 Mar 2020 10:03:06 -0700 Subject: [PATCH 3/7] enable prediction logging reverting accidental commit on ag/10673926 Bug: 142753423 Change-Id: I8d2f5f591b200484282f0b170fccab4f99b93fae (cherry picked from commit 0570a795f99e67079fb999eb5b7e86d1672a4094) --- .../launcher3/hybridhotseat/HotseatPredictionController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 d82e9f0115..801408f488 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 @@ -48,6 +48,7 @@ import com.android.launcher3.Launcher; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherState; import com.android.launcher3.R; +import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.allapps.AllAppsStore; @@ -325,7 +326,7 @@ public class HotseatPredictionController implements DragController.DragListener, mComponentKeyMappers.add(new ComponentKeyMapper(key, mDynamicItemCache)); } predictionLog.append("]"); - if (false) FileLog.d(TAG, predictionLog.toString()); + if (Utilities.IS_DEBUG_DEVICE) FileLog.d(TAG, predictionLog.toString()); updateDependencies(); if (isReady()) { fillGapsWithPrediction(); From cac6ef1ee97d51bf1587560a93e35b6a890f98b7 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Tue, 24 Mar 2020 16:46:12 -0700 Subject: [PATCH 4/7] Resume UI update on user active resume UI update for hybrid hotseat if user returns to launcher while app launch transition is animating. Bug: 142753423 Test: Manual Change-Id: I11ffa080bb78e7b4269747b1602b32d706f2405d (cherry picked from commit 28f3136c6a0f6101be7ca6e9132becabe9a9bbf6) --- .../com/android/launcher3/uioverrides/QuickstepLauncher.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 30a4e508d9..9352acef12 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -184,8 +184,8 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { onStateOrResumeChanged(); } - if ((changeBits & ACTIVITY_STATE_STARTED) != 0 && mHotseatPredictionController != null - && (getActivityFlags() & ACTIVITY_STATE_USER_ACTIVE) == 0) { + if (mHotseatPredictionController != null && ((changeBits & ACTIVITY_STATE_STARTED) != 0 + || (changeBits & getActivityFlags() & ACTIVITY_STATE_DEFERRED_RESUMED) != 0)) { mHotseatPredictionController.setPauseUIUpdate(false); } } From 32bf6cd6509a9cd5a81b1b319ee5ce8973301ae5 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Wed, 25 Mar 2020 13:42:23 -0700 Subject: [PATCH 5/7] Remove Edu notification if predictions are empty Bug: 142753423 Test: Manual Change-Id: I1111fa15b9b677bb077478309a185e70e6784bce (cherry picked from commit ca1c32537c94872393ca2d2568c5a251c0246913) --- .../android/launcher3/hybridhotseat/HotseatEduController.java | 3 +++ 1 file changed, 3 insertions(+) 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 da588173af..d68c3f5e07 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 @@ -238,6 +238,9 @@ public class HotseatEduController { && mLauncher.getOrientation() == Configuration.ORIENTATION_PORTRAIT) { mNotificationManager.notify(ONBOARDING_NOTIFICATION_ID, mNotification); } + else { + removeNotification(); + } } private void createNotificationChannel() { From 0068e1861c2bc6f0339bccca005afc91a04466dc Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Tue, 24 Mar 2020 18:34:12 -0700 Subject: [PATCH 6/7] 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 (cherry picked from commit aa2aff5a8f29027b3e49246028f8e5261f3b2cc8) --- .../hybridhotseat/HotseatEduController.java | 43 ++++++++++++++++--- .../hybridhotseat/HotseatEduDialog.java | 13 +++--- .../HotseatPredictionController.java | 6 +-- quickstep/res/values/strings.xml | 15 ++++--- 4 files changed, 55 insertions(+), 22 deletions(-) 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 d68c3f5e07..dd3802bd5b 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 android.view.View; 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.ActivityTracker; 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 @@ public class HotseatEduController { 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 @@ public class HotseatEduController { private ArrayList 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 @@ public class HotseatEduController { //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 @@ public class HotseatEduController { */ private int migrateHotseatWhole() { Workspace workspace = mLauncher.getWorkspace(); - Hotseat hotseatVG = mLauncher.getHotseat(); int pageId = -1; int toRow = 0; @@ -196,7 +202,7 @@ public class HotseatEduController { .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 @@ public class HotseatEduController { 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 animated = new ArrayList<>(); @@ -227,11 +233,25 @@ public class HotseatEduController { } 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 predictedApps) { mPredictedApps = predictedApps; if (!mPredictedApps.isEmpty() @@ -278,6 +298,17 @@ public class HotseatEduController { } } + 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; @@ -294,7 +325,7 @@ public class HotseatEduController { ActivityTracker.SchedulerCallback { @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 f7db9eaa5b..3569c7155b 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.LayoutInflater; 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; @@ -108,18 +107,16 @@ public class HotseatEduDialog extends AbstractSlideInView implements Insettable 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 801408f488..7eb82a9428 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 @@ public class HotseatPredictionController implements DragController.DragListener, } /** - * 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 b55b042dda..31a9bdf47b 100644 --- a/quickstep/res/values/strings.xml +++ b/quickstep/res/values/strings.xml @@ -78,16 +78,21 @@ 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. 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. - - Your hotseat items have been moved up to your homescreen - Your hotseat items have been moved to a folder - - Drag apps off the bottom row to see app suggestions Get app suggestions No thanks + + Settings + + + Most-used apps appear here, and change based on routines + + Drag apps off the bottom row to get app suggestions + + App suggestions added to empty space. + Try the back gesture From 59affa428ec8396638d7b76c771d861adb0bcf93 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Wed, 25 Mar 2020 13:11:38 -0700 Subject: [PATCH 7/7] Beta specific hotseat opt in behavior https://docs.google.com/document/d/1CKK-3vTl-SPGxx3Cwty7r69jk_vaDs9MlanbhpH85cY/edit Bug: 142753423 Test: Manual Change-Id: I51e949fa9962bc8e9d0cdb66d07fbe9e344fb35d (cherry picked from commit 6b13c841c90289c3ad75dcee32d0741c6b502e9b) --- .../hybridhotseat/HotseatEduController.java | 2 +- .../hybridhotseat/HotseatEduDialog.java | 1 + .../HotseatPredictionController.java | 46 ++++++++++++++++++- 3 files changed, 46 insertions(+), 3 deletions(-) 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 dd3802bd5b..5b01185ca3 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 @@ public class HotseatEduController { "android.settings.ACTION_CONTENT_SUGGESTIONS_SETTINGS"; private final Launcher mLauncher; + private final Hotseat mHotseat; private final NotificationManager mNotificationManager; private final Notification mNotification; private List mPredictedApps; @@ -70,7 +71,6 @@ public class HotseatEduController { private ArrayList 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 3569c7155b..ffc1e291be 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 @@ -162,6 +162,7 @@ public class HotseatEduDialog extends AbstractSlideInView implements Insettable 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 7eb82a9428..d3bb4f9062 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.AppTargetEvent; 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.DragController; 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 @@ public class HotseatPredictionController implements DragController.DragListener, 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 @@ public class HotseatPredictionController implements DragController.DragListener, private HotseatEduController mHotseatEduController; - private List mOutlineDrawings = new ArrayList<>(); + private List mOutlineDrawings = new ArrayList<>(); private final View.OnLongClickListener mPredictionLongClickListener = v -> { if (!ItemLongClickListener.canStartDrag(mLauncher)) return false; @@ -278,7 +287,7 @@ public class HotseatPredictionController implements DragController.DragListener, mAppPredictor.registerPredictionUpdates(mLauncher.getMainExecutor(), this::setPredictedApps); setPauseUIUpdate(false); - + performBetaCheck(); if (!isReady()) { mHotseatEduController = new HotseatEduController(mLauncher, this::createPredictor); } @@ -590,6 +599,39 @@ public class HotseatPredictionController implements DragController.DragListener, } } + 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