Home | History | Annotate | Download | only in list
      1 /*
      2  * Copyright (C) 2011 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 
     17 package com.android.contacts.common.list;
     18 
     19 import android.app.ActionBar;
     20 import android.app.Activity;
     21 import android.app.LoaderManager.LoaderCallbacks;
     22 import android.content.AsyncTaskLoader;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.content.Loader;
     26 import android.graphics.drawable.Drawable;
     27 import android.os.Bundle;
     28 import android.util.Log;
     29 import android.view.LayoutInflater;
     30 import android.view.MenuItem;
     31 import android.view.View;
     32 import android.view.ViewGroup;
     33 import android.widget.AdapterView;
     34 import android.widget.BaseAdapter;
     35 import android.widget.ListView;
     36 
     37 import com.android.contacts.common.R;
     38 import com.android.contacts.common.model.AccountTypeManager;
     39 import com.android.contacts.common.model.account.AccountType;
     40 import com.android.contacts.common.model.account.AccountWithDataSet;
     41 import com.google.common.collect.Lists;
     42 
     43 import java.util.ArrayList;
     44 import java.util.List;
     45 
     46 /**
     47  * Shows a list of all available accounts, letting the user select under which account to view
     48  * contacts.
     49  */
     50 public class AccountFilterActivity extends Activity implements AdapterView.OnItemClickListener {
     51 
     52     private static final String TAG = AccountFilterActivity.class.getSimpleName();
     53 
     54     private static final int SUBACTIVITY_CUSTOMIZE_FILTER = 0;
     55 
     56     public static final String KEY_EXTRA_CONTACT_LIST_FILTER = "contactListFilter";
     57     public static final String KEY_EXTRA_CURRENT_FILTER = "currentFilter";
     58 
     59     private static final int FILTER_LOADER_ID = 0;
     60 
     61     private ListView mListView;
     62 
     63     private ContactListFilter mCurrentFilter;
     64 
     65     @Override
     66     protected void onCreate(Bundle icicle) {
     67         super.onCreate(icicle);
     68         setContentView(R.layout.contact_list_filter);
     69 
     70         mListView = (ListView) findViewById(android.R.id.list);
     71         mListView.setOnItemClickListener(this);
     72 
     73         ActionBar actionBar = getActionBar();
     74         if (actionBar != null) {
     75             actionBar.setDisplayHomeAsUpEnabled(true);
     76         }
     77 
     78         mCurrentFilter = getIntent().getParcelableExtra(KEY_EXTRA_CURRENT_FILTER);
     79 
     80         getLoaderManager().initLoader(FILTER_LOADER_ID, null, new MyLoaderCallbacks());
     81     }
     82 
     83     private static class FilterLoader extends AsyncTaskLoader<List<ContactListFilter>> {
     84         private Context mContext;
     85 
     86         public FilterLoader(Context context) {
     87             super(context);
     88             mContext = context;
     89         }
     90 
     91         @Override
     92         public List<ContactListFilter> loadInBackground() {
     93             return loadAccountFilters(mContext);
     94         }
     95 
     96         @Override
     97         protected void onStartLoading() {
     98             forceLoad();
     99         }
    100 
    101         @Override
    102         protected void onStopLoading() {
    103             cancelLoad();
    104         }
    105 
    106         @Override
    107         protected void onReset() {
    108             onStopLoading();
    109         }
    110     }
    111 
    112     private static List<ContactListFilter> loadAccountFilters(Context context) {
    113         final ArrayList<ContactListFilter> result = Lists.newArrayList();
    114         final ArrayList<ContactListFilter> accountFilters = Lists.newArrayList();
    115         final AccountTypeManager accountTypes = AccountTypeManager.getInstance(context);
    116         List<AccountWithDataSet> accounts = accountTypes.getAccounts(false);
    117         for (AccountWithDataSet account : accounts) {
    118             AccountType accountType = accountTypes.getAccountType(account.type, account.dataSet);
    119             if (accountType.isExtension() && !account.hasData(context)) {
    120                 // Hide extensions with no raw_contacts.
    121                 continue;
    122             }
    123             Drawable icon = accountType != null ? accountType.getDisplayIcon(context) : null;
    124             accountFilters.add(ContactListFilter.createAccountFilter(
    125                     account.type, account.name, account.dataSet, icon));
    126         }
    127 
    128         // Always show "All", even when there's no accounts.  (We may have local contacts)
    129         result.add(ContactListFilter.createFilterWithType(
    130                 ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS));
    131 
    132         final int count = accountFilters.size();
    133         if (count >= 1) {
    134             // If we only have one account, don't show it as "account", instead show it as "all"
    135             if (count > 1) {
    136                 result.addAll(accountFilters);
    137             }
    138             result.add(ContactListFilter.createFilterWithType(
    139                     ContactListFilter.FILTER_TYPE_CUSTOM));
    140         }
    141         return result;
    142     }
    143 
    144     private class MyLoaderCallbacks implements LoaderCallbacks<List<ContactListFilter>> {
    145         @Override
    146         public Loader<List<ContactListFilter>> onCreateLoader(int id, Bundle args) {
    147             return new FilterLoader(AccountFilterActivity.this);
    148         }
    149 
    150         @Override
    151         public void onLoadFinished(
    152                 Loader<List<ContactListFilter>> loader, List<ContactListFilter> data) {
    153             if (data == null) { // Just in case...
    154                 Log.e(TAG, "Failed to load filters");
    155                 return;
    156             }
    157             mListView.setAdapter(
    158                     new FilterListAdapter(AccountFilterActivity.this, data, mCurrentFilter));
    159         }
    160 
    161         @Override
    162         public void onLoaderReset(Loader<List<ContactListFilter>> loader) {
    163         }
    164     }
    165 
    166     @Override
    167     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    168         final ContactListFilter filter = (ContactListFilter) view.getTag();
    169         if (filter == null) return; // Just in case
    170         if (filter.filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
    171             final Intent intent = new Intent(this,
    172                     CustomContactListFilterActivity.class);
    173             startActivityForResult(intent, SUBACTIVITY_CUSTOMIZE_FILTER);
    174         } else {
    175             final Intent intent = new Intent();
    176             intent.putExtra(KEY_EXTRA_CONTACT_LIST_FILTER, filter);
    177             setResult(Activity.RESULT_OK, intent);
    178             finish();
    179         }
    180     }
    181 
    182     @Override
    183     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    184         if (resultCode != Activity.RESULT_OK) {
    185             return;
    186         }
    187 
    188         switch (requestCode) {
    189             case SUBACTIVITY_CUSTOMIZE_FILTER: {
    190                 final Intent intent = new Intent();
    191                 ContactListFilter filter = ContactListFilter.createFilterWithType(
    192                         ContactListFilter.FILTER_TYPE_CUSTOM);
    193                 intent.putExtra(KEY_EXTRA_CONTACT_LIST_FILTER, filter);
    194                 setResult(Activity.RESULT_OK, intent);
    195                 finish();
    196                 break;
    197             }
    198         }
    199     }
    200 
    201     private static class FilterListAdapter extends BaseAdapter {
    202         private final List<ContactListFilter> mFilters;
    203         private final LayoutInflater mLayoutInflater;
    204         private final AccountTypeManager mAccountTypes;
    205         private final ContactListFilter mCurrentFilter;
    206 
    207         public FilterListAdapter(
    208                 Context context, List<ContactListFilter> filters, ContactListFilter current) {
    209             mLayoutInflater = (LayoutInflater) context.getSystemService
    210                     (Context.LAYOUT_INFLATER_SERVICE);
    211             mFilters = filters;
    212             mCurrentFilter = current;
    213             mAccountTypes = AccountTypeManager.getInstance(context);
    214         }
    215 
    216         @Override
    217         public int getCount() {
    218             return mFilters.size();
    219         }
    220 
    221         @Override
    222         public long getItemId(int position) {
    223             return position;
    224         }
    225 
    226         @Override
    227         public ContactListFilter getItem(int position) {
    228             return mFilters.get(position);
    229         }
    230 
    231         public View getView(int position, View convertView, ViewGroup parent) {
    232             final ContactListFilterView view;
    233             if (convertView != null) {
    234                 view = (ContactListFilterView) convertView;
    235             } else {
    236                 view = (ContactListFilterView) mLayoutInflater.inflate(
    237                         R.layout.contact_list_filter_item, parent, false);
    238             }
    239             view.setSingleAccount(mFilters.size() == 1);
    240             final ContactListFilter filter = mFilters.get(position);
    241             view.setContactListFilter(filter);
    242             view.bindView(mAccountTypes);
    243             view.setTag(filter);
    244             view.setActivated(filter.equals(mCurrentFilter));
    245             return view;
    246         }
    247     }
    248 
    249     @Override
    250     public boolean onOptionsItemSelected(MenuItem item) {
    251         switch (item.getItemId()) {
    252             case android.R.id.home:
    253                 // We have two logical "up" Activities: People and Phone.
    254                 // Instead of having one static "up" direction, behave like back as an
    255                 // exceptional case.
    256                 onBackPressed();
    257                 return true;
    258             default:
    259                 break;
    260         }
    261         return super.onOptionsItemSelected(item);
    262     }
    263 }
    264