Home | History | Annotate | Download | only in list
      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