Moving onboarding prefs to use LauncherPrefs

Bug: 301661768
Test: Presubmit
Flag: N/A
Change-Id: Iec8a5e739f394a152d5ffc57b01e0449e94b4084
diff --git a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
index e8374b8..037f7a8 100644
--- a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
@@ -35,9 +35,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.allapps.FloatingHeaderRow;
 import com.android.launcher3.allapps.FloatingHeaderView;
-import com.android.launcher3.util.OnboardingPrefs;
 import com.android.launcher3.util.Themes;
-import com.android.launcher3.views.ActivityContext;
 
 /**
  * A view which shows a horizontal divider
@@ -93,10 +91,7 @@
                 ? R.color.all_apps_label_text_dark
                 : R.color.all_apps_label_text);
 
-        OnboardingPrefs<?> onboardingPrefs = ActivityContext.lookupContext(
-                getContext()).getOnboardingPrefs();
-        mShowAllAppsLabel = onboardingPrefs == null || !onboardingPrefs.hasReachedMaxCount(
-                ALL_APPS_VISITED_COUNT);
+        mShowAllAppsLabel = !ALL_APPS_VISITED_COUNT.hasReachedMax(context);
     }
 
     public void setup(FloatingHeaderView parent, FloatingHeaderRow[] rows, boolean tabsHidden) {
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index a63f9e8..baea418 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -23,6 +23,7 @@
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_RANKED;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.FlagDebugUtils.appendFlag;
+import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_LONGPRESS_TIP_SEEN;
 
 import android.animation.Animator;
 import android.animation.AnimatorSet;
@@ -41,6 +42,7 @@
 import com.android.launcher3.DragSource;
 import com.android.launcher3.DropTarget;
 import com.android.launcher3.Hotseat;
+import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.AnimationSuccessListener;
@@ -59,7 +61,6 @@
 import com.android.launcher3.touch.ItemLongClickListener;
 import com.android.launcher3.uioverrides.PredictedAppIcon;
 import com.android.launcher3.uioverrides.QuickstepLauncher;
-import com.android.launcher3.util.OnboardingPrefs;
 import com.android.launcher3.views.Snackbar;
 
 import java.io.PrintWriter;
@@ -104,12 +105,11 @@
         if (mLauncher.getWorkspace().isSwitchingState()) return false;
 
         TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onWorkspaceItemLongClick");
-        if (mEnableHotseatLongPressTipForTesting && !mLauncher.getOnboardingPrefs().getBoolean(
-                OnboardingPrefs.HOTSEAT_LONGPRESS_TIP_SEEN)) {
+        if (mEnableHotseatLongPressTipForTesting && !HOTSEAT_LONGPRESS_TIP_SEEN.get(mLauncher)) {
             Snackbar.show(mLauncher, R.string.hotseat_tip_gaps_filled,
                     R.string.hotseat_prediction_settings, null,
                     () -> mLauncher.startActivity(getSettingsIntent()));
-            mLauncher.getOnboardingPrefs().markChecked(OnboardingPrefs.HOTSEAT_LONGPRESS_TIP_SEEN);
+            LauncherPrefs.get(mLauncher).put(HOTSEAT_LONGPRESS_TIP_SEEN, true);
             mLauncher.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
             return true;
         }
diff --git a/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java b/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java
index b982688..8b71f01 100644
--- a/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java
+++ b/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java
@@ -22,7 +22,6 @@
 import com.android.launcher3.appprediction.AppsDividerView;
 import com.android.launcher3.appprediction.PredictionRowView;
 import com.android.launcher3.model.BgDataModel;
-import com.android.launcher3.util.OnboardingPrefs;
 import com.android.launcher3.views.ActivityContext;
 
 /**
@@ -30,22 +29,21 @@
  */
 @SuppressWarnings("unused")
 public final class SecondaryDisplayPredictionsImpl extends SecondaryDisplayPredictions {
+
     private final ActivityContext mActivityContext;
+    private final Context mContext;
 
     public SecondaryDisplayPredictionsImpl(Context context) {
+        mContext = context;
         mActivityContext = ActivityContext.lookupContext(context);
     }
 
     @Override
     void updateAppDivider() {
-        OnboardingPrefs<?> onboardingPrefs = mActivityContext.getOnboardingPrefs();
-        if (onboardingPrefs != null) {
-            mActivityContext.getAppsView().getFloatingHeaderView()
-                    .findFixedRowByType(AppsDividerView.class)
-                    .setShowAllAppsLabel(
-                            !onboardingPrefs.hasReachedMaxCount(ALL_APPS_VISITED_COUNT));
-            onboardingPrefs.incrementEventCount(ALL_APPS_VISITED_COUNT);
-        }
+        mActivityContext.getAppsView().getFloatingHeaderView()
+                .findFixedRowByType(AppsDividerView.class)
+                .setShowAllAppsLabel(!ALL_APPS_VISITED_COUNT.hasReachedMax(mContext));
+        ALL_APPS_VISITED_COUNT.increment(mContext);
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java b/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
index 331184a..c201236 100644
--- a/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
@@ -20,8 +20,6 @@
 import android.view.LayoutInflater;
 
 import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
-import com.android.launcher3.LauncherPrefs;
-import com.android.launcher3.util.OnboardingPrefs;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.ActivityContext;
 
@@ -34,12 +32,10 @@
 
     protected final LayoutInflater mLayoutInflater;
     private final List<OnDeviceProfileChangeListener> mDPChangeListeners = new ArrayList<>();
-    private final OnboardingPrefs<BaseTaskbarContext> mOnboardingPrefs;
 
     public BaseTaskbarContext(Context windowContext) {
         super(windowContext, Themes.getActivityThemeRes(windowContext));
         mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
-        mOnboardingPrefs = new OnboardingPrefs<>(this, LauncherPrefs.getPrefs(this));
     }
 
     @Override
@@ -52,11 +48,6 @@
         return mDPChangeListeners;
     }
 
-    @Override
-    public OnboardingPrefs<BaseTaskbarContext> getOnboardingPrefs() {
-        return mOnboardingPrefs;
-    }
-
     /** Callback invoked when a drag is initiated within this context. */
     public abstract void onDragStart();
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 1c7d7e0..a321734 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -288,8 +288,7 @@
 
         // Persistent features EDU tooltip.
         if (!DisplayController.isTransientTaskbar(mLauncher)) {
-            return !mLauncher.getOnboardingPrefs().hasReachedMaxCount(
-                    OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP);
+            return !OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP.hasReachedMax(mLauncher);
         }
 
         // Transient swipe EDU tooltip.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
index de4175d..0ac2019 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
@@ -67,11 +67,10 @@
     @TaskbarEduTooltipStep
     var tooltipStep: Int
         get() {
-            return activityContext.onboardingPrefs?.getCount(TASKBAR_EDU_TOOLTIP_STEP)
-                ?: TOOLTIP_STEP_NONE
+            return TASKBAR_EDU_TOOLTIP_STEP.get(activityContext)
         }
         private set(step) {
-            activityContext.onboardingPrefs?.setEventCount(step, TASKBAR_EDU_TOOLTIP_STEP)
+            TASKBAR_EDU_TOOLTIP_STEP.set(step, activityContext)
         }
 
     private var tooltip: TaskbarEduTooltip? = null
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
index cf5fd59..b1c5151 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
@@ -83,9 +83,8 @@
     private void setUpAppDivider() {
         mAppsView.getFloatingHeaderView()
                 .findFixedRowByType(AppsDividerView.class)
-                .setShowAllAppsLabel(!mContext.getOnboardingPrefs().hasReachedMaxCount(
-                        ALL_APPS_VISITED_COUNT));
-        mContext.getOnboardingPrefs().incrementEventCount(ALL_APPS_VISITED_COUNT);
+                .setShowAllAppsLabel(!ALL_APPS_VISITED_COUNT.hasReachedMax(mContext));
+        ALL_APPS_VISITED_COUNT.increment(mContext);
     }
 
     private void setUpTaskbarStashing() {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index a71333a..7d88f05 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -61,7 +61,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentSender;
-import android.content.SharedPreferences;
 import android.content.res.Configuration;
 import android.graphics.Color;
 import android.graphics.Rect;
@@ -344,11 +343,6 @@
     }
 
     @Override
-    protected QuickstepOnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs) {
-        return new QuickstepOnboardingPrefs(this, sharedPrefs);
-    }
-
-    @Override
     public void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
         onStateOrResumeChanging(false /* inTransition */);
@@ -619,6 +613,7 @@
             mViewCapture = SettingsAwareViewCapture.getInstance(this).startCapture(getWindow());
         }
         getWindow().addPrivateFlags(PRIVATE_FLAG_OPTIMIZE_MEASURE);
+        QuickstepOnboardingPrefs.setup(this);
         View.setTraceLayoutSteps(TRACE_LAYOUTS);
         View.setTracedRequestLayoutClassClass(TRACE_RELAYOUT_CLASS);
     }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
index a76eb43..bd87536 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
@@ -27,6 +27,12 @@
 import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
 import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.PLUGIN_CHANGED;
 import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.pluginEnabledKey;
+import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
+import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_COUNT;
+import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
+import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_DISCOVERY_TIP_COUNT;
+import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_LONGPRESS_TIP_SEEN;
+import static com.android.launcher3.util.OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP;
 
 import android.annotation.TargetApi;
 import android.content.ComponentName;
@@ -68,12 +74,10 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher;
 import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
-import com.android.launcher3.util.OnboardingPrefs;
 import com.android.launcher3.util.SimpleBroadcastReceiver;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -378,24 +382,33 @@
     private void addOnboardingPrefsCatergory() {
         PreferenceCategory onboardingCategory = newCategory("Onboarding Flows");
         onboardingCategory.setSummary("Reset these if you want to see the education again.");
-        for (Map.Entry<String, String[]> titleAndKeys : OnboardingPrefs.ALL_PREF_KEYS.entrySet()) {
-            String title = titleAndKeys.getKey();
-            String[] keys = titleAndKeys.getValue();
-            Preference onboardingPref = new Preference(getContext());
-            onboardingPref.setTitle(title);
-            onboardingPref.setSummary("Tap to reset");
-            onboardingPref.setOnPreferenceClickListener(preference -> {
-                SharedPreferences.Editor sharedPrefsEdit = LauncherPrefs.getPrefs(getContext())
-                        .edit();
-                for (String key : keys) {
-                    sharedPrefsEdit.remove(key);
-                }
-                sharedPrefsEdit.apply();
-                Toast.makeText(getContext(), "Reset " + title, Toast.LENGTH_SHORT).show();
-                return true;
-            });
-            onboardingCategory.addPreference(onboardingPref);
-        }
+
+        onboardingCategory.addPreference(createOnboardPref("All Apps Bounce",
+                HOME_BOUNCE_SEEN.getSharedPrefKey(), HOME_BOUNCE_COUNT.getSharedPrefKey()));
+        onboardingCategory.addPreference(createOnboardPref("Hybrid Hotseat Education",
+                HOTSEAT_DISCOVERY_TIP_COUNT.getSharedPrefKey(),
+                HOTSEAT_LONGPRESS_TIP_SEEN.getSharedPrefKey()));
+        onboardingCategory.addPreference(createOnboardPref("Taskbar Education",
+                TASKBAR_EDU_TOOLTIP_STEP.getSharedPrefKey()));
+        onboardingCategory.addPreference(createOnboardPref("All Apps Visited Count",
+                ALL_APPS_VISITED_COUNT.getSharedPrefKey()));
+    }
+
+    private Preference createOnboardPref(String title, String... keys) {
+        Preference onboardingPref = new Preference(getContext());
+        onboardingPref.setTitle(title);
+        onboardingPref.setSummary("Tap to reset");
+        onboardingPref.setOnPreferenceClickListener(preference -> {
+            SharedPreferences.Editor sharedPrefsEdit = LauncherPrefs.getPrefs(getContext())
+                    .edit();
+            for (String key : keys) {
+                sharedPrefsEdit.remove(key);
+            }
+            sharedPrefsEdit.apply();
+            Toast.makeText(getContext(), "Reset " + title, Toast.LENGTH_SHORT).show();
+            return true;
+        });
+        return onboardingPref;
     }
 
     private void addAllAppsFromOverviewCatergory() {
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index f840707..b2f04b8 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -24,10 +24,12 @@
 import static android.view.MotionEvent.ACTION_UP;
 
 import static com.android.launcher3.Launcher.INTENT_ACTION_ALL_APPS_TOGGLE;
+import static com.android.launcher3.LauncherPrefs.backedUpItem;
 import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent;
 import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_TRACKPAD_GESTURE;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
 import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH;
 import static com.android.quickstep.GestureState.DEFAULT_STATE;
 import static com.android.quickstep.GestureState.TrackpadGestureType.getTrackpadGestureType;
@@ -60,7 +62,6 @@
 import android.content.IIntentReceiver;
 import android.content.IIntentSender;
 import android.content.Intent;
-import android.content.SharedPreferences;
 import android.content.res.Configuration;
 import android.graphics.Region;
 import android.graphics.drawable.Icon;
@@ -84,7 +85,9 @@
 import androidx.annotation.UiThread;
 
 import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.ConstantItem;
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.EncryptionType;
 import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.AnimatedFloat;
@@ -100,7 +103,6 @@
 import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.LockedUserState;
-import com.android.launcher3.util.OnboardingPrefs;
 import com.android.launcher3.util.SafeCloseable;
 import com.android.launcher3.util.ScreenOnTracker;
 import com.android.launcher3.util.TraceHelper;
@@ -158,7 +160,8 @@
 
     private static final String TAG = "TouchInteractionService";
 
-    private static final String HAS_ENABLED_QUICKSTEP_ONCE = "launcher.has_enabled_quickstep_once";
+    private static final ConstantItem<Boolean> HAS_ENABLED_QUICKSTEP_ONCE = backedUpItem(
+            "launcher.has_enabled_quickstep_once", false, EncryptionType.ENCRYPTED);
 
     private final TISBinder mTISBinder = new TISBinder(this);
 
@@ -569,12 +572,11 @@
         }
 
         // Reset home bounce seen on quick step enabled for first time
-        SharedPreferences sharedPrefs = LauncherPrefs.getPrefs(this);
-        if (!sharedPrefs.getBoolean(HAS_ENABLED_QUICKSTEP_ONCE, true)) {
-            sharedPrefs.edit()
-                    .putBoolean(HAS_ENABLED_QUICKSTEP_ONCE, true)
-                    .putBoolean(OnboardingPrefs.HOME_BOUNCE_SEEN, false)
-                    .apply();
+        LauncherPrefs prefs = LauncherPrefs.get(this);
+        if (!prefs.get(HAS_ENABLED_QUICKSTEP_ONCE)) {
+            prefs.put(
+                    HAS_ENABLED_QUICKSTEP_ONCE.to(true),
+                    HOME_BOUNCE_SEEN.to(false));
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
index ef7d7a9..9df568e 100644
--- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
+++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
@@ -22,9 +22,12 @@
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
+import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_COUNT;
+import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
+import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_DISCOVERY_TIP_COUNT;
 
-import android.content.SharedPreferences;
-
+import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
@@ -34,30 +37,30 @@
 import com.android.launcher3.statemanager.StateManager.StateListener;
 import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.OnboardingPrefs;
 import com.android.quickstep.views.AllAppsEduView;
 
 /**
- * Extends {@link OnboardingPrefs} for quickstep-specific onboarding data.
+ * Class to setup onboarding behavior for quickstep launcher
  */
-public class QuickstepOnboardingPrefs extends OnboardingPrefs<QuickstepLauncher> {
+public class QuickstepOnboardingPrefs {
 
-    public QuickstepOnboardingPrefs(QuickstepLauncher launcher, SharedPreferences sharedPrefs) {
-        super(launcher, sharedPrefs);
-
+    /**
+     * Sets up the initial onboarding behavior for the launcher
+     */
+    public static void setup(QuickstepLauncher launcher) {
         StateManager<LauncherState> stateManager = launcher.getStateManager();
-        if (!getBoolean(HOME_BOUNCE_SEEN)) {
+        if (!HOME_BOUNCE_SEEN.get(launcher)) {
             stateManager.addStateListener(new StateListener<LauncherState>() {
                 @Override
                 public void onStateTransitionComplete(LauncherState finalState) {
                     boolean swipeUpEnabled =
-                            DisplayController.getNavigationMode(mLauncher).hasGestures;
+                            DisplayController.getNavigationMode(launcher).hasGestures;
                     LauncherState prevState = stateManager.getLastState();
 
                     if (((swipeUpEnabled && finalState == OVERVIEW) || (!swipeUpEnabled
                             && finalState == ALL_APPS && prevState == NORMAL) ||
-                            hasReachedMaxCount(HOME_BOUNCE_COUNT))) {
-                        mSharedPrefs.edit().putBoolean(HOME_BOUNCE_SEEN, true).apply();
+                            HOME_BOUNCE_COUNT.hasReachedMax(launcher))) {
+                        LauncherPrefs.get(launcher).put(HOME_BOUNCE_SEEN, true);
                         stateManager.removeStateListener(this);
                     }
                 }
@@ -65,21 +68,21 @@
         }
 
         if (!Utilities.isRunningInTestHarness()
-                && !hasReachedMaxCount(HOTSEAT_DISCOVERY_TIP_COUNT)) {
+                && !HOTSEAT_DISCOVERY_TIP_COUNT.hasReachedMax(launcher)) {
             stateManager.addStateListener(new StateListener<LauncherState>() {
                 boolean mFromAllApps = false;
 
                 @Override
                 public void onStateTransitionStart(LauncherState toState) {
-                    mFromAllApps = mLauncher.getStateManager().getCurrentStableState() == ALL_APPS;
+                    mFromAllApps = launcher.getStateManager().getCurrentStableState() == ALL_APPS;
                 }
 
                 @Override
                 public void onStateTransitionComplete(LauncherState finalState) {
-                    HotseatPredictionController client = mLauncher.getHotseatPredictionController();
+                    HotseatPredictionController client = launcher.getHotseatPredictionController();
                     if (mFromAllApps && finalState == NORMAL && client.hasPredictions()) {
-                        if (!mLauncher.getDeviceProfile().isTablet
-                                && incrementEventCount(HOTSEAT_DISCOVERY_TIP_COUNT)) {
+                        if (!launcher.getDeviceProfile().isTablet
+                                && HOTSEAT_DISCOVERY_TIP_COUNT.increment(launcher)) {
                             client.showEdu();
                             stateManager.removeStateListener(this);
                         }
@@ -109,7 +112,7 @@
                 public void onStateTransitionComplete(LauncherState finalState) {
                     if (finalState == NORMAL) {
                         if (mCount >= MAX_NUM_SWIPES_TO_TRIGGER_EDU) {
-                            if (getOpenView(mLauncher, TYPE_ALL_APPS_EDU) == null) {
+                            if (getOpenView(launcher, TYPE_ALL_APPS_EDU) == null) {
                                 AllAppsEduView.show(launcher);
                             }
                             mCount = 0;
@@ -124,7 +127,7 @@
                     }
 
                     if (finalState == ALL_APPS) {
-                        AllAppsEduView view = getOpenView(mLauncher, TYPE_ALL_APPS_EDU);
+                        AllAppsEduView view = getOpenView(launcher, TYPE_ALL_APPS_EDU);
                         if (view != null) {
                             view.close(false);
                         }
@@ -133,20 +136,20 @@
             });
         }
 
-        if (!hasReachedMaxCount(ALL_APPS_VISITED_COUNT)) {
-            mLauncher.getStateManager().addStateListener(new StateListener<LauncherState>() {
+        if (!ALL_APPS_VISITED_COUNT.hasReachedMax(launcher)) {
+            launcher.getStateManager().addStateListener(new StateListener<LauncherState>() {
                 @Override
                 public void onStateTransitionComplete(LauncherState finalState) {
                     if (finalState == ALL_APPS) {
-                        incrementEventCount(ALL_APPS_VISITED_COUNT);
+                        ALL_APPS_VISITED_COUNT.increment(launcher);
                         return;
                     }
 
-                    boolean hasReachedMaxCount = hasReachedMaxCount(ALL_APPS_VISITED_COUNT);
-                    mLauncher.getAppsView().getFloatingHeaderView().findFixedRowByType(
+                    boolean hasReachedMaxCount = ALL_APPS_VISITED_COUNT.hasReachedMax(launcher);
+                    launcher.getAppsView().getFloatingHeaderView().findFixedRowByType(
                             AppsDividerView.class).setShowAllAppsLabel(!hasReachedMaxCount);
                     if (hasReachedMaxCount) {
-                        mLauncher.getStateManager().removeStateListener(this);
+                        launcher.getStateManager().removeStateListener(this);
                     }
                 }
             });
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 919ad21..dfcd279 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -206,7 +206,6 @@
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.KeyboardShortcutsDelegate;
 import com.android.launcher3.util.LockedUserState;
-import com.android.launcher3.util.OnboardingPrefs;
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.PendingRequestArgs;
 import com.android.launcher3.util.RunnableList;
@@ -390,7 +389,6 @@
     // We only want to get the SharedPreferences once since it does an FS stat each time we get
     // it from the context.
     private SharedPreferences mSharedPrefs;
-    private OnboardingPrefs<? extends Launcher> mOnboardingPrefs;
 
     // Activity result which needs to be processed after workspace has loaded.
     private ActivityResultInfo mPendingActivityResult;
@@ -537,8 +535,6 @@
         mAllAppsController = new AllAppsTransitionController(this);
         mStateManager = new StateManager<>(this, NORMAL);
 
-        mOnboardingPrefs = createOnboardingPrefs(mSharedPrefs);
-
         // TODO: move the SearchConfig to SearchState when new LauncherState is created.
         mBaseSearchConfig = new BaseSearchConfig();
 
@@ -688,11 +684,6 @@
         return new LauncherOverlayManager() { };
     }
 
-    protected OnboardingPrefs<? extends Launcher> createOnboardingPrefs(
-            SharedPreferences sharedPrefs) {
-        return new OnboardingPrefs<>(this, sharedPrefs);
-    }
-
     @Override
     public void onPluginConnected(LauncherOverlayPlugin overlayManager, Context context) {
         switchOverlay(() -> overlayManager.createOverlayManager(this));
@@ -3271,10 +3262,6 @@
         mPagesToBindSynchronously = pages;
     }
 
-    public OnboardingPrefs<? extends Launcher> getOnboardingPrefs() {
-        return mOnboardingPrefs;
-    }
-
     @Override
     public CellPosMapper getCellPosMapper() {
         return mCellPosMapper;
diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt
index f2df230..9a760d7 100644
--- a/src/com/android/launcher3/LauncherPrefs.kt
+++ b/src/com/android/launcher3/LauncherPrefs.kt
@@ -389,7 +389,6 @@
         @JvmField
         val WIDGETS_EDUCATION_TIP_SEEN = backedUpItem("launcher.widgets_education_tip_seen", false)
 
-        @VisibleForTesting
         @JvmStatic
         fun <T> backedUpItem(
             sharedPrefKey: String,
@@ -477,6 +476,8 @@
             ITEMS_TO_MOVE_TO_DEVICE_PROTECTED_STORAGE.add(this)
         }
     }
+
+    fun get(c: Context): T = LauncherPrefs.get(c).get(this)
 }
 
 data class ContextualItem<T>(
@@ -494,6 +495,8 @@
         }
         return default!!
     }
+
+    fun get(c: Context): T = LauncherPrefs.get(c).get(this)
 }
 
 enum class EncryptionType {
diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java
index df22425..1692912 100644
--- a/src/com/android/launcher3/allapps/DiscoveryBounce.java
+++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java
@@ -17,6 +17,7 @@
 package com.android.launcher3.allapps;
 
 import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
 
 import android.animation.Animator;
 import android.animation.AnimatorInflater;
@@ -122,9 +123,8 @@
     }
 
     private static void showForHomeIfNeeded(Launcher launcher, boolean withDelay) {
-        OnboardingPrefs onboardingPrefs = launcher.getOnboardingPrefs();
         if (!launcher.isInState(NORMAL)
-                || onboardingPrefs.getBoolean(OnboardingPrefs.HOME_BOUNCE_SEEN)
+                || HOME_BOUNCE_SEEN.get(launcher)
                 || AbstractFloatingView.getTopOpenView(launcher) != null
                 || launcher.getSystemService(UserManager.class).isDemoUser()
                 || Utilities.isRunningInTestHarness()) {
@@ -135,7 +135,7 @@
             new Handler().postDelayed(() -> showForHomeIfNeeded(launcher, false), DELAY_MS);
             return;
         }
-        onboardingPrefs.incrementEventCount(OnboardingPrefs.HOME_BOUNCE_COUNT);
+        OnboardingPrefs.HOME_BOUNCE_COUNT.increment(launcher);
         new DiscoveryBounce(launcher).show();
     }
 
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index a10c0ad..910b029 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -36,7 +36,6 @@
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherModel;
-import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
 import com.android.launcher3.allapps.ActivityAllAppsContainerView;
@@ -56,7 +55,6 @@
 import com.android.launcher3.touch.ItemClickHandler.ItemClickProxy;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.IntSet;
-import com.android.launcher3.util.OnboardingPrefs;
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.Themes;
@@ -82,7 +80,6 @@
     private boolean mAppDrawerShown = false;
 
     private StringCache mStringCache;
-    private OnboardingPrefs<?> mOnboardingPrefs;
     private boolean mBindingItems = false;
     private SecondaryDisplayPredictions mSecondaryDisplayPredictions;
 
@@ -93,7 +90,6 @@
         super.onCreate(savedInstanceState);
         mModel = LauncherAppState.getInstance(this).getModel();
         mDragController = new SecondaryDragController(this);
-        mOnboardingPrefs = new OnboardingPrefs<>(this, LauncherPrefs.getPrefs(this));
         mSecondaryDisplayPredictions = SecondaryDisplayPredictions.newInstance(this);
         if (getWindow().getDecorView().isAttachedToWindow()) {
             initUi();
@@ -272,11 +268,6 @@
     }
 
     @Override
-    public OnboardingPrefs<?> getOnboardingPrefs() {
-        return mOnboardingPrefs;
-    }
-
-    @Override
     public void startBinding() {
         mBindingItems = true;
         mDragController.cancelDrag();
diff --git a/src/com/android/launcher3/util/OnboardingPrefs.java b/src/com/android/launcher3/util/OnboardingPrefs.java
deleted file mode 100644
index f8f4b5f..0000000
--- a/src/com/android/launcher3/util/OnboardingPrefs.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.util;
-
-import android.content.SharedPreferences;
-import android.util.ArrayMap;
-
-import androidx.annotation.StringDef;
-
-import com.android.launcher3.views.ActivityContext;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * Stores and retrieves onboarding-related data via SharedPreferences.
- *
- * @param <T> Context which owns these preferences.
- */
-public class OnboardingPrefs<T extends ActivityContext> {
-
-    public static final String HOME_BOUNCE_SEEN = "launcher.apps_view_shown";
-    public static final String HOME_BOUNCE_COUNT = "launcher.home_bounce_count";
-    public static final String HOTSEAT_DISCOVERY_TIP_COUNT = "launcher.hotseat_discovery_tip_count";
-    public static final String HOTSEAT_LONGPRESS_TIP_SEEN = "launcher.hotseat_longpress_tip_seen";
-    public static final String ALL_APPS_VISITED_COUNT = "launcher.all_apps_visited_count";
-    public static final String TASKBAR_EDU_TOOLTIP_STEP = "launcher.taskbar_edu_tooltip_step";
-    // When adding a new key, add it here as well, to be able to reset it from Developer Options.
-    public static final Map<String, String[]> ALL_PREF_KEYS = Map.of(
-            "All Apps Bounce", new String[] { HOME_BOUNCE_SEEN, HOME_BOUNCE_COUNT },
-            "Hybrid Hotseat Education", new String[] { HOTSEAT_DISCOVERY_TIP_COUNT,
-                    HOTSEAT_LONGPRESS_TIP_SEEN },
-            "Taskbar Education", new String[] { TASKBAR_EDU_TOOLTIP_STEP },
-            "All Apps Visited Count", new String[] {ALL_APPS_VISITED_COUNT}
-    );
-
-    /**
-     * Events that either have happened or have not (booleans).
-     */
-    @StringDef(value = {
-            HOME_BOUNCE_SEEN,
-            HOTSEAT_LONGPRESS_TIP_SEEN,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface EventBoolKey {}
-
-    /**
-     * Events that occur multiple times, which we count up to a max defined in {@link #MAX_COUNTS}.
-     */
-    @StringDef(value = {
-            HOME_BOUNCE_COUNT,
-            HOTSEAT_DISCOVERY_TIP_COUNT,
-            ALL_APPS_VISITED_COUNT,
-            TASKBAR_EDU_TOOLTIP_STEP,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface EventCountKey {}
-
-    private static final Map<String, Integer> MAX_COUNTS;
-
-    static {
-        Map<String, Integer> maxCounts = new ArrayMap<>(5);
-        maxCounts.put(HOME_BOUNCE_COUNT, 3);
-        maxCounts.put(HOTSEAT_DISCOVERY_TIP_COUNT, 5);
-        maxCounts.put(ALL_APPS_VISITED_COUNT, 20);
-        maxCounts.put(TASKBAR_EDU_TOOLTIP_STEP, 2);
-        MAX_COUNTS = Collections.unmodifiableMap(maxCounts);
-    }
-
-    protected final T mLauncher;
-    protected final SharedPreferences mSharedPrefs;
-
-    public OnboardingPrefs(T launcher, SharedPreferences sharedPrefs) {
-        mLauncher = launcher;
-        mSharedPrefs = sharedPrefs;
-    }
-
-    /** @return The number of times we have seen the given event. */
-    public int getCount(@EventCountKey String key) {
-        return mSharedPrefs.getInt(key, 0);
-    }
-
-    /** @return Whether we have seen this event enough times, as defined by {@link #MAX_COUNTS}. */
-    public boolean hasReachedMaxCount(@EventCountKey String eventKey) {
-        return hasReachedMaxCount(getCount(eventKey), eventKey);
-    }
-
-    private boolean hasReachedMaxCount(int count, @EventCountKey String eventKey) {
-        return count >= MAX_COUNTS.get(eventKey);
-    }
-
-    /** @return Whether we have seen the given event. */
-    public boolean getBoolean(@EventBoolKey String key) {
-        return mSharedPrefs.getBoolean(key, false);
-    }
-
-    /**
-     * Marks on-boarding preference boolean at true
-     */
-    public void markChecked(String flag) {
-        mSharedPrefs.edit().putBoolean(flag, true).apply();
-    }
-
-    /**
-     * Add 1 to the given event count, if we haven't already reached the max count.
-     *
-     * @return Whether we have now reached the max count.
-     */
-    public boolean incrementEventCount(@EventCountKey String eventKey) {
-        int count = getCount(eventKey);
-        if (hasReachedMaxCount(count, eventKey)) {
-            return true;
-        }
-        count++;
-        mSharedPrefs.edit().putInt(eventKey, count).apply();
-        return hasReachedMaxCount(count, eventKey);
-    }
-
-    /**
-     * Sets the event count to the given value.
-     *
-     * @return Whether we have now reached the max count.
-     */
-    public boolean setEventCount(int count, @EventCountKey String eventKey) {
-        mSharedPrefs.edit().putInt(eventKey, count).apply();
-        return hasReachedMaxCount(count, eventKey);
-    }
-}
diff --git a/src/com/android/launcher3/util/OnboardingPrefs.kt b/src/com/android/launcher3/util/OnboardingPrefs.kt
new file mode 100644
index 0000000..8586c43
--- /dev/null
+++ b/src/com/android/launcher3/util/OnboardingPrefs.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util
+
+import android.content.Context
+import com.android.launcher3.LauncherPrefs
+import com.android.launcher3.LauncherPrefs.Companion.backedUpItem
+
+/** Stores and retrieves onboarding-related data via SharedPreferences. */
+object OnboardingPrefs {
+
+    data class CountedItem(
+        val sharedPrefKey: String,
+        val maxCount: Int,
+    ) {
+        private val prefItem = backedUpItem(sharedPrefKey, 0)
+
+        /** @return The number of times we have seen the given event. */
+        fun get(c: Context): Int {
+            return prefItem.get(c)
+        }
+
+        /** @return Whether we have seen this event enough times, as defined by [.MAX_COUNTS]. */
+        fun hasReachedMax(c: Context): Boolean {
+            return get(c) >= maxCount
+        }
+
+        /**
+         * Add 1 to the given event count, if we haven't already reached the max count.
+         *
+         * @return Whether we have now reached the max count.
+         */
+        fun increment(c: Context): Boolean {
+            val count = get(c)
+            if (count >= maxCount) {
+                return true
+            }
+            return set(count + 1, c)
+        }
+
+        /**
+         * Sets the event count to the given value.
+         *
+         * @return Whether we have now reached the max count.
+         */
+        fun set(count: Int, c: Context): Boolean {
+            LauncherPrefs.get(c).put(prefItem, count)
+            return count >= maxCount
+        }
+    }
+
+    @JvmField val TASKBAR_EDU_TOOLTIP_STEP = CountedItem("launcher.taskbar_edu_tooltip_step", 2)
+
+    @JvmField val HOME_BOUNCE_COUNT = CountedItem("launcher.home_bounce_count", 3)
+
+    @JvmField
+    val HOTSEAT_DISCOVERY_TIP_COUNT = CountedItem("launcher.hotseat_discovery_tip_count", 5)
+
+    @JvmField val ALL_APPS_VISITED_COUNT = CountedItem("launcher.all_apps_visited_count", 20)
+
+    @JvmField val HOME_BOUNCE_SEEN = backedUpItem("launcher.apps_view_shown", false)
+
+    @JvmField
+    val HOTSEAT_LONGPRESS_TIP_SEEN = backedUpItem("launcher.hotseat_longpress_tip_seen", false)
+}
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index 0d55f15..3921e12 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -74,7 +74,6 @@
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.popup.PopupDataProvider;
 import com.android.launcher3.util.ActivityOptionsWrapper;
-import com.android.launcher3.util.OnboardingPrefs;
 import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.RunnableList;
@@ -231,12 +230,6 @@
      */
     default void applyOverwritesToLogItem(LauncherAtom.ItemInfo.Builder itemInfoBuilder) { }
 
-    /** Onboarding preferences for any onboarding data within this context. */
-    @Nullable
-    default OnboardingPrefs<?> getOnboardingPrefs() {
-        return null;
-    }
-
     /** Returns {@code true} if items are currently being bound within this context. */
     default boolean isBindingItems() {
         return false;