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.SharedPreferences; 20 21 import com.android.deskclock.data.Timer.State; 22 23 import java.util.ArrayList; 24 import java.util.Collections; 25 import java.util.HashSet; 26 import java.util.List; 27 import java.util.Set; 28 29 import static com.android.deskclock.data.Timer.State.RESET; 30 31 /** 32 * This class encapsulates the transfer of data between {@link Timer} domain objects and their 33 * permanent storage in {@link SharedPreferences}. 34 */ 35 final class TimerDAO { 36 37 /** Key to a preference that stores the set of timer ids. */ 38 private static final String TIMER_IDS = "timers_list"; 39 40 /** Key to a preference that stores the id to assign to the next timer. */ 41 private static final String NEXT_TIMER_ID = "next_timer_id"; 42 43 /** Prefix for a key to a preference that stores the state of the timer. */ 44 private static final String STATE = "timer_state_"; 45 46 /** Prefix for a key to a preference that stores the original timer length at creation. */ 47 private static final String LENGTH = "timer_setup_timet_"; 48 49 /** Prefix for a key to a preference that stores the total timer length with additions. */ 50 private static final String TOTAL_LENGTH = "timer_original_timet_"; 51 52 /** Prefix for a key to a preference that stores the last start time of the timer. */ 53 private static final String LAST_START_TIME = "timer_start_time_"; 54 55 /** Prefix for a key to a preference that stores the epoch time when the timer last started. */ 56 private static final String LAST_WALL_CLOCK_TIME = "timer_wall_clock_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 TimerDAO()67 private TimerDAO() {} 68 69 /** 70 * @return the timers from permanent storage 71 */ getTimers(SharedPreferences prefs)72 static List<Timer> getTimers(SharedPreferences prefs) { 73 // Read the set of timer ids. 74 final Set<String> timerIds = prefs.getStringSet(TIMER_IDS, Collections.<String>emptySet()); 75 final List<Timer> timers = new ArrayList<>(timerIds.size()); 76 77 // Build a timer using the data associated with each timer id. 78 for (String timerId : timerIds) { 79 final int id = Integer.parseInt(timerId); 80 final int stateValue = prefs.getInt(STATE + id, RESET.getValue()); 81 final State state = State.fromValue(stateValue); 82 83 // Timer state may be null when migrating timers from prior releases which defined a 84 // "deleted" state. Such a state is no longer required. 85 if (state != null) { 86 final long length = prefs.getLong(LENGTH + id, Long.MIN_VALUE); 87 final long totalLength = prefs.getLong(TOTAL_LENGTH + id, Long.MIN_VALUE); 88 final long lastStartTime = prefs.getLong(LAST_START_TIME + id, Timer.UNUSED); 89 final long lastWallClockTime = prefs.getLong(LAST_WALL_CLOCK_TIME + id, 90 Timer.UNUSED); 91 final long remainingTime = prefs.getLong(REMAINING_TIME + id, totalLength); 92 final String label = prefs.getString(LABEL + id, null); 93 final boolean deleteAfterUse = prefs.getBoolean(DELETE_AFTER_USE + id, false); 94 timers.add(new Timer(id, state, length, totalLength, lastStartTime, 95 lastWallClockTime, remainingTime, label, deleteAfterUse)); 96 } 97 } 98 99 return timers; 100 } 101 102 /** 103 * @param timer the timer to be added 104 */ addTimer(SharedPreferences prefs, Timer timer)105 static Timer addTimer(SharedPreferences prefs, Timer timer) { 106 final SharedPreferences.Editor editor = prefs.edit(); 107 108 // Fetch the next timer id. 109 final int id = prefs.getInt(NEXT_TIMER_ID, 0); 110 editor.putInt(NEXT_TIMER_ID, id + 1); 111 112 // Add the new timer id to the set of all timer ids. 113 final Set<String> timerIds = new HashSet<>(getTimerIds(prefs)); 114 timerIds.add(String.valueOf(id)); 115 editor.putStringSet(TIMER_IDS, timerIds); 116 117 // Record the fields of the timer. 118 editor.putInt(STATE + id, timer.getState().getValue()); 119 editor.putLong(LENGTH + id, timer.getLength()); 120 editor.putLong(TOTAL_LENGTH + id, timer.getTotalLength()); 121 editor.putLong(LAST_START_TIME + id, timer.getLastStartTime()); 122 editor.putLong(LAST_WALL_CLOCK_TIME + id, timer.getLastWallClockTime()); 123 editor.putLong(REMAINING_TIME + id, timer.getRemainingTime()); 124 editor.putString(LABEL + id, timer.getLabel()); 125 editor.putBoolean(DELETE_AFTER_USE + id, timer.getDeleteAfterUse()); 126 127 editor.apply(); 128 129 // Return a new timer with the generated timer id present. 130 return new Timer(id, timer.getState(), timer.getLength(), timer.getTotalLength(), 131 timer.getLastStartTime(), timer.getLastWallClockTime(), timer.getRemainingTime(), 132 timer.getLabel(), timer.getDeleteAfterUse()); 133 } 134 135 /** 136 * @param timer the timer to be updated 137 */ updateTimer(SharedPreferences prefs, Timer timer)138 static void updateTimer(SharedPreferences prefs, Timer timer) { 139 final SharedPreferences.Editor editor = prefs.edit(); 140 141 // Record the fields of the timer. 142 final int id = timer.getId(); 143 editor.putInt(STATE + id, timer.getState().getValue()); 144 editor.putLong(LENGTH + id, timer.getLength()); 145 editor.putLong(TOTAL_LENGTH + id, timer.getTotalLength()); 146 editor.putLong(LAST_START_TIME + id, timer.getLastStartTime()); 147 editor.putLong(LAST_WALL_CLOCK_TIME + id, timer.getLastWallClockTime()); 148 editor.putLong(REMAINING_TIME + id, timer.getRemainingTime()); 149 editor.putString(LABEL + id, timer.getLabel()); 150 editor.putBoolean(DELETE_AFTER_USE + id, timer.getDeleteAfterUse()); 151 152 editor.apply(); 153 } 154 155 /** 156 * @param timer the timer to be removed 157 */ removeTimer(SharedPreferences prefs, Timer timer)158 static void removeTimer(SharedPreferences prefs, Timer timer) { 159 final SharedPreferences.Editor editor = prefs.edit(); 160 161 final int id = timer.getId(); 162 163 // Remove the timer id from the set of all timer ids. 164 final Set<String> timerIds = new HashSet<>(getTimerIds(prefs)); 165 timerIds.remove(String.valueOf(id)); 166 if (timerIds.isEmpty()) { 167 editor.remove(TIMER_IDS); 168 editor.remove(NEXT_TIMER_ID); 169 } else { 170 editor.putStringSet(TIMER_IDS, timerIds); 171 } 172 173 // Record the fields of the timer. 174 editor.remove(STATE + id); 175 editor.remove(LENGTH + id); 176 editor.remove(TOTAL_LENGTH + id); 177 editor.remove(LAST_START_TIME + id); 178 editor.remove(LAST_WALL_CLOCK_TIME + id); 179 editor.remove(REMAINING_TIME + id); 180 editor.remove(LABEL + id); 181 editor.remove(DELETE_AFTER_USE + id); 182 183 editor.apply(); 184 } 185 getTimerIds(SharedPreferences prefs)186 private static Set<String> getTimerIds(SharedPreferences prefs) { 187 return prefs.getStringSet(TIMER_IDS, Collections.<String>emptySet()); 188 } 189 }