Home | History | Annotate | Download | only in list
      1 /*
      2  * Copyright (C) 2010 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.contacts.list;
     17 
     18 import android.content.Context;
     19 import android.content.SharedPreferences;
     20 import android.preference.PreferenceManager;
     21 
     22 import com.android.contacts.model.AccountTypeManager;
     23 import com.android.contacts.model.account.AccountWithDataSet;
     24 
     25 import java.util.ArrayList;
     26 import java.util.List;
     27 
     28 /**
     29  * Manages {@link ContactListFilter}. All methods must be called from UI thread.
     30  */
     31 public abstract class ContactListFilterController {
     32 
     33     public static final String CONTACT_LIST_FILTER_SERVICE = "contactListFilter";
     34 
     35     public interface ContactListFilterListener {
     36         void onContactListFilterChanged();
     37     }
     38 
     39     public static ContactListFilterController getInstance(Context context) {
     40         return (ContactListFilterController)
     41                 context.getApplicationContext().getSystemService(CONTACT_LIST_FILTER_SERVICE);
     42     }
     43 
     44     public static ContactListFilterController
     45             createContactListFilterController(Context context) {
     46         return new ContactListFilterControllerImpl(context);
     47     }
     48 
     49     public abstract void addListener(ContactListFilterListener listener);
     50 
     51     public abstract void removeListener(ContactListFilterListener listener);
     52 
     53     /**
     54      * Return the currently-active filter.
     55      */
     56     public abstract ContactListFilter getFilter();
     57 
     58     /**
     59      * @param filter the filter
     60      * @param persistent True when the given filter should be saved soon. False when the filter
     61      * should not be saved. The latter case may happen when some Intent requires a certain type of
     62      * UI (e.g. single contact) temporarily.
     63      */
     64     public abstract void setContactListFilter(ContactListFilter filter, boolean persistent);
     65 
     66     public abstract void selectCustomFilter();
     67 
     68     /**
     69      * Checks if the current filter is valid and reset the filter if not. It may happen when
     70      * an account is removed while the filter points to the account with
     71      * {@link ContactListFilter#FILTER_TYPE_ACCOUNT} type, for example. It may also happen if
     72      * the current filter is {@link ContactListFilter#FILTER_TYPE_SINGLE_CONTACT}, in
     73      * which case, we should switch to the last saved filter in {@link SharedPreferences}.
     74      */
     75     public abstract void checkFilterValidity(boolean notifyListeners);
     76 }
     77 
     78 /**
     79  * Stores the {@link ContactListFilter} selected by the user and saves it to
     80  * {@link SharedPreferences} if necessary.
     81  */
     82 class ContactListFilterControllerImpl extends ContactListFilterController {
     83     private final Context mContext;
     84     private final List<ContactListFilterListener> mListeners =
     85             new ArrayList<ContactListFilterListener>();
     86     private ContactListFilter mFilter;
     87 
     88     public ContactListFilterControllerImpl(Context context) {
     89         mContext = context;
     90         mFilter = ContactListFilter.restoreDefaultPreferences(getSharedPreferences());
     91         checkFilterValidity(true /* notify listeners */);
     92     }
     93 
     94     @Override
     95     public void addListener(ContactListFilterListener listener) {
     96         mListeners.add(listener);
     97     }
     98 
     99     @Override
    100     public void removeListener(ContactListFilterListener listener) {
    101         mListeners.remove(listener);
    102     }
    103 
    104     @Override
    105     public ContactListFilter getFilter() {
    106         return mFilter;
    107     }
    108 
    109     private SharedPreferences getSharedPreferences() {
    110         return PreferenceManager.getDefaultSharedPreferences(mContext);
    111     }
    112 
    113     @Override
    114     public void setContactListFilter(ContactListFilter filter, boolean persistent) {
    115         setContactListFilter(filter, persistent, true);
    116     }
    117 
    118     private void setContactListFilter(ContactListFilter filter, boolean persistent,
    119             boolean notifyListeners) {
    120         if (!filter.equals(mFilter)) {
    121             mFilter = filter;
    122             if (persistent) {
    123                 ContactListFilter.storeToPreferences(getSharedPreferences(), mFilter);
    124             }
    125             if (notifyListeners && !mListeners.isEmpty()) {
    126                 notifyContactListFilterChanged();
    127             }
    128         }
    129     }
    130 
    131     @Override
    132     public void selectCustomFilter() {
    133         setContactListFilter(ContactListFilter.createFilterWithType(
    134                 ContactListFilter.FILTER_TYPE_CUSTOM), true);
    135     }
    136 
    137     private void notifyContactListFilterChanged() {
    138         for (ContactListFilterListener listener : mListeners) {
    139             listener.onContactListFilterChanged();
    140         }
    141     }
    142 
    143     @Override
    144     public void checkFilterValidity(boolean notifyListeners) {
    145         if (mFilter == null) {
    146             return;
    147         }
    148 
    149         switch (mFilter.filterType) {
    150             case ContactListFilter.FILTER_TYPE_SINGLE_CONTACT:
    151                 setContactListFilter(
    152                         ContactListFilter.restoreDefaultPreferences(getSharedPreferences()),
    153                         false, notifyListeners);
    154                 break;
    155             case ContactListFilter.FILTER_TYPE_ACCOUNT:
    156                 if (!filterAccountExists()) {
    157                     // The current account filter points to invalid account. Use "all" filter
    158                     // instead.
    159                     setContactListFilter(ContactListFilter.createFilterWithType(
    160                             ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS), true, notifyListeners);
    161                 }
    162         }
    163     }
    164 
    165     /**
    166      * @return true if the Account for the current filter exists.
    167      */
    168     private boolean filterAccountExists() {
    169         final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(mContext);
    170         final AccountWithDataSet filterAccount = new AccountWithDataSet(
    171                 mFilter.accountName, mFilter.accountType, mFilter.dataSet);
    172         return accountTypeManager.contains(filterAccount, false);
    173     }
    174 }
    175