summaryrefslogtreecommitdiff
path: root/src/com/android/calendar/GeneralPreferences.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/calendar/GeneralPreferences.kt')
-rw-r--r--src/com/android/calendar/GeneralPreferences.kt378
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