Home | History | Annotate | Download | only in ui
      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      */
     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      */
     82     public boolean activated() {
     83         return mContext != null;
     84     }
     85 
     86     /**
     87      * Unregisters this receiver.
     88      */
     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      */
    104     public boolean notificationsDisabledForAccount(Account account) {
    105         return mContext != null && TextUtils.equals(account.mimeType, mMimeType);
    106     }
    107 
    108     @Override
    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