Home | History | Annotate | Download | only in calendar
      1 /*
      2  * Copyright (C) 2007 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.calendar;
     18 
     19 import android.app.Notification;
     20 import android.app.PendingIntent;
     21 import android.app.Service;
     22 import android.content.BroadcastReceiver;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.content.res.Resources;
     26 import android.net.Uri;
     27 import android.os.PowerManager;
     28 import android.util.Log;
     29 
     30 /**
     31  * Receives android.intent.action.EVENT_REMINDER intents and handles
     32  * event reminders.  The intent URI specifies an alert id in the
     33  * CalendarAlerts database table.  This class also receives the
     34  * BOOT_COMPLETED intent so that it can add a status bar notification
     35  * if there are Calendar event alarms that have not been dismissed.
     36  * It also receives the TIME_CHANGED action so that it can fire off
     37  * snoozed alarms that have become ready.  The real work is done in
     38  * the AlertService class.
     39  */
     40 public class AlertReceiver extends BroadcastReceiver {
     41     private static final String TAG = "AlertReceiver";
     42 
     43     private static final String DELETE_ACTION = "delete";
     44 
     45     static final Object mStartingServiceSync = new Object();
     46     static PowerManager.WakeLock mStartingService;
     47 
     48     @Override
     49     public void onReceive(Context context, Intent intent) {
     50         if (AlertService.DEBUG) {
     51             Log.d(TAG, "onReceive: a=" + intent.getAction() + " " + intent.toString());
     52         }
     53 
     54         if (DELETE_ACTION.equals(intent.getAction())) {
     55 
     56             /* The user has clicked the "Clear All Notifications"
     57              * buttons so dismiss all Calendar alerts.
     58              */
     59             // TODO Grab a wake lock here?
     60             Intent serviceIntent = new Intent(context, DismissAllAlarmsService.class);
     61             context.startService(serviceIntent);
     62         } else {
     63             Intent i = new Intent();
     64             i.setClass(context, AlertService.class);
     65             i.putExtras(intent);
     66             i.putExtra("action", intent.getAction());
     67             Uri uri = intent.getData();
     68 
     69             // This intent might be a BOOT_COMPLETED so it might not have a Uri.
     70             if (uri != null) {
     71                 i.putExtra("uri", uri.toString());
     72             }
     73             beginStartingService(context, i);
     74         }
     75     }
     76 
     77     /**
     78      * Start the service to process the current event notifications, acquiring
     79      * the wake lock before returning to ensure that the service will run.
     80      */
     81     public static void beginStartingService(Context context, Intent intent) {
     82         synchronized (mStartingServiceSync) {
     83             if (mStartingService == null) {
     84                 PowerManager pm =
     85                     (PowerManager)context.getSystemService(Context.POWER_SERVICE);
     86                 mStartingService = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
     87                         "StartingAlertService");
     88                 mStartingService.setReferenceCounted(false);
     89             }
     90             mStartingService.acquire();
     91             context.startService(intent);
     92         }
     93     }
     94 
     95     /**
     96      * Called back by the service when it has finished processing notifications,
     97      * releasing the wake lock if the service is now stopping.
     98      */
     99     public static void finishStartingService(Service service, int startId) {
    100         synchronized (mStartingServiceSync) {
    101             if (mStartingService != null) {
    102                 if (service.stopSelfResult(startId)) {
    103                     mStartingService.release();
    104                 }
    105             }
    106         }
    107     }
    108 
    109     public static Notification makeNewAlertNotification(Context context, String title,
    110             String location, int numReminders) {
    111         return makeNewAlertNotification(context, title, location,
    112                 numReminders, false);
    113     }
    114 
    115     /**
    116      * Creates an alert notification. If high priority, this will attach a pending intent.
    117      * Otherwise, it creates a standard notification.
    118      */
    119     public static Notification makeNewAlertNotification(Context context,
    120             String title, String location, int numReminders,
    121             boolean highPriority) {
    122         Resources res = context.getResources();
    123 
    124         // Create an intent triggered by clicking on the status icon.
    125         Intent clickIntent = new Intent();
    126         clickIntent.setClass(context, AlertActivity.class);
    127         clickIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    128 
    129         // Create an intent triggered by clicking on the "Clear All Notifications" button
    130         Intent deleteIntent = new Intent();
    131         deleteIntent.setClass(context, AlertReceiver.class);
    132         deleteIntent.setAction(DELETE_ACTION);
    133 
    134         if (title == null || title.length() == 0) {
    135             title = res.getString(R.string.no_title_label);
    136         }
    137 
    138         String helperString;
    139         if (numReminders > 1) {
    140             String format;
    141             if (numReminders == 2) {
    142                 format = res.getString(R.string.alert_missed_events_single);
    143             } else {
    144                 format = res.getString(R.string.alert_missed_events_multiple);
    145             }
    146             helperString = String.format(format, numReminders - 1);
    147         } else {
    148             helperString = location;
    149         }
    150 
    151         PendingIntent pendingClickIntent = PendingIntent.getActivity(
    152                 context, 0, clickIntent, 0);
    153         Notification notification = new Notification(
    154                 R.drawable.stat_notify_calendar,
    155                 null,
    156                 System.currentTimeMillis());
    157         notification.setLatestEventInfo(context,
    158                 title,
    159                 helperString,
    160                 pendingClickIntent
    161                 );
    162         notification.deleteIntent = PendingIntent.getBroadcast(context, 0,
    163                 deleteIntent, 0);
    164         if (highPriority) {
    165             notification.fullScreenIntent = pendingClickIntent;
    166         }
    167 
    168         return notification;
    169     }
    170 }
    171 
    172