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.preference; 18 19 import android.content.Context; 20 import android.content.SharedPreferences; 21 import android.content.SharedPreferences.Editor; 22 import android.content.SharedPreferences.OnSharedPreferenceChangeListener; 23 import android.os.Handler; 24 import android.preference.PreferenceManager; 25 import android.provider.Settings; 26 import android.provider.Settings.SettingNotFoundException; 27 import android.text.TextUtils; 28 import com.android.contacts.common.R; 29 import com.android.contacts.common.model.account.AccountWithDataSet; 30 31 /** Manages user preferences for contacts. */ 32 public class ContactsPreferences implements OnSharedPreferenceChangeListener { 33 34 /** The value for the DISPLAY_ORDER key to show the given name first. */ 35 public static final int DISPLAY_ORDER_PRIMARY = 1; 36 37 /** The value for the DISPLAY_ORDER key to show the family name first. */ 38 public static final int DISPLAY_ORDER_ALTERNATIVE = 2; 39 40 public static final String DISPLAY_ORDER_KEY = "android.contacts.DISPLAY_ORDER"; 41 42 /** The value for the SORT_ORDER key corresponding to sort by given name first. */ 43 public static final int SORT_ORDER_PRIMARY = 1; 44 45 public static final String SORT_ORDER_KEY = "android.contacts.SORT_ORDER"; 46 47 /** The value for the SORT_ORDER key corresponding to sort by family name first. */ 48 public static final int SORT_ORDER_ALTERNATIVE = 2; 49 50 public static final String PREF_DISPLAY_ONLY_PHONES = "only_phones"; 51 52 public static final boolean PREF_DISPLAY_ONLY_PHONES_DEFAULT = false; 53 54 /** 55 * Value to use when a preference is unassigned and needs to be read from the shared preferences 56 */ 57 private static final int PREFERENCE_UNASSIGNED = -1; 58 59 private final Context mContext; 60 private final SharedPreferences mPreferences; 61 private int mSortOrder = PREFERENCE_UNASSIGNED; 62 private int mDisplayOrder = PREFERENCE_UNASSIGNED; 63 private String mDefaultAccount = null; 64 private ChangeListener mListener = null; 65 private Handler mHandler; 66 private String mDefaultAccountKey; 67 private String mDefaultAccountSavedKey; 68 ContactsPreferences(Context context)69 public ContactsPreferences(Context context) { 70 mContext = context; 71 mHandler = new Handler(); 72 mPreferences = mContext.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE); 73 mDefaultAccountKey = 74 mContext.getResources().getString(R.string.contact_editor_default_account_key); 75 mDefaultAccountSavedKey = 76 mContext.getResources().getString(R.string.contact_editor_anything_saved_key); 77 maybeMigrateSystemSettings(); 78 } 79 isSortOrderUserChangeable()80 public boolean isSortOrderUserChangeable() { 81 return mContext.getResources().getBoolean(R.bool.config_sort_order_user_changeable); 82 } 83 getDefaultSortOrder()84 public int getDefaultSortOrder() { 85 if (mContext.getResources().getBoolean(R.bool.config_default_sort_order_primary)) { 86 return SORT_ORDER_PRIMARY; 87 } else { 88 return SORT_ORDER_ALTERNATIVE; 89 } 90 } 91 getSortOrder()92 public int getSortOrder() { 93 if (!isSortOrderUserChangeable()) { 94 return getDefaultSortOrder(); 95 } 96 if (mSortOrder == PREFERENCE_UNASSIGNED) { 97 mSortOrder = mPreferences.getInt(SORT_ORDER_KEY, getDefaultSortOrder()); 98 } 99 return mSortOrder; 100 } 101 setSortOrder(int sortOrder)102 public void setSortOrder(int sortOrder) { 103 mSortOrder = sortOrder; 104 final Editor editor = mPreferences.edit(); 105 editor.putInt(SORT_ORDER_KEY, sortOrder); 106 editor.commit(); 107 } 108 isDisplayOrderUserChangeable()109 public boolean isDisplayOrderUserChangeable() { 110 return mContext.getResources().getBoolean(R.bool.config_display_order_user_changeable); 111 } 112 getDefaultDisplayOrder()113 public int getDefaultDisplayOrder() { 114 if (mContext.getResources().getBoolean(R.bool.config_default_display_order_primary)) { 115 return DISPLAY_ORDER_PRIMARY; 116 } else { 117 return DISPLAY_ORDER_ALTERNATIVE; 118 } 119 } 120 getDisplayOrder()121 public int getDisplayOrder() { 122 if (!isDisplayOrderUserChangeable()) { 123 return getDefaultDisplayOrder(); 124 } 125 if (mDisplayOrder == PREFERENCE_UNASSIGNED) { 126 mDisplayOrder = mPreferences.getInt(DISPLAY_ORDER_KEY, getDefaultDisplayOrder()); 127 } 128 return mDisplayOrder; 129 } 130 setDisplayOrder(int displayOrder)131 public void setDisplayOrder(int displayOrder) { 132 mDisplayOrder = displayOrder; 133 final Editor editor = mPreferences.edit(); 134 editor.putInt(DISPLAY_ORDER_KEY, displayOrder); 135 editor.commit(); 136 } 137 isDefaultAccountUserChangeable()138 public boolean isDefaultAccountUserChangeable() { 139 return mContext.getResources().getBoolean(R.bool.config_default_account_user_changeable); 140 } 141 getDefaultAccount()142 public String getDefaultAccount() { 143 if (!isDefaultAccountUserChangeable()) { 144 return mDefaultAccount; 145 } 146 if (TextUtils.isEmpty(mDefaultAccount)) { 147 final String accountString = mPreferences.getString(mDefaultAccountKey, mDefaultAccount); 148 if (!TextUtils.isEmpty(accountString)) { 149 final AccountWithDataSet accountWithDataSet = AccountWithDataSet.unstringify(accountString); 150 mDefaultAccount = accountWithDataSet.name; 151 } 152 } 153 return mDefaultAccount; 154 } 155 setDefaultAccount(AccountWithDataSet accountWithDataSet)156 public void setDefaultAccount(AccountWithDataSet accountWithDataSet) { 157 mDefaultAccount = accountWithDataSet == null ? null : accountWithDataSet.name; 158 final Editor editor = mPreferences.edit(); 159 if (TextUtils.isEmpty(mDefaultAccount)) { 160 editor.remove(mDefaultAccountKey); 161 } else { 162 editor.putString(mDefaultAccountKey, accountWithDataSet.stringify()); 163 } 164 editor.putBoolean(mDefaultAccountSavedKey, true); 165 editor.commit(); 166 } 167 registerChangeListener(ChangeListener listener)168 public void registerChangeListener(ChangeListener listener) { 169 if (mListener != null) { 170 unregisterChangeListener(); 171 } 172 173 mListener = listener; 174 175 // Reset preferences to "unknown" because they may have changed while the 176 // listener was unregistered. 177 mDisplayOrder = PREFERENCE_UNASSIGNED; 178 mSortOrder = PREFERENCE_UNASSIGNED; 179 mDefaultAccount = null; 180 181 mPreferences.registerOnSharedPreferenceChangeListener(this); 182 } 183 unregisterChangeListener()184 public void unregisterChangeListener() { 185 if (mListener != null) { 186 mListener = null; 187 } 188 189 mPreferences.unregisterOnSharedPreferenceChangeListener(this); 190 } 191 192 @Override onSharedPreferenceChanged(SharedPreferences sharedPreferences, final String key)193 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, final String key) { 194 // This notification is not sent on the Ui thread. Use the previously created Handler 195 // to switch to the Ui thread 196 mHandler.post( 197 new Runnable() { 198 @Override 199 public void run() { 200 refreshValue(key); 201 } 202 }); 203 } 204 205 /** 206 * Forces the value for the given key to be looked up from shared preferences and notifies the 207 * registered {@link ChangeListener} 208 * 209 * @param key the {@link SharedPreferences} key to look up 210 */ refreshValue(String key)211 public void refreshValue(String key) { 212 if (DISPLAY_ORDER_KEY.equals(key)) { 213 mDisplayOrder = PREFERENCE_UNASSIGNED; 214 mDisplayOrder = getDisplayOrder(); 215 } else if (SORT_ORDER_KEY.equals(key)) { 216 mSortOrder = PREFERENCE_UNASSIGNED; 217 mSortOrder = getSortOrder(); 218 } else if (mDefaultAccountKey.equals(key)) { 219 mDefaultAccount = null; 220 mDefaultAccount = getDefaultAccount(); 221 } 222 if (mListener != null) { 223 mListener.onChange(); 224 } 225 } 226 227 /** 228 * If there are currently no preferences (which means this is the first time we are run), For sort 229 * order and display order, check to see if there are any preferences stored in system settings 230 * (pre-L) which can be copied into our own SharedPreferences. For default account setting, check 231 * to see if there are any preferences stored in the previous SharedPreferences which can be 232 * copied into current SharedPreferences. 233 */ maybeMigrateSystemSettings()234 private void maybeMigrateSystemSettings() { 235 if (!mPreferences.contains(SORT_ORDER_KEY)) { 236 int sortOrder = getDefaultSortOrder(); 237 try { 238 sortOrder = Settings.System.getInt(mContext.getContentResolver(), SORT_ORDER_KEY); 239 } catch (SettingNotFoundException e) { 240 } 241 setSortOrder(sortOrder); 242 } 243 244 if (!mPreferences.contains(DISPLAY_ORDER_KEY)) { 245 int displayOrder = getDefaultDisplayOrder(); 246 try { 247 displayOrder = Settings.System.getInt(mContext.getContentResolver(), DISPLAY_ORDER_KEY); 248 } catch (SettingNotFoundException e) { 249 } 250 setDisplayOrder(displayOrder); 251 } 252 253 if (!mPreferences.contains(mDefaultAccountKey)) { 254 final SharedPreferences previousPrefs = 255 PreferenceManager.getDefaultSharedPreferences(mContext); 256 final String defaultAccount = previousPrefs.getString(mDefaultAccountKey, null); 257 if (!TextUtils.isEmpty(defaultAccount)) { 258 final AccountWithDataSet accountWithDataSet = 259 AccountWithDataSet.unstringify(defaultAccount); 260 setDefaultAccount(accountWithDataSet); 261 } 262 } 263 } 264 265 public interface ChangeListener { 266 onChange()267 void onChange(); 268 } 269 } 270