diff --git a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java index e8374b813c..037f7a8fea 100644 --- a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java +++ b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java @@ -35,9 +35,7 @@ import androidx.core.content.ContextCompat; 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 @@ public class AppsDividerView extends View implements FloatingHeaderRow { ? 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 a63f9e8b29..baea418160 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.LAUNCH 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.DeviceProfile; 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.testing.shared.TestProtocol; 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 @@ public class HotseatPredictionController implements DragController.DragListener, 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 b982688ce7..8b71f01396 100644 --- a/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java +++ b/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java @@ -22,7 +22,6 @@ import android.content.Context; 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 @@ import com.android.launcher3.views.ActivityContext; */ @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 331184a081..c201236586 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.ContextThemeWrapper; 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 @@ public abstract class BaseTaskbarContext extends ContextThemeWrapper implements protected final LayoutInflater mLayoutInflater; private final List mDPChangeListeners = new ArrayList<>(); - private final OnboardingPrefs 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 @@ public abstract class BaseTaskbarContext extends ContextThemeWrapper implements return mDPChangeListeners; } - @Override - public OnboardingPrefs 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 1c7d7e06c7..a321734cc5 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -288,8 +288,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController { // 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 de4175ddc1..0ac2019ad3 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt @@ -67,11 +67,10 @@ class TaskbarEduTooltipController(val activityContext: TaskbarActivityContext) : @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 cf5fd59cfe..b1c515177b 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 @@ final class TaskbarAllAppsViewController { 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 a71333a3bc..7d88f051fb 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.app.ActivityOptions; 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; @@ -343,11 +342,6 @@ public class QuickstepLauncher extends Launcher { return new QuickstepTransitionManager(this); } - @Override - protected QuickstepOnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs) { - return new QuickstepOnboardingPrefs(this, sharedPrefs); - } - @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -619,6 +613,7 @@ public class QuickstepLauncher extends Launcher { 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 a76eb437de..bd875367db 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.LauncherPrefs.ALL_APPS_OVERVIEW_THRESHOLD; 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.R; 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 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat { private void addOnboardingPrefsCatergory() { PreferenceCategory onboardingCategory = newCategory("Onboarding Flows"); onboardingCategory.setSummary("Reset these if you want to see the education again."); - for (Map.Entry 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 f840707055..b2f04b89e1 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_POINTER_UP; 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.app.Service; 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.Nullable; 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.flags.FlagsFactory; 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 @@ public class TouchInteractionService extends Service { private static final String TAG = "TouchInteractionService"; - private static final String HAS_ENABLED_QUICKSTEP_ONCE = "launcher.has_enabled_quickstep_once"; + private static final ConstantItem HAS_ENABLED_QUICKSTEP_ONCE = backedUpItem( + "launcher.has_enabled_quickstep_once", false, EncryptionType.ENCRYPTED); private final TISBinder mTISBinder = new TISBinder(this); @@ -569,12 +572,11 @@ public class TouchInteractionService extends Service { } // 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 ef7d7a911a..9df568ec76 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.HINT_STATE; 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; 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 { - - public QuickstepOnboardingPrefs(QuickstepLauncher launcher, SharedPreferences sharedPrefs) { - super(launcher, sharedPrefs); +public class QuickstepOnboardingPrefs { + /** + * Sets up the initial onboarding behavior for the launcher + */ + public static void setup(QuickstepLauncher launcher) { StateManager stateManager = launcher.getStateManager(); - if (!getBoolean(HOME_BOUNCE_SEEN)) { + if (!HOME_BOUNCE_SEEN.get(launcher)) { stateManager.addStateListener(new StateListener() { @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 @@ public class QuickstepOnboardingPrefs extends OnboardingPrefs } if (!Utilities.isRunningInTestHarness() - && !hasReachedMaxCount(HOTSEAT_DISCOVERY_TIP_COUNT)) { + && !HOTSEAT_DISCOVERY_TIP_COUNT.hasReachedMax(launcher)) { stateManager.addStateListener(new StateListener() { 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 class QuickstepOnboardingPrefs extends OnboardingPrefs 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 @@ public class QuickstepOnboardingPrefs extends OnboardingPrefs } 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 @@ public class QuickstepOnboardingPrefs extends OnboardingPrefs }); } - if (!hasReachedMaxCount(ALL_APPS_VISITED_COUNT)) { - mLauncher.getStateManager().addStateListener(new StateListener() { + if (!ALL_APPS_VISITED_COUNT.hasReachedMax(launcher)) { + launcher.getStateManager().addStateListener(new StateListener() { @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 919ad21327..dfcd2799a2 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -206,7 +206,6 @@ import com.android.launcher3.util.IntArray; 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 @@ public class Launcher extends StatefulActivity // 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; @@ -537,8 +535,6 @@ public class Launcher extends StatefulActivity 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 @@ public class Launcher extends StatefulActivity return new LauncherOverlayManager() { }; } - protected OnboardingPrefs createOnboardingPrefs( - SharedPreferences sharedPrefs) { - return new OnboardingPrefs<>(this, sharedPrefs); - } - @Override public void onPluginConnected(LauncherOverlayPlugin overlayManager, Context context) { switchOverlay(() -> overlayManager.createOverlayManager(this)); @@ -3271,10 +3262,6 @@ public class Launcher extends StatefulActivity mPagesToBindSynchronously = pages; } - public OnboardingPrefs 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 f2df230152..9a760d7f3a 100644 --- a/src/com/android/launcher3/LauncherPrefs.kt +++ b/src/com/android/launcher3/LauncherPrefs.kt @@ -389,7 +389,6 @@ class LauncherPrefs(private val encryptedContext: Context) { @JvmField val WIDGETS_EDUCATION_TIP_SEEN = backedUpItem("launcher.widgets_education_tip_seen", false) - @VisibleForTesting @JvmStatic fun backedUpItem( sharedPrefKey: String, @@ -477,6 +476,8 @@ data class ConstantItem( ITEMS_TO_MOVE_TO_DEVICE_PROTECTED_STORAGE.add(this) } } + + fun get(c: Context): T = LauncherPrefs.get(c).get(this) } data class ContextualItem( @@ -494,6 +495,8 @@ data class ContextualItem( } 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 df22425379..1692912a9f 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 @@ public class DiscoveryBounce extends AbstractFloatingView { } 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 @@ public class DiscoveryBounce extends AbstractFloatingView { 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 a10c0ad842..910b0293ec 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.DropTarget; 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.popup.PopupDataProvider; 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 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity private boolean mAppDrawerShown = false; private StringCache mStringCache; - private OnboardingPrefs mOnboardingPrefs; private boolean mBindingItems = false; private SecondaryDisplayPredictions mSecondaryDisplayPredictions; @@ -93,7 +90,6 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity 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(); @@ -271,11 +267,6 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity animator.start(); } - @Override - public OnboardingPrefs getOnboardingPrefs() { - return mOnboardingPrefs; - } - @Override public void startBinding() { mBindingItems = true; diff --git a/src/com/android/launcher3/util/OnboardingPrefs.java b/src/com/android/launcher3/util/OnboardingPrefs.java deleted file mode 100644 index f8f4b5fc98..0000000000 --- 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 Context which owns these preferences. - */ -public class OnboardingPrefs { - - 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 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 MAX_COUNTS; - - static { - Map 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 0000000000..8586c43896 --- /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 0d55f159a6..3921e126b4 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.ItemInfo; 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 @@ public interface ActivityContext { */ 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;