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