1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.deskclock.data; 18 19 import android.content.Context; 20 import android.content.SharedPreferences; 21 import android.preference.PreferenceManager; 22 23 import com.android.deskclock.Utils; 24 import com.android.deskclock.data.Timer.State; 25 26 import java.util.ArrayList; 27 import java.util.Collections; 28 import java.util.HashSet; 29 import java.util.List; 30 import java.util.Set; 31 32 import static com.android.deskclock.data.Timer.State.RESET; 33 34 /** 35 * This class encapsulates the transfer of data between {@link Timer} domain objects and their 36 * permanent storage in {@link SharedPreferences}. 37 */ 38 final class TimerDAO { 39 40 // Key to a preference that stores the set of timer ids. 41 private static final String TIMER_IDS = "timers_list"; 42 43 // Key to a preference that stores the id to assign to the next timer. 44 private static final String NEXT_TIMER_ID = "next_timer_id"; 45 46 // Prefix for a key to a preference that stores the state of the timer. 47 private static final String STATE = "timer_state_"; 48 49 // Prefix for a key to a preference that stores the length of the timer when it was created. 50 private static final String LENGTH = "timer_setup_timet_"; 51 52 // Prefix for a key to a preference that stores the total length of the timer with additions. 53 private static final String TOTAL_LENGTH = "timer_original_timet_"; 54 55 // Prefix for a key to a preference that stores the last start time of the timer. 56 private static final String LAST_START_TIME = "timer_start_time_"; 57 58 // Prefix for a key to a preference that stores the remaining time before expiry. 59 private static final String REMAINING_TIME = "timer_time_left_"; 60 61 // Prefix for a key to a preference that stores the label of the timer. 62 private static final String LABEL = "timer_label_"; 63 64 // Prefix for a key to a preference that signals the timer should be deleted on first reset. 65 private static final String DELETE_AFTER_USE = "delete_after_use_"; 66 67 // Lazily instantiated and cached for the life of the application. 68 private static SharedPreferences sPrefs; 69 TimerDAO()70 private TimerDAO() {} 71 72 /** 73 * @return the timers from permanent storage 74 */ getTimers(Context context)75 public static List<Timer> getTimers(Context context) { 76 final SharedPreferences prefs = getSharedPreferences(context); 77 78 // Read the set of timer ids. 79 final Set<String> timerIds = prefs.getStringSet(TIMER_IDS, Collections.<String>emptySet()); 80 final List<Timer> timers = new ArrayList<>(timerIds.size()); 81 82 // Build a timer using the data associated with each timer id. 83 for (String timerId : timerIds) { 84 final int id = Integer.parseInt(timerId); 85 final int stateValue = prefs.getInt(STATE + id, RESET.getValue()); 86 final State state = State.fromValue(stateValue); 87 88 // Timer state may be null when migrating timers from prior releases which defined a 89 // "deleted" state. Such a state is no longer required. 90 if (state != null) { 91 final long length = prefs.getLong(LENGTH + id, Long.MIN_VALUE); 92 final long totalLength = prefs.getLong(TOTAL_LENGTH + id, Long.MIN_VALUE); 93 final long lastStartTime = prefs.getLong(LAST_START_TIME + id, Long.MIN_VALUE); 94 final long remainingTime = prefs.getLong(REMAINING_TIME + id, totalLength); 95 final String label = prefs.getString(LABEL + id, null); 96 final boolean deleteAfterUse = prefs.getBoolean(DELETE_AFTER_USE + id, false); 97 timers.add(new Timer(id, state, length, totalLength, lastStartTime, remainingTime, 98 label, deleteAfterUse)); 99 } 100 } 101 102 return timers; 103 } 104 105 /** 106 * @param timer the timer to be added 107 */ addTimer(Context context, Timer timer)108 public static Timer addTimer(Context context, Timer timer) { 109 final SharedPreferences prefs = getSharedPreferences(context); 110 final SharedPreferences.Editor editor = prefs.edit(); 111 112 // Fetch the next timer id. 113 final int id = prefs.getInt(NEXT_TIMER_ID, 0); 114 editor.putInt(NEXT_TIMER_ID, id + 1); 115 116 // Add the new timer id to the set of all timer ids. 117 final Set<String> timerIds = new HashSet<>(getTimerIds(context)); 118 timerIds.add(String.valueOf(id)); 119 editor.putStringSet(TIMER_IDS, timerIds); 120 121 // Record the fields of the timer. 122 editor.putInt(STATE + id, timer.getState().getValue()); 123 editor.putLong(LENGTH + id, timer.getLength()); 124 editor.putLong(TOTAL_LENGTH + id, timer.getTotalLength()); 125 editor.putLong(LAST_START_TIME + id, timer.getLastStartTime()); 126 editor.putLong(REMAINING_TIME + id, timer.getRemainingTime()); 127 editor.putString(LABEL + id, timer.getLabel()); 128 editor.putBoolean(DELETE_AFTER_USE + id, timer.getDeleteAfterUse()); 129 130 editor.apply(); 131 132 // Return a new timer with the generated timer id present. 133 return new Timer(id, timer.getState(), timer.getLength(), timer.getTotalLength(), 134 timer.getLastStartTime(), timer.getRemainingTime(), timer.getLabel(), 135 timer.getDeleteAfterUse()); 136 } 137 138 /** 139 * @param timer the timer to be updated 140 */ updateTimer(Context context, Timer timer)141 public static void updateTimer(Context context, Timer timer) { 142 final SharedPreferences prefs = getSharedPreferences(context); 143 final SharedPreferences.Editor editor = prefs.edit(); 144 145 // Record the fields of the timer. 146 final int id = timer.getId(); 147 editor.putInt(STATE + id, timer.getState().getValue()); 148 editor.putLong(LENGTH + id, timer.getLength()); 149 editor.putLong(TOTAL_LENGTH + id, timer.getTotalLength()); 150 editor.putLong(LAST_START_TIME + id, timer.getLastStartTime()); 151 editor.putLong(REMAINING_TIME + id, timer.getRemainingTime()); 152 editor.putString(LABEL + id, timer.getLabel()); 153 editor.putBoolean(DELETE_AFTER_USE + id, timer.getDeleteAfterUse()); 154 155 editor.apply(); 156 } 157 158 /** 159 * @param timer the timer to be removed 160 */ removeTimer(Context context, Timer timer)161 public static void removeTimer(Context context, Timer timer) { 162 final SharedPreferences prefs = getSharedPreferences(context); 163 final SharedPreferences.Editor editor = prefs.edit(); 164 165 final int id = timer.getId(); 166 167 // Remove the timer id from the set of all timer ids. 168 final Set<String> timerIds = new HashSet<>(getTimerIds(context)); 169 timerIds.remove(String.valueOf(id)); 170 if (timerIds.isEmpty()) { 171 editor.remove(TIMER_IDS); 172 editor.remove(NEXT_TIMER_ID); 173 } else { 174 editor.putStringSet(TIMER_IDS, timerIds); 175 } 176 177 // Record the fields of the timer. 178 editor.remove(STATE + id); 179 editor.remove(LENGTH + id); 180 editor.remove(TOTAL_LENGTH + id); 181 editor.remove(LAST_START_TIME + id); 182 editor.remove(REMAINING_TIME + id); 183 editor.remove(LABEL + id); 184 editor.remove(DELETE_AFTER_USE + id); 185 186 editor.apply(); 187 } 188 getTimerIds(Context context)189 private static Set<String> getTimerIds(Context context) { 190 final SharedPreferences prefs = getSharedPreferences(context); 191 return prefs.getStringSet(TIMER_IDS, Collections.<String>emptySet()); 192 } 193 getSharedPreferences(Context context)194 private static SharedPreferences getSharedPreferences(Context context) { 195 if (sPrefs == null) { 196 sPrefs = Utils.getDefaultSharedPreferences(context.getApplicationContext()); 197 } 198 199 return sPrefs; 200 } 201 } 202