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