Loading quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java +11 −14 Original line number Diff line number Diff line Loading @@ -47,12 +47,12 @@ public class HotseatEduController { public static final String KEY_HOTSEAT_EDU_SEEN = "hotseat_edu_seen"; public static final String HOTSEAT_EDU_ACTION = "com.android.launcher3.action.SHOW_HYBRID_HOTSEAT_EDU"; private static final String SETTINGS_ACTION = public static final String SETTINGS_ACTION = "android.settings.ACTION_CONTENT_SUGGESTIONS_SETTINGS"; private final Launcher mLauncher; private final Hotseat mHotseat; private final HotseatRestoreHelper mRestoreHelper; private HotseatRestoreHelper mRestoreHelper; private List<WorkspaceItemInfo> mPredictedApps; private HotseatEduDialog mActiveDialog; Loading @@ -71,14 +71,17 @@ public class HotseatEduController { * Checks what type of migration should be used and migrates hotseat */ void migrate() { if (mRestoreHelper != null) { mRestoreHelper.createBackup(); } if (FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get()) { migrateToFolder(); } else { migrateHotseatWhole(); } Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_enabled, R.string.hotseat_turn_off, null, () -> mLauncher.startActivity(new Intent(SETTINGS_ACTION))); Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_enabled, R.string.hotseat_prediction_settings, null, () -> mLauncher.startActivity(new Intent(SETTINGS_ACTION))); } /** Loading Loading @@ -223,15 +226,15 @@ public class HotseatEduController { 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))); Snackbar.show(mLauncher, R.string.hotseat_tip_gaps_filled, R.string.hotseat_prediction_settings, null, () -> mLauncher.startActivity(new Intent(SETTINGS_ACTION))); } else { new ArrowTipView(mLauncher).show( mLauncher.getString(R.string.hotseat_tip_no_empty_slots), mHotseat.getTop()); Loading @@ -242,12 +245,6 @@ public class HotseatEduController { mPredictedApps = predictedApps; } void destroy() { if (mActiveDialog != null) { mActiveDialog.setHotseatEduController(null); } } void showEdu() { int childCount = mHotseat.getShortcutsAndWidgets().getChildCount(); CellLayout cellLayout = mLauncher.getWorkspace().getScreenWithId(Workspace.FIRST_SCREEN_ID); Loading quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java +2 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.view.View; import android.widget.Button; import android.widget.TextView; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.CellLayout; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; Loading Loading @@ -245,6 +246,7 @@ public class HotseatEduDialog extends AbstractSlideInView implements Insettable || mHotseatEduController == null) { return; } AbstractFloatingView.closeAllOpenViews(mLauncher); attachToContainer(); logOnBoardingSeen(); animateOpen(); Loading quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java +44 −16 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.launcher3.hybridhotseat; import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.hybridhotseat.HotseatEduController.SETTINGS_ACTION; import android.animation.Animator; import android.animation.AnimatorSet; Loading @@ -27,6 +28,7 @@ import android.app.prediction.AppPredictor; import android.app.prediction.AppTarget; import android.app.prediction.AppTargetEvent; import android.content.ComponentName; import android.content.Intent; import android.util.Log; import android.view.View; import android.view.ViewGroup; Loading Loading @@ -64,6 +66,8 @@ import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.IntArray; import com.android.launcher3.views.ArrowTipView; import com.android.launcher3.views.Snackbar; import java.lang.ref.WeakReference; import java.util.ArrayList; Loading Loading @@ -107,8 +111,6 @@ public class HotseatPredictionController implements DragController.DragListener, private boolean mIsCacheEmpty; private boolean mIsDestroyed = false; private HotseatEduController mHotseatEduController; private List<PredictedAppIcon.PredictedIconOutlineDrawing> mOutlineDrawings = new ArrayList<>(); Loading Loading @@ -146,11 +148,48 @@ public class HotseatPredictionController implements DragController.DragListener, } /** * Transitions to NORMAL workspace mode and shows edu * Shows appropriate hotseat education based on prediction enabled and migration states. */ public void showEdu() { if (mHotseatEduController == null) return; mHotseatEduController.showEdu(); if (mComponentKeyMappers.isEmpty()) { // launcher has empty predictions set Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_disabled, R.string.hotseat_prediction_settings, null, () -> mLauncher.startActivity( new Intent(SETTINGS_ACTION))); } else if (isEduSeen()) { // user has already went through education new ArrowTipView(mLauncher).show( mLauncher.getString(R.string.hotsaet_tip_prediction_enabled), mHotseat.getTop()); } else { HotseatEduController eduController = new HotseatEduController(mLauncher, mRestoreHelper, this::createPredictor); eduController.setPredictedApps(mapToWorkspaceItemInfo(mComponentKeyMappers)); eduController.showEdu(); } } /** * Shows educational tip for hotseat if user does not go through Tips app. */ public void showDiscoveryTip() { if (getPredictedIcons().size() == mHotSeatItemsCount) { new ArrowTipView(mLauncher).show( mLauncher.getString(R.string.hotseat_tip_no_empty_slots), mHotseat.getTop()); } else { Snackbar.show(mLauncher, R.string.hotseat_tip_gaps_filled, R.string.hotseat_prediction_settings, null, () -> mLauncher.startActivity(new Intent(SETTINGS_ACTION))); } } /** * Returns if hotseat client has predictions * @return */ public boolean hasPredictions() { return !mComponentKeyMappers.isEmpty(); } @Override Loading Loading @@ -250,10 +289,6 @@ public class HotseatPredictionController implements DragController.DragListener, if (mAppPredictor != null) { mAppPredictor.destroy(); } if (mHotseatEduController != null) { mHotseatEduController.destroy(); mHotseatEduController = null; } } /** Loading Loading @@ -299,10 +334,6 @@ public class HotseatPredictionController implements DragController.DragListener, mAppPredictor.requestPredictionUpdate(); }); setPauseUIUpdate(false); if (!isEduSeen()) { mHotseatEduController = new HotseatEduController(mLauncher, mRestoreHelper, this::createPredictor); } } /** Loading Loading @@ -350,9 +381,6 @@ public class HotseatPredictionController implements DragController.DragListener, if (Utilities.IS_DEBUG_DEVICE) FileLog.d(TAG, predictionLog.toString()); updateDependencies(); fillGapsWithPrediction(); if (!isEduSeen() && mHotseatEduController != null) { mHotseatEduController.setPredictedApps(mapToWorkspaceItemInfo(mComponentKeyMappers)); } cachePredictionComponentKeysIfNecessary(componentKeys); } Loading quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +2 −9 Original line number Diff line number Diff line Loading @@ -88,7 +88,6 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { */ public static final AsyncCommand SET_SHELF_HEIGHT = (context, arg1, arg2) -> SystemUiProxy.INSTANCE.get(context).setShelfHeight(arg1 != 0, arg2); private HotseatPredictionController mHotseatPredictionController; @Override protected void onCreate(Bundle savedInstanceState) { Loading Loading @@ -168,13 +167,6 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { } } /** * Returns Prediction controller for hybrid hotseat */ public HotseatPredictionController getHotseatPredictionController() { return mHotseatPredictionController; } /** * Recents logic that triggers when launcher state changes or launcher activity stops/resumes. */ Loading @@ -195,7 +187,8 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { @Override public void bindPredictedItems(List<AppInfo> appInfos, IntArray ranks) { super.bindPredictedItems(appInfos, ranks); if (mHotseatPredictionController != null) { if (mHotseatPredictionController != null && !mHotseatPredictionController.hasPredictions()) { mHotseatPredictionController.showCachedItems(appInfos, ranks); } } Loading quickstep/res/values/strings.xml +5 −3 Original line number Diff line number Diff line Loading @@ -76,8 +76,8 @@ <!-- Button text to dismiss opt in for fully predicted hotseat --> <string name="hotseat_edu_dismiss">No thanks</string> <!-- action shown to turn off predictions after onboarding --> <string name="hotseat_turn_off">Settings</string> <!-- action shown to toggle predictions after onboarding --> <string name="hotseat_prediction_settings">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> Loading @@ -86,7 +86,9 @@ <!-- 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> <!-- tip shown when user migrates and predictions are enabled in hotseat --> <string name="hotsaet_tip_prediction_enabled">App suggestions Enabled</string> <string name="hotsaet_tip_prediction_enabled">App suggestions enabled</string> <!-- tip shown when hotseat edu is requested while predicions are disabled --> <string name="hotsaet_tip_prediction_disabled">App suggestions are disabled</string> <!-- content description for hotseat items --> <string name="hotseat_prediction_content_description">Predicted app: <xliff:g id="title" example="Chrome">%1$s</xliff:g></string> Loading Loading
quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java +11 −14 Original line number Diff line number Diff line Loading @@ -47,12 +47,12 @@ public class HotseatEduController { public static final String KEY_HOTSEAT_EDU_SEEN = "hotseat_edu_seen"; public static final String HOTSEAT_EDU_ACTION = "com.android.launcher3.action.SHOW_HYBRID_HOTSEAT_EDU"; private static final String SETTINGS_ACTION = public static final String SETTINGS_ACTION = "android.settings.ACTION_CONTENT_SUGGESTIONS_SETTINGS"; private final Launcher mLauncher; private final Hotseat mHotseat; private final HotseatRestoreHelper mRestoreHelper; private HotseatRestoreHelper mRestoreHelper; private List<WorkspaceItemInfo> mPredictedApps; private HotseatEduDialog mActiveDialog; Loading @@ -71,14 +71,17 @@ public class HotseatEduController { * Checks what type of migration should be used and migrates hotseat */ void migrate() { if (mRestoreHelper != null) { mRestoreHelper.createBackup(); } if (FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get()) { migrateToFolder(); } else { migrateHotseatWhole(); } Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_enabled, R.string.hotseat_turn_off, null, () -> mLauncher.startActivity(new Intent(SETTINGS_ACTION))); Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_enabled, R.string.hotseat_prediction_settings, null, () -> mLauncher.startActivity(new Intent(SETTINGS_ACTION))); } /** Loading Loading @@ -223,15 +226,15 @@ public class HotseatEduController { 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))); Snackbar.show(mLauncher, R.string.hotseat_tip_gaps_filled, R.string.hotseat_prediction_settings, null, () -> mLauncher.startActivity(new Intent(SETTINGS_ACTION))); } else { new ArrowTipView(mLauncher).show( mLauncher.getString(R.string.hotseat_tip_no_empty_slots), mHotseat.getTop()); Loading @@ -242,12 +245,6 @@ public class HotseatEduController { mPredictedApps = predictedApps; } void destroy() { if (mActiveDialog != null) { mActiveDialog.setHotseatEduController(null); } } void showEdu() { int childCount = mHotseat.getShortcutsAndWidgets().getChildCount(); CellLayout cellLayout = mLauncher.getWorkspace().getScreenWithId(Workspace.FIRST_SCREEN_ID); Loading
quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java +2 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.view.View; import android.widget.Button; import android.widget.TextView; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.CellLayout; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; Loading Loading @@ -245,6 +246,7 @@ public class HotseatEduDialog extends AbstractSlideInView implements Insettable || mHotseatEduController == null) { return; } AbstractFloatingView.closeAllOpenViews(mLauncher); attachToContainer(); logOnBoardingSeen(); animateOpen(); Loading
quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java +44 −16 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.launcher3.hybridhotseat; import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.hybridhotseat.HotseatEduController.SETTINGS_ACTION; import android.animation.Animator; import android.animation.AnimatorSet; Loading @@ -27,6 +28,7 @@ import android.app.prediction.AppPredictor; import android.app.prediction.AppTarget; import android.app.prediction.AppTargetEvent; import android.content.ComponentName; import android.content.Intent; import android.util.Log; import android.view.View; import android.view.ViewGroup; Loading Loading @@ -64,6 +66,8 @@ import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.IntArray; import com.android.launcher3.views.ArrowTipView; import com.android.launcher3.views.Snackbar; import java.lang.ref.WeakReference; import java.util.ArrayList; Loading Loading @@ -107,8 +111,6 @@ public class HotseatPredictionController implements DragController.DragListener, private boolean mIsCacheEmpty; private boolean mIsDestroyed = false; private HotseatEduController mHotseatEduController; private List<PredictedAppIcon.PredictedIconOutlineDrawing> mOutlineDrawings = new ArrayList<>(); Loading Loading @@ -146,11 +148,48 @@ public class HotseatPredictionController implements DragController.DragListener, } /** * Transitions to NORMAL workspace mode and shows edu * Shows appropriate hotseat education based on prediction enabled and migration states. */ public void showEdu() { if (mHotseatEduController == null) return; mHotseatEduController.showEdu(); if (mComponentKeyMappers.isEmpty()) { // launcher has empty predictions set Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_disabled, R.string.hotseat_prediction_settings, null, () -> mLauncher.startActivity( new Intent(SETTINGS_ACTION))); } else if (isEduSeen()) { // user has already went through education new ArrowTipView(mLauncher).show( mLauncher.getString(R.string.hotsaet_tip_prediction_enabled), mHotseat.getTop()); } else { HotseatEduController eduController = new HotseatEduController(mLauncher, mRestoreHelper, this::createPredictor); eduController.setPredictedApps(mapToWorkspaceItemInfo(mComponentKeyMappers)); eduController.showEdu(); } } /** * Shows educational tip for hotseat if user does not go through Tips app. */ public void showDiscoveryTip() { if (getPredictedIcons().size() == mHotSeatItemsCount) { new ArrowTipView(mLauncher).show( mLauncher.getString(R.string.hotseat_tip_no_empty_slots), mHotseat.getTop()); } else { Snackbar.show(mLauncher, R.string.hotseat_tip_gaps_filled, R.string.hotseat_prediction_settings, null, () -> mLauncher.startActivity(new Intent(SETTINGS_ACTION))); } } /** * Returns if hotseat client has predictions * @return */ public boolean hasPredictions() { return !mComponentKeyMappers.isEmpty(); } @Override Loading Loading @@ -250,10 +289,6 @@ public class HotseatPredictionController implements DragController.DragListener, if (mAppPredictor != null) { mAppPredictor.destroy(); } if (mHotseatEduController != null) { mHotseatEduController.destroy(); mHotseatEduController = null; } } /** Loading Loading @@ -299,10 +334,6 @@ public class HotseatPredictionController implements DragController.DragListener, mAppPredictor.requestPredictionUpdate(); }); setPauseUIUpdate(false); if (!isEduSeen()) { mHotseatEduController = new HotseatEduController(mLauncher, mRestoreHelper, this::createPredictor); } } /** Loading Loading @@ -350,9 +381,6 @@ public class HotseatPredictionController implements DragController.DragListener, if (Utilities.IS_DEBUG_DEVICE) FileLog.d(TAG, predictionLog.toString()); updateDependencies(); fillGapsWithPrediction(); if (!isEduSeen() && mHotseatEduController != null) { mHotseatEduController.setPredictedApps(mapToWorkspaceItemInfo(mComponentKeyMappers)); } cachePredictionComponentKeysIfNecessary(componentKeys); } Loading
quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +2 −9 Original line number Diff line number Diff line Loading @@ -88,7 +88,6 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { */ public static final AsyncCommand SET_SHELF_HEIGHT = (context, arg1, arg2) -> SystemUiProxy.INSTANCE.get(context).setShelfHeight(arg1 != 0, arg2); private HotseatPredictionController mHotseatPredictionController; @Override protected void onCreate(Bundle savedInstanceState) { Loading Loading @@ -168,13 +167,6 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { } } /** * Returns Prediction controller for hybrid hotseat */ public HotseatPredictionController getHotseatPredictionController() { return mHotseatPredictionController; } /** * Recents logic that triggers when launcher state changes or launcher activity stops/resumes. */ Loading @@ -195,7 +187,8 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { @Override public void bindPredictedItems(List<AppInfo> appInfos, IntArray ranks) { super.bindPredictedItems(appInfos, ranks); if (mHotseatPredictionController != null) { if (mHotseatPredictionController != null && !mHotseatPredictionController.hasPredictions()) { mHotseatPredictionController.showCachedItems(appInfos, ranks); } } Loading
quickstep/res/values/strings.xml +5 −3 Original line number Diff line number Diff line Loading @@ -76,8 +76,8 @@ <!-- Button text to dismiss opt in for fully predicted hotseat --> <string name="hotseat_edu_dismiss">No thanks</string> <!-- action shown to turn off predictions after onboarding --> <string name="hotseat_turn_off">Settings</string> <!-- action shown to toggle predictions after onboarding --> <string name="hotseat_prediction_settings">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> Loading @@ -86,7 +86,9 @@ <!-- 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> <!-- tip shown when user migrates and predictions are enabled in hotseat --> <string name="hotsaet_tip_prediction_enabled">App suggestions Enabled</string> <string name="hotsaet_tip_prediction_enabled">App suggestions enabled</string> <!-- tip shown when hotseat edu is requested while predicions are disabled --> <string name="hotsaet_tip_prediction_disabled">App suggestions are disabled</string> <!-- content description for hotseat items --> <string name="hotseat_prediction_content_description">Predicted app: <xliff:g id="title" example="Chrome">%1$s</xliff:g></string> Loading