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