1/*
2 * Copyright (C) 2013 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 */
16package com.android.deskclock.alarms;
17
18import android.app.PendingIntent;
19import android.content.Context;
20import android.content.Intent;
21import android.content.res.Resources;
22import android.support.v4.app.NotificationCompat;
23import android.support.v4.app.NotificationManagerCompat;
24
25import com.android.deskclock.AlarmClockFragment;
26import com.android.deskclock.AlarmUtils;
27import com.android.deskclock.DeskClock;
28import com.android.deskclock.LogUtils;
29import com.android.deskclock.R;
30import com.android.deskclock.provider.Alarm;
31import com.android.deskclock.provider.AlarmInstance;
32
33public final class AlarmNotifications {
34    public static final String EXTRA_NOTIFICATION_ID = "extra_notification_id";
35
36    public static void showLowPriorityNotification(Context context, AlarmInstance instance) {
37        LogUtils.v("Displaying low priority notification for alarm instance: " + instance.mId);
38        NotificationManagerCompat nm = NotificationManagerCompat.from(context);
39
40        NotificationCompat.Builder notification = new NotificationCompat.Builder(context)
41                .setContentTitle(context.getString(
42                        R.string.alarm_alert_predismiss_title))
43                .setContentText(AlarmUtils.getAlarmText(context, instance))
44                .setSmallIcon(R.drawable.stat_notify_alarm)
45                .setAutoCancel(false)
46                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
47                .setCategory(NotificationCompat.CATEGORY_ALARM)
48                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
49                .setLocalOnly(true);
50
51        // Setup up hide notification
52        Intent hideIntent = AlarmStateManager.createStateChangeIntent(context,
53                AlarmStateManager.ALARM_DELETE_TAG, instance,
54                AlarmInstance.HIDE_NOTIFICATION_STATE);
55        notification.setDeleteIntent(PendingIntent.getBroadcast(context, instance.hashCode(),
56                hideIntent, PendingIntent.FLAG_UPDATE_CURRENT));
57
58        // Setup up dismiss action
59        Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context,
60                AlarmStateManager.ALARM_DISMISS_TAG, instance, AlarmInstance.PREDISMISSED_STATE);
61        notification.addAction(R.drawable.ic_alarm_off_24dp,
62                context.getString(R.string.alarm_alert_dismiss_now_text),
63                PendingIntent.getBroadcast(context, instance.hashCode(),
64                        dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));
65
66        // Setup content action if instance is owned by alarm
67        Intent viewAlarmIntent = createViewAlarmIntent(context, instance);
68        notification.setContentIntent(PendingIntent.getActivity(context, instance.hashCode(),
69                viewAlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT));
70
71        nm.cancel(instance.hashCode());
72        nm.notify(instance.hashCode(), notification.build());
73    }
74
75    public static void showHighPriorityNotification(Context context, AlarmInstance instance) {
76        LogUtils.v("Displaying high priority notification for alarm instance: " + instance.mId);
77        NotificationManagerCompat nm = NotificationManagerCompat.from(context);
78
79        NotificationCompat.Builder notification = new NotificationCompat.Builder(context)
80                .setContentTitle(context.getString(R.string.alarm_alert_predismiss_title))
81                .setContentText(AlarmUtils.getAlarmText(context, instance))
82                .setSmallIcon(R.drawable.stat_notify_alarm)
83                .setAutoCancel(false)
84                .setOngoing(true)
85                .setGroup(Integer.toString(instance.hashCode()))
86                .setGroupSummary(true)
87                .setPriority(NotificationCompat.PRIORITY_HIGH)
88                .setCategory(NotificationCompat.CATEGORY_ALARM)
89                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
90                .setLocalOnly(true);
91
92        // Setup up dismiss action
93        Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context,
94                AlarmStateManager.ALARM_DISMISS_TAG, instance, AlarmInstance.PREDISMISSED_STATE);
95        notification.addAction(R.drawable.ic_alarm_off_24dp,
96                context.getString(R.string.alarm_alert_dismiss_now_text),
97                PendingIntent.getBroadcast(context, instance.hashCode(),
98                        dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));
99
100        // Setup content action if instance is owned by alarm
101        Intent viewAlarmIntent = createViewAlarmIntent(context, instance);
102        notification.setContentIntent(PendingIntent.getActivity(context, instance.hashCode(),
103                viewAlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT));
104
105        nm.cancel(instance.hashCode());
106        nm.notify(instance.hashCode(), notification.build());
107    }
108
109    public static void showSnoozeNotification(Context context, AlarmInstance instance) {
110        LogUtils.v("Displaying snoozed notification for alarm instance: " + instance.mId);
111        NotificationManagerCompat nm = NotificationManagerCompat.from(context);
112
113        NotificationCompat.Builder notification = new NotificationCompat.Builder(context)
114                .setContentTitle(instance.getLabelOrDefault(context))
115                .setContentText(context.getString(R.string.alarm_alert_snooze_until,
116                        AlarmUtils.getFormattedTime(context, instance.getAlarmTime())))
117                .setSmallIcon(R.drawable.stat_notify_alarm)
118                .setAutoCancel(false)
119                .setOngoing(true)
120                .setPriority(NotificationCompat.PRIORITY_MAX)
121                .setCategory(NotificationCompat.CATEGORY_ALARM)
122                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
123                .setLocalOnly(true);
124
125        // Setup up dismiss action
126        Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context,
127                AlarmStateManager.ALARM_DISMISS_TAG, instance, AlarmInstance.DISMISSED_STATE);
128        notification.addAction(R.drawable.ic_alarm_off_24dp,
129                context.getString(R.string.alarm_alert_dismiss_text),
130                PendingIntent.getBroadcast(context, instance.hashCode(),
131                        dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));
132
133        // Setup content action if instance is owned by alarm
134        Intent viewAlarmIntent = createViewAlarmIntent(context, instance);
135        notification.setContentIntent(PendingIntent.getActivity(context, instance.hashCode(),
136                viewAlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT));
137        nm.cancel(instance.hashCode());
138        nm.notify(instance.hashCode(), notification.build());
139    }
140
141    public static void showMissedNotification(Context context, AlarmInstance instance) {
142        LogUtils.v("Displaying missed notification for alarm instance: " + instance.mId);
143        NotificationManagerCompat nm = NotificationManagerCompat.from(context);
144
145        String label = instance.mLabel;
146        String alarmTime = AlarmUtils.getFormattedTime(context, instance.getAlarmTime());
147        NotificationCompat.Builder notification = new NotificationCompat.Builder(context)
148                .setContentTitle(context.getString(R.string.alarm_missed_title))
149                .setContentText(instance.mLabel.isEmpty() ? alarmTime :
150                        context.getString(R.string.alarm_missed_text, alarmTime, label))
151                .setSmallIcon(R.drawable.stat_notify_alarm)
152                .setPriority(NotificationCompat.PRIORITY_HIGH)
153                .setCategory(NotificationCompat.CATEGORY_ALARM)
154                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
155                .setLocalOnly(true);
156
157        final int hashCode = instance.hashCode();
158
159        // Setup dismiss intent
160        Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context,
161                AlarmStateManager.ALARM_DISMISS_TAG, instance, AlarmInstance.DISMISSED_STATE);
162        notification.setDeleteIntent(PendingIntent.getBroadcast(context, hashCode,
163                dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));
164
165        // Setup content intent
166        Intent showAndDismiss = AlarmInstance.createIntent(context, AlarmStateManager.class,
167                instance.mId);
168        showAndDismiss.putExtra(EXTRA_NOTIFICATION_ID, hashCode);
169        showAndDismiss.setAction(AlarmStateManager.SHOW_AND_DISMISS_ALARM_ACTION);
170        notification.setContentIntent(PendingIntent.getBroadcast(context, hashCode,
171                showAndDismiss, PendingIntent.FLAG_UPDATE_CURRENT));
172
173        nm.cancel(hashCode);
174        nm.notify(hashCode, notification.build());
175    }
176
177    public static void showAlarmNotification(Context context, AlarmInstance instance) {
178        LogUtils.v("Displaying alarm notification for alarm instance: " + instance.mId);
179        NotificationManagerCompat nm = NotificationManagerCompat.from(context);
180
181        Resources resources = context.getResources();
182        NotificationCompat.Builder notification = new NotificationCompat.Builder(context)
183                .setContentTitle(instance.getLabelOrDefault(context))
184                .setContentText(AlarmUtils.getFormattedTime(context, instance.getAlarmTime()))
185                .setSmallIcon(R.drawable.stat_notify_alarm)
186                .setOngoing(true)
187                .setAutoCancel(false)
188                .setDefaults(NotificationCompat.DEFAULT_LIGHTS)
189                .setWhen(0)
190                .setCategory(NotificationCompat.CATEGORY_ALARM)
191                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
192                .setLocalOnly(true);
193
194        // Setup Snooze Action
195        Intent snoozeIntent = AlarmStateManager.createStateChangeIntent(context,
196                AlarmStateManager.ALARM_SNOOZE_TAG, instance, AlarmInstance.SNOOZE_STATE);
197        snoozeIntent.putExtra(AlarmStateManager.FROM_NOTIFICATION_EXTRA, true);
198        PendingIntent snoozePendingIntent = PendingIntent.getBroadcast(context, instance.hashCode(),
199                snoozeIntent,
200                PendingIntent.FLAG_UPDATE_CURRENT);
201        notification.addAction(R.drawable.ic_snooze_24dp,
202                resources.getString(R.string.alarm_alert_snooze_text), snoozePendingIntent);
203
204        // Setup Dismiss Action
205        Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context,
206                AlarmStateManager.ALARM_DISMISS_TAG, instance, AlarmInstance.DISMISSED_STATE);
207        dismissIntent.putExtra(AlarmStateManager.FROM_NOTIFICATION_EXTRA, true);
208        PendingIntent dismissPendingIntent = PendingIntent.getBroadcast(context,
209                instance.hashCode(), dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT);
210        notification.addAction(R.drawable.ic_alarm_off_24dp,
211                resources.getString(R.string.alarm_alert_dismiss_text),
212                dismissPendingIntent);
213
214        // Setup Content Action
215        Intent contentIntent = AlarmInstance.createIntent(context, AlarmActivity.class,
216                instance.mId);
217        notification.setContentIntent(PendingIntent.getActivity(context,
218                instance.hashCode(), contentIntent, PendingIntent.FLAG_UPDATE_CURRENT));
219
220        // Setup fullscreen intent
221        Intent fullScreenIntent = AlarmInstance.createIntent(context, AlarmActivity.class,
222                instance.mId);
223        // set action, so we can be different then content pending intent
224        fullScreenIntent.setAction("fullscreen_activity");
225        fullScreenIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
226                Intent.FLAG_ACTIVITY_NO_USER_ACTION);
227        notification.setFullScreenIntent(PendingIntent.getActivity(context,
228                instance.hashCode(), fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT), true);
229        notification.setPriority(NotificationCompat.PRIORITY_MAX);
230
231        nm.cancel(instance.hashCode());
232        nm.notify(instance.hashCode(), notification.build());
233    }
234
235    public static void clearNotification(Context context, AlarmInstance instance) {
236        LogUtils.v("Clearing notifications for alarm instance: " + instance.mId);
237        NotificationManagerCompat nm = NotificationManagerCompat.from(context);
238        nm.cancel(instance.hashCode());
239    }
240
241    public static Intent createViewAlarmIntent(Context context, AlarmInstance instance) {
242        long alarmId = instance.mAlarmId == null ? Alarm.INVALID_ID : instance.mAlarmId;
243        Intent viewAlarmIntent = Alarm.createIntent(context, DeskClock.class, alarmId);
244        viewAlarmIntent.putExtra(DeskClock.SELECT_TAB_INTENT_EXTRA, DeskClock.ALARM_TAB_INDEX);
245        viewAlarmIntent.putExtra(AlarmClockFragment.SCROLL_TO_ALARM_INTENT_EXTRA, alarmId);
246        viewAlarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
247        return viewAlarmIntent;
248    }
249}
250