/* * Copyright (C) 2016 Google Inc. All Rights Reserved. * * 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.google.android.apps.santatracker.data; import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.util.Log; /** * Singleton that manages access to internal data stored as preferences. */ @SuppressLint("CommitPrefEdits") public class SantaPreferences { private static final int PREFERENCE_VERSION = 3; // for a +/- this value (ms) retrieved offset, the difference is simply // ignored and not adjusted public static final int OFFSET_ACCEPTABLE_RANGE_DIFFERENCE = 120000; private static final String TAG = "SantaPreferences"; // Shared time offset private static long TIME_OFFSET = 0L; private SharedPreferences settings; private static final String PREFERENCES_FILENAME = "SantaTracker"; // Preference parameters private static final String PREF_TIMESTAMP = "PREF_TIMESTAMP"; private static final String PREF_NEXT_INFO_ACCESS_TIMESTAMP = "PREF_INFO_API_TIMESTAMP"; private static final String PREF_FINGERPRINT = "PREF_FINGERPRINT"; private static final String PREF_ROUTEOFFSET = "PREF_ROUTEOFFSET"; private static final String PREF_STREAMOFFSET = "PREF_STREAMOFFSET"; private static final String PREF_TOTALPRESENTS = "PREF_TOTALPRESENTS"; private static final String PREF_OFFSET = "PREF_OFFSET"; private static final String PREF_SWITCHOFF = "PREF_SWITCHOFF"; private static final String PREF_VIDEO1 = "PREF_VIDEO1"; private static final String PREF_VIDEO15 = "PREF_VIDEO15"; private static final String PREF_VIDEO23 = "PREF_VIDEO23"; private static final String PREF_CASTDISABLED = "PREF_CASTDISABLED"; private static final String PREF_PHOTODISABLED = "PREF_PHOTODISABLED"; private static final String PREF_GUMBALLDISABLED = "PREF_GUMBALLDISABLED"; private static final String PREF_JETPACKDISABLED = "PREF_JETPACKDISABLED"; private static final String PREF_MEMORYDISABLED = "PREF_MEMORYDISABLED"; private static final String PREF_ROCKETDISABLED = "PREF_ROCKETDISABLED"; private static final String PREF_DANCERDISABLED = "PREF_DANCERDISABLED"; private static final String PREF_SNOWDOWNDISABLED = "PREF_SNOWDOWNDISABLED"; private final static String PREF_SWIMMING_DISABLED = "PREF_SWIMMING_DISABLED"; private final static String PREF_BMX_DISABLED = "PREF_BMX_DISABLED"; private final static String PREF_RUNNING_DISABLED = "PREF_RUNNING_DISABLED"; private final static String PREF_TENNIS_DISABLED = "PREF_TENNIS_DISABLED"; private final static String PREF_WATERPOLO_DISABLED = "PREF_WATERPOLO_DISABLED"; private final static String PREF_CITY_QUIZ_DISABLED = "PREF_CITY_QUIZ_DISABLED"; private final static String PREF_PRESENT_QUEST_DISABLED = "PREF_PRESENT_QUEST_DISABLED"; private static final String PREF_RANDVALUE = "PREF_RANDVALUE"; private static final String PREF_DBVERSION_DEST = "PREF_DBVERSION"; private static final String PREF_DBVERSION_STREAM = "PREF_DBSTREAMVERSION"; private static final String PREF_PREFVERSION = "PREF_PREFERENCEVERSION"; // cached rand value private static float rand; public SantaPreferences(Context context) { settings = context.getSharedPreferences(PREFERENCES_FILENAME, Context.MODE_PRIVATE); // update the cached rand value if it has been set, otherwise it will be // overwritten later rand = settings.getFloat(PREF_RANDVALUE, -1f); // initialise time offset SantaPreferences.TIME_OFFSET = getOffset(); // Handle Preference upgrades checkUpgrade(); } private void checkUpgrade() { final int storedVersion = settings.getInt(PREF_PREFVERSION, 1); if (PREFERENCE_VERSION > storedVersion) { onUpgrade(storedVersion, PREFERENCE_VERSION); } } private void onUpgrade(int oldVersion, int preferenceVersion) { Editor editor = settings.edit(); Log.d(TAG, String.format("Upgrading from %d to %d.", oldVersion, preferenceVersion)); if (oldVersion >= 1) { // Delete all unused cast flags from v1 for (String key : LegacyPreferences.CastFlags_1.ALL_FLAGS) { editor.remove(key); } // Delete all other unused flags for (String key : LegacyPreferences.PREFERENCES){ editor.remove(key); } } // store new preference version editor.putInt(PREF_PREFVERSION, preferenceVersion); editor.commit(); } /** * Returns true if the preferences have been initialised and the database contains valid data. */ public boolean hasValidData() { return getFingerprint() != null && getRandValue() >= 0 && getDBTimestamp() > 1; } /** * Returns the hash of the current data stored in the database. Returns {@link Long#MIN_VALUE} * if no hash has been set. */ public String getFingerprint() { return settings.getString(PREF_FINGERPRINT, null); } public boolean getSwitchOff() { return settings.getBoolean(PREF_SWITCHOFF, false); } public void setSwitchOff(boolean switchOff) { Editor editor = settings.edit(); editor.putBoolean(PREF_SWITCHOFF, switchOff); editor.commit(); } /** * Returns the timestamp at which the INFO-API should next be accessed or 0 if not set. */ public long getNextInfoAPIAccess() { return settings.getLong(PREF_NEXT_INFO_ACCESS_TIMESTAMP, 0L); } public void setNextInfoAPIAccess(long time) { Editor editor = settings.edit(); editor.putLong(PREF_NEXT_INFO_ACCESS_TIMESTAMP, time); editor.commit(); } public int getRouteOffset() { return settings.getInt(PREF_ROUTEOFFSET, 0); } public void setRouteOffset(int routeOffset) { Editor editor = settings.edit(); editor.putInt(PREF_ROUTEOFFSET, routeOffset); editor.commit(); } public int getStreamOffset() { return settings.getInt(PREF_STREAMOFFSET, 0); } public void setStreamOffset(int streamOffset) { Editor editor = settings.edit(); editor.putInt(PREF_STREAMOFFSET, streamOffset); editor.commit(); } public long getTotalPresents() { return settings.getLong(PREF_TOTALPRESENTS, 0L); } public void setTotalPresents(long presents) { Editor editor = settings.edit(); editor.putLong(PREF_TOTALPRESENTS, presents); editor.commit(); } public void invalidateData() { Editor editor = settings.edit(); editor.putLong(PREF_TIMESTAMP, Long.MIN_VALUE); editor.putString(PREF_FINGERPRINT, null); editor.putInt(PREF_ROUTEOFFSET, 0); editor.putInt(PREF_STREAMOFFSET, 0); editor.putLong(PREF_TOTALPRESENTS, 0L); editor.commit(); } public long getOffset() { return settings.getLong(PREF_OFFSET, 0); } public void setOffset(long offset) { Editor editor = settings.edit(); editor.putLong(PREF_OFFSET, offset); editor.commit(); SantaPreferences.TIME_OFFSET = offset; } private long getDBTimestamp() { return settings.getLong(PREF_TIMESTAMP, 0); } public void setDBTimestamp(long time) { Editor editor = settings.edit(); editor.putLong(PREF_TIMESTAMP, time); editor.commit(); } public float getRandValue() { return rand; } public void setRandValue(float value) { Editor editor = settings.edit(); editor.putFloat(PREF_RANDVALUE, value); editor.commit(); rand = value; } /** * Stores the fingerprint of the data stored in the database. */ public void setFingerprint(String fingerprint) { Editor editor = settings.edit(); editor.putString(PREF_FINGERPRINT, fingerprint); editor.commit(); } /** * Checks if all values in Switches are consistent with stored prefs. */ public boolean gameDisabledStateConsistent(GameDisabledState state) { return getGumballDisabled() == state.disableGumballGame && getJetpackDisabled() == state.disableJetpackGame && getMemoryDisabled() == state.disableMemoryGame && getRocketDisabled() == state.disableRocketGame && getDancerDisabled() == state.disableDancerGame && getSnowdownDisabled() == state.disableSnowdownGame && getSwimmingDisabled() == state.disableSwimmingGame && getBmxDisabled() == state.disableBmxGame && getRunningDisabled() == state.disableRunningGame && getTennisDisabled() == state.disableTennisGame && getWaterpoloDisabled() == state.disableWaterpoloGame && getCityQuizDisabled() == state.disableCityQuizGame && getPresentQuestDisabled() == state.disablePresentQuest; } /** * Overwrite all game disabled prefs from Switches. */ public void setGamesDisabled(GameDisabledState state) { Editor editor = settings.edit(); editor.putBoolean(PREF_GUMBALLDISABLED, state.disableGumballGame); editor.putBoolean(PREF_JETPACKDISABLED, state.disableJetpackGame); editor.putBoolean(PREF_MEMORYDISABLED, state.disableMemoryGame); editor.putBoolean(PREF_ROCKETDISABLED, state.disableRocketGame); editor.putBoolean(PREF_DANCERDISABLED, state.disableDancerGame); editor.putBoolean(PREF_SNOWDOWNDISABLED, state.disableSnowdownGame); editor.putBoolean(PREF_SWIMMING_DISABLED, state.disableSwimmingGame); editor.putBoolean(PREF_BMX_DISABLED, state.disableBmxGame); editor.putBoolean(PREF_RUNNING_DISABLED, state.disableRunningGame); editor.putBoolean(PREF_TENNIS_DISABLED, state.disableTennisGame); editor.putBoolean(PREF_WATERPOLO_DISABLED, state.disableWaterpoloGame); editor.putBoolean(PREF_CITY_QUIZ_DISABLED, state.disableCityQuizGame); editor.putBoolean(PREF_PRESENT_QUEST_DISABLED, state.disablePresentQuest); editor.commit(); } boolean getGumballDisabled() { return settings.getBoolean(PREF_GUMBALLDISABLED, false); } boolean getJetpackDisabled() { return settings.getBoolean(PREF_JETPACKDISABLED, false); } boolean getMemoryDisabled() { return settings.getBoolean(PREF_MEMORYDISABLED, false); } boolean getRocketDisabled() { return settings.getBoolean(PREF_ROCKETDISABLED, false); } boolean getDancerDisabled() { return settings.getBoolean(PREF_DANCERDISABLED, false); } boolean getSnowdownDisabled() { return settings.getBoolean(PREF_SNOWDOWNDISABLED, false); } boolean getSwimmingDisabled() { return settings.getBoolean(PREF_SWIMMING_DISABLED, false); } boolean getBmxDisabled() { return settings.getBoolean(PREF_BMX_DISABLED, false); } boolean getRunningDisabled() { return settings.getBoolean(PREF_RUNNING_DISABLED, false); } boolean getTennisDisabled() { return settings.getBoolean(PREF_TENNIS_DISABLED, false); } boolean getWaterpoloDisabled() { return settings.getBoolean(PREF_WATERPOLO_DISABLED, false); } boolean getCityQuizDisabled() { return settings.getBoolean(PREF_CITY_QUIZ_DISABLED, false); } boolean getPresentQuestDisabled() { return settings.getBoolean(PREF_PRESENT_QUEST_DISABLED, false); } public void setVideos(String video1, String video15, String video23) { Editor editor = settings.edit(); editor.putString(PREF_VIDEO1, video1); editor.putString(PREF_VIDEO15, video15); editor.putString(PREF_VIDEO23, video23); editor.commit(); } public String[] getVideos() { return new String[] { settings.getString(PREF_VIDEO1, null), settings.getString(PREF_VIDEO15, null), settings.getString(PREF_VIDEO23, null) }; } public void setCastDisabled(boolean disableCast) { Editor editor = settings.edit(); editor.putBoolean(PREF_CASTDISABLED, disableCast); editor.commit(); } public boolean getCastDisabled() { return settings.getBoolean(PREF_CASTDISABLED, false); } public void setDestinationPhotoDisabled(boolean disablePhoto) { Editor editor = settings.edit(); editor.putBoolean(PREF_PHOTODISABLED, disablePhoto); editor.commit(); } public boolean getDestinationPhotoDisabled() { return settings.getBoolean(PREF_PHOTODISABLED, false); } public void setDestDBVersion(int version) { Editor editor = settings.edit(); editor.putInt(PREF_DBVERSION_DEST, version); editor.commit(); } public int getDestDBVersion() { return settings.getInt(PREF_DBVERSION_DEST, 0); } public void setStreamDBVersion(int version) { Editor editor = settings.edit(); editor.putInt(PREF_DBVERSION_STREAM, version); editor.commit(); } public int getStreamDBVersion() { return settings.getInt(PREF_DBVERSION_STREAM, 0); } /** * Returns the current time in milliseconds with the offset applied. */ public static long getCurrentTime() { return System.currentTimeMillis() + SantaPreferences.TIME_OFFSET; } /** * Returns the time adjusted for the offset */ public static long getAdjustedTime(long time) { return time - SantaPreferences.TIME_OFFSET; } public static int getRandom(int min, int max) { return (int) (min + (Math.random() * ((max - min)))); } public static float getRandom(float min, float max) { return (min + ((float) Math.random() * ((max - min)))); } public static void cacheOffset(long offset) { SantaPreferences.TIME_OFFSET = offset; } }