OSDN Git Service

7d8c8a32caf8e048878175db8841a0fc5944a405
[android-x86/packages-apps-DeskClock.git] / src / com / android / deskclock / Alarm.java
1 /*
2  * Copyright (C) 2009 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;
18
19 import android.content.Context;
20 import android.database.Cursor;
21 import android.media.RingtoneManager;
22 import android.net.Uri;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 import android.provider.BaseColumns;
26 import android.text.format.DateFormat;
27
28 import java.text.DateFormatSymbols;
29 import java.util.Calendar;
30
31 public final class Alarm implements Parcelable {
32
33     //////////////////////////////
34     // Parcelable apis
35     //////////////////////////////
36     public static final Parcelable.Creator<Alarm> CREATOR
37             = new Parcelable.Creator<Alarm>() {
38                 public Alarm createFromParcel(Parcel p) {
39                     return new Alarm(p);
40                 }
41
42                 public Alarm[] newArray(int size) {
43                     return new Alarm[size];
44                 }
45             };
46
47     public int describeContents() {
48         return 0;
49     }
50
51     public void writeToParcel(Parcel p, int flags) {
52         p.writeInt(id);
53         p.writeInt(enabled ? 1 : 0);
54         p.writeInt(hour);
55         p.writeInt(minutes);
56         p.writeInt(daysOfWeek.getCoded());
57         p.writeLong(time);
58         p.writeInt(vibrate ? 1 : 0);
59         p.writeString(label);
60         p.writeParcelable(alert, flags);
61         p.writeInt(silent ? 1 : 0);
62     }
63     //////////////////////////////
64     // end Parcelable apis
65     //////////////////////////////
66
67     //////////////////////////////
68     // Column definitions
69     //////////////////////////////
70     public static class Columns implements BaseColumns {
71         /**
72          * The content:// style URL for this table
73          */
74         public static final Uri CONTENT_URI =
75                 Uri.parse("content://com.android.deskclock/alarm");
76
77         /**
78          * Hour in 24-hour localtime 0 - 23.
79          * <P>Type: INTEGER</P>
80          */
81         public static final String HOUR = "hour";
82
83         /**
84          * Minutes in localtime 0 - 59
85          * <P>Type: INTEGER</P>
86          */
87         public static final String MINUTES = "minutes";
88
89         /**
90          * Days of week coded as integer
91          * <P>Type: INTEGER</P>
92          */
93         public static final String DAYS_OF_WEEK = "daysofweek";
94
95         /**
96          * Alarm time in UTC milliseconds from the epoch.
97          * <P>Type: INTEGER</P>
98          */
99         public static final String ALARM_TIME = "alarmtime";
100
101         /**
102          * True if alarm is active
103          * <P>Type: BOOLEAN</P>
104          */
105         public static final String ENABLED = "enabled";
106
107         /**
108          * True if alarm should vibrate
109          * <P>Type: BOOLEAN</P>
110          */
111         public static final String VIBRATE = "vibrate";
112
113         /**
114          * Message to show when alarm triggers
115          * Note: not currently used
116          * <P>Type: STRING</P>
117          */
118         public static final String MESSAGE = "message";
119
120         /**
121          * Audio alert to play when alarm triggers
122          * <P>Type: STRING</P>
123          */
124         public static final String ALERT = "alert";
125
126         /**
127          * The default sort order for this table
128          */
129         public static final String DEFAULT_SORT_ORDER =
130                 HOUR + ", " + MINUTES + " ASC";
131
132         // Used when filtering enabled alarms.
133         public static final String WHERE_ENABLED = ENABLED + "=1";
134
135         static final String[] ALARM_QUERY_COLUMNS = {
136             _ID, HOUR, MINUTES, DAYS_OF_WEEK, ALARM_TIME,
137             ENABLED, VIBRATE, MESSAGE, ALERT };
138
139         /**
140          * These save calls to cursor.getColumnIndexOrThrow()
141          * THEY MUST BE KEPT IN SYNC WITH ABOVE QUERY COLUMNS
142          */
143         public static final int ALARM_ID_INDEX = 0;
144         public static final int ALARM_HOUR_INDEX = 1;
145         public static final int ALARM_MINUTES_INDEX = 2;
146         public static final int ALARM_DAYS_OF_WEEK_INDEX = 3;
147         public static final int ALARM_TIME_INDEX = 4;
148         public static final int ALARM_ENABLED_INDEX = 5;
149         public static final int ALARM_VIBRATE_INDEX = 6;
150         public static final int ALARM_MESSAGE_INDEX = 7;
151         public static final int ALARM_ALERT_INDEX = 8;
152     }
153     //////////////////////////////
154     // End column definitions
155     //////////////////////////////
156
157     // Public fields
158     public int        id;
159     public boolean    enabled;
160     public int        hour;
161     public int        minutes;
162     public DaysOfWeek daysOfWeek;
163     public long       time;
164     public boolean    vibrate;
165     public String     label;
166     public Uri        alert;
167     public boolean    silent;
168
169     public Alarm(Cursor c) {
170         id = c.getInt(Columns.ALARM_ID_INDEX);
171         enabled = c.getInt(Columns.ALARM_ENABLED_INDEX) == 1;
172         hour = c.getInt(Columns.ALARM_HOUR_INDEX);
173         minutes = c.getInt(Columns.ALARM_MINUTES_INDEX);
174         daysOfWeek = new DaysOfWeek(c.getInt(Columns.ALARM_DAYS_OF_WEEK_INDEX));
175         time = c.getLong(Columns.ALARM_TIME_INDEX);
176         vibrate = c.getInt(Columns.ALARM_VIBRATE_INDEX) == 1;
177         label = c.getString(Columns.ALARM_MESSAGE_INDEX);
178         String alertString = c.getString(Columns.ALARM_ALERT_INDEX);
179         if (Alarms.ALARM_ALERT_SILENT.equals(alertString)) {
180             if (Log.LOGV) {
181                 Log.v("Alarm is marked as silent");
182             }
183             silent = true;
184         } else {
185             if (alertString != null && alertString.length() != 0) {
186                 alert = Uri.parse(alertString);
187             }
188
189             // If the database alert is null or it failed to parse, use the
190             // default alert.
191             if (alert == null) {
192                 alert = RingtoneManager.getDefaultUri(
193                         RingtoneManager.TYPE_ALARM);
194             }
195         }
196     }
197
198     public Alarm(Parcel p) {
199         id = p.readInt();
200         enabled = p.readInt() == 1;
201         hour = p.readInt();
202         minutes = p.readInt();
203         daysOfWeek = new DaysOfWeek(p.readInt());
204         time = p.readLong();
205         vibrate = p.readInt() == 1;
206         label = p.readString();
207         alert = (Uri) p.readParcelable(null);
208         silent = p.readInt() == 1;
209     }
210
211     public String getLabelOrDefault(Context context) {
212         if (label == null || label.length() == 0) {
213             return context.getString(R.string.default_label);
214         }
215         return label;
216     }
217
218     /*
219      * Days of week code as a single int.
220      * 0x00: no day
221      * 0x01: Monday
222      * 0x02: Tuesday
223      * 0x04: Wednesday
224      * 0x08: Thursday
225      * 0x10: Friday
226      * 0x20: Saturday
227      * 0x40: Sunday
228      */
229     static final class DaysOfWeek {
230
231         private static int[] DAY_MAP = new int[] {
232             Calendar.MONDAY,
233             Calendar.TUESDAY,
234             Calendar.WEDNESDAY,
235             Calendar.THURSDAY,
236             Calendar.FRIDAY,
237             Calendar.SATURDAY,
238             Calendar.SUNDAY,
239         };
240
241         // Bitmask of all repeating days
242         private int mDays;
243
244         DaysOfWeek(int days) {
245             mDays = days;
246         }
247
248         public String toString(Context context, boolean showNever) {
249             StringBuilder ret = new StringBuilder();
250
251             // no days
252             if (mDays == 0) {
253                 return showNever ?
254                         context.getText(R.string.never).toString() : "";
255             }
256
257             // every day
258             if (mDays == 0x7f) {
259                 return context.getText(R.string.every_day).toString();
260             }
261
262             // count selected days
263             int dayCount = 0, days = mDays;
264             while (days > 0) {
265                 if ((days & 1) == 1) dayCount++;
266                 days >>= 1;
267             }
268
269             // short or long form?
270             DateFormatSymbols dfs = new DateFormatSymbols();
271             String[] dayList = (dayCount > 1) ?
272                     dfs.getShortWeekdays() :
273                     dfs.getWeekdays();
274
275             // selected days
276             for (int i = 0; i < 7; i++) {
277                 if ((mDays & (1 << i)) != 0) {
278                     ret.append(dayList[DAY_MAP[i]]);
279                     dayCount -= 1;
280                     if (dayCount > 0) ret.append(
281                             context.getText(R.string.day_concat));
282                 }
283             }
284             return ret.toString();
285         }
286
287         private boolean isSet(int day) {
288             return ((mDays & (1 << day)) > 0);
289         }
290
291         public void set(int day, boolean set) {
292             if (set) {
293                 mDays |= (1 << day);
294             } else {
295                 mDays &= ~(1 << day);
296             }
297         }
298
299         public void set(DaysOfWeek dow) {
300             mDays = dow.mDays;
301         }
302
303         public int getCoded() {
304             return mDays;
305         }
306
307         // Returns days of week encoded in an array of booleans.
308         public boolean[] getBooleanArray() {
309             boolean[] ret = new boolean[7];
310             for (int i = 0; i < 7; i++) {
311                 ret[i] = isSet(i);
312             }
313             return ret;
314         }
315
316         public boolean isRepeatSet() {
317             return mDays != 0;
318         }
319
320         /**
321          * returns number of days from today until next alarm
322          * @param c must be set to today
323          */
324         public int getNextAlarm(Calendar c) {
325             if (mDays == 0) {
326                 return -1;
327             }
328
329             int today = (c.get(Calendar.DAY_OF_WEEK) + 5) % 7;
330
331             int day = 0;
332             int dayCount = 0;
333             for (; dayCount < 7; dayCount++) {
334                 day = (today + dayCount) % 7;
335                 if (isSet(day)) {
336                     break;
337                 }
338             }
339             return dayCount;
340         }
341     }
342 }