/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.contacts.common.preference; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.Handler; import android.preference.PreferenceManager; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.text.TextUtils; import com.android.contacts.common.R; import com.android.contacts.common.model.account.AccountWithDataSet; /** Manages user preferences for contacts. */ public class ContactsPreferences implements OnSharedPreferenceChangeListener { /** The value for the DISPLAY_ORDER key to show the given name first. */ public static final int DISPLAY_ORDER_PRIMARY = 1; /** The value for the DISPLAY_ORDER key to show the family name first. */ public static final int DISPLAY_ORDER_ALTERNATIVE = 2; public static final String DISPLAY_ORDER_KEY = "android.contacts.DISPLAY_ORDER"; /** The value for the SORT_ORDER key corresponding to sort by given name first. */ public static final int SORT_ORDER_PRIMARY = 1; public static final String SORT_ORDER_KEY = "android.contacts.SORT_ORDER"; /** The value for the SORT_ORDER key corresponding to sort by family name first. */ public static final int SORT_ORDER_ALTERNATIVE = 2; public static final String PREF_DISPLAY_ONLY_PHONES = "only_phones"; public static final boolean PREF_DISPLAY_ONLY_PHONES_DEFAULT = false; /** * Value to use when a preference is unassigned and needs to be read from the shared preferences */ private static final int PREFERENCE_UNASSIGNED = -1; private final Context mContext; private final SharedPreferences mPreferences; private int mSortOrder = PREFERENCE_UNASSIGNED; private int mDisplayOrder = PREFERENCE_UNASSIGNED; private String mDefaultAccount = null; private ChangeListener mListener = null; private Handler mHandler; private String mDefaultAccountKey; private String mDefaultAccountSavedKey; public ContactsPreferences(Context context) { mContext = context; mHandler = new Handler(); mPreferences = mContext.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE); mDefaultAccountKey = mContext.getResources().getString(R.string.contact_editor_default_account_key); mDefaultAccountSavedKey = mContext.getResources().getString(R.string.contact_editor_anything_saved_key); maybeMigrateSystemSettings(); } public boolean isSortOrderUserChangeable() { return mContext.getResources().getBoolean(R.bool.config_sort_order_user_changeable); } public int getDefaultSortOrder() { if (mContext.getResources().getBoolean(R.bool.config_default_sort_order_primary)) { return SORT_ORDER_PRIMARY; } else { return SORT_ORDER_ALTERNATIVE; } } public int getSortOrder() { if (!isSortOrderUserChangeable()) { return getDefaultSortOrder(); } if (mSortOrder == PREFERENCE_UNASSIGNED) { mSortOrder = mPreferences.getInt(SORT_ORDER_KEY, getDefaultSortOrder()); } return mSortOrder; } public void setSortOrder(int sortOrder) { mSortOrder = sortOrder; final Editor editor = mPreferences.edit(); editor.putInt(SORT_ORDER_KEY, sortOrder); editor.commit(); } public boolean isDisplayOrderUserChangeable() { return mContext.getResources().getBoolean(R.bool.config_display_order_user_changeable); } public int getDefaultDisplayOrder() { if (mContext.getResources().getBoolean(R.bool.config_default_display_order_primary)) { return DISPLAY_ORDER_PRIMARY; } else { return DISPLAY_ORDER_ALTERNATIVE; } } public int getDisplayOrder() { if (!isDisplayOrderUserChangeable()) { return getDefaultDisplayOrder(); } if (mDisplayOrder == PREFERENCE_UNASSIGNED) { mDisplayOrder = mPreferences.getInt(DISPLAY_ORDER_KEY, getDefaultDisplayOrder()); } return mDisplayOrder; } public void setDisplayOrder(int displayOrder) { mDisplayOrder = displayOrder; final Editor editor = mPreferences.edit(); editor.putInt(DISPLAY_ORDER_KEY, displayOrder); editor.commit(); } public boolean isDefaultAccountUserChangeable() { return mContext.getResources().getBoolean(R.bool.config_default_account_user_changeable); } public String getDefaultAccount() { if (!isDefaultAccountUserChangeable()) { return mDefaultAccount; } if (TextUtils.isEmpty(mDefaultAccount)) { final String accountString = mPreferences.getString(mDefaultAccountKey, mDefaultAccount); if (!TextUtils.isEmpty(accountString)) { final AccountWithDataSet accountWithDataSet = AccountWithDataSet.unstringify(accountString); mDefaultAccount = accountWithDataSet.name; } } return mDefaultAccount; } public void setDefaultAccount(AccountWithDataSet accountWithDataSet) { mDefaultAccount = accountWithDataSet == null ? null : accountWithDataSet.name; final Editor editor = mPreferences.edit(); if (TextUtils.isEmpty(mDefaultAccount)) { editor.remove(mDefaultAccountKey); } else { editor.putString(mDefaultAccountKey, accountWithDataSet.stringify()); } editor.putBoolean(mDefaultAccountSavedKey, true); editor.commit(); } public void registerChangeListener(ChangeListener listener) { if (mListener != null) { unregisterChangeListener(); } mListener = listener; // Reset preferences to "unknown" because they may have changed while the // listener was unregistered. mDisplayOrder = PREFERENCE_UNASSIGNED; mSortOrder = PREFERENCE_UNASSIGNED; mDefaultAccount = null; mPreferences.registerOnSharedPreferenceChangeListener(this); } public void unregisterChangeListener() { if (mListener != null) { mListener = null; } mPreferences.unregisterOnSharedPreferenceChangeListener(this); } @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, final String key) { // This notification is not sent on the Ui thread. Use the previously created Handler // to switch to the Ui thread mHandler.post( new Runnable() { @Override public void run() { refreshValue(key); } }); } /** * Forces the value for the given key to be looked up from shared preferences and notifies the * registered {@link ChangeListener} * * @param key the {@link SharedPreferences} key to look up */ public void refreshValue(String key) { if (DISPLAY_ORDER_KEY.equals(key)) { mDisplayOrder = PREFERENCE_UNASSIGNED; mDisplayOrder = getDisplayOrder(); } else if (SORT_ORDER_KEY.equals(key)) { mSortOrder = PREFERENCE_UNASSIGNED; mSortOrder = getSortOrder(); } else if (mDefaultAccountKey.equals(key)) { mDefaultAccount = null; mDefaultAccount = getDefaultAccount(); } if (mListener != null) { mListener.onChange(); } } /** * If there are currently no preferences (which means this is the first time we are run), For sort * order and display order, check to see if there are any preferences stored in system settings * (pre-L) which can be copied into our own SharedPreferences. For default account setting, check * to see if there are any preferences stored in the previous SharedPreferences which can be * copied into current SharedPreferences. */ private void maybeMigrateSystemSettings() { if (!mPreferences.contains(SORT_ORDER_KEY)) { int sortOrder = getDefaultSortOrder(); try { sortOrder = Settings.System.getInt(mContext.getContentResolver(), SORT_ORDER_KEY); } catch (SettingNotFoundException e) { } setSortOrder(sortOrder); } if (!mPreferences.contains(DISPLAY_ORDER_KEY)) { int displayOrder = getDefaultDisplayOrder(); try { displayOrder = Settings.System.getInt(mContext.getContentResolver(), DISPLAY_ORDER_KEY); } catch (SettingNotFoundException e) { } setDisplayOrder(displayOrder); } if (!mPreferences.contains(mDefaultAccountKey)) { final SharedPreferences previousPrefs = PreferenceManager.getDefaultSharedPreferences(mContext); final String defaultAccount = previousPrefs.getString(mDefaultAccountKey, null); if (!TextUtils.isEmpty(defaultAccount)) { final AccountWithDataSet accountWithDataSet = AccountWithDataSet.unstringify(defaultAccount); setDefaultAccount(accountWithDataSet); } } } public interface ChangeListener { void onChange(); } }