GeneralPreferences.java revision 31489e9749cbcb6574b6b60c7942241aa2d8df7b
1/*
2 * Copyright (C) 2007 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
17package com.android.calendar;
18
19import com.android.calendar.alerts.AlertReceiver;
20
21import android.app.Activity;
22import android.app.backup.BackupManager;
23import android.content.Context;
24import android.content.Intent;
25import android.content.SharedPreferences;
26import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
27import android.os.Bundle;
28import android.os.Vibrator;
29import android.preference.CheckBoxPreference;
30import android.preference.ListPreference;
31import android.preference.Preference;
32import android.preference.Preference.OnPreferenceChangeListener;
33import android.preference.PreferenceCategory;
34import android.preference.PreferenceFragment;
35import android.preference.PreferenceManager;
36import android.preference.PreferenceScreen;
37import android.preference.RingtonePreference;
38import android.provider.CalendarContract;
39import android.provider.CalendarContract.CalendarCache;
40import android.provider.SearchRecentSuggestions;
41import android.text.TextUtils;
42import android.widget.Toast;
43
44public class GeneralPreferences extends PreferenceFragment implements
45        OnSharedPreferenceChangeListener, OnPreferenceChangeListener {
46    // The name of the shared preferences file. This name must be maintained for historical
47    // reasons, as it's what PreferenceManager assigned the first time the file was created.
48    static final String SHARED_PREFS_NAME = "com.android.calendar_preferences";
49
50    // Preference keys
51    public static final String KEY_HIDE_DECLINED = "preferences_hide_declined";
52    public static final String KEY_WEEK_START_DAY = "preferences_week_start_day";
53    public static final String KEY_SHOW_WEEK_NUM = "preferences_show_week_num";
54    public static final String KEY_DAYS_PER_WEEK = "preferences_days_per_week";
55    public static final String KEY_SKIP_SETUP = "preferences_skip_setup";
56
57    public static final String KEY_CLEAR_SEARCH_HISTORY = "preferences_clear_search_history";
58
59    public static final String KEY_ALERTS_CATEGORY = "preferences_alerts_category";
60    public static final String KEY_ALERTS = "preferences_alerts";
61    public static final String KEY_ALERTS_VIBRATE = "preferences_alerts_vibrate";
62    public static final String KEY_ALERTS_VIBRATE_WHEN = "preferences_alerts_vibrateWhen";
63    public static final String KEY_ALERTS_RINGTONE = "preferences_alerts_ringtone";
64    public static final String KEY_ALERTS_POPUP = "preferences_alerts_popup";
65
66    public static final String KEY_SHOW_CONTROLS = "preferences_show_controls";
67
68    public static final String KEY_DEFAULT_REMINDER = "preferences_default_reminder";
69    public static final int NO_REMINDER = -1;
70    public static final String NO_REMINDER_STRING = "-1";
71    public static final int REMINDER_DEFAULT_TIME = 10; // in minutes
72
73    public static final String KEY_DEFAULT_CELL_HEIGHT = "preferences_default_cell_height";
74
75    /** Key to SharePreference for default view (CalendarController.ViewType) */
76    public static final String KEY_START_VIEW = "preferred_startView";
77    /**
78     *  Key to SharePreference for default detail view (CalendarController.ViewType)
79     *  Typically used by widget
80     */
81    public static final String KEY_DETAILED_VIEW = "preferred_detailedView";
82    public static final String KEY_DEFAULT_CALENDAR = "preference_defaultCalendar";
83
84    // These must be in sync with the array preferences_week_start_day_values
85    public static final String WEEK_START_DEFAULT = "-1";
86    public static final String WEEK_START_SATURDAY = "7";
87    public static final String WEEK_START_SUNDAY = "1";
88    public static final String WEEK_START_MONDAY = "2";
89
90    // These keys are kept to enable migrating users from previous versions
91    private static final String KEY_ALERTS_TYPE = "preferences_alerts_type";
92    private static final String ALERT_TYPE_ALERTS = "0";
93    private static final String ALERT_TYPE_STATUS_BAR = "1";
94    private static final String ALERT_TYPE_OFF = "2";
95    static final String KEY_HOME_TZ_ENABLED = "preferences_home_tz_enabled";
96    static final String KEY_HOME_TZ = "preferences_home_tz";
97
98    // Default preference values
99    public static final int DEFAULT_START_VIEW = CalendarController.ViewType.WEEK;
100    public static final int DEFAULT_DETAILED_VIEW = CalendarController.ViewType.DAY;
101    public static final boolean DEFAULT_SHOW_WEEK_NUM = false;
102
103    CheckBoxPreference mAlert;
104    ListPreference mVibrateWhen;
105    RingtonePreference mRingtone;
106    CheckBoxPreference mPopup;
107    CheckBoxPreference mUseHomeTZ;
108    CheckBoxPreference mHideDeclined;
109    ListPreference mHomeTZ;
110    ListPreference mWeekStart;
111    ListPreference mDefaultReminder;
112
113    private static CharSequence[][] mTimezones;
114
115    /** Return a properly configured SharedPreferences instance */
116    public static SharedPreferences getSharedPreferences(Context context) {
117        return context.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE);
118    }
119
120    /** Set the default shared preferences in the proper context */
121    public static void setDefaultValues(Context context) {
122        PreferenceManager.setDefaultValues(context, SHARED_PREFS_NAME, Context.MODE_PRIVATE,
123                R.xml.general_preferences, false);
124    }
125
126    @Override
127    public void onCreate(Bundle icicle) {
128        super.onCreate(icicle);
129
130        final Activity activity = getActivity();
131
132        // Make sure to always use the same preferences file regardless of the package name
133        // we're running under
134        final PreferenceManager preferenceManager = getPreferenceManager();
135        final SharedPreferences sharedPreferences = getSharedPreferences(activity);
136        preferenceManager.setSharedPreferencesName(SHARED_PREFS_NAME);
137
138        // Load the preferences from an XML resource
139        addPreferencesFromResource(R.xml.general_preferences);
140
141        final PreferenceScreen preferenceScreen = getPreferenceScreen();
142        mAlert = (CheckBoxPreference) preferenceScreen.findPreference(KEY_ALERTS);
143        mVibrateWhen = (ListPreference) preferenceScreen.findPreference(KEY_ALERTS_VIBRATE_WHEN);
144        Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
145        if (vibrator == null || !vibrator.hasVibrator()) {
146            PreferenceCategory mAlertGroup = (PreferenceCategory) preferenceScreen
147                    .findPreference(KEY_ALERTS_CATEGORY);
148            mAlertGroup.removePreference(mVibrateWhen);
149        } else {
150            mVibrateWhen.setSummary(mVibrateWhen.getEntry());
151        }
152
153        mRingtone = (RingtonePreference) preferenceScreen.findPreference(KEY_ALERTS_RINGTONE);
154        mPopup = (CheckBoxPreference) preferenceScreen.findPreference(KEY_ALERTS_POPUP);
155        mUseHomeTZ = (CheckBoxPreference) preferenceScreen.findPreference(KEY_HOME_TZ_ENABLED);
156        mHideDeclined = (CheckBoxPreference) preferenceScreen.findPreference(KEY_HIDE_DECLINED);
157        mWeekStart = (ListPreference) preferenceScreen.findPreference(KEY_WEEK_START_DAY);
158        mDefaultReminder = (ListPreference) preferenceScreen.findPreference(KEY_DEFAULT_REMINDER);
159        mHomeTZ = (ListPreference) preferenceScreen.findPreference(KEY_HOME_TZ);
160        String tz = mHomeTZ.getValue();
161
162        mWeekStart.setSummary(mWeekStart.getEntry());
163        mDefaultReminder.setSummary(mDefaultReminder.getEntry());
164
165        if (mTimezones == null) {
166            mTimezones = (new TimezoneAdapter(activity, tz)).getAllTimezones();
167        }
168        mHomeTZ.setEntryValues(mTimezones[0]);
169        mHomeTZ.setEntries(mTimezones[1]);
170        CharSequence tzName = mHomeTZ.getEntry();
171        if (TextUtils.isEmpty(tzName)) {
172            tzName = Utils.getTimeZone(activity, null);
173        }
174        mHomeTZ.setSummary(tzName);
175
176        migrateOldPreferences(sharedPreferences);
177
178        updateChildPreferences();
179    }
180
181    @Override
182    public void onResume() {
183        super.onResume();
184        getPreferenceScreen().getSharedPreferences()
185                .registerOnSharedPreferenceChangeListener(this);
186        setPreferenceListeners(this);
187    }
188
189    /**
190     * Sets up all the preference change listeners to use the specified
191     * listener.
192     */
193    private void setPreferenceListeners(OnPreferenceChangeListener listener) {
194        mUseHomeTZ.setOnPreferenceChangeListener(listener);
195        mHomeTZ.setOnPreferenceChangeListener(listener);
196        mWeekStart.setOnPreferenceChangeListener(listener);
197        mDefaultReminder.setOnPreferenceChangeListener(listener);
198        mRingtone.setOnPreferenceChangeListener(listener);
199        mHideDeclined.setOnPreferenceChangeListener(listener);
200        mVibrateWhen.setOnPreferenceChangeListener(listener);
201
202    }
203
204    @Override
205    public void onPause() {
206        super.onPause();
207        getPreferenceScreen().getSharedPreferences()
208                .unregisterOnSharedPreferenceChangeListener(this);
209        setPreferenceListeners(null);
210    }
211
212    @Override
213    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
214        Activity a = getActivity();
215        if (key.equals(KEY_ALERTS)) {
216            updateChildPreferences();
217            if (a != null) {
218                Intent intent = new Intent();
219                intent.setClass(a, AlertReceiver.class);
220                if (mAlert.isChecked()) {
221                    intent.setAction(AlertReceiver.ACTION_DISMISS_OLD_REMINDERS);
222                } else {
223                    intent.setAction(CalendarContract.ACTION_EVENT_REMINDER);
224                }
225                a.sendBroadcast(intent);
226            }
227        }
228        if (a != null) {
229            BackupManager.dataChanged(a.getPackageName());
230        }
231    }
232
233    /**
234     * Handles time zone preference changes
235     */
236    @Override
237    public boolean onPreferenceChange(Preference preference, Object newValue) {
238        String tz;
239        if (preference == mUseHomeTZ) {
240            if ((Boolean)newValue) {
241                tz = mHomeTZ.getValue();
242            } else {
243                tz = CalendarCache.TIMEZONE_TYPE_AUTO;
244            }
245            Utils.setTimeZone(getActivity(), tz);
246            return true;
247        } else if (preference == mHideDeclined) {
248            mHideDeclined.setChecked((Boolean) newValue);
249            Activity act = getActivity();
250            Intent intent = new Intent(Utils.getWidgetScheduledUpdateAction(act));
251            intent.setDataAndType(CalendarContract.CONTENT_URI, Utils.APPWIDGET_DATA_TYPE);
252            act.sendBroadcast(intent);
253            return true;
254        } else if (preference == mHomeTZ) {
255            tz = (String) newValue;
256            // We set the value here so we can read back the entry
257            mHomeTZ.setValue(tz);
258            mHomeTZ.setSummary(mHomeTZ.getEntry());
259            Utils.setTimeZone(getActivity(), tz);
260        } else if (preference == mWeekStart) {
261            mWeekStart.setValue((String) newValue);
262            mWeekStart.setSummary(mWeekStart.getEntry());
263        } else if (preference == mDefaultReminder) {
264            mDefaultReminder.setValue((String) newValue);
265            mDefaultReminder.setSummary(mDefaultReminder.getEntry());
266        } else if (preference == mRingtone) {
267            // TODO update this after b/3417832 is fixed
268            return true;
269        } else if (preference == mVibrateWhen) {
270            mVibrateWhen.setValue((String)newValue);
271            mVibrateWhen.setSummary(mVibrateWhen.getEntry());
272        } else {
273            return true;
274        }
275        return false;
276    }
277
278    /**
279     * If necessary, upgrades previous versions of preferences to the current
280     * set of keys and values.
281     * @param prefs the preferences to upgrade
282     */
283    private void migrateOldPreferences(SharedPreferences prefs) {
284        // If needed, migrate vibration setting from a previous version
285        if (!prefs.contains(KEY_ALERTS_VIBRATE_WHEN) &&
286                prefs.contains(KEY_ALERTS_VIBRATE)) {
287            int stringId = prefs.getBoolean(KEY_ALERTS_VIBRATE, false) ?
288                    R.string.prefDefault_alerts_vibrate_true :
289                    R.string.prefDefault_alerts_vibrate_false;
290            mVibrateWhen.setValue(getActivity().getString(stringId));
291        }
292        // If needed, migrate the old alerts type settin
293        if (!prefs.contains(KEY_ALERTS) && prefs.contains(KEY_ALERTS_TYPE)) {
294            String type = prefs.getString(KEY_ALERTS_TYPE, ALERT_TYPE_STATUS_BAR);
295            if (type.equals(ALERT_TYPE_OFF)) {
296                mAlert.setChecked(false);
297                mPopup.setChecked(false);
298                mPopup.setEnabled(false);
299            } else if (type.equals(ALERT_TYPE_STATUS_BAR)) {
300                mAlert.setChecked(true);
301                mPopup.setChecked(false);
302                mPopup.setEnabled(true);
303            } else if (type.equals(ALERT_TYPE_ALERTS)) {
304                mAlert.setChecked(true);
305                mPopup.setChecked(true);
306                mPopup.setEnabled(true);
307            }
308            // clear out the old setting
309            prefs.edit().remove(KEY_ALERTS_TYPE).commit();
310        }
311    }
312
313    /**
314     * Keeps the dependent settings in sync with the parent preference, so for
315     * example, when notifications are turned off, we disable the preferences
316     * for configuring the exact notification behavior.
317     */
318    private void updateChildPreferences() {
319        if (mAlert.isChecked()) {
320            mVibrateWhen.setEnabled(true);
321            mRingtone.setEnabled(true);
322            mPopup.setEnabled(true);
323        } else {
324            mVibrateWhen.setValue(
325                    getActivity().getString(R.string.prefDefault_alerts_vibrate_false));
326            mVibrateWhen.setEnabled(false);
327            mRingtone.setEnabled(false);
328            mPopup.setEnabled(false);
329        }
330    }
331
332
333    @Override
334    public boolean onPreferenceTreeClick(
335            PreferenceScreen preferenceScreen, Preference preference) {
336        final String key = preference.getKey();
337        if (key.equals(KEY_CLEAR_SEARCH_HISTORY)) {
338            SearchRecentSuggestions suggestions = new SearchRecentSuggestions(getActivity(),
339                    Utils.getSearchAuthority(getActivity()),
340                    CalendarRecentSuggestionsProvider.MODE);
341            suggestions.clearHistory();
342            Toast.makeText(getActivity(), R.string.search_history_cleared,
343                    Toast.LENGTH_SHORT).show();
344            return true;
345        }
346        return false;
347    }
348
349}
350