// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.chrome.browser.contextualsearch; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.preferences.ChromePreferenceManager; /** * Manages the Contextual Search disable-able promo tap counter. * This counter stores a single persistent integer preference that can indicate both a count * and whether it's been disabled (and remembers the count before being disabled). */ class DisableablePromoTapCounter { // -------------------------------------------------------------------------------------------- // Opt-out style Promo counter // // The Opt-out style promo tap counter needs to do two things: // 1) Count Taps that trigger the promo, so they can be limited. // 2) Support a "disabled" state; when the user opens the panel then Taps trigger from then on. // We use a single persistent setting to record both meanings by using a negative value to // indicate disabled. // -------------------------------------------------------------------------------------------- // Amount to bias a disabled value when making it negative (so 0 can be disabled). private static final int PROMO_TAPS_DISABLED_BIAS = -1; private static DisableablePromoTapCounter sInstance; private final ChromePreferenceManager mPrefsManager; private int mCounter; /** * Gets the singleton instance used to access the persistent counter. * @param prefsManager The ChromePreferenceManager to get prefs from. * @return the counter. */ static DisableablePromoTapCounter getInstance( ChromePreferenceManager prefsManager) { if (sInstance == null) { sInstance = new DisableablePromoTapCounter(prefsManager); } return sInstance; } /** * Private constructor -- use {@link #getInstance} to get the singleton instance. * @param prefsManager The preferences manager to use. */ private DisableablePromoTapCounter(ChromePreferenceManager prefsManager) { mPrefsManager = prefsManager; setRawCounter(prefsManager.getContextualSearchTapTriggeredPromoCount()); } /** * @return whether the counter is currently enabled. */ boolean isEnabled() { return mCounter >= 0; } /** * Disables the counter. */ void disable() { if (isEnabled()) setRawCounter(getToggledCounter(mCounter)); } /** * @return The current count (always non-negative). */ int getCount() { if (isEnabled()) return mCounter; return getToggledCounter(mCounter); } /** * Increments the counter. */ void increment() { assert isEnabled(); setRawCounter(getCount() + 1); } /** * Resets the counter to zero and enabled. */ @VisibleForTesting void reset() { setRawCounter(0); } /** * Sets the persistent storage to the given value. * @param rawCounter The raw value to write. */ private void setRawCounter(int rawCounter) { mCounter = rawCounter; writeRawCounter(); } /** * Writes the current counter's raw value to persistent storage. */ private void writeRawCounter() { mPrefsManager.setContextualSearchTapTriggeredPromoCount(mCounter); } /** * Toggles the counter's raw value from the enabled to disabled state, or vice versa. * @param rawCounter The current raw counter value. * @return The toggled raw counter value. */ private int getToggledCounter(int rawCounter) { // In order to encode a 0 value we need to introduce a bias when we create negative // raw values. Since -1 is a special value for some code, we make the bias big // enough that we'll never have a raw value of -1 (though that's not strictly needed). return PROMO_TAPS_DISABLED_BIAS - rawCounter; } }