• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.mail;
17 
18 import android.app.IntentService;
19 import android.content.ContentResolver;
20 import android.content.ContentValues;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.net.Uri;
24 import android.os.Parcel;
25 
26 import com.android.mail.analytics.Analytics;
27 import com.android.mail.providers.Message;
28 import com.android.mail.providers.UIProvider;
29 import com.android.mail.utils.LogUtils;
30 import com.android.mail.utils.NotificationActionUtils;
31 import com.android.mail.utils.NotificationActionUtils.NotificationAction;
32 
33 /**
34  * Processes notification action {@link Intent}s that need to run off the main thread.
35  */
36 public class NotificationActionIntentService extends IntentService {
37     private static final String LOG_TAG = "NotifActionIS";
38 
39     // Compose actions
40     public static final String ACTION_REPLY = "com.android.mail.action.notification.REPLY";
41     public static final String ACTION_REPLY_ALL = "com.android.mail.action.notification.REPLY_ALL";
42     public static final String ACTION_FORWARD = "com.android.mail.action.notification.FORWARD";
43     // Toggle actions
44     public static final String ACTION_MARK_READ = "com.android.mail.action.notification.MARK_READ";
45 
46     // Destructive actions - These just display the undo bar
47     public static final String ACTION_ARCHIVE_REMOVE_LABEL =
48             "com.android.mail.action.notification.ARCHIVE";
49     public static final String ACTION_DELETE = "com.android.mail.action.notification.DELETE";
50 
51     /**
52      * This action cancels the undo notification, and does not commit any changes.
53      */
54     public static final String ACTION_UNDO = "com.android.mail.action.notification.UNDO";
55 
56     /**
57      * This action performs the actual destructive action.
58      */
59     public static final String ACTION_DESTRUCT = "com.android.mail.action.notification.DESTRUCT";
60 
61     public static final String EXTRA_NOTIFICATION_ACTION =
62             "com.android.mail.extra.EXTRA_NOTIFICATION_ACTION";
63     public static final String ACTION_UNDO_TIMEOUT =
64             "com.android.mail.action.notification.UNDO_TIMEOUT";
65 
NotificationActionIntentService()66     public NotificationActionIntentService() {
67         super("NotificationActionIntentService");
68     }
69 
logNotificationAction(String intentAction, NotificationAction action)70     private static void logNotificationAction(String intentAction, NotificationAction action) {
71         final String eventAction;
72         final String eventLabel;
73 
74         if (ACTION_ARCHIVE_REMOVE_LABEL.equals(intentAction)) {
75             eventAction = "archive_remove_label";
76             eventLabel = action.getFolder().getTypeDescription();
77         } else if (ACTION_DELETE.equals(intentAction)) {
78             eventAction = "delete";
79             eventLabel = null;
80         } else {
81             eventAction = intentAction;
82             eventLabel = null;
83         }
84 
85         Analytics.getInstance().sendEvent("notification_action", eventAction, eventLabel, 0);
86     }
87 
88     @Override
onHandleIntent(final Intent intent)89     protected void onHandleIntent(final Intent intent) {
90         final Context context = this;
91         final String action = intent.getAction();
92 
93         /*
94          * Grab the alarm from the intent. Since the remote AlarmManagerService fills in the Intent
95          * to add some extra data, it must unparcel the NotificationAction object. It throws a
96          * ClassNotFoundException when unparcelling.
97          * To avoid this, do the marshalling ourselves.
98          */
99         final NotificationAction notificationAction;
100         final byte[] data = intent.getByteArrayExtra(EXTRA_NOTIFICATION_ACTION);
101         if (data != null) {
102             final Parcel in = Parcel.obtain();
103             in.unmarshall(data, 0, data.length);
104             in.setDataPosition(0);
105             notificationAction = NotificationAction.CREATOR.createFromParcel(in,
106                     NotificationAction.class.getClassLoader());
107         } else {
108             LogUtils.wtf(LOG_TAG, "data was null trying to unparcel the NotificationAction");
109             return;
110         }
111 
112         final Message message = notificationAction.getMessage();
113 
114         final ContentResolver contentResolver = getContentResolver();
115 
116         LogUtils.i(LOG_TAG, "Handling %s", action);
117 
118         logNotificationAction(action, notificationAction);
119 
120         if (ACTION_UNDO.equals(action)) {
121             NotificationActionUtils.cancelUndoTimeout(context, notificationAction);
122             NotificationActionUtils.cancelUndoNotification(context, notificationAction);
123         } else if (ACTION_ARCHIVE_REMOVE_LABEL.equals(action) || ACTION_DELETE.equals(action)) {
124             // All we need to do is switch to an Undo notification
125             NotificationActionUtils.createUndoNotification(context, notificationAction);
126 
127             NotificationActionUtils.registerUndoTimeout(context, notificationAction);
128         } else {
129             if (ACTION_UNDO_TIMEOUT.equals(action) || ACTION_DESTRUCT.equals(action)) {
130                 // Process the action
131                 NotificationActionUtils.cancelUndoTimeout(this, notificationAction);
132                 NotificationActionUtils.processUndoNotification(this, notificationAction);
133             } else if (ACTION_MARK_READ.equals(action)) {
134                 final Uri uri = message.uri;
135 
136                 final ContentValues values = new ContentValues(1);
137                 values.put(UIProvider.MessageColumns.READ, 1);
138 
139                 contentResolver.update(uri, values, null, null);
140             }
141 
142             NotificationActionUtils.resendNotifications(context, notificationAction.getAccount(),
143                     notificationAction.getFolder());
144         }
145     }
146 }
147