blob: 34efaf86c88a4ab5bb20bacb1b21c102f38edfe1 [file] [log] [blame]
Chiao Chengbeca8562012-11-28 18:06:44 -08001/*
2 * Copyright (C) 2012 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.common.util;
18
19import android.app.Activity;
Walter Jangf2cad222016-07-14 19:49:06 +000020import android.app.Fragment;
Wenyi Wangb3186762016-04-17 17:29:31 -070021import android.content.AsyncTaskLoader;
Chiao Chengbeca8562012-11-28 18:06:44 -080022import android.content.Context;
23import android.content.Intent;
Wenyi Wangaa0e6ff2016-07-06 17:22:42 -070024import android.content.SharedPreferences;
Wenyi Wangb3186762016-04-17 17:29:31 -070025import android.graphics.drawable.Drawable;
Wenyi Wangaa0e6ff2016-07-06 17:22:42 -070026import android.text.TextUtils;
Chiao Chengbeca8562012-11-28 18:06:44 -080027import android.util.Log;
Chiao Chengbeca8562012-11-28 18:06:44 -080028
29import com.android.contacts.common.R;
Walter Jangf2cad222016-07-14 19:49:06 +000030import com.android.contacts.common.list.AccountFilterActivity;
Chiao Chengbeca8562012-11-28 18:06:44 -080031import com.android.contacts.common.list.ContactListFilter;
32import com.android.contacts.common.list.ContactListFilterController;
Wenyi Wangb3186762016-04-17 17:29:31 -070033import com.android.contacts.common.model.AccountTypeManager;
34import com.android.contacts.common.model.account.AccountType;
35import com.android.contacts.common.model.account.AccountWithDataSet;
36
37import com.google.common.collect.Lists;
38
39import java.util.ArrayList;
40import java.util.List;
Chiao Chengbeca8562012-11-28 18:06:44 -080041
42/**
43 * Utility class for account filter manipulation.
44 */
45public class AccountFilterUtil {
46 private static final String TAG = AccountFilterUtil.class.getSimpleName();
47
Walter Jangf2cad222016-07-14 19:49:06 +000048 /**
49 * Launches account filter setting Activity using
50 * {@link Fragment#startActivityForResult(Intent, int)}.
51 *
52 * @param requestCode requestCode for {@link Activity#startActivityForResult(Intent, int)}
53 * @param currentFilter currently-selected filter, so that it can be displayed as activated.
54 */
55 public static void startAccountFilterActivityForResult(
56 Fragment fragment, int requestCode, ContactListFilter currentFilter) {
57 final Activity activity = fragment.getActivity();
58 if (activity != null) {
59 final Intent intent = new Intent(activity, AccountFilterActivity.class);
60 fragment.startActivityForResult(intent, requestCode);
61 } else {
62 Log.w(TAG, "getActivity() returned null. Ignored");
63 }
64 }
Wenyi Wang1aa9d9f2016-04-22 16:31:51 -070065
Chiao Chengbeca8562012-11-28 18:06:44 -080066 /**
Walter Jangf2cad222016-07-14 19:49:06 +000067 * Useful method to handle onActivityResult() for
68 * {@link #startAccountFilterActivityForResult(Fragment, int, ContactListFilter)}.
69 *
Chiao Chengbeca8562012-11-28 18:06:44 -080070 * This will update filter via a given ContactListFilterController.
71 */
72 public static void handleAccountFilterResult(
73 ContactListFilterController filterController, int resultCode, Intent data) {
74 if (resultCode == Activity.RESULT_OK) {
75 final ContactListFilter filter = (ContactListFilter)
Walter Jangf2cad222016-07-14 19:49:06 +000076 data.getParcelableExtra(AccountFilterActivity.EXTRA_CONTACT_LIST_FILTER);
Chiao Chengbeca8562012-11-28 18:06:44 -080077 if (filter == null) {
78 return;
79 }
80 if (filter.filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
81 filterController.selectCustomFilter();
82 } else {
Wenyi Wang1cfe9c62016-06-01 20:49:13 -070083 filterController.setContactListFilter(filter, /* persistent */
84 filter.filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
Chiao Chengbeca8562012-11-28 18:06:44 -080085 }
86 }
87 }
Wenyi Wangb3186762016-04-17 17:29:31 -070088
89 /**
90 * Loads a list of contact list filters
91 */
92 public static class FilterLoader extends AsyncTaskLoader<List<ContactListFilter>> {
93 private Context mContext;
94
95 public FilterLoader(Context context) {
96 super(context);
97 mContext = context;
98 }
99
100 @Override
101 public List<ContactListFilter> loadInBackground() {
102 return loadAccountFilters(mContext);
103 }
104
105 @Override
106 protected void onStartLoading() {
107 forceLoad();
108 }
109
110 @Override
111 protected void onStopLoading() {
112 cancelLoad();
113 }
114
115 @Override
116 protected void onReset() {
117 onStopLoading();
118 }
119 }
120
121 private static List<ContactListFilter> loadAccountFilters(Context context) {
122 final ArrayList<ContactListFilter> accountFilters = Lists.newArrayList();
123 final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(context);
Wenyi Wangaa0e6ff2016-07-06 17:22:42 -0700124 accountTypeManager.sortAccounts(/* defaultAccount */ getDefaultAccount(context));
Wenyi Wangb3186762016-04-17 17:29:31 -0700125 final List<AccountWithDataSet> accounts =
Tingting Wang0ac73ba2016-07-05 22:33:01 -0700126 accountTypeManager.getAccounts(/* contactWritableOnly */ false);
127 final List<AccountWithDataSet> writableAccounts =
128 accountTypeManager.getAccounts(/* contactWritableOnly */ true);
129 final AccountWithDataSet localAccount = AccountWithDataSet.getLocalAccount();
130 if ((writableAccounts == null || writableAccounts.size() == 0)
131 && !accounts.contains(localAccount)) {
132 // Add "local account" if there is no writable account.
133 accounts.add(localAccount);
134 }
135
Wenyi Wangb3186762016-04-17 17:29:31 -0700136 for (AccountWithDataSet account : accounts) {
137 final AccountType accountType =
138 accountTypeManager.getAccountType(account.type, account.dataSet);
Tingting Wang0ac73ba2016-07-05 22:33:01 -0700139 if ((accountType.isExtension() || !accountType.areContactsWritable())
140 && !account.hasData(context)) {
141 // Hide extensions and read-only accounts with no raw_contacts.
Wenyi Wangb3186762016-04-17 17:29:31 -0700142 continue;
143 }
144 final Drawable icon = accountType != null ? accountType.getDisplayIcon(context) : null;
Tingting Wang0ac73ba2016-07-05 22:33:01 -0700145 if (account.isLocalAccount()) {
146 accountFilters.add(ContactListFilter.createDeviceContactsFilter(icon));
147 } else {
148 accountFilters.add(ContactListFilter.createAccountFilter(
149 account.type, account.name, account.dataSet, icon));
150 }
Wenyi Wangb3186762016-04-17 17:29:31 -0700151 }
Tingting Wang0ac73ba2016-07-05 22:33:01 -0700152
Wenyi Wangb3186762016-04-17 17:29:31 -0700153 final ArrayList<ContactListFilter> result = Lists.newArrayList();
154 result.addAll(accountFilters);
155 return result;
156 }
Wenyi Wangaa0e6ff2016-07-06 17:22:42 -0700157
158 private static AccountWithDataSet getDefaultAccount(Context context) {
159 final SharedPreferences prefs =
160 context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
161 final String defaultAccountKey =
162 context.getResources().getString(R.string.contact_editor_default_account_key);
163 final String defaultAccountString = prefs.getString(defaultAccountKey, null);
164 if (TextUtils.isEmpty(defaultAccountString)) {
165 return null;
166 }
167 try {
168 return AccountWithDataSet.unstringify(defaultAccountString);
169 } catch (IllegalArgumentException exception) {
170 Log.e(TAG, "Error with retrieving default account " + exception.toString(), exception);
171 return null;
172 }
173 }
Chiao Chengbeca8562012-11-28 18:06:44 -0800174}