diff options
Diffstat (limited to 'src/com/android/calendar/GeneralPreferences.kt')
-rw-r--r-- | src/com/android/calendar/GeneralPreferences.kt | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/src/com/android/calendar/GeneralPreferences.kt b/src/com/android/calendar/GeneralPreferences.kt new file mode 100644 index 00000000..dd4c9550 --- /dev/null +++ b/src/com/android/calendar/GeneralPreferences.kt @@ -0,0 +1,378 @@ +/* + * Copyright (C) 2021 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.calendar + +import android.app.Activity +import android.app.FragmentManager +import android.app.backup.BackupManager +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences +import android.content.SharedPreferences.OnSharedPreferenceChangeListener +import android.media.Ringtone +import android.media.RingtoneManager +import android.net.Uri +import android.os.Bundle +import android.os.Vibrator +import android.preference.CheckBoxPreference +import android.preference.ListPreference +import android.preference.Preference +import android.preference.Preference.OnPreferenceChangeListener +import android.preference.Preference.OnPreferenceClickListener +import android.preference.PreferenceCategory +import android.preference.PreferenceFragment +import android.preference.PreferenceManager +import android.preference.PreferenceScreen +import android.provider.CalendarContract +import android.provider.CalendarContract.CalendarCache +import android.text.TextUtils +import android.text.format.Time +import com.android.calendar.alerts.AlertReceiver +import com.android.timezonepicker.TimeZoneInfo +import com.android.timezonepicker.TimeZonePickerDialog +import com.android.timezonepicker.TimeZonePickerDialog.OnTimeZoneSetListener +import com.android.timezonepicker.TimeZonePickerUtils + +class GeneralPreferences : PreferenceFragment(), OnSharedPreferenceChangeListener, + OnPreferenceChangeListener, OnTimeZoneSetListener { + var mAlert: CheckBoxPreference? = null + var mVibrate: CheckBoxPreference? = null + var mPopup: CheckBoxPreference? = null + var mUseHomeTZ: CheckBoxPreference? = null + var mHideDeclined: CheckBoxPreference? = null + var mHomeTZ: Preference? = null + var mTzPickerUtils: TimeZonePickerUtils? = null + var mWeekStart: ListPreference? = null + var mDefaultReminder: ListPreference? = null + private var mTimeZoneId: String? = null + + @Override + override fun onCreate(icicle: Bundle?) { + super.onCreate(icicle) + val activity: Activity = getActivity() + + // Make sure to always use the same preferences file regardless of the package name + // we're running under + val preferenceManager: PreferenceManager = getPreferenceManager() + val sharedPreferences: SharedPreferences? = getSharedPreferences(activity) + preferenceManager.setSharedPreferencesName(SHARED_PREFS_NAME) + + // Load the preferences from an XML resource + addPreferencesFromResource(R.xml.general_preferences) + val preferenceScreen: PreferenceScreen = getPreferenceScreen() + mAlert = preferenceScreen.findPreference(KEY_ALERTS) as CheckBoxPreference + mVibrate = preferenceScreen.findPreference(KEY_ALERTS_VIBRATE) as CheckBoxPreference + val vibrator: Vibrator = activity.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator + if (vibrator == null || !vibrator.hasVibrator()) { + val mAlertGroup: PreferenceCategory = preferenceScreen + .findPreference(KEY_ALERTS_CATEGORY) as PreferenceCategory + mAlertGroup.removePreference(mVibrate) + } + mPopup = preferenceScreen.findPreference(KEY_ALERTS_POPUP) as CheckBoxPreference + mUseHomeTZ = preferenceScreen.findPreference(KEY_HOME_TZ_ENABLED) as CheckBoxPreference + mHideDeclined = preferenceScreen.findPreference(KEY_HIDE_DECLINED) as CheckBoxPreference + mWeekStart = preferenceScreen.findPreference(KEY_WEEK_START_DAY) as ListPreference + mDefaultReminder = preferenceScreen.findPreference(KEY_DEFAULT_REMINDER) as ListPreference + mHomeTZ = preferenceScreen.findPreference(KEY_HOME_TZ) + mWeekStart?.setSummary(mWeekStart?.getEntry()) + mDefaultReminder?.setSummary(mDefaultReminder?.getEntry()) + + // This triggers an asynchronous call to the provider to refresh the data in shared pref + mTimeZoneId = Utils.getTimeZone(activity, null) + val prefs: SharedPreferences = CalendarUtils.getSharedPreferences(activity, + Utils.SHARED_PREFS_NAME) + + // Utils.getTimeZone will return the currentTimeZone instead of the one + // in the shared_pref if home time zone is disabled. So if home tz is + // off, we will explicitly read it. + if (!prefs.getBoolean(KEY_HOME_TZ_ENABLED, false)) { + mTimeZoneId = prefs.getString(KEY_HOME_TZ, Time.getCurrentTimezone()) + } + + mHomeTZ?.setOnPreferenceClickListener(object : Preference.OnPreferenceClickListener { + @Override + override fun onPreferenceClick(preference: Preference?): Boolean { + showTimezoneDialog() + return true + } + }) + + if (mTzPickerUtils == null) { + mTzPickerUtils = TimeZonePickerUtils(getActivity()) + } + val timezoneName: CharSequence? = mTzPickerUtils?.getGmtDisplayName(getActivity(), + mTimeZoneId, System.currentTimeMillis(), false) + mHomeTZ?.setSummary(timezoneName ?: mTimeZoneId) + val tzpd: TimeZonePickerDialog = activity.getFragmentManager() + .findFragmentByTag(FRAG_TAG_TIME_ZONE_PICKER) as TimeZonePickerDialog + if (tzpd != null) { + tzpd.setOnTimeZoneSetListener(this) + } + migrateOldPreferences(sharedPreferences) + updateChildPreferences() + } + + private fun showTimezoneDialog() { + val activity: Activity = getActivity() ?: return + val b = Bundle() + b.putLong(TimeZonePickerDialog.BUNDLE_START_TIME_MILLIS, System.currentTimeMillis()) + b.putString(TimeZonePickerDialog.BUNDLE_TIME_ZONE, Utils.getTimeZone(activity, null)) + val fm: FragmentManager = getActivity().getFragmentManager() + var tzpd: TimeZonePickerDialog? = fm + .findFragmentByTag(FRAG_TAG_TIME_ZONE_PICKER) as TimeZonePickerDialog + if (tzpd != null) { + tzpd.dismiss() + } + tzpd = TimeZonePickerDialog() + tzpd.setArguments(b) + tzpd.setOnTimeZoneSetListener(this) + tzpd.show(fm, FRAG_TAG_TIME_ZONE_PICKER) + } + + @Override + override fun onStart() { + super.onStart() + getPreferenceScreen().getSharedPreferences() + .registerOnSharedPreferenceChangeListener(this) + setPreferenceListeners(this) + } + + /** + * Sets up all the preference change listeners to use the specified + * listener. + */ + private fun setPreferenceListeners(listener: OnPreferenceChangeListener?) { + mUseHomeTZ?.setOnPreferenceChangeListener(listener) + mHomeTZ?.setOnPreferenceChangeListener(listener) + mWeekStart?.setOnPreferenceChangeListener(listener) + mDefaultReminder?.setOnPreferenceChangeListener(listener) + mHideDeclined?.setOnPreferenceChangeListener(listener) + mVibrate?.setOnPreferenceChangeListener(listener) + } + + @Override + override fun onStop() { + getPreferenceScreen().getSharedPreferences() + .unregisterOnSharedPreferenceChangeListener(this) + setPreferenceListeners(null) + super.onStop() + } + + @Override + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String) { + val a: Activity = getActivity() + if (key.equals(KEY_ALERTS)) { + updateChildPreferences() + if (a != null) { + val intent = Intent() + intent.setClass(a, AlertReceiver::class.java) + if (mAlert?.isChecked() ?: false) { + intent.setAction(AlertReceiver.ACTION_DISMISS_OLD_REMINDERS) + } else { + intent.setAction(AlertReceiver.EVENT_REMINDER_APP_ACTION) + } + a.sendBroadcast(intent) + } + } + if (a != null) { + BackupManager.dataChanged(a.getPackageName()) + } + } + + /** + * Handles time zone preference changes + */ + @Override + override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean { + val tz: String? + val activity: Activity = getActivity() + if (preference === mUseHomeTZ) { + tz = if (newValue != null) { + mTimeZoneId + } else { + CalendarCache.TIMEZONE_TYPE_AUTO + } + Utils.setTimeZone(activity, tz) + return true + } else if (preference === mHideDeclined) { + mHideDeclined?.setChecked(newValue as Boolean) + val intent = Intent(Utils.getWidgetScheduledUpdateAction(activity)) + intent.setDataAndType(CalendarContract.CONTENT_URI, Utils.APPWIDGET_DATA_TYPE) + activity.sendBroadcast(intent) + return true + } else if (preference === mWeekStart) { + mWeekStart?.setValue(newValue as String) + mWeekStart?.setSummary(mWeekStart?.getEntry()) + } else if (preference === mDefaultReminder) { + mDefaultReminder?.setValue(newValue as String) + mDefaultReminder?.setSummary(mDefaultReminder?.getEntry()) + } else if (preference === mVibrate) { + mVibrate?.setChecked(newValue as Boolean) + return true + } else { + return true + } + return false + } + + fun getRingtoneTitleFromUri(context: Context?, uri: String?): String? { + if (TextUtils.isEmpty(uri)) { + return null + } + val ring: Ringtone = RingtoneManager.getRingtone(getActivity(), Uri.parse(uri)) + return if (ring != null) { + ring.getTitle(context) + } else null + } + + /** + * If necessary, upgrades previous versions of preferences to the current + * set of keys and values. + * @param prefs the preferences to upgrade + */ + private fun migrateOldPreferences(prefs: SharedPreferences?) { + // If needed, migrate vibration setting from a previous version + mVibrate?.setChecked(Utils.getDefaultVibrate(getActivity(), prefs)) + + // If needed, migrate the old alerts type settin + if (prefs?.contains(KEY_ALERTS) == false && prefs?.contains(KEY_ALERTS_TYPE) == true) { + val type: String? = prefs?.getString(KEY_ALERTS_TYPE, ALERT_TYPE_STATUS_BAR) + if (type.equals(ALERT_TYPE_OFF)) { + mAlert?.setChecked(false) + mPopup?.setChecked(false) + mPopup?.setEnabled(false) + } else if (type.equals(ALERT_TYPE_STATUS_BAR)) { + mAlert?.setChecked(true) + mPopup?.setChecked(false) + mPopup?.setEnabled(true) + } else if (type.equals(ALERT_TYPE_ALERTS)) { + mAlert?.setChecked(true) + mPopup?.setChecked(true) + mPopup?.setEnabled(true) + } + // clear out the old setting + prefs?.edit().remove(KEY_ALERTS_TYPE).commit() + } + } + + /** + * Keeps the dependent settings in sync with the parent preference, so for + * example, when notifications are turned off, we disable the preferences + * for configuring the exact notification behavior. + */ + private fun updateChildPreferences() { + if (mAlert?.isChecked() ?: false) { + mVibrate?.setEnabled(true) + mPopup?.setEnabled(true) + } else { + mVibrate?.setEnabled(false) + mPopup?.setEnabled(false) + } + } + + @Override + override fun onPreferenceTreeClick( + preferenceScreen: PreferenceScreen?, + preference: Preference + ): Boolean { + val key: String = preference.getKey() + return super.onPreferenceTreeClick(preferenceScreen, preference) + } + + @Override + override fun onTimeZoneSet(tzi: TimeZoneInfo) { + if (mTzPickerUtils == null) { + mTzPickerUtils = TimeZonePickerUtils(getActivity()) + } + val timezoneName: CharSequence? = mTzPickerUtils?.getGmtDisplayName( + getActivity(), tzi.mTzId, System.currentTimeMillis(), false) + mHomeTZ?.setSummary(timezoneName) + Utils.setTimeZone(getActivity(), tzi.mTzId) + } + + companion object { + // The name of the shared preferences file. This name must be maintained for historical + // reasons, as it's what PreferenceManager assigned the first time the file was created. + const val SHARED_PREFS_NAME = "com.android.calendar_preferences" + const val SHARED_PREFS_NAME_NO_BACKUP = "com.android.calendar_preferences_no_backup" + private const val FRAG_TAG_TIME_ZONE_PICKER = "TimeZonePicker" + + // Preference keys + const val KEY_HIDE_DECLINED = "preferences_hide_declined" + const val KEY_WEEK_START_DAY = "preferences_week_start_day" + const val KEY_SHOW_WEEK_NUM = "preferences_show_week_num" + const val KEY_DAYS_PER_WEEK = "preferences_days_per_week" + const val KEY_SKIP_SETUP = "preferences_skip_setup" + const val KEY_CLEAR_SEARCH_HISTORY = "preferences_clear_search_history" + const val KEY_ALERTS_CATEGORY = "preferences_alerts_category" + const val KEY_ALERTS = "preferences_alerts" + const val KEY_ALERTS_VIBRATE = "preferences_alerts_vibrate" + const val KEY_ALERTS_RINGTONE = "preferences_alerts_ringtone" + const val KEY_ALERTS_POPUP = "preferences_alerts_popup" + const val KEY_SHOW_CONTROLS = "preferences_show_controls" + const val KEY_DEFAULT_REMINDER = "preferences_default_reminder" + const val NO_REMINDER = -1 + const val NO_REMINDER_STRING = "-1" + const val REMINDER_DEFAULT_TIME = 10 // in minutes + const val KEY_DEFAULT_CELL_HEIGHT = "preferences_default_cell_height" + const val KEY_VERSION = "preferences_version" + + /** Key to SharePreference for default view (CalendarController.ViewType) */ + const val KEY_START_VIEW = "preferred_startView" + + /** + * Key to SharePreference for default detail view (CalendarController.ViewType) + * Typically used by widget + */ + const val KEY_DETAILED_VIEW = "preferred_detailedView" + const val KEY_DEFAULT_CALENDAR = "preference_defaultCalendar" + + // These must be in sync with the array preferences_week_start_day_values + const val WEEK_START_DEFAULT = "-1" + const val WEEK_START_SATURDAY = "7" + const val WEEK_START_SUNDAY = "1" + const val WEEK_START_MONDAY = "2" + + // These keys are kept to enable migrating users from previous versions + private const val KEY_ALERTS_TYPE = "preferences_alerts_type" + private const val ALERT_TYPE_ALERTS = "0" + private const val ALERT_TYPE_STATUS_BAR = "1" + private const val ALERT_TYPE_OFF = "2" + const val KEY_HOME_TZ_ENABLED = "preferences_home_tz_enabled" + const val KEY_HOME_TZ = "preferences_home_tz" + + // Default preference values + const val DEFAULT_START_VIEW: Int = CalendarController.ViewType.WEEK + const val DEFAULT_DETAILED_VIEW: Int = CalendarController.ViewType.DAY + const val DEFAULT_SHOW_WEEK_NUM = false + + // This should match the XML file. + const val DEFAULT_RINGTONE = "content://settings/system/notification_sound" + + /** Return a properly configured SharedPreferences instance */ + @JvmStatic + fun getSharedPreferences(context: Context?): SharedPreferences? { + return context?.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE) + } + + /** Set the default shared preferences in the proper context */ + @JvmStatic + fun setDefaultValues(context: Context?) { + PreferenceManager.setDefaultValues(context, SHARED_PREFS_NAME, Context.MODE_PRIVATE, + R.xml.general_preferences, false) + } + } +}
\ No newline at end of file |