16ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook/******************************************************************************* 26ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * Copyright (C) 2012 Google Inc. 36ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * Licensed to The Android Open Source Project. 46ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * 56ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * Licensed under the Apache License, Version 2.0 (the "License"); 66ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * you may not use this file except in compliance with the License. 76ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * You may obtain a copy of the License at 86ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * 96ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * http://www.apache.org/licenses/LICENSE-2.0 106ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * 116ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * Unless required by applicable law or agreed to in writing, software 126ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * distributed under the License is distributed on an "AS IS" BASIS, 136ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 146ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * See the License for the specific language governing permissions and 156ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * limitations under the License. 166ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook *******************************************************************************/ 176ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 186ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookpackage com.android.mail.ui; 196ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 206ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookimport com.android.mail.providers.Account; 216ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookimport com.android.mail.providers.Folder; 226ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookimport com.android.mail.providers.UIProvider; 23b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrookimport com.android.mail.utils.LogTag; 246ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookimport com.android.mail.utils.LogUtils; 256ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookimport com.android.mail.ConversationListContext; 266ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 276ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookimport android.net.Uri; 286ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 296ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookimport android.content.BroadcastReceiver; 306ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookimport android.content.Context; 316ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookimport android.content.Intent; 326ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookimport android.content.IntentFilter; 336ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookimport android.content.IntentFilter.MalformedMimeTypeException; 346ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookimport android.text.TextUtils; 356ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 366ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 376ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook/** 38d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * A simple {@code BroadcastReceiver} which suppresses new e-mail notifications for a given folder. 396ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook */ 406ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrookpublic class SuppressNotificationReceiver extends BroadcastReceiver { 41b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrook private static final String LOG_TAG = LogTag.getLogTag(); 426ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 436ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook private Context mContext; 446ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook private AbstractActivityController mController; 456ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook private String mMimeType; 466ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 476ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook /** 48d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy * Registers this receiver to suppress the new mail notifications for a given folder so 496ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * that other {@code BroadcastReceiver}s don't receive them. 506ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook */ 516ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook public boolean activate(Context context, AbstractActivityController controller) { 526ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook final Account account = controller.getCurrentAccount(); 536ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 546ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook mContext = context; 556ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook mController = controller; 566ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 576ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook final IntentFilter filter = new IntentFilter(UIProvider.ACTION_UPDATE_NOTIFICATION); 586ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 596ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook // Note: the real notification receiver must have a lower (i.e. negative) priority 606ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook // than this receiver. 616ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook filter.setPriority(0); 626ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook if (account != null) { 636ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook mMimeType = account.mimeType; 646ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook try { 656ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook filter.addDataType(mMimeType); 666ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } catch (MalformedMimeTypeException e) { 676ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook LogUtils.wtf(LOG_TAG, "Malformed mimetype: %s", mMimeType); 686ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 696ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } else { 706ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook // If the current account is null, still register the receiver. This allows the 716ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook // internal state of the receiver to match what the caller requested. 726ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook LogUtils.d(LOG_TAG, "Registering receiver with no mime type"); 736ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 746ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook context.registerReceiver(this, filter); 756ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 766ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook return true; 776ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 786ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 796ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook /** 806ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * Returns true if this suppressNotificationReceiver is activated 816ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook */ 826ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook public boolean activated() { 836ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook return mContext != null; 846ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 856ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 866ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook /** 876ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * Unregisters this receiver. 886ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook */ 896ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook public void deactivate() { 906ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook try { 916ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook if (mContext != null) { 926ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook mContext.unregisterReceiver(this); 936ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook mContext = null; 946ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook mMimeType = null; 956ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 966ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } catch (IllegalArgumentException e) { 976ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook // May throw if already unregistered. Ignore exception. 986ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 996ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 1006ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 1016ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook /** 1026ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook * Returns a boolean indicating whether notifications are suppressed for the specified account. 1036ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook */ 1046ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook public boolean notificationsDisabledForAccount(Account account) { 105c4b9ca097025e8f9541ffb03c66d25bd7835242fMindy Pereira return mContext != null && TextUtils.equals(account.mimeType, mMimeType); 1066ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 1076ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 1086ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook @Override 1096ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook public void onReceive(Context context, Intent intent) { 1106ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook final String action = intent.getAction(); 1116ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook if (!UIProvider.ACTION_UPDATE_NOTIFICATION.equals(action)) { 1126ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook return; 1136ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 1146ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 1156ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook if (!mController.isConversationListVisible()) { 1166ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook // The conversation list is not visible, don't suppress notifications. 1176ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook return; 1186ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 1196ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 1206ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook final ConversationListContext listContext = mController.getCurrentListContext(); 1216ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook if (listContext == null) { 1226ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook // A non-null list context was expected 12300a77fa36c722d750e13781c9aa8b8eb7320c71bPaul Westbrook LogUtils.e(LOG_TAG, "unexpected null context"); 1246ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook return; 1256ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 1266ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 127ae4ea997d3d3f3c8c11fc5a3e7f9d49f82b4e2e7Vikram Aggarwal if (ConversationListContext.isSearchResult(listContext)) { 1286ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook // The user is looking at a search result, don't suppress notifications. 1296ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook return; 1306ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 1316ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 1326ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook final Account listContextAccount = listContext.account; 1336ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook final Folder listContextFolder = listContext.folder; 1341672ff8ed6741df5c245e55f7a4e847f6ccb8c52Vikram Aggarwal // Guard against degenerate state in the controller 1351672ff8ed6741df5c245e55f7a4e847f6ccb8c52Vikram Aggarwal if (listContextAccount == null || listContextFolder == null) { 1361672ff8ed6741df5c245e55f7a4e847f6ccb8c52Vikram Aggarwal LogUtils.e(LOG_TAG, "SuppressNotificationReceiver.onReceive: account=%s, folder=%s", 1371672ff8ed6741df5c245e55f7a4e847f6ccb8c52Vikram Aggarwal listContextAccount, listContextFolder); 1381672ff8ed6741df5c245e55f7a4e847f6ccb8c52Vikram Aggarwal return; 1391672ff8ed6741df5c245e55f7a4e847f6ccb8c52Vikram Aggarwal } 1406ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 1416ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook final Uri intentAccountUri = 1426ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook (Uri)intent.getParcelableExtra(UIProvider.UpdateNotificationExtras.EXTRA_ACCOUNT); 1436ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook if (!listContextAccount.uri.equals(intentAccountUri)) { 1446ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook return; 1456ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 1466ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook final Uri intentFolderUri = 1476ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook (Uri)intent.getParcelableExtra(UIProvider.UpdateNotificationExtras.EXTRA_FOLDER); 1486ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook 149259df5b9e11908c8ef7c91483924891dd96b3c27Scott Kennedy if (!listContextFolder.folderUri.equals(intentFolderUri)) { 1506ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook return; 1516ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 1526ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook final int count = intent.getIntExtra( 1536ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook UIProvider.UpdateNotificationExtras.EXTRA_UPDATED_UNREAD_COUNT, 0); 1546ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook // If the count is zero we want to let the intent through so that the 1556ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook // regular receiver can remove the notification. 1566ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook // This will allow a server change, that modifies the unread count to 0, to be handled 1576ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook // by the intended recpient to clear the notification. 1586ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook if (count == 0) { 1596ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook return; 1606ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 1616ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook LogUtils.i(LOG_TAG, "Aborting broadcast of intent %s, folder uri is %s", 1626ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook intent, intentFolderUri); 1636ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook abortBroadcast(); 1646ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook } 1656ead20dd9643e6435d6c1111f99c520870812ea8Paul Westbrook} 166