/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.mozstumbler.service;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build.VERSION;
import android.text.TextUtils;
import android.util.Log;
import org.mozilla.mozstumbler.service.stumblerthread.motiondetection.SignificantMotionSensor;
import org.mozilla.mozstumbler.svclocator.services.log.LoggerUtil;
import java.util.regex.Pattern;
public class Prefs {
public static final String NICKNAME_PREF = "nickname";
public static final String EMAIL_PREF = "email";
public static final String WIFI_ONLY = "wifi_only";
public static final String MOTION_SENSOR_IS_SIGNIFICANT_TYPE = "motion_sensor_is_significant";
public static final String MOTION_SENSOR_ENABLED = "motion_sensor_enabled";
protected static final String PREFS_FILE = Prefs.class.getSimpleName();
private static final String LOG_TAG = LoggerUtil.makeLogTag(Prefs.class);
private static final String USER_AGENT_PREF = "user-agent";
private static final String VALUES_VERSION_PREF = "values_version";
private static final String FIREFOX_SCAN_ENABLED = "firefox_scan_on";
private static final String MOZ_API_KEY = "moz_api_key";
private static final String LAST_ATTEMPTED_UPLOAD_TIME = "last_attempted_upload_time";
// Simulation prefs
private static final String SIMULATE_STUMBLE = "simulate_stumble";
private static final String SIMULATION_LAT = "simulate_lat";
private static final String SIMULATION_LON = "simulate_lon";
private static final String MOTION_CHANGE_DISTANCE_METERS = "motion_change_distance";
private static final String MOTION_CHANGE_TIME_WINDOW_SECONDS = "motion_change_time";
private static final String MOTION_SENSOR_MIN_PAUSE_SECONDS = "motion_sensor_min_pause_sec";
private static final String SAVE_STUMBLE_LOGS = "save_stumble_logs";
private static final String USE_OFFLINE_GEO = "use_offline_geo";
private static final String USE_HIGH_POWER = "use_high_power";
public static final String FXA_LOGIN_PREF = "fxaLogin";
public static final String UID_PREF = "leaderboard_uid";
protected static Prefs sInstance;
private final SharedPreferences mSharedPrefs;
private final boolean mSignificantMotionDefaultValue;
protected Prefs(Context context) {
mSharedPrefs = context.getSharedPreferences(PREFS_FILE, Context.MODE_PRIVATE);
if (getPrefs().getInt(VALUES_VERSION_PREF, -1) != AppGlobals.appVersionCode) {
Log.i(LOG_TAG, "Version of the application has changed. Updating default values.");
// Remove old keys
getPrefs().edit()
.remove("reports")
.remove("power_saving_mode")
.commit();
getPrefs().edit().putInt(VALUES_VERSION_PREF, AppGlobals.appVersionCode).commit();
getPrefs().edit().commit();
}
boolean defaultSetting = false;
try {
if (SignificantMotionSensor.getSensor(context) != null) {
String device = android.os.Build.MODEL.toLowerCase();
String pattern = "(nexus \\d)|(a0001)";
if (Pattern.compile(pattern).matcher(device).find()) {
// Most users aren't going to know to switch this setting to on, set the default for known good devices
defaultSetting = true;
}
}
} catch (Exception ex) {}
mSignificantMotionDefaultValue = defaultSetting;
}
// Allows code without a context handle to grab the prefs. The caller must null check the return value.
public static Prefs getInstanceWithoutContext() {
return sInstance;
}
/* Only access after CreatePrefsInstance(Context) has been called at startup. */
public static synchronized Prefs getInstance(Context c) {
if (sInstance == null) {
sInstance = new Prefs(c);
}
return sInstance;
}
@TargetApi(9)
protected static void apply(SharedPreferences.Editor editor) {
if (VERSION.SDK_INT >= 9) {
editor.apply();
} else if (!editor.commit()) {
Log.e(LOG_TAG, "", new IllegalStateException("commit() failed?!"));
}
}
///
/// Getters
///
public synchronized String getUserAgent() {
String s = getStringPref(USER_AGENT_PREF);
return (TextUtils.isEmpty(s)) ? AppGlobals.appName + "/" + AppGlobals.appVersionName : s;
}
///
/// Setters
///
public synchronized void setUserAgent(String userAgent) {
setStringPref(USER_AGENT_PREF, userAgent);
}
public synchronized boolean getFirefoxScanEnabled() {
return getBoolPrefWithDefault(FIREFOX_SCAN_ENABLED, false);
}
public synchronized void setFirefoxScanEnabled(boolean on) {
setBoolPref(FIREFOX_SCAN_ENABLED, on);
}
public synchronized String getMozApiKey() {
String s = getStringPref(MOZ_API_KEY);
return (TextUtils.isEmpty(s)) ? "no-mozilla-api-key" : s;
}
public synchronized void setMozApiKey(String s) {
setStringPref(MOZ_API_KEY, s);
}
// This is the time an upload was last attempted, not necessarily successful.
// Used to ensure upload attempts aren't happening too frequently.
public synchronized long getLastAttemptedUploadTime() {
return getPrefs().getLong(LAST_ATTEMPTED_UPLOAD_TIME, 0);
}
public synchronized void setLastAttemptedUploadTime(long time) {
SharedPreferences.Editor editor = getPrefs().edit();
editor.putLong(LAST_ATTEMPTED_UPLOAD_TIME, time);
apply(editor);
}
public synchronized String getNickname() {
String nickname = getStringPref(NICKNAME_PREF);
if (!TextUtils.isEmpty(nickname)) {
return nickname.trim();
}
return TextUtils.isEmpty(nickname) ? "" : nickname;
}
public synchronized void setNickname(String nick) {
if (nick != null) {
nick = nick.trim();
setStringPref(NICKNAME_PREF, nick);
}
}
public synchronized String getLeaderboardUID() {
String uid = getStringPref(UID_PREF);
if (!TextUtils.isEmpty(uid)) {
return uid;
}
return "";
}
public synchronized void setLeaderboardUID(String uid) {
if (!TextUtils.isEmpty(uid)) {
setStringPref(UID_PREF, uid);
}
}
public synchronized String getEmail() {
String email = getStringPref(EMAIL_PREF);
if (!TextUtils.isEmpty(email)) {
email = email.trim();
}
return TextUtils.isEmpty(email) ? "" : email;
}
public synchronized void setEmail(String email) {
if (email != null) {
email = email.trim();
setStringPref(EMAIL_PREF, email);
}
}
public synchronized boolean getUseWifiOnly() {
return getBoolPrefWithDefault(WIFI_ONLY, true);
}
public synchronized void setUseWifiOnly(boolean state) {
setBoolPref(WIFI_ONLY, state);
}
public synchronized boolean isSaveStumbleLogs() {
return getBoolPrefWithDefault(SAVE_STUMBLE_LOGS, false);
}
public synchronized void setSaveStumbleLogs(boolean state) {
setBoolPref(SAVE_STUMBLE_LOGS, state);
}
///
/// Privates
///
protected String getStringPref(String key) {
return getPrefs().getString(key, "");
}
protected boolean getBoolPrefWithDefault(String key, boolean def) {
return getPrefs().getBoolean(key, def);
}
protected void setBoolPref(String key, Boolean state) {
SharedPreferences.Editor editor = getPrefs().edit();
editor.putBoolean(key, state);
apply(editor);
}
protected float getFloatPrefWithDefault(String key, float def) {
return getPrefs().getFloat(key, def);
}
protected void setFloatPref(String key, float value) {
SharedPreferences.Editor editor = getPrefs().edit();
editor.putFloat(key, value);
apply(editor);
}
protected void setLongPref(String key, long value) {
SharedPreferences.Editor editor = getPrefs().edit();
editor.putLong(key, value);
apply(editor);
}
protected void setStringPref(String key, String value) {
SharedPreferences.Editor editor = getPrefs().edit();
editor.putString(key, value);
apply(editor);
}
@SuppressLint("InlinedApi")
protected SharedPreferences getPrefs() {
return mSharedPrefs;
}
private float getFloatPref(String name, float value) {
return getFloatPrefWithDefault(name, value);
}
public boolean isSimulateStumble() {
return getBoolPrefWithDefault(SIMULATE_STUMBLE, false);
}
public void setSimulateStumble(boolean b) {
setBoolPref(SIMULATE_STUMBLE, b);
}
public float getSimulationLat() {
return getFloatPref(SIMULATION_LAT, (float) 43.6472969);
}
protected void setSimulationLat(float value) {
setFloatPref(SIMULATION_LAT, value);
}
public float getSimulationLon() {
return getFloatPref(SIMULATION_LON, (float) -79.3943137);
}
protected void setSimulationLon(float value) {
setFloatPref(SIMULATION_LON, value);
}
public int getMotionChangeDistanceMeters() {
return getPrefs().getInt(MOTION_CHANGE_DISTANCE_METERS, 50);
}
public void setMotionChangeDistanceMeters(int value) {
SharedPreferences.Editor editor = getPrefs().edit();
editor.putInt(MOTION_CHANGE_DISTANCE_METERS, value);
apply(editor);
}
public int getMotionChangeTimeWindowSeconds() {
return getPrefs().getInt(MOTION_CHANGE_TIME_WINDOW_SECONDS, 120);
}
public void setMotionChangeTimeWindowSeconds(int value) {
SharedPreferences.Editor editor = getPrefs().edit();
editor.putInt(MOTION_CHANGE_TIME_WINDOW_SECONDS, value);
apply(editor);
}
public boolean isMotionSensorEnabled() {
return getPrefs().getBoolean(MOTION_SENSOR_ENABLED, true);
}
public void setMotionSensorEnabled(boolean on) {
setBoolPref(MOTION_SENSOR_ENABLED, on);
}
public boolean isMotionSensorTypeSignificant() {
return getBoolPrefWithDefault(MOTION_SENSOR_IS_SIGNIFICANT_TYPE, mSignificantMotionDefaultValue);
}
public void setMotionSensorTypeSignificant(boolean on) {
setBoolPref(MOTION_SENSOR_IS_SIGNIFICANT_TYPE, on);
}
public void setMotionDetectionMinPauseTime(long seconds) {
SharedPreferences.Editor editor = getPrefs().edit();
editor.putLong(MOTION_SENSOR_MIN_PAUSE_SECONDS, seconds);
apply(editor);
}
public long getMotionDetectionMinPauseTime() {
return getPrefs().getLong(MOTION_SENSOR_MIN_PAUSE_SECONDS, 20);
}
public boolean useOfflineGeo() {
return getPrefs().getBoolean(USE_OFFLINE_GEO, false);
}
public void setOfflineGeo(boolean offlineGeo) {
setBoolPref(USE_OFFLINE_GEO, offlineGeo);
}
public boolean isHighPowerMode() {
return getPrefs().getBoolean(USE_HIGH_POWER, false);
}
public void setIsHighPowerMode(boolean highPower) {
setBoolPref(USE_HIGH_POWER, highPower);
}
public void setBearerToken(String bearerToken) {
if (bearerToken != null) {
bearerToken = bearerToken.trim();
setStringPref(FXA_LOGIN_PREF, bearerToken);
}
}
public String getBearerToken() {
String bearerToken = getStringPref(FXA_LOGIN_PREF);
if (!TextUtils.isEmpty(bearerToken)) {
bearerToken = bearerToken.trim();
}
return TextUtils.isEmpty(bearerToken) ? "" : bearerToken;
}
}