OSDN Git Service

Adds hooks to DeskClock so that other programs may kill or
[android-x86/packages-apps-DeskClock.git] / src / com / android / deskclock / Alarms.java
index ebb337b..1e331a2 100644 (file)
@@ -44,6 +44,19 @@ public class Alarms {
     // from the alarm manager.
     public static final String ALARM_ALERT_ACTION = "com.android.deskclock.ALARM_ALERT";
 
+    // A public action sent by AlarmKlaxon when the alarm has stopped sounding
+    // for any reason (e.g. because it has been dismissed from AlarmAlertFullScreen,
+    // or killed due to an incoming phone call, etc).
+    public static final String ALARM_DONE_ACTION = "com.android.deskclock.ALARM_DONE";
+
+    // AlarmAlertFullScreen listens for this broadcast intent, so that other applications
+    // can snooze the alarm (after ALARM_ALERT_ACTION and before ALARM_DONE_ACTION).
+    public static final String ALARM_SNOOZE_ACTION = "com.android.deskclock.ALARM_SNOOZE";
+
+    // AlarmAlertFullScreen listens for this broadcast intent, so that other applications
+    // can dismiss the alarm (after ALARM_ALERT_ACTION and before ALARM_DONE_ACTION).
+    public static final String ALARM_DISMISS_ACTION = "com.android.deskclock.ALARM_DISMISS";
+
     // This is a private action used by the AlarmKlaxon to update the UI to
     // show the alarm has been killed.
     public static final String ALARM_KILLED = "alarm_killed";
@@ -84,10 +97,16 @@ public class Alarms {
     /**
      * Creates a new Alarm.
      */
-    public static Uri addAlarm(ContentResolver contentResolver) {
-        ContentValues values = new ContentValues();
-        values.put(Alarm.Columns.HOUR, 8);
-        return contentResolver.insert(Alarm.Columns.CONTENT_URI, values);
+    public static long addAlarm(Context context, Alarm alarm) {
+        ContentValues values = createContentValues(alarm);
+        context.getContentResolver().insert(Alarm.Columns.CONTENT_URI, values);
+
+        long timeInMillis = calculateAlarm(alarm);
+        if (alarm.enabled) {
+            clearSnoozeIfNeeded(context, timeInMillis);
+        }
+        setNextAlert(context);
+        return timeInMillis;
     }
 
     /**
@@ -125,6 +144,41 @@ public class Alarms {
                 null, null);
     }
 
+    private static ContentValues createContentValues(Alarm alarm) {
+        ContentValues values = new ContentValues(8);
+        // Set the alarm_time value if this alarm does not repeat. This will be
+        // used later to disable expire alarms.
+        long time = 0;
+        if (!alarm.daysOfWeek.isRepeatSet()) {
+            time = calculateAlarm(alarm);
+        }
+
+        values.put(Alarm.Columns.ENABLED, alarm.enabled ? 1 : 0);
+        values.put(Alarm.Columns.HOUR, alarm.hour);
+        values.put(Alarm.Columns.MINUTES, alarm.minutes);
+        values.put(Alarm.Columns.ALARM_TIME, alarm.time);
+        values.put(Alarm.Columns.DAYS_OF_WEEK, alarm.daysOfWeek.getCoded());
+        values.put(Alarm.Columns.VIBRATE, alarm.vibrate);
+        values.put(Alarm.Columns.MESSAGE, alarm.label);
+
+        // A null alert Uri indicates a silent alarm.
+        values.put(Alarm.Columns.ALERT, alarm.alert == null ? ALARM_ALERT_SILENT
+                : alarm.alert.toString());
+
+        return values;
+    }
+
+    private static void clearSnoozeIfNeeded(Context context, long alarmTime) {
+        // If this alarm fires before the next snooze, clear the snooze to
+        // enable this alarm.
+        SharedPreferences prefs =
+                context.getSharedPreferences(AlarmClock.PREFERENCES, 0);
+        long snoozeTime = prefs.getLong(PREF_SNOOZE_TIME, 0);
+        if (alarmTime < snoozeTime) {
+            clearSnoozePreference(context, prefs);
+        }
+    }
+
     /**
      * Return an Alarm object representing the alarm id in the database.
      * Returns null if no alarm exists.
@@ -148,59 +202,28 @@ public class Alarms {
     /**
      * A convenience method to set an alarm in the Alarms
      * content provider.
-     *
-     * @param id             corresponds to the _id column
-     * @param enabled        corresponds to the ENABLED column
-     * @param hour           corresponds to the HOUR column
-     * @param minutes        corresponds to the MINUTES column
-     * @param daysOfWeek     corresponds to the DAYS_OF_WEEK column
-     * @param time           corresponds to the ALARM_TIME column
-     * @param vibrate        corresponds to the VIBRATE column
-     * @param message        corresponds to the MESSAGE column
-     * @param alert          corresponds to the ALERT column
      * @return Time when the alarm will fire.
      */
-    public static long setAlarm(
-            Context context, int id, boolean enabled, int hour, int minutes,
-            Alarm.DaysOfWeek daysOfWeek, boolean vibrate, String message,
-            String alert) {
-
-        ContentValues values = new ContentValues(8);
+    public static long setAlarm(Context context, Alarm alarm) {
+        ContentValues values = createContentValues(alarm);
         ContentResolver resolver = context.getContentResolver();
-        // Set the alarm_time value if this alarm does not repeat. This will be
-        // used later to disable expired alarms.
-        long time = 0;
-        if (!daysOfWeek.isRepeatSet()) {
-            time = calculateAlarm(hour, minutes, daysOfWeek).getTimeInMillis();
-        }
-
-        if (Log.LOGV) Log.v(
-                "**  setAlarm * idx " + id + " hour " + hour + " minutes " +
-                minutes + " enabled " + enabled + " time " + time);
-
-        values.put(Alarm.Columns.ENABLED, enabled ? 1 : 0);
-        values.put(Alarm.Columns.HOUR, hour);
-        values.put(Alarm.Columns.MINUTES, minutes);
-        values.put(Alarm.Columns.ALARM_TIME, time);
-        values.put(Alarm.Columns.DAYS_OF_WEEK, daysOfWeek.getCoded());
-        values.put(Alarm.Columns.VIBRATE, vibrate);
-        values.put(Alarm.Columns.MESSAGE, message);
-        values.put(Alarm.Columns.ALERT, alert);
-        resolver.update(ContentUris.withAppendedId(Alarm.Columns.CONTENT_URI, id),
-                        values, null, null);
-
-        long timeInMillis =
-                calculateAlarm(hour, minutes, daysOfWeek).getTimeInMillis();
-
-        if (enabled) {
-            // If this alarm fires before the next snooze, clear the snooze to
-            // enable this alarm.
-            SharedPreferences prefs = context.getSharedPreferences(
-                    AlarmClock.PREFERENCES, 0);
-            long snoozeTime = prefs.getLong(PREF_SNOOZE_TIME, 0);
-            if (timeInMillis < snoozeTime) {
-                clearSnoozePreference(context, prefs);
-            }
+        resolver.update(
+                ContentUris.withAppendedId(Alarm.Columns.CONTENT_URI, alarm.id),
+                values, null, null);
+
+        long timeInMillis = calculateAlarm(alarm);
+
+        if (alarm.enabled) {
+            // Disable the snooze if we just changed the snoozed alarm. This
+            // only does work if the snoozed alarm is the same as the given
+            // alarm.
+            // TODO: disableSnoozeAlert should have a better name.
+            disableSnoozeAlert(context, alarm.id);
+
+            // Disable the snooze if this alarm fires before the snoozed alarm.
+            // This works on every alarm since the user most likely intends to
+            // have the modified alarm fire next.
+            clearSnoozeIfNeeded(context, timeInMillis);
         }
 
         setNextAlert(context);
@@ -229,6 +252,9 @@ public class Alarms {
 
     private static void enableAlarmInternal(final Context context,
             final Alarm alarm, boolean enabled) {
+        if (alarm == null) {
+            return;
+        }
         ContentResolver resolver = context.getContentResolver();
 
         ContentValues values = new ContentValues(2);
@@ -239,10 +265,12 @@ public class Alarms {
         if (enabled) {
             long time = 0;
             if (!alarm.daysOfWeek.isRepeatSet()) {
-                time = calculateAlarm(alarm.hour, alarm.minutes,
-                        alarm.daysOfWeek).getTimeInMillis();
+                time = calculateAlarm(alarm);
             }
             values.put(Alarm.Columns.ALARM_TIME, time);
+        } else {
+            // Clear the snooze if the id matches.
+            disableSnoozeAlert(context, alarm.id);
         }
 
         resolver.update(ContentUris.withAppendedId(
@@ -261,8 +289,7 @@ public class Alarms {
                     // A time of 0 indicates this is a repeating alarm, so
                     // calculate the time to get the next alert.
                     if (a.time == 0) {
-                        a.time = calculateAlarm(a.hour, a.minutes, a.daysOfWeek)
-                                .getTimeInMillis();
+                        a.time = calculateAlarm(a);
                     } else if (a.time < now) {
                         // Expired alarm, disable it and move along.
                         enableAlarmInternal(context, a, false);
@@ -360,7 +387,7 @@ public class Alarms {
         setStatusBarIcon(context, true);
 
         Calendar c = Calendar.getInstance();
-        c.setTime(new java.util.Date(atTimeInMillis));
+        c.setTimeInMillis(atTimeInMillis);
         String timeString = formatDayAndTime(context, c);
         saveNextAlarm(context, timeString);
     }
@@ -447,6 +474,9 @@ public class Alarms {
 
         // Get the alarm from the db.
         final Alarm alarm = getAlarm(context.getContentResolver(), id);
+        if (alarm == null) {
+            return false;
+        }
         // The time in the database is either 0 (repeating) or a specific time
         // for a non-repeating alarm. Update this value so the AlarmReceiver
         // has the right time to compare.
@@ -460,19 +490,22 @@ public class Alarms {
      * Tells the StatusBar whether the alarm is enabled or disabled
      */
     private static void setStatusBarIcon(Context context, boolean enabled) {
-        Intent alarmChanged = new Intent(Intent.ACTION_ALARM_CHANGED);
+        Intent alarmChanged = new Intent("android.intent.action.ALARM_CHANGED");
         alarmChanged.putExtra("alarmSet", enabled);
         context.sendBroadcast(alarmChanged);
     }
 
+    private static long calculateAlarm(Alarm alarm) {
+        return calculateAlarm(alarm.hour, alarm.minutes, alarm.daysOfWeek)
+                .getTimeInMillis();
+    }
+
     /**
      * Given an alarm in hours and minutes, return a time suitable for
      * setting in AlarmManager.
-     * @param hour Always in 24 hour 0-23
-     * @param minute 0-59
-     * @param daysOfWeek 0-59
      */
-    static Calendar calculateAlarm(int hour, int minute, Alarm.DaysOfWeek daysOfWeek) {
+    static Calendar calculateAlarm(int hour, int minute,
+            Alarm.DaysOfWeek daysOfWeek) {
 
         // start with now
         Calendar c = Calendar.getInstance();
@@ -492,9 +525,6 @@ public class Alarms {
         c.set(Calendar.MILLISECOND, 0);
 
         int addDays = daysOfWeek.getNextAlarm(c);
-        /* Log.v("** TIMES * " + c.getTimeInMillis() + " hour " + hour +
-           " minute " + minute + " dow " + c.get(Calendar.DAY_OF_WEEK) + " from now " +
-           addDays); */
         if (addDays > 0) c.add(Calendar.DAY_OF_WEEK, addDays);
         return c;
     }