• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  *      Copyright (C) 2012 Google Inc.
3  *      Licensed to The Android Open Source Project.
4  *
5  *      Licensed under the Apache License, Version 2.0 (the "License");
6  *      you may not use this file except in compliance with the License.
7  *      You may obtain a copy of the License at
8  *
9  *           http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *      Unless required by applicable law or agreed to in writing, software
12  *      distributed under the License is distributed on an "AS IS" BASIS,
13  *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *      See the License for the specific language governing permissions and
15  *      limitations under the License.
16  *******************************************************************************/
17 
18 package com.android.mail.ui;
19 
20 import com.android.mail.providers.Account;
21 import com.android.mail.providers.Folder;
22 import com.android.mail.providers.UIProvider;
23 import com.android.mail.utils.LogTag;
24 import com.android.mail.utils.LogUtils;
25 import com.android.mail.ConversationListContext;
26 
27 import android.net.Uri;
28 
29 import android.content.BroadcastReceiver;
30 import android.content.Context;
31 import android.content.Intent;
32 import android.content.IntentFilter;
33 import android.content.IntentFilter.MalformedMimeTypeException;
34 import android.text.TextUtils;
35 
36 
37 /**
38  * A simple {@code BroadcastReceiver} which suppresses new e-mail notifications for a given folder.
39  */
40 public class SuppressNotificationReceiver extends BroadcastReceiver {
41     private static final String LOG_TAG = LogTag.getLogTag();
42 
43     private Context mContext;
44     private AbstractActivityController mController;
45     private String mMimeType;
46 
47     /**
48      * Registers this receiver to suppress the new mail notifications for a given folder so
49      * that other {@code BroadcastReceiver}s don't receive them.
50      */
activate(Context context, AbstractActivityController controller)51     public boolean activate(Context context, AbstractActivityController controller) {
52         final Account account = controller.getCurrentAccount();
53 
54         mContext = context;
55         mController = controller;
56 
57         final IntentFilter filter = new IntentFilter(UIProvider.ACTION_UPDATE_NOTIFICATION);
58 
59         // Note: the real notification receiver must have a lower (i.e. negative) priority
60         // than this receiver.
61         filter.setPriority(0);
62         if (account != null) {
63             mMimeType = account.mimeType;
64             try {
65                 filter.addDataType(mMimeType);
66             } catch (MalformedMimeTypeException e) {
67                 LogUtils.wtf(LOG_TAG, "Malformed mimetype: %s", mMimeType);
68             }
69         } else {
70             // If the current account is null, still register the receiver.  This allows the
71             // internal state of the receiver to match what the caller requested.
72             LogUtils.d(LOG_TAG, "Registering receiver with no mime type");
73         }
74         context.registerReceiver(this, filter);
75 
76         return true;
77     }
78 
79     /**
80      * Returns true if this suppressNotificationReceiver is activated
81      */
activated()82     public boolean activated() {
83         return mContext != null;
84     }
85 
86     /**
87      * Unregisters this receiver.
88      */
deactivate()89     public void deactivate() {
90         try {
91             if (mContext != null) {
92                 mContext.unregisterReceiver(this);
93                 mContext = null;
94                 mMimeType = null;
95             }
96         } catch (IllegalArgumentException e) {
97             // May throw if already unregistered. Ignore exception.
98         }
99     }
100 
101     /**
102      * Returns a boolean indicating whether notifications are suppressed for the specified account.
103      */
notificationsDisabledForAccount(Account account)104     public boolean notificationsDisabledForAccount(Account account) {
105         return mContext != null && TextUtils.equals(account.mimeType, mMimeType);
106     }
107 
108     @Override
onReceive(Context context, Intent intent)109     public void onReceive(Context context, Intent intent) {
110         final String action = intent.getAction();
111         if (!UIProvider.ACTION_UPDATE_NOTIFICATION.equals(action)) {
112             return;
113         }
114 
115         if (!mController.isConversationListVisible()) {
116             // The conversation list is not visible, don't suppress notifications.
117             return;
118         }
119 
120         final ConversationListContext listContext = mController.getCurrentListContext();
121         if (listContext == null) {
122             // A non-null list context was expected
123             LogUtils.e(LOG_TAG, "unexpected null context");
124             return;
125         }
126 
127         if (ConversationListContext.isSearchResult(listContext)) {
128             // The user is looking at a search result, don't suppress notifications.
129             return;
130         }
131 
132         final Account listContextAccount = listContext.account;
133         final Folder listContextFolder = listContext.folder;
134         // Guard against degenerate state in the controller
135         if (listContextAccount == null || listContextFolder == null) {
136             LogUtils.e(LOG_TAG, "SuppressNotificationReceiver.onReceive: account=%s, folder=%s",
137                     listContextAccount, listContextFolder);
138             return;
139         }
140 
141         final Uri intentAccountUri =
142                 (Uri)intent.getParcelableExtra(UIProvider.UpdateNotificationExtras.EXTRA_ACCOUNT);
143         if (!listContextAccount.uri.equals(intentAccountUri)) {
144             return;
145         }
146         final Uri intentFolderUri =
147                 (Uri)intent.getParcelableExtra(UIProvider.UpdateNotificationExtras.EXTRA_FOLDER);
148 
149         if (!listContextFolder.folderUri.equals(intentFolderUri)) {
150             return;
151         }
152         final int count = intent.getIntExtra(
153                 UIProvider.UpdateNotificationExtras.EXTRA_UPDATED_UNREAD_COUNT, 0);
154         // If the count is zero we want to let the intent through so that the
155         // regular receiver can remove the notification.
156         // This will allow a server change, that modifies the unread count to 0, to be handled
157         // by the intended recpient to clear the notification.
158         if (count == 0) {
159             return;
160         }
161         LogUtils.i(LOG_TAG, "Aborting broadcast of intent %s, folder uri is %s",
162                 intent, intentFolderUri);
163         abortBroadcast();
164     }
165 }
166