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