1 /* 2 * Copyright (C) 2020 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 /** 22 * This class encapsulates the transfer of data between [Timer] domain objects and their 23 * permanent storage in [SharedPreferences]. 24 */ 25 internal object TimerDAO { 26 /** Key to a preference that stores the set of timer ids. */ 27 private const val TIMER_IDS = "timers_list" 28 29 /** Key to a preference that stores the id to assign to the next timer. */ 30 private const val NEXT_TIMER_ID = "next_timer_id" 31 32 /** Prefix for a key to a preference that stores the state of the timer. */ 33 private const val STATE = "timer_state_" 34 35 /** Prefix for a key to a preference that stores the original timer length at creation. */ 36 private const val LENGTH = "timer_setup_timet_" 37 38 /** Prefix for a key to a preference that stores the total timer length with additions. */ 39 private const val TOTAL_LENGTH = "timer_original_timet_" 40 41 /** Prefix for a key to a preference that stores the last start time of the timer. */ 42 private const val LAST_START_TIME = "timer_start_time_" 43 44 /** Prefix for a key to a preference that stores the epoch time when the timer last started. */ 45 private const val LAST_WALL_CLOCK_TIME = "timer_wall_clock_time_" 46 47 /** Prefix for a key to a preference that stores the remaining time before expiry. */ 48 private const val REMAINING_TIME = "timer_time_left_" 49 50 /** Prefix for a key to a preference that stores the label of the timer. */ 51 private const val LABEL = "timer_label_" 52 53 /** Prefix for a key to a preference that signals the timer should be deleted on first reset. */ 54 private const val DELETE_AFTER_USE = "delete_after_use_" 55 56 /** 57 * @return the timers from permanent storage 58 */ 59 @JvmStatic getTimersnull60 fun getTimers(prefs: SharedPreferences): MutableList<Timer> { 61 // Read the set of timer ids. 62 val timerIds: Set<String> = prefs.getStringSet(TIMER_IDS, emptySet<String>())!! 63 val timers: MutableList<Timer> = ArrayList(timerIds.size) 64 65 // Build a timer using the data associated with each timer id. 66 for (timerId in timerIds) { 67 val id = timerId.toInt() 68 val stateValue: Int = prefs.getInt(STATE + id, Timer.State.RESET.value) 69 val state: Timer.State? = Timer.State.fromValue(stateValue) 70 71 // Timer state may be null when migrating timers from prior releases which defined a 72 // "deleted" state. Such a state is no longer required. 73 state?.let { 74 val length: Long = prefs.getLong(LENGTH + id, Long.MIN_VALUE) 75 val totalLength: Long = prefs.getLong(TOTAL_LENGTH + id, Long.MIN_VALUE) 76 val lastStartTime: Long = prefs.getLong(LAST_START_TIME + id, Timer.UNUSED) 77 val lastWallClockTime: Long = prefs.getLong(LAST_WALL_CLOCK_TIME + id, Timer.UNUSED) 78 val remainingTime: Long = prefs.getLong(REMAINING_TIME + id, totalLength) 79 val label: String? = prefs.getString(LABEL + id, null) 80 val deleteAfterUse: Boolean = prefs.getBoolean(DELETE_AFTER_USE + id, false) 81 timers.add(Timer(id, it, length, totalLength, lastStartTime, 82 lastWallClockTime, remainingTime, label, deleteAfterUse)) 83 } 84 } 85 86 return timers 87 } 88 89 /** 90 * @param timer the timer to be added 91 */ 92 @JvmStatic addTimernull93 fun addTimer(prefs: SharedPreferences, timer: Timer): Timer { 94 val editor: SharedPreferences.Editor = prefs.edit() 95 96 // Fetch the next timer id. 97 val id: Int = prefs.getInt(NEXT_TIMER_ID, 0) 98 editor.putInt(NEXT_TIMER_ID, id + 1) 99 100 // Add the new timer id to the set of all timer ids. 101 val timerIds: MutableSet<String> = HashSet(getTimerIds(prefs)) 102 timerIds.add(id.toString()) 103 editor.putStringSet(TIMER_IDS, timerIds) 104 105 // Record the fields of the timer. 106 editor.putInt(STATE + id, timer.state.value) 107 editor.putLong(LENGTH + id, timer.length) 108 editor.putLong(TOTAL_LENGTH + id, timer.totalLength) 109 editor.putLong(LAST_START_TIME + id, timer.lastStartTime) 110 editor.putLong(LAST_WALL_CLOCK_TIME + id, timer.lastWallClockTime) 111 editor.putLong(REMAINING_TIME + id, timer.remainingTime) 112 editor.putString(LABEL + id, timer.label) 113 editor.putBoolean(DELETE_AFTER_USE + id, timer.deleteAfterUse) 114 115 editor.apply() 116 117 // Return a new timer with the generated timer id present. 118 return Timer(id, timer.state, timer.length, timer.totalLength, 119 timer.lastStartTime, timer.lastWallClockTime, timer.remainingTime, 120 timer.label, timer.deleteAfterUse) 121 } 122 123 /** 124 * @param timer the timer to be updated 125 */ 126 @JvmStatic updateTimernull127 fun updateTimer(prefs: SharedPreferences, timer: Timer) { 128 val editor: SharedPreferences.Editor = prefs.edit() 129 130 // Record the fields of the timer. 131 val id = timer.id 132 editor.putInt(STATE + id, timer.state.value) 133 editor.putLong(LENGTH + id, timer.length) 134 editor.putLong(TOTAL_LENGTH + id, timer.totalLength) 135 editor.putLong(LAST_START_TIME + id, timer.lastStartTime) 136 editor.putLong(LAST_WALL_CLOCK_TIME + id, timer.lastWallClockTime) 137 editor.putLong(REMAINING_TIME + id, timer.remainingTime) 138 editor.putString(LABEL + id, timer.label) 139 editor.putBoolean(DELETE_AFTER_USE + id, timer.deleteAfterUse) 140 141 editor.apply() 142 } 143 144 /** 145 * @param timer the timer to be removed 146 */ 147 @JvmStatic removeTimernull148 fun removeTimer(prefs: SharedPreferences, timer: Timer) { 149 val editor: SharedPreferences.Editor = prefs.edit() 150 val id = timer.id 151 152 // Remove the timer id from the set of all timer ids. 153 val timerIds: MutableSet<String> = HashSet(getTimerIds(prefs)) 154 timerIds.remove(id.toString()) 155 if (timerIds.isEmpty()) { 156 editor.remove(TIMER_IDS) 157 editor.remove(NEXT_TIMER_ID) 158 } else { 159 editor.putStringSet(TIMER_IDS, timerIds) 160 } 161 162 // Record the fields of the timer. 163 editor.remove(STATE + id) 164 editor.remove(LENGTH + id) 165 editor.remove(TOTAL_LENGTH + id) 166 editor.remove(LAST_START_TIME + id) 167 editor.remove(LAST_WALL_CLOCK_TIME + id) 168 editor.remove(REMAINING_TIME + id) 169 editor.remove(LABEL + id) 170 editor.remove(DELETE_AFTER_USE + id) 171 172 editor.apply() 173 } 174 getTimerIdsnull175 private fun getTimerIds(prefs: SharedPreferences): Set<String> { 176 return prefs.getStringSet(TIMER_IDS, emptySet<String>())!! 177 } 178 }