Remove notifications on reply/forward action
Clear the notifications when the user selects the reply/reply-all/
forward action.
Also fixes a bug with those actions not always doing the right thing.
Bug: 7742529
Change-Id: I479eef30864fe1fcae3e9c7aafaa21481e51d05c
diff --git a/src/com/android/mail/MailIntentService.java b/src/com/android/mail/MailIntentService.java
new file mode 100644
index 0000000..e1e5d82
--- /dev/null
+++ b/src/com/android/mail/MailIntentService.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.mail;
+
+import android.app.IntentService;
+import android.content.Intent;
+
+/**
+ * A service to handle various intents asynchronously.
+ */
+public class MailIntentService extends IntentService {
+ public static final String ACTION_RESEND_NOTIFICATIONS =
+ "com.android.mail.action.RESEND_NOTIFICATIONS";
+ public static final String ACTION_CLEAR_NEW_MAIL_NOTIFICATIONS =
+ "com.android.mail.action.CLEAR_NEW_MAIL_NOTIFICATIONS";
+
+ public static final String CLEAR_NEW_MAIL_NOTIFICATIONS_ACCOUNT_EXTRA = "account";
+ public static final String CLEAR_NEW_MAIL_NOTIFICATIONS_FOLDER_EXTRA = "folder";
+ public static final String CLEAR_NEW_MAIL_NOTIFICATIONS_MARK_SEEN_EXTRA = "markSeen";
+
+ public MailIntentService() {
+ super("MailIntentService");
+ }
+
+ protected MailIntentService(final String name) {
+ super(name);
+ }
+
+ @Override
+ protected void onHandleIntent(final Intent intent) {
+ // UnifiedEmail does not handle any of these at the moment
+ }
+}
diff --git a/src/com/android/mail/NotificationActionIntentService.java b/src/com/android/mail/NotificationActionIntentService.java
index aabd117..7813ce7 100644
--- a/src/com/android/mail/NotificationActionIntentService.java
+++ b/src/com/android/mail/NotificationActionIntentService.java
@@ -16,6 +16,8 @@
package com.android.mail;
import android.app.IntentService;
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
@@ -23,8 +25,11 @@
import android.net.Uri;
import android.os.Bundle;
+import com.android.mail.providers.Account;
+import com.android.mail.providers.Folder;
import com.android.mail.providers.Message;
import com.android.mail.providers.UIProvider;
+import com.android.mail.utils.LogUtils;
import com.android.mail.utils.NotificationActionUtils;
import com.android.mail.utils.NotificationActionUtils.NotificationAction;
@@ -32,6 +37,12 @@
* Processes notification action {@link Intent}s that need to run off the main thread.
*/
public class NotificationActionIntentService extends IntentService {
+ private static final String TAG = "NotificationActionIntentService";
+
+ // Compose actions
+ public static final String ACTION_REPLY = "com.android.mail.action.NOTIF_REPLY";
+ public static final String ACTION_REPLY_ALL = "com.android.mail.action.NOTIF_REPLY_ALL";
+ public static final String ACTION_FORWARD = "com.android.mail.action.NOTIF_FORWARD";
// Toggle actions
public static final String ACTION_MARK_READ = "com.android.mail.action.NOTIF_MARK_READ";
@@ -52,6 +63,8 @@
public static final String EXTRA_NOTIFICATION_ACTION =
"com.android.mail.extra.EXTRA_NOTIFICATION_ACTION";
+ public static final String EXTRA_NOTIFICATION_PENDING_INTENT =
+ "com.android.mail.extra.EXTRA_NOTIFICATION_PENDING_INTENT";
public static final String ACTION_UNDO_TIMEOUT = "com.android.mail.action.NOTIF_UNDO_TIMEOUT";
public NotificationActionIntentService() {
@@ -78,10 +91,24 @@
NotificationActionUtils.registerUndoTimeout(context, notificationAction);
} else {
+ final Account account = notificationAction.getAccount();
+ final String accountName = account.name;
+
if (ACTION_UNDO_TIMEOUT.equals(action) || ACTION_DESTRUCT.equals(action)) {
// Process the action
NotificationActionUtils.cancelUndoTimeout(this, notificationAction);
NotificationActionUtils.processUndoNotification(this, notificationAction);
+ } else if (ACTION_REPLY.equals(action) || ACTION_REPLY_ALL.equals(action)
+ || ACTION_FORWARD.equals(action)) {
+ cancelNotifications(accountName, notificationAction.getFolder());
+
+ final PendingIntent pendingIntent =
+ intent.getParcelableExtra(EXTRA_NOTIFICATION_PENDING_INTENT);
+ try {
+ pendingIntent.send();
+ } catch (final CanceledException e) {
+ LogUtils.e(TAG, "Error replying from notification action", e);
+ }
} else if (ACTION_MARK_READ.equals(action)) {
final Uri uri = message.uri;
@@ -94,4 +121,12 @@
NotificationActionUtils.resendNotifications(context);
}
}
+
+ private void cancelNotifications(final String account, final Folder folder) {
+ final Intent intent = new Intent(MailIntentService.ACTION_CLEAR_NEW_MAIL_NOTIFICATIONS);
+ intent.putExtra(MailIntentService.CLEAR_NEW_MAIL_NOTIFICATIONS_ACCOUNT_EXTRA, account);
+ intent.putExtra(MailIntentService.CLEAR_NEW_MAIL_NOTIFICATIONS_FOLDER_EXTRA, folder);
+
+ startService(intent);
+ }
}
diff --git a/src/com/android/mail/utils/NotificationActionUtils.java b/src/com/android/mail/utils/NotificationActionUtils.java
index b8b165b..1182561 100644
--- a/src/com/android/mail/utils/NotificationActionUtils.java
+++ b/src/com/android/mail/utils/NotificationActionUtils.java
@@ -34,6 +34,7 @@
import android.text.format.DateUtils;
import android.widget.RemoteViews;
+import com.android.mail.MailIntentService;
import com.android.mail.NotificationActionIntentService;
import com.android.mail.R;
import com.android.mail.compose.ComposeActivity;
@@ -70,9 +71,6 @@
*/
public static final SparseLongArray sNotificationTimestamps = new SparseLongArray();
- public static final String ACTION_RESEND_NOTIFICATIONS =
- "com.android.mail.action.RESEND_NOTIFICATIONS";
-
public enum NotificationActionType {
REPLY("reply", R.drawable.ic_reply_holo_dark, R.string.notification_action_reply),
REPLY_ALL("reply_all", R.drawable.ic_reply_all_holo_dark,
@@ -331,8 +329,19 @@
taskStackBuilder.addNextIntent(notificationIntent).addNextIntent(replyIntent);
- return taskStackBuilder.getPendingIntent(
+ final PendingIntent pendingIntent = taskStackBuilder.getPendingIntent(
notificationId, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ final String intentAction = NotificationActionIntentService.ACTION_REPLY;
+
+ final Intent intent = new Intent(intentAction);
+ intent.putExtra(NotificationActionIntentService.EXTRA_NOTIFICATION_ACTION,
+ notificationAction);
+ intent.putExtra(NotificationActionIntentService.EXTRA_NOTIFICATION_PENDING_INTENT,
+ pendingIntent);
+
+ return PendingIntent.getService(
+ context, notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
} case REPLY_ALL: {
// Build a task stack that forces the conversation view on the stack before the
// reply activity.
@@ -342,13 +351,24 @@
// To make sure that the reply intents one notification don't clobber over
// intents for other notification, force a data uri on the intent
final Uri notificationUri =
- Uri.parse("gmailfrom://gmail-ls/account/" + "reply/" + notificationId);
+ Uri.parse("gmailfrom://gmail-ls/account/" + "replyall/" + notificationId);
replyIntent.setData(notificationUri);
taskStackBuilder.addNextIntent(notificationIntent).addNextIntent(replyIntent);
- return taskStackBuilder.getPendingIntent(
+ final PendingIntent pendingIntent = taskStackBuilder.getPendingIntent(
notificationId, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ final String intentAction = NotificationActionIntentService.ACTION_REPLY_ALL;
+
+ final Intent intent = new Intent(intentAction);
+ intent.putExtra(NotificationActionIntentService.EXTRA_NOTIFICATION_ACTION,
+ notificationAction);
+ intent.putExtra(NotificationActionIntentService.EXTRA_NOTIFICATION_PENDING_INTENT,
+ pendingIntent);
+
+ return PendingIntent.getService(
+ context, notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
} case FORWARD: {
// Build a task stack that forces the conversation view on the stack before the
// reply activity.
@@ -358,13 +378,24 @@
// To make sure that the reply intents one notification don't clobber over
// intents for other notification, force a data uri on the intent
final Uri notificationUri =
- Uri.parse("gmailfrom://gmail-ls/account/" + "reply/" + notificationId);
+ Uri.parse("gmailfrom://gmail-ls/account/" + "forward/" + notificationId);
replyIntent.setData(notificationUri);
taskStackBuilder.addNextIntent(notificationIntent).addNextIntent(replyIntent);
- return taskStackBuilder.getPendingIntent(
+ final PendingIntent pendingIntent = taskStackBuilder.getPendingIntent(
notificationId, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ final String intentAction = NotificationActionIntentService.ACTION_FORWARD;
+
+ final Intent intent = new Intent(intentAction);
+ intent.putExtra(NotificationActionIntentService.EXTRA_NOTIFICATION_ACTION,
+ notificationAction);
+ intent.putExtra(NotificationActionIntentService.EXTRA_NOTIFICATION_PENDING_INTENT,
+ pendingIntent);
+
+ return PendingIntent.getService(
+ context, notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
} case ARCHIVE_REMOVE_LABEL: {
final String intentAction =
NotificationActionIntentService.ACTION_ARCHIVE_REMOVE_LABEL;
@@ -680,7 +711,7 @@
*/
public static void createUndoNotification(final Context context,
final NotificationAction notificationAction) {
- final int notificationId = getUndoNotificationId(
+ final int notificationId = getNotificationId(
notificationAction.getAccount().name, notificationAction.getFolder());
final Notification notification =
@@ -696,7 +727,7 @@
public static void cancelUndoNotification(final Context context,
final NotificationAction notificationAction) {
- sUndoNotifications.delete(getUndoNotificationId(
+ sUndoNotifications.delete(getNotificationId(
notificationAction.getAccount().name, notificationAction.getFolder()));
resendNotifications(context);
}
@@ -707,7 +738,7 @@
*/
public static void processUndoNotification(final Context context,
final NotificationAction notificationAction) {
- final int notificationId = getUndoNotificationId(
+ final int notificationId = getNotificationId(
notificationAction.getAccount().name, notificationAction.getFolder());
sUndoNotifications.delete(notificationId);
sNotificationTimestamps.delete(notificationId);
@@ -715,7 +746,7 @@
resendNotifications(context);
}
- private static int getUndoNotificationId(final String account, final Folder folder) {
+ public static int getNotificationId(final String account, final Folder folder) {
// TODO(skennedy): When notifications are fully in UnifiedEmail, remove this method and use
// the one in Utils
// 1 == Gmail.NOTIFICATION_ID
@@ -726,7 +757,7 @@
* Broadcasts an {@link Intent} to inform the app to resend its notifications.
*/
public static void resendNotifications(final Context context) {
- final Intent intent = new Intent(ACTION_RESEND_NOTIFICATIONS);
+ final Intent intent = new Intent(MailIntentService.ACTION_RESEND_NOTIFICATIONS);
intent.setPackage(context.getPackageName()); // Make sure we only deliver this to ourself
context.startService(intent);
}
diff --git a/src/com/android/mail/utils/Utils.java b/src/com/android/mail/utils/Utils.java
index 40f3b83..3ab91ac 100644
--- a/src/com/android/mail/utils/Utils.java
+++ b/src/com/android/mail/utils/Utils.java
@@ -16,6 +16,12 @@
package com.android.mail.utils;
+import com.google.android.common.html.parser.HtmlDocument;
+import com.google.android.common.html.parser.HtmlParser;
+import com.google.android.common.html.parser.HtmlTree;
+import com.google.android.common.html.parser.HtmlTreeBuilder;
+import com.google.common.collect.Maps;
+
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
@@ -28,7 +34,6 @@
import android.os.Build;
import android.os.Bundle;
import android.provider.Browser;
-import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
@@ -49,16 +54,12 @@
import com.android.mail.R;
import com.android.mail.browse.ConversationCursor;
+import com.android.mail.compose.ComposeActivity;
import com.android.mail.providers.Account;
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Folder;
import com.android.mail.providers.UIProvider;
import com.android.mail.providers.UIProvider.EditSettingsExtras;
-import com.google.android.common.html.parser.HtmlDocument;
-import com.google.android.common.html.parser.HtmlParser;
-import com.google.android.common.html.parser.HtmlTree;
-import com.google.android.common.html.parser.HtmlTreeBuilder;
-import com.google.common.collect.Maps;
import org.json.JSONObject;
@@ -1161,4 +1162,22 @@
return count;
}
+ /**
+ * @return an intent which, if launched, will reply to the conversation
+ */
+ public static Intent createReplyIntent(final Context context, final Account account,
+ final Uri messageUri, final boolean isReplyAll) {
+ final Intent intent =
+ ComposeActivity.createReplyIntent(context, account, messageUri, isReplyAll);
+ return intent;
+ }
+
+ /**
+ * @return an intent which, if launched, will forward the conversation
+ */
+ public static Intent createForwardIntent(
+ final Context context, final Account account, final Uri messageUri) {
+ final Intent intent = ComposeActivity.createForwardIntent(context, account, messageUri);
+ return intent;
+ }
}