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.Context;
20 import android.content.Intent;
21 import android.net.Uri;
22 
23 import com.android.mail.analytics.Analytics;
24 import com.android.mail.photo.ContactFetcher;
25 import com.android.mail.providers.Account;
26 import com.android.mail.providers.Folder;
27 import com.android.mail.utils.FolderUri;
28 import com.android.mail.utils.LogTag;
29 import com.android.mail.utils.LogUtils;
30 import com.android.mail.utils.NotificationUtils;
31 import com.android.mail.utils.StorageLowState;
32 import com.android.mail.utils.Utils;
33 
34 /**
35  * A service to handle various intents asynchronously.
36  */
37 public class MailIntentService extends IntentService {
38     private static final String LOG_TAG = LogTag.getLogTag();
39 
40     public static final String ACTION_RESEND_NOTIFICATIONS =
41             "com.android.mail.action.RESEND_NOTIFICATIONS";
42     public static final String ACTION_CLEAR_NEW_MAIL_NOTIFICATIONS =
43             "com.android.mail.action.CLEAR_NEW_MAIL_NOTIFICATIONS";
44 
45     /**
46      * After user replies an email from Wear, it marks the conversation as read and resend
47      * notifications.
48      */
49     public static final String ACTION_RESEND_NOTIFICATIONS_WEAR =
50             "com.android.mail.action.RESEND_NOTIFICATIONS_WEAR";
51 
52     public static final String ACTION_BACKUP_DATA_CHANGED =
53             "com.android.mail.action.BACKUP_DATA_CHANGED";
54     public static final String ACTION_SEND_SET_NEW_EMAIL_INDICATOR =
55             "com.android.mail.action.SEND_SET_NEW_EMAIL_INDICATOR";
56 
57     public static final String CONVERSATION_EXTRA = "conversation";
58 
MailIntentService()59     public MailIntentService() {
60         super("MailIntentService");
61     }
62 
MailIntentService(final String name)63     protected MailIntentService(final String name) {
64         super(name);
65     }
66 
67     @Override
onHandleIntent(final Intent intent)68     protected void onHandleIntent(final Intent intent) {
69         // UnifiedEmail does not handle all Intents
70 
71         LogUtils.v(LOG_TAG, "Handling intent %s", intent);
72 
73         final String action = intent.getAction();
74 
75         if (Intent.ACTION_LOCALE_CHANGED.equals(action)) {
76             NotificationUtils.cancelAndResendNotificationsOnLocaleChange(
77                     this, getContactFetcher());
78         } else if (ACTION_CLEAR_NEW_MAIL_NOTIFICATIONS.equals(action)) {
79             final Account account = intent.getParcelableExtra(Utils.EXTRA_ACCOUNT);
80             final Folder folder = intent.getParcelableExtra(Utils.EXTRA_FOLDER);
81 
82             NotificationUtils.clearFolderNotification(this, account, folder, true /* markSeen */);
83             Analytics.getInstance().sendEvent("notification_dismiss", folder.getTypeDescription(),
84                     null, 0);
85         } else if (ACTION_RESEND_NOTIFICATIONS.equals(action)) {
86             final Uri accountUri = intent.getParcelableExtra(Utils.EXTRA_ACCOUNT_URI);
87 
88             final Uri extraFolderUri = intent.getParcelableExtra(Utils.EXTRA_FOLDER_URI);
89             final FolderUri folderUri =
90                     extraFolderUri == null ? null : new FolderUri(extraFolderUri);
91 
92             NotificationUtils.resendNotifications(
93                     this, false, accountUri, folderUri, getContactFetcher());
94         } else if (ACTION_RESEND_NOTIFICATIONS_WEAR.equals(action)) {
95             final Account account = intent.getParcelableExtra(Utils.EXTRA_ACCOUNT);
96             final Folder folder = intent.getParcelableExtra(Utils.EXTRA_FOLDER);
97             final Uri conversationUri = intent.getParcelableExtra(Utils.EXTRA_CONVERSATION);
98 
99             // Mark the conversation as read and refresh the notifications.  This happens
100             // when user replies to a conversation remotely from a Wear device.
101             NotificationUtils.markConversationAsReadAndSeen(this, conversationUri);
102             NotificationUtils.resendNotifications(this, false, account.uri,
103                     folder.folderUri, getContactFetcher());
104         } else if (ACTION_SEND_SET_NEW_EMAIL_INDICATOR.equals(action)) {
105             final int unreadCount = intent.getIntExtra(NotificationUtils.EXTRA_UNREAD_COUNT, 0);
106             final int unseenCount = intent.getIntExtra(NotificationUtils.EXTRA_UNSEEN_COUNT, 0);
107             final Account account = intent.getParcelableExtra(Utils.EXTRA_ACCOUNT);
108             final Folder folder = intent.getParcelableExtra(Utils.EXTRA_FOLDER);
109             final boolean getAttention =
110                     intent.getBooleanExtra(NotificationUtils.EXTRA_GET_ATTENTION, false);
111 
112             NotificationUtils.setNewEmailIndicator(this, unreadCount, unseenCount,
113                     account, folder, getAttention, getContactFetcher());
114         } else if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(action)) {
115             // The storage_low state is recorded centrally even though
116             // no handler might be present to change application state
117             // based on state changes.
118             StorageLowState.setIsStorageLow(true);
119         } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
120             StorageLowState.setIsStorageLow(false);
121         }
122     }
123 
broadcastBackupDataChanged(final Context context)124     public static void broadcastBackupDataChanged(final Context context) {
125         final Intent intent = new Intent(ACTION_BACKUP_DATA_CHANGED);
126         intent.setPackage(context.getPackageName());
127         context.startService(intent);
128     }
129 
130     /**
131      * Derived classes should override this method if they wish to provide their own contact loading
132      * behavior separate from the ContactProvider-based default. The default behavior of this method
133      * returns null.
134      */
getContactFetcher()135     public ContactFetcher getContactFetcher() {
136         return null;
137     }
138 }
139