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.ContentResolver;
20 import android.content.Context;
21 import android.content.SharedPreferences;
22 import android.content.SharedPreferences.Editor;
23 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
24 import android.database.ContentObserver;
25 import android.os.Handler;
26 import android.provider.ContactsContract;
27 import android.provider.Settings;
28 import android.provider.Settings.SettingNotFoundException;
29 
30 import com.android.contacts.common.R;
31 
32 /**
33  * Manages user preferences for contacts.
34  */
35 public final class ContactsPreferences implements OnSharedPreferenceChangeListener {
36 
37     /**
38      * The value for the DISPLAY_ORDER key to show the given name first.
39      */
40     public static final int DISPLAY_ORDER_PRIMARY = 1;
41 
42     /**
43      * The value for the DISPLAY_ORDER key to show the family name first.
44      */
45     public static final int DISPLAY_ORDER_ALTERNATIVE = 2;
46 
47     public static final String DISPLAY_ORDER_KEY = "android.contacts.DISPLAY_ORDER";
48 
49     /**
50      * The value for the SORT_ORDER key corresponding to sort by given name first.
51      */
52     public static final int SORT_ORDER_PRIMARY = 1;
53 
54     public static final String SORT_ORDER_KEY = "android.contacts.SORT_ORDER";
55 
56     /**
57      * The value for the SORT_ORDER key corresponding to sort by family name first.
58      */
59     public static final int SORT_ORDER_ALTERNATIVE = 2;
60 
61     public static final String PREF_DISPLAY_ONLY_PHONES = "only_phones";
62     public static final boolean PREF_DISPLAY_ONLY_PHONES_DEFAULT = false;
63 
64     private final Context mContext;
65     private int mSortOrder = -1;
66     private int mDisplayOrder = -1;
67     private ChangeListener mListener = null;
68     private Handler mHandler;
69     private final SharedPreferences mPreferences;
70 
ContactsPreferences(Context context)71     public ContactsPreferences(Context context) {
72         mContext = context;
73         mHandler = new Handler();
74         mPreferences = mContext.getSharedPreferences(context.getPackageName(),
75                 Context.MODE_PRIVATE);
76         maybeMigrateSystemSettings();
77     }
78 
isSortOrderUserChangeable()79     public boolean isSortOrderUserChangeable() {
80         return mContext.getResources().getBoolean(R.bool.config_sort_order_user_changeable);
81     }
82 
getDefaultSortOrder()83     public int getDefaultSortOrder() {
84         if (mContext.getResources().getBoolean(R.bool.config_default_sort_order_primary)) {
85             return SORT_ORDER_PRIMARY;
86         } else {
87             return SORT_ORDER_ALTERNATIVE;
88         }
89     }
90 
getSortOrder()91     public int getSortOrder() {
92         if (!isSortOrderUserChangeable()) {
93             return getDefaultSortOrder();
94         }
95         if (mSortOrder == -1) {
96             mSortOrder = mPreferences.getInt(SORT_ORDER_KEY, getDefaultSortOrder());
97         }
98         return mSortOrder;
99     }
100 
setSortOrder(int sortOrder)101     public void setSortOrder(int sortOrder) {
102         mSortOrder = sortOrder;
103         final Editor editor = mPreferences.edit();
104         editor.putInt(SORT_ORDER_KEY, sortOrder);
105         editor.commit();
106     }
107 
isDisplayOrderUserChangeable()108     public boolean isDisplayOrderUserChangeable() {
109         return mContext.getResources().getBoolean(R.bool.config_display_order_user_changeable);
110     }
111 
getDefaultDisplayOrder()112     public int getDefaultDisplayOrder() {
113         if (mContext.getResources().getBoolean(R.bool.config_default_display_order_primary)) {
114             return DISPLAY_ORDER_PRIMARY;
115         } else {
116             return DISPLAY_ORDER_ALTERNATIVE;
117         }
118     }
119 
getDisplayOrder()120     public int getDisplayOrder() {
121         if (!isDisplayOrderUserChangeable()) {
122             return getDefaultDisplayOrder();
123         }
124         if (mDisplayOrder == -1) {
125             mDisplayOrder = mPreferences.getInt(DISPLAY_ORDER_KEY, getDefaultDisplayOrder());
126         }
127         return mDisplayOrder;
128     }
129 
setDisplayOrder(int displayOrder)130     public void setDisplayOrder(int displayOrder) {
131         mDisplayOrder = displayOrder;
132         final Editor editor = mPreferences.edit();
133         editor.putInt(DISPLAY_ORDER_KEY, displayOrder);
134         editor.commit();
135     }
136 
registerChangeListener(ChangeListener listener)137     public void registerChangeListener(ChangeListener listener) {
138         if (mListener != null) unregisterChangeListener();
139 
140         mListener = listener;
141 
142         // Reset preferences to "unknown" because they may have changed while the
143         // listener was unregistered.
144         mDisplayOrder = -1;
145         mSortOrder = -1;
146 
147         mPreferences.registerOnSharedPreferenceChangeListener(this);
148     }
149 
unregisterChangeListener()150     public void unregisterChangeListener() {
151         if (mListener != null) {
152             mListener = null;
153         }
154 
155         mPreferences.unregisterOnSharedPreferenceChangeListener(this);
156     }
157 
158     @Override
onSharedPreferenceChanged(SharedPreferences sharedPreferences, final String key)159     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, final String key) {
160         // This notification is not sent on the Ui thread. Use the previously created Handler
161         // to switch to the Ui thread
162         mHandler.post(new Runnable() {
163             @Override
164             public void run() {
165                 if (DISPLAY_ORDER_KEY.equals(key)) {
166                     mDisplayOrder = getDisplayOrder();
167                 } else if (SORT_ORDER_KEY.equals(key)) {
168                     mSortOrder = getSortOrder();
169                 }
170                 if (mListener != null) mListener.onChange();
171             }
172         });
173     }
174 
175     public interface ChangeListener {
onChange()176         void onChange();
177     }
178 
179     /**
180      * If there are currently no preferences (which means this is the first time we are run),
181      * check to see if there are any preferences stored in system settings (pre-L) which can be
182      * copied into our own SharedPreferences.
183      */
maybeMigrateSystemSettings()184     private void maybeMigrateSystemSettings() {
185         if (!mPreferences.contains(SORT_ORDER_KEY)) {
186             int sortOrder = getDefaultSortOrder();
187             try {
188                  sortOrder = Settings.System.getInt(mContext.getContentResolver(),
189                         SORT_ORDER_KEY);
190             } catch (SettingNotFoundException e) {
191             }
192             setSortOrder(sortOrder);
193         }
194 
195         if (!mPreferences.contains(DISPLAY_ORDER_KEY)) {
196             int displayOrder = getDefaultDisplayOrder();
197             try {
198                 displayOrder = Settings.System.getInt(mContext.getContentResolver(),
199                         DISPLAY_ORDER_KEY);
200             } catch (SettingNotFoundException e) {
201             }
202             setDisplayOrder(displayOrder);
203         }
204     }
205 }
206