// 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;
}
}