blob: c19540a726bbbaaadef635a2cd0a303156cd6582 [file] [log] [blame]
Chiao Cheng89437e82012-11-01 13:41:51 -07001/*
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
17package com.android.contacts.common.list;
18
19import android.content.SharedPreferences;
20import android.graphics.drawable.Drawable;
21import android.net.Uri;
22import android.os.Parcel;
23import android.os.Parcelable;
24import android.provider.ContactsContract.RawContacts;
25import android.text.TextUtils;
26
27/**
28 * Contact list filter parameters.
29 */
30public final class ContactListFilter implements Comparable<ContactListFilter>, Parcelable {
31
32 public static final int FILTER_TYPE_DEFAULT = -1;
33 public static final int FILTER_TYPE_ALL_ACCOUNTS = -2;
34 public static final int FILTER_TYPE_CUSTOM = -3;
35 public static final int FILTER_TYPE_STARRED = -4;
36 public static final int FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY = -5;
37 public static final int FILTER_TYPE_SINGLE_CONTACT = -6;
Walter Jang08379b12016-06-14 15:35:28 -070038 public static final int FILTER_TYPE_GROUP_MEMBERS = -7;
Chiao Cheng89437e82012-11-01 13:41:51 -070039
40 public static final int FILTER_TYPE_ACCOUNT = 0;
41
42 /**
43 * Obsolete filter which had been used in Honeycomb. This may be stored in
44 * {@link SharedPreferences}, but should be replaced with ALL filter when it is found.
45 *
46 * TODO: "group" filter and relevant variables are all obsolete. Remove them.
47 */
48 private static final int FILTER_TYPE_GROUP = 1;
49
50 private static final String KEY_FILTER_TYPE = "filter.type";
51 private static final String KEY_ACCOUNT_NAME = "filter.accountName";
52 private static final String KEY_ACCOUNT_TYPE = "filter.accountType";
53 private static final String KEY_DATA_SET = "filter.dataSet";
54
55 public final int filterType;
56 public final String accountType;
57 public final String accountName;
58 public final String dataSet;
59 public final Drawable icon;
60 private String mId;
61
62 public ContactListFilter(int filterType, String accountType, String accountName, String dataSet,
63 Drawable icon) {
64 this.filterType = filterType;
65 this.accountType = accountType;
66 this.accountName = accountName;
67 this.dataSet = dataSet;
68 this.icon = icon;
69 }
70
71 public static ContactListFilter createFilterWithType(int filterType) {
72 return new ContactListFilter(filterType, null, null, null, null);
73 }
74
75 public static ContactListFilter createAccountFilter(String accountType, String accountName,
76 String dataSet, Drawable icon) {
77 return new ContactListFilter(ContactListFilter.FILTER_TYPE_ACCOUNT, accountType,
78 accountName, dataSet, icon);
79 }
80
Walter Jang08379b12016-06-14 15:35:28 -070081 public static ContactListFilter createGroupMembersFilter(String accountType, String accountName,
82 String dataSet) {
83 return new ContactListFilter(ContactListFilter.FILTER_TYPE_GROUP_MEMBERS, accountType,
84 accountName, dataSet, /* icon */ null);
85 }
86
Chiao Cheng89437e82012-11-01 13:41:51 -070087 /**
88 * Returns true if this filter is based on data and may become invalid over time.
89 */
90 public boolean isValidationRequired() {
91 return filterType == FILTER_TYPE_ACCOUNT;
92 }
93
94 @Override
95 public String toString() {
96 switch (filterType) {
97 case FILTER_TYPE_DEFAULT:
98 return "default";
99 case FILTER_TYPE_ALL_ACCOUNTS:
100 return "all_accounts";
101 case FILTER_TYPE_CUSTOM:
102 return "custom";
103 case FILTER_TYPE_STARRED:
104 return "starred";
105 case FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY:
106 return "with_phones";
107 case FILTER_TYPE_SINGLE_CONTACT:
108 return "single";
109 case FILTER_TYPE_ACCOUNT:
110 return "account: " + accountType + (dataSet != null ? "/" + dataSet : "")
111 + " " + accountName;
Walter Jang08379b12016-06-14 15:35:28 -0700112 case FILTER_TYPE_GROUP_MEMBERS:
113 return "group_members";
Chiao Cheng89437e82012-11-01 13:41:51 -0700114 }
115 return super.toString();
116 }
117
118 @Override
119 public int compareTo(ContactListFilter another) {
120 int res = accountName.compareTo(another.accountName);
121 if (res != 0) {
122 return res;
123 }
124
125 res = accountType.compareTo(another.accountType);
126 if (res != 0) {
127 return res;
128 }
129
130 return filterType - another.filterType;
131 }
132
133 @Override
134 public int hashCode() {
135 int code = filterType;
136 if (accountType != null) {
137 code = code * 31 + accountType.hashCode();
138 code = code * 31 + accountName.hashCode();
139 }
140 if (dataSet != null) {
141 code = code * 31 + dataSet.hashCode();
142 }
143 return code;
144 }
145
146 @Override
147 public boolean equals(Object other) {
148 if (this == other) {
149 return true;
150 }
151
152 if (!(other instanceof ContactListFilter)) {
153 return false;
154 }
155
156 ContactListFilter otherFilter = (ContactListFilter) other;
157 if (filterType != otherFilter.filterType
158 || !TextUtils.equals(accountName, otherFilter.accountName)
159 || !TextUtils.equals(accountType, otherFilter.accountType)
160 || !TextUtils.equals(dataSet, otherFilter.dataSet)) {
161 return false;
162 }
163
164 return true;
165 }
166
167 /**
168 * Store the given {@link ContactListFilter} to preferences. If the requested filter is
169 * of type {@link #FILTER_TYPE_SINGLE_CONTACT} then do not save it to preferences because
170 * it is a temporary state.
171 */
172 public static void storeToPreferences(SharedPreferences prefs, ContactListFilter filter) {
173 if (filter != null && filter.filterType == FILTER_TYPE_SINGLE_CONTACT) {
174 return;
175 }
176 prefs.edit()
177 .putInt(KEY_FILTER_TYPE, filter == null ? FILTER_TYPE_DEFAULT : filter.filterType)
178 .putString(KEY_ACCOUNT_NAME, filter == null ? null : filter.accountName)
179 .putString(KEY_ACCOUNT_TYPE, filter == null ? null : filter.accountType)
180 .putString(KEY_DATA_SET, filter == null ? null : filter.dataSet)
181 .apply();
182 }
183
184 /**
185 * Try to obtain ContactListFilter object saved in SharedPreference.
186 * If there's no info there, return ALL filter instead.
187 */
188 public static ContactListFilter restoreDefaultPreferences(SharedPreferences prefs) {
189 ContactListFilter filter = restoreFromPreferences(prefs);
190 if (filter == null) {
191 filter = ContactListFilter.createFilterWithType(FILTER_TYPE_ALL_ACCOUNTS);
192 }
193 // "Group" filter is obsolete and thus is not exposed anymore. The "single contact mode"
194 // should also not be stored in preferences anymore since it is a temporary state.
195 if (filter.filterType == FILTER_TYPE_GROUP ||
196 filter.filterType == FILTER_TYPE_SINGLE_CONTACT) {
197 filter = ContactListFilter.createFilterWithType(FILTER_TYPE_ALL_ACCOUNTS);
198 }
199 return filter;
200 }
201
202 private static ContactListFilter restoreFromPreferences(SharedPreferences prefs) {
203 int filterType = prefs.getInt(KEY_FILTER_TYPE, FILTER_TYPE_DEFAULT);
204 if (filterType == FILTER_TYPE_DEFAULT) {
205 return null;
206 }
207
208 String accountName = prefs.getString(KEY_ACCOUNT_NAME, null);
209 String accountType = prefs.getString(KEY_ACCOUNT_TYPE, null);
210 String dataSet = prefs.getString(KEY_DATA_SET, null);
211 return new ContactListFilter(filterType, accountType, accountName, dataSet, null);
212 }
213
214
215 @Override
216 public void writeToParcel(Parcel dest, int flags) {
217 dest.writeInt(filterType);
218 dest.writeString(accountName);
219 dest.writeString(accountType);
220 dest.writeString(dataSet);
221 }
222
223 public static final Parcelable.Creator<ContactListFilter> CREATOR =
224 new Parcelable.Creator<ContactListFilter>() {
225 @Override
226 public ContactListFilter createFromParcel(Parcel source) {
227 int filterType = source.readInt();
228 String accountName = source.readString();
229 String accountType = source.readString();
230 String dataSet = source.readString();
231 return new ContactListFilter(filterType, accountType, accountName, dataSet, null);
232 }
233
234 @Override
235 public ContactListFilter[] newArray(int size) {
236 return new ContactListFilter[size];
237 }
238 };
239
240 @Override
241 public int describeContents() {
242 return 0;
243 }
244
245 /**
246 * Returns a string that can be used as a stable persistent identifier for this filter.
247 */
248 public String getId() {
249 if (mId == null) {
250 StringBuilder sb = new StringBuilder();
251 sb.append(filterType);
252 if (accountType != null) {
253 sb.append('-').append(accountType);
254 }
255 if (dataSet != null) {
256 sb.append('/').append(dataSet);
257 }
258 if (accountName != null) {
259 sb.append('-').append(accountName.replace('-', '_'));
260 }
261 mId = sb.toString();
262 }
263 return mId;
264 }
265
266 /**
267 * Adds the account query parameters to the given {@code uriBuilder}.
268 *
269 * @throws IllegalStateException if the filter type is not {@link #FILTER_TYPE_ACCOUNT}.
270 */
271 public Uri.Builder addAccountQueryParameterToUrl(Uri.Builder uriBuilder) {
Walter Jang08379b12016-06-14 15:35:28 -0700272 if (filterType != FILTER_TYPE_ACCOUNT
273 && filterType != FILTER_TYPE_GROUP_MEMBERS) {
274 throw new IllegalStateException(
275 "filterType must be FILTER_TYPE_ACCOUNT or FILER_TYPE_GROUP_MEMBERS");
Chiao Cheng89437e82012-11-01 13:41:51 -0700276 }
277 uriBuilder.appendQueryParameter(RawContacts.ACCOUNT_NAME, accountName);
278 uriBuilder.appendQueryParameter(RawContacts.ACCOUNT_TYPE, accountType);
279 if (!TextUtils.isEmpty(dataSet)) {
280 uriBuilder.appendQueryParameter(RawContacts.DATA_SET, dataSet);
281 }
282 return uriBuilder;
283 }
284
285 public String toDebugString() {
286 final StringBuilder builder = new StringBuilder();
287 builder.append("[filter type: " + filterType + " (" + filterTypeToString(filterType) + ")");
288 if (filterType == FILTER_TYPE_ACCOUNT) {
289 builder.append(", accountType: " + accountType)
290 .append(", accountName: " + accountName)
291 .append(", dataSet: " + dataSet);
292 }
293 builder.append(", icon: " + icon + "]");
294 return builder.toString();
295 }
296
297 public static final String filterTypeToString(int filterType) {
298 switch (filterType) {
299 case FILTER_TYPE_DEFAULT:
300 return "FILTER_TYPE_DEFAULT";
301 case FILTER_TYPE_ALL_ACCOUNTS:
302 return "FILTER_TYPE_ALL_ACCOUNTS";
303 case FILTER_TYPE_CUSTOM:
304 return "FILTER_TYPE_CUSTOM";
305 case FILTER_TYPE_STARRED:
306 return "FILTER_TYPE_STARRED";
307 case FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY:
308 return "FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY";
309 case FILTER_TYPE_SINGLE_CONTACT:
310 return "FILTER_TYPE_SINGLE_CONTACT";
311 case FILTER_TYPE_ACCOUNT:
312 return "FILTER_TYPE_ACCOUNT";
Walter Jang08379b12016-06-14 15:35:28 -0700313 case FILTER_TYPE_GROUP_MEMBERS:
314 return "FILTER_TYPE_GROUP_MEMBERS";
Chiao Cheng89437e82012-11-01 13:41:51 -0700315 default:
316 return "(unknown)";
317 }
318 }
319}