1 /* 2 * Copyright (C) 2012 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.timer; 18 19 import android.content.Context; 20 import android.content.SharedPreferences; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.util.Log; 24 import android.view.View; 25 26 import com.android.deskclock.R; 27 import com.android.deskclock.Utils; 28 29 import java.util.ArrayList; 30 import java.util.Collections; 31 import java.util.Comparator; 32 import java.util.HashSet; 33 import java.util.Iterator; 34 import java.util.Set; 35 36 public class TimerObj implements Parcelable { 37 38 private static final String TAG = "TimerObj"; 39 // Max timer length is 9 hours + 99 minutes + 9 seconds 40 public static final long MAX_TIMER_LENGTH = (9 * 3600 + 99 * 60 + 99) * 1000; 41 public static final long MINUTE_IN_MILLIS = 60 * 1000; 42 43 public int mTimerId; // Unique id 44 public long mStartTime; // With mTimeLeft , used to calculate the correct time 45 public long mTimeLeft; // in the timer. 46 public long mOriginalLength; // length set at start of timer and by +1 min after times up 47 public long mSetupLength; // length set at start of timer 48 public View mView; 49 public int mState; 50 public String mLabel; 51 public boolean mDeleteAfterUse; 52 53 public static final int STATE_RUNNING = 1; 54 public static final int STATE_STOPPED = 2; 55 public static final int STATE_TIMESUP = 3; 56 public static final int STATE_DONE = 4; 57 public static final int STATE_RESTART = 5; 58 public static final int STATE_DELETED = 6; 59 60 private static final String PREF_TIMER_ID = "timer_id_"; 61 private static final String PREF_START_TIME = "timer_start_time_"; 62 private static final String PREF_TIME_LEFT = "timer_time_left_"; 63 private static final String PREF_ORIGINAL_TIME = "timer_original_timet_"; 64 private static final String PREF_SETUP_TIME = "timer_setup_timet_"; 65 private static final String PREF_STATE = "timer_state_"; 66 private static final String PREF_LABEL = "timer_label_"; 67 private static final String PREF_DELETE_AFTER_USE = "delete_after_use_"; 68 69 private static final String PREF_TIMERS_LIST = "timers_list"; 70 71 public static final Parcelable.Creator<TimerObj> CREATOR = new Parcelable.Creator<TimerObj>() { 72 @Override 73 public TimerObj createFromParcel(Parcel p) { 74 return new TimerObj(p); 75 } 76 77 @Override 78 public TimerObj[] newArray(int size) { 79 return new TimerObj[size]; 80 } 81 }; 82 83 public void writeToSharedPref(SharedPreferences prefs) { 84 SharedPreferences.Editor editor = prefs.edit(); 85 String key = PREF_TIMER_ID + Integer.toString(mTimerId); 86 String id = Integer.toString(mTimerId); 87 editor.putInt (key, mTimerId); 88 key = PREF_START_TIME + id; 89 editor.putLong (key, mStartTime); 90 key = PREF_TIME_LEFT + id; 91 editor.putLong (key, mTimeLeft); 92 key = PREF_ORIGINAL_TIME + id; 93 editor.putLong (key, mOriginalLength); 94 key = PREF_SETUP_TIME + id; 95 editor.putLong (key, mSetupLength); 96 key = PREF_STATE + id; 97 editor.putInt (key, mState); 98 Set <String> timersList = prefs.getStringSet(PREF_TIMERS_LIST, new HashSet<String>()); 99 timersList.add(id); 100 editor.putStringSet(PREF_TIMERS_LIST, timersList); 101 key = PREF_LABEL + id; 102 editor.putString(key, mLabel); 103 key = PREF_DELETE_AFTER_USE + id; 104 editor.putBoolean(key, mDeleteAfterUse); 105 editor.apply(); 106 } 107 108 109 public void readFromSharedPref(SharedPreferences prefs) { 110 String id = Integer.toString(mTimerId); 111 String key = PREF_START_TIME + id; 112 mStartTime = prefs.getLong(key, 0); 113 key = PREF_TIME_LEFT + id; 114 mTimeLeft = prefs.getLong(key, 0); 115 key = PREF_ORIGINAL_TIME + id; 116 mOriginalLength = prefs.getLong(key, 0); 117 key = PREF_SETUP_TIME + id; 118 mSetupLength = prefs.getLong(key, 0); 119 key = PREF_STATE + id; 120 mState = prefs.getInt(key, 0); 121 key = PREF_LABEL + id; 122 mLabel = prefs.getString(key, ""); 123 key = PREF_DELETE_AFTER_USE + id; 124 mDeleteAfterUse = prefs.getBoolean(key, false); 125 } 126 127 public void deleteFromSharedPref(SharedPreferences prefs) { 128 SharedPreferences.Editor editor = prefs.edit(); 129 String key = PREF_TIMER_ID + Integer.toString(mTimerId); 130 String id = Integer.toString(mTimerId); 131 editor.remove (key); 132 key = PREF_START_TIME + id; 133 editor.remove (key); 134 key = PREF_TIME_LEFT + id; 135 editor.remove (key); 136 key = PREF_ORIGINAL_TIME + id; 137 editor.remove (key); 138 key = PREF_SETUP_TIME + id; 139 editor.remove (key); 140 key = PREF_STATE + id; 141 editor.remove (key); 142 Set <String> timersList = prefs.getStringSet(PREF_TIMERS_LIST, new HashSet<String>()); 143 timersList.remove(id); 144 editor.putStringSet(PREF_TIMERS_LIST, timersList); 145 key = PREF_LABEL + id; 146 editor.remove(key); 147 key = PREF_DELETE_AFTER_USE + id; 148 editor.remove(key); 149 editor.commit(); 150 //dumpTimersFromSharedPrefs(prefs); 151 } 152 153 154 @Override 155 public int describeContents() { 156 return 0; 157 } 158 159 @Override 160 public void writeToParcel(Parcel dest, int flags) { 161 dest.writeInt(mTimerId); 162 dest.writeLong(mStartTime); 163 dest.writeLong(mTimeLeft); 164 dest.writeLong(mOriginalLength); 165 dest.writeLong(mSetupLength); 166 dest.writeInt(mState); 167 dest.writeString(mLabel); 168 } 169 170 public TimerObj(Parcel p) { 171 mTimerId = p.readInt(); 172 mStartTime = p.readLong(); 173 mTimeLeft = p.readLong(); 174 mOriginalLength = p.readLong(); 175 mSetupLength = p.readLong(); 176 mState = p.readInt(); 177 mLabel = p.readString(); 178 } 179 180 public TimerObj() { 181 this(0); 182 } 183 184 public TimerObj(long timerLength) { 185 init(timerLength); 186 } 187 188 public TimerObj(long length, String label) { 189 this(length); 190 mLabel = label != null ? label : ""; 191 } 192 193 private void init (long length) { 194 /* TODO: mTimerId must avoid StopwatchService.NOTIFICATION_ID, 195 * TimerReceiver.IN_USE_NOTIFICATION_ID, and alarm ID's (which seem to be 1, 2, ..) 196 */ 197 mTimerId = (int) Utils.getTimeNow(); 198 mStartTime = Utils.getTimeNow(); 199 mTimeLeft = mOriginalLength = mSetupLength = length; 200 mLabel = ""; 201 } 202 203 public long updateTimeLeft(boolean forceUpdate) { 204 if (isTicking() || forceUpdate) { 205 long millis = Utils.getTimeNow(); 206 mTimeLeft = mOriginalLength - (millis - mStartTime); 207 } 208 return mTimeLeft; 209 } 210 211 public String getLabelOrDefault(Context context) { 212 return (mLabel == null || mLabel.length() == 0) ? context.getString( 213 R.string.timer_notification_label) 214 : mLabel; 215 } 216 217 public boolean isTicking() { 218 return mState == STATE_RUNNING || mState == STATE_TIMESUP; 219 } 220 221 public boolean isInUse() { 222 return mState == STATE_RUNNING || mState == STATE_STOPPED; 223 } 224 225 public void addTime(long time) { 226 mTimeLeft = mOriginalLength - (Utils.getTimeNow() - mStartTime); 227 if (mTimeLeft < MAX_TIMER_LENGTH - time) { 228 mOriginalLength += time; 229 } 230 } 231 232 public boolean getDeleteAfterUse() { 233 return mDeleteAfterUse; 234 } 235 236 public long getTimesupTime() { 237 return mStartTime + mOriginalLength; 238 } 239 240 241 public static void getTimersFromSharedPrefs( 242 SharedPreferences prefs, ArrayList<TimerObj> timers) { 243 Object[] timerStrings = 244 prefs.getStringSet(PREF_TIMERS_LIST, new HashSet<String>()).toArray(); 245 if (timerStrings.length > 0) { 246 for (int i = 0; i < timerStrings.length; i++) { 247 TimerObj t = new TimerObj(); 248 t.mTimerId = Integer.parseInt((String)timerStrings[i]); 249 t.readFromSharedPref(prefs); 250 timers.add(t); 251 } 252 Collections.sort(timers, new Comparator<TimerObj>() { 253 @Override 254 public int compare(TimerObj timerObj1, TimerObj timerObj2) { 255 return timerObj2.mTimerId - timerObj1.mTimerId; 256 } 257 }); 258 } 259 } 260 261 public static void getTimersFromSharedPrefs( 262 SharedPreferences prefs, ArrayList<TimerObj> timers, int match) { 263 Object[] timerStrings = prefs.getStringSet(PREF_TIMERS_LIST, new HashSet<String>()) 264 .toArray(); 265 if (timerStrings.length > 0) { 266 for (int i = 0; i < timerStrings.length; i++) { 267 TimerObj t = new TimerObj(); 268 t.mTimerId = Integer.parseInt((String) timerStrings[i]); 269 t.readFromSharedPref(prefs); 270 if (t.mState == match) { 271 timers.add(t); 272 } 273 } 274 } 275 } 276 277 public static void putTimersInSharedPrefs( 278 SharedPreferences prefs, ArrayList<TimerObj> timers) { 279 if (timers.size() > 0) { 280 for (int i = 0; i < timers.size(); i++) { 281 TimerObj t = timers.get(i); 282 timers.get(i).writeToSharedPref(prefs); 283 } 284 } 285 } 286 287 public static void dumpTimersFromSharedPrefs( 288 SharedPreferences prefs) { 289 Object[] timerStrings = 290 prefs.getStringSet(PREF_TIMERS_LIST, new HashSet<String>()).toArray(); 291 Log.v(TAG,"--------------------- timers list in shared prefs"); 292 if (timerStrings.length > 0) { 293 for (int i = 0; i < timerStrings.length; i++) { 294 int id = Integer.parseInt((String)timerStrings[i]); 295 Log.v(TAG,"---------------------timer " + (i + 1) + ": id - " + id); 296 } 297 } 298 } 299 300 public static void resetTimersInSharedPrefs(SharedPreferences prefs) { 301 ArrayList<TimerObj> timers = new ArrayList<TimerObj>(); 302 getTimersFromSharedPrefs(prefs, timers); 303 Iterator<TimerObj> i = timers.iterator(); 304 while(i.hasNext()) { 305 TimerObj t = i.next(); 306 t.mState = TimerObj.STATE_RESTART; 307 t.mTimeLeft = t. mOriginalLength = t.mSetupLength; 308 t.writeToSharedPref(prefs); 309 } 310 } 311 312 } 313