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