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
17package com.android.contacts.list;
18
19import android.app.ActionBar;
20import android.app.Activity;
21import android.content.Context;
22import android.content.Intent;
23import android.os.Bundle;
24import android.view.LayoutInflater;
25import android.view.MenuItem;
26import android.view.View;
27import android.view.ViewGroup;
28import android.widget.AdapterView;
29import android.widget.BaseAdapter;
30import android.widget.ListView;
31
32import com.android.contacts.R;
33import com.android.contacts.model.AccountTypeManager;
34
35import java.util.ArrayList;
36import java.util.List;
37
38/**
39 * Shows a list of all available accounts, letting the user select under which account to view
40 * contacts.
41 */
42public class AccountFilterActivity extends Activity implements AdapterView.OnItemClickListener {
43
44    private static final int SUBACTIVITY_CUSTOMIZE_FILTER = 0;
45
46    public static final String EXTRA_CONTACT_LIST_FILTER = "contactListFilter";
47
48    private ListView mListView;
49
50    // The default contact list type, it should be either FILTER_TYPE_ALL_ACCOUNTS or
51    // FILTER_TYPE_CUSTOM, since those are the only two options we give the user.
52    private int mCurrentFilterType;
53
54    private ContactListFilterView mCustomFilterView; // the "Customize" filter
55
56    private boolean mIsCustomFilterViewSelected;
57
58    @Override
59    protected void onCreate(Bundle icicle) {
60        super.onCreate(icicle);
61        setContentView(R.layout.contact_list_filter);
62
63        mListView = (ListView) findViewById(android.R.id.list);
64        mListView.setOnItemClickListener(this);
65
66        ActionBar actionBar = getActionBar();
67        if (actionBar != null) {
68            actionBar.setDisplayHomeAsUpEnabled(true);
69        }
70
71        mCurrentFilterType = ContactListFilterController.getInstance(this).isCustomFilterPersisted()
72                ? ContactListFilter.FILTER_TYPE_CUSTOM
73                : ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS;
74
75        // We don't need to use AccountFilterUtil.FilterLoader since we only want to show
76        // the "All contacts" and "Customize" options.
77        final List<ContactListFilter> filters = new ArrayList<>();
78        filters.add(ContactListFilter.createFilterWithType(
79                ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS));
80        filters.add(ContactListFilter.createFilterWithType(
81                ContactListFilter.FILTER_TYPE_CUSTOM));
82        mListView.setAdapter(new FilterListAdapter(this, filters, mCurrentFilterType));
83    }
84
85    @Override
86    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
87        final ContactListFilterView listFilterView = (ContactListFilterView) view;
88        final ContactListFilter filter = (ContactListFilter) view.getTag();
89        if (filter == null) return; // Just in case
90        if (filter.filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
91            mCustomFilterView = listFilterView;
92            mIsCustomFilterViewSelected = listFilterView.isChecked();
93            final Intent intent = new Intent(this, CustomContactListFilterActivity.class)
94                    .putExtra(CustomContactListFilterActivity.EXTRA_CURRENT_LIST_FILTER_TYPE,
95                            mCurrentFilterType);
96            listFilterView.setActivated(true);
97            // Switching activity has the highest priority. So when we open another activity, the
98            // announcement that indicates an account is checked will be interrupted. This is the
99            // way to overcome -- View.announceForAccessibility(CharSequence text);
100            listFilterView.announceForAccessibility(listFilterView.generateContentDescription());
101            startActivityForResult(intent, SUBACTIVITY_CUSTOMIZE_FILTER);
102        } else {
103            listFilterView.setActivated(true);
104            listFilterView.announceForAccessibility(listFilterView.generateContentDescription());
105            final Intent intent = new Intent();
106            intent.putExtra(EXTRA_CONTACT_LIST_FILTER, filter);
107            setResult(Activity.RESULT_OK, intent);
108            finish();
109        }
110    }
111
112    @Override
113    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
114        if (resultCode == Activity.RESULT_CANCELED && mCustomFilterView != null &&
115                !mIsCustomFilterViewSelected) {
116            mCustomFilterView.setActivated(false);
117            return;
118        }
119
120        if (resultCode != Activity.RESULT_OK) {
121            return;
122        }
123
124        switch (requestCode) {
125            case SUBACTIVITY_CUSTOMIZE_FILTER: {
126                final Intent intent = new Intent();
127                ContactListFilter filter = ContactListFilter.createFilterWithType(
128                        ContactListFilter.FILTER_TYPE_CUSTOM);
129                intent.putExtra(EXTRA_CONTACT_LIST_FILTER, filter);
130                setResult(Activity.RESULT_OK, intent);
131                finish();
132                break;
133            }
134        }
135    }
136
137    private static class FilterListAdapter extends BaseAdapter {
138        private final List<ContactListFilter> mFilters;
139        private final LayoutInflater mLayoutInflater;
140        private final AccountTypeManager mAccountTypes;
141        private final int mCurrentFilter;
142
143        public FilterListAdapter(
144                Context context, List<ContactListFilter> filters, int current) {
145            mLayoutInflater = (LayoutInflater) context.getSystemService
146                    (Context.LAYOUT_INFLATER_SERVICE);
147            mFilters = filters;
148            mCurrentFilter = current;
149            mAccountTypes = AccountTypeManager.getInstance(context);
150        }
151
152        @Override
153        public int getCount() {
154            return mFilters.size();
155        }
156
157        @Override
158        public long getItemId(int position) {
159            return position;
160        }
161
162        @Override
163        public ContactListFilter getItem(int position) {
164            return mFilters.get(position);
165        }
166
167        public View getView(int position, View convertView, ViewGroup parent) {
168            final ContactListFilterView view;
169            if (convertView != null) {
170                view = (ContactListFilterView) convertView;
171            } else {
172                view = (ContactListFilterView) mLayoutInflater.inflate(
173                        R.layout.contact_list_filter_item, parent, false);
174            }
175            view.setSingleAccount(mFilters.size() == 1);
176            final ContactListFilter filter = mFilters.get(position);
177            view.setContactListFilter(filter);
178            view.bindView(mAccountTypes);
179            view.setTag(filter);
180            view.setActivated(filter.filterType == mCurrentFilter);
181            return view;
182        }
183    }
184
185    @Override
186    public boolean onOptionsItemSelected(MenuItem item) {
187        switch (item.getItemId()) {
188            case android.R.id.home:
189                // We have two logical "up" Activities: People and Phone.
190                // Instead of having one static "up" direction, behave like back as an
191                // exceptional case.
192                onBackPressed();
193                return true;
194            default:
195                break;
196        }
197        return super.onOptionsItemSelected(item);
198    }
199}
200