Refactor some onboarding-related shared prefs into a class
Bug: 151768994
Change-Id: I938e23af8c1874714e02fe34d0f9f82bb21d00a2
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 48db5ea..f69940b 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -139,6 +139,7 @@
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.PendingRequestArgs;
@@ -300,6 +301,7 @@
// 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 mOnboardingPrefs;
// Activity result which needs to be processed after workspace has loaded.
private ActivityResultInfo mPendingActivityResult;
@@ -367,6 +369,8 @@
mAllAppsController = new AllAppsTransitionController(this);
mStateManager = new LauncherStateManager(this);
+ mOnboardingPrefs = createOnboardingPrefs(mSharedPrefs, mStateManager);
+
mAppWidgetManager = new WidgetManagerHelper(this);
mAppWidgetHost = new LauncherAppWidgetHost(this,
appWidgetId -> getWorkspace().removeWidget(appWidgetId));
@@ -458,6 +462,15 @@
return new LauncherOverlayManager() { };
}
+ protected OnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs,
+ LauncherStateManager stateManager) {
+ return new OnboardingPrefs<>(this, sharedPrefs, stateManager);
+ }
+
+ public OnboardingPrefs getOnboardingPrefs() {
+ return mOnboardingPrefs;
+ }
+
@Override
public void onPluginConnected(OverlayPlugin overlayManager, Context context) {
switchOverlay(() -> overlayManager.createOverlayManager(this, this));
diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java
index 0f0fc3a..fc29a30 100644
--- a/src/com/android/launcher3/allapps/DiscoveryBounce.java
+++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java
@@ -24,7 +24,6 @@
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
-import android.content.SharedPreferences;
import android.os.Handler;
import android.os.UserManager;
import android.view.MotionEvent;
@@ -35,6 +34,7 @@
import com.android.launcher3.LauncherStateManager.StateListener;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.util.OnboardingPrefs;
/**
* Abstract base class of floating view responsible for showing discovery bounce animation
@@ -43,13 +43,6 @@
private static final long DELAY_MS = 450;
- public static final String HOME_BOUNCE_SEEN = "launcher.apps_view_shown";
- public static final String SHELF_BOUNCE_SEEN = "launcher.shelf_bounce_seen";
- public static final String HOME_BOUNCE_COUNT = "launcher.home_bounce_count";
- public static final String SHELF_BOUNCE_COUNT = "launcher.shelf_bounce_count";
-
- public static final int BOUNCE_MAX_COUNT = 3;
-
private final Launcher mLauncher;
private final Animator mDiscoBounceAnimation;
@@ -142,8 +135,9 @@
}
private static void showForHomeIfNeeded(Launcher launcher, boolean withDelay) {
+ OnboardingPrefs onboardingPrefs = launcher.getOnboardingPrefs();
if (!launcher.isInState(NORMAL)
- || launcher.getSharedPrefs().getBoolean(HOME_BOUNCE_SEEN, false)
+ || onboardingPrefs.getBoolean(OnboardingPrefs.HOME_BOUNCE_SEEN)
|| AbstractFloatingView.getTopOpenView(launcher) != null
|| launcher.getSystemService(UserManager.class).isDemoUser()
|| Utilities.IS_RUNNING_IN_TEST_HARNESS) {
@@ -154,7 +148,7 @@
new Handler().postDelayed(() -> showForHomeIfNeeded(launcher, false), DELAY_MS);
return;
}
- incrementHomeBounceCount(launcher);
+ onboardingPrefs.incrementEventCount(OnboardingPrefs.HOME_BOUNCE_COUNT);
new DiscoveryBounce(launcher, 0).show(HOTSEAT);
}
@@ -164,11 +158,12 @@
}
private static void showForOverviewIfNeeded(Launcher launcher, boolean withDelay) {
+ OnboardingPrefs onboardingPrefs = launcher.getOnboardingPrefs();
if (!launcher.isInState(OVERVIEW)
|| !launcher.hasBeenResumed()
|| launcher.isForceInvisible()
|| launcher.getDeviceProfile().isVerticalBarLayout()
- || launcher.getSharedPrefs().getBoolean(SHELF_BOUNCE_SEEN, false)
+ || onboardingPrefs.getBoolean(OnboardingPrefs.SHELF_BOUNCE_SEEN)
|| launcher.getSystemService(UserManager.class).isDemoUser()
|| Utilities.IS_RUNNING_IN_TEST_HARNESS) {
return;
@@ -182,7 +177,7 @@
// TODO: Move these checks to the top and call this method after invalidate handler.
return;
}
- incrementShelfBounceCount(launcher);
+ onboardingPrefs.incrementEventCount(OnboardingPrefs.SHELF_BOUNCE_COUNT);
new DiscoveryBounce(launcher, (1 - OVERVIEW.getVerticalProgress(launcher)))
.show(PREDICTION);
@@ -209,22 +204,4 @@
mController.setProgress(progress - mDelta);
}
}
-
- private static void incrementShelfBounceCount(Launcher launcher) {
- SharedPreferences sharedPrefs = launcher.getSharedPrefs();
- int count = sharedPrefs.getInt(SHELF_BOUNCE_COUNT, 0);
- if (count > BOUNCE_MAX_COUNT) {
- return;
- }
- sharedPrefs.edit().putInt(SHELF_BOUNCE_COUNT, count + 1).apply();
- }
-
- private static void incrementHomeBounceCount(Launcher launcher) {
- SharedPreferences sharedPrefs = launcher.getSharedPrefs();
- int count = sharedPrefs.getInt(HOME_BOUNCE_COUNT, 0);
- if (count > BOUNCE_MAX_COUNT) {
- return;
- }
- sharedPrefs.edit().putInt(HOME_BOUNCE_COUNT, count + 1).apply();
- }
}
diff --git a/src/com/android/launcher3/util/OnboardingPrefs.java b/src/com/android/launcher3/util/OnboardingPrefs.java
new file mode 100644
index 0000000..cdb60e9
--- /dev/null
+++ b/src/com/android/launcher3/util/OnboardingPrefs.java
@@ -0,0 +1,110 @@
+/*
+ * 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.Launcher;
+import com.android.launcher3.LauncherStateManager;
+
+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.
+ */
+public class OnboardingPrefs<T extends Launcher> {
+
+ public static final String HOME_BOUNCE_SEEN = "launcher.apps_view_shown";
+ public static final String SHELF_BOUNCE_SEEN = "launcher.shelf_bounce_seen";
+ public static final String HOME_BOUNCE_COUNT = "launcher.home_bounce_count";
+ public static final String SHELF_BOUNCE_COUNT = "launcher.shelf_bounce_count";
+
+ /**
+ * Events that either have happened or have not (booleans).
+ */
+ @StringDef(value = {
+ HOME_BOUNCE_SEEN,
+ SHELF_BOUNCE_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,
+ SHELF_BOUNCE_COUNT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface EventCountKey {}
+
+ private static final Map<String, Integer> MAX_COUNTS;
+ static {
+ Map<String, Integer> maxCounts = new ArrayMap<>(2);
+ maxCounts.put(HOME_BOUNCE_COUNT, 3);
+ maxCounts.put(SHELF_BOUNCE_COUNT, 3);
+ MAX_COUNTS = Collections.unmodifiableMap(maxCounts);
+ }
+
+ protected final T mLauncher;
+ protected final SharedPreferences mSharedPrefs;
+ protected final LauncherStateManager mStateManager;
+
+ public OnboardingPrefs(T launcher, SharedPreferences sharedPrefs,
+ LauncherStateManager stateManager) {
+ mLauncher = launcher;
+ mSharedPrefs = sharedPrefs;
+ mStateManager = stateManager;
+ }
+
+ /** @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);
+ }
+
+ /**
+ * Add 1 to the given event count, if we haven't already reached the max count.
+ */
+ public void incrementEventCount(@EventCountKey String eventKey) {
+ int count = getCount(eventKey);
+ if (hasReachedMaxCount(count, eventKey)) {
+ return;
+ }
+ count++;
+ mSharedPrefs.edit().putInt(eventKey, count).apply();
+ }
+}