Moving onboarding prefs to use LauncherPrefs

Bug: 301661768
Test: Presubmit
Flag: N/A
Change-Id: Iec8a5e739f394a152d5ffc57b01e0449e94b4084
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;