blob: 8c7cbfcc9144ccdd1720b02910395303aa7f4186 [file] [log] [blame]
/*
* Copyright (C) 2020 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.deskclock.settings
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Vibrator
import android.provider.Settings
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.preference.ListPreference
import androidx.preference.ListPreferenceDialogFragmentCompat
import androidx.preference.Preference
import androidx.preference.PreferenceDialogFragmentCompat
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.TwoStatePreference
import com.android.deskclock.BaseActivity
import com.android.deskclock.DropShadowController
import com.android.deskclock.R
import com.android.deskclock.Utils
import com.android.deskclock.actionbarmenu.MenuItemControllerFactory
import com.android.deskclock.actionbarmenu.NavUpMenuItemController
import com.android.deskclock.actionbarmenu.OptionsMenuManager
import com.android.deskclock.data.DataModel
import com.android.deskclock.ringtone.RingtonePickerActivity
/**
* Settings for the Alarm Clock.
*/
class SettingsActivity : BaseActivity() {
private val mOptionsMenuManager = OptionsMenuManager()
/**
* The controller that shows the drop shadow when content is not scrolled to the top.
*/
private lateinit var mDropShadowController: DropShadowController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.settings)
mOptionsMenuManager.addMenuItemController(NavUpMenuItemController(this))
.addMenuItemController(*MenuItemControllerFactory.getInstance()
.buildMenuItemControllers(this))
// Create the prefs fragment in code to ensure it's created before PreferenceDialogFragment
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.main, PrefsFragment(), PREFS_FRAGMENT_TAG)
.disallowAddToBackStack()
.commit()
}
}
override fun onResume() {
super.onResume()
val dropShadow: View = findViewById(R.id.drop_shadow)
val fragment = getSupportFragmentManager().findFragmentById(R.id.main) as PrefsFragment
mDropShadowController = DropShadowController(dropShadow, fragment.getListView())
}
override fun onPause() {
mDropShadowController.stop()
super.onPause()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
mOptionsMenuManager.onCreateOptionsMenu(menu)
return true
}
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
mOptionsMenuManager.onPrepareOptionsMenu(menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return (mOptionsMenuManager.onOptionsItemSelected(item) ||
super.onOptionsItemSelected(item))
}
class PrefsFragment :
PreferenceFragmentCompat(),
Preference.OnPreferenceChangeListener,
Preference.OnPreferenceClickListener {
override fun onCreatePreferences(bundle: Bundle?, rootKey: String?) {
getPreferenceManager().setStorageDeviceProtected()
addPreferencesFromResource(R.xml.settings)
val timerVibrate: Preference? = findPreference(KEY_TIMER_VIBRATE)
timerVibrate?.let {
val hasVibrator: Boolean = (it.getContext()
.getSystemService(VIBRATOR_SERVICE) as Vibrator).hasVibrator()
it.setVisible(hasVibrator)
}
loadTimeZoneList()
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
// By default, do not recreate the DeskClock activity
getActivity()?.setResult(RESULT_CANCELED)
}
override fun onResume() {
super.onResume()
refresh()
}
override fun onPreferenceChange(pref: Preference, newValue: Any): Boolean {
when (pref.getKey()) {
KEY_ALARM_CRESCENDO, KEY_HOME_TZ, KEY_ALARM_SNOOZE, KEY_TIMER_CRESCENDO -> {
val preference: ListPreference = pref as ListPreference
val index: Int = preference.findIndexOfValue(newValue as String)
preference.setSummary(preference.getEntries().get(index))
}
KEY_CLOCK_STYLE, KEY_WEEK_START, KEY_VOLUME_BUTTONS -> {
val simpleMenuPreference = pref as SimpleMenuPreference
val i: Int = simpleMenuPreference.findIndexOfValue(newValue as String)
pref.setSummary(simpleMenuPreference.getEntries().get(i))
}
KEY_CLOCK_DISPLAY_SECONDS -> {
DataModel.dataModel.displayClockSeconds = newValue as Boolean
}
KEY_AUTO_SILENCE -> {
val delay = newValue as String
updateAutoSnoozeSummary(pref as ListPreference, delay)
}
KEY_AUTO_HOME_CLOCK -> {
val autoHomeClockEnabled: Boolean = (pref as TwoStatePreference).isChecked()
val homeTimeZonePref: Preference? = findPreference(KEY_HOME_TZ)
homeTimeZonePref?.setEnabled(!autoHomeClockEnabled)
}
KEY_TIMER_VIBRATE -> {
val timerVibratePref: TwoStatePreference = pref as TwoStatePreference
DataModel.dataModel.timerVibrate = timerVibratePref.isChecked()
}
KEY_TIMER_RINGTONE -> pref.setSummary(DataModel.dataModel.timerRingtoneTitle)
}
// Set result so DeskClock knows to refresh itself
getActivity()?.setResult(RESULT_OK)
return true
}
override fun onPreferenceClick(pref: Preference): Boolean {
val context: Context = getActivity() ?: return false
when (pref.getKey()) {
KEY_DATE_TIME -> {
val dialogIntent = Intent(Settings.ACTION_DATE_SETTINGS)
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(dialogIntent)
return true
}
KEY_TIMER_RINGTONE -> {
startActivity(RingtonePickerActivity.createTimerRingtonePickerIntent(context))
return true
}
else -> return false
}
}
override fun onDisplayPreferenceDialog(preference: Preference) {
// Only single-selection lists are currently supported.
val f: PreferenceDialogFragmentCompat
f = if (preference is ListPreference) {
ListPreferenceDialogFragmentCompat.newInstance(preference.getKey())
} else {
throw IllegalArgumentException("Unsupported DialogPreference type")
}
showDialog(f)
}
private fun showDialog(fragment: PreferenceDialogFragmentCompat) {
// TODO(colinmarsch) Replace deprecated getFragmentManager with AndroidX equivalent
// Don't show dialog if one is already shown.
if (getFragmentManager()?.findFragmentByTag(PREFERENCE_DIALOG_FRAGMENT_TAG) != null) {
return
}
// Always set the target fragment, this is required by PreferenceDialogFragment
// internally.
fragment.setTargetFragment(this, 0)
// Don't use getChildFragmentManager(), it causes issues on older platforms when the
// target fragment is being restored after an orientation change.
fragment.show(getFragmentManager()!!, PREFERENCE_DIALOG_FRAGMENT_TAG)
}
/**
* Reconstruct the timezone list.
*/
private fun loadTimeZoneList() {
val timezones = DataModel.dataModel.timeZones
val homeTimezonePref: ListPreference? = findPreference(KEY_HOME_TZ)
homeTimezonePref?.let {
it.setEntryValues(timezones.timeZoneIds)
it.setEntries(timezones.timeZoneNames)
it.setSummary(homeTimezonePref.getEntry())
it.setOnPreferenceChangeListener(this)
}
}
private fun refresh() {
val autoSilencePref: ListPreference? = findPreference(KEY_AUTO_SILENCE)
autoSilencePref?.let {
val delay: String = it.getValue()
updateAutoSnoozeSummary(it, delay)
it.setOnPreferenceChangeListener(this)
}
val clockStylePref: SimpleMenuPreference? = findPreference(KEY_CLOCK_STYLE)
clockStylePref?.let {
it.setSummary(it.getEntry())
it.setOnPreferenceChangeListener(this)
}
val volumeButtonsPref: SimpleMenuPreference? = findPreference(KEY_VOLUME_BUTTONS)
volumeButtonsPref?.let {
it.setSummary(volumeButtonsPref.getEntry())
it.setOnPreferenceChangeListener(this)
}
val clockSecondsPref: Preference? = findPreference(KEY_CLOCK_DISPLAY_SECONDS)
clockSecondsPref?.setOnPreferenceChangeListener(this)
val autoHomeClockPref: Preference? = findPreference(KEY_AUTO_HOME_CLOCK)
val autoHomeClockEnabled: Boolean =
(autoHomeClockPref as TwoStatePreference).isChecked()
autoHomeClockPref.setOnPreferenceChangeListener(this)
val homeTimezonePref: ListPreference? = findPreference(KEY_HOME_TZ)
homeTimezonePref?.setEnabled(autoHomeClockEnabled)
refreshListPreference(homeTimezonePref!!)
refreshListPreference(findPreference(KEY_ALARM_CRESCENDO)!!)
refreshListPreference(findPreference(KEY_TIMER_CRESCENDO)!!)
refreshListPreference(findPreference(KEY_ALARM_SNOOZE)!!)
val dateAndTimeSetting: Preference? = findPreference(KEY_DATE_TIME)
dateAndTimeSetting?.setOnPreferenceClickListener(this)
val weekStartPref: SimpleMenuPreference? = findPreference(KEY_WEEK_START)
// Set the default value programmatically
val weekdayOrder = DataModel.dataModel.weekdayOrder
val firstDay = weekdayOrder.calendarDays[0]
val value = firstDay.toString()
weekStartPref?.let {
val idx: Int = it.findIndexOfValue(value)
it.setValueIndex(idx)
it.setSummary(weekStartPref.getEntries().get(idx))
it.setOnPreferenceChangeListener(this)
}
val timerRingtonePref: Preference? = findPreference(KEY_TIMER_RINGTONE)
timerRingtonePref?.let {
it.setOnPreferenceClickListener(this)
it.setSummary(DataModel.dataModel.timerRingtoneTitle)
}
}
private fun refreshListPreference(preference: ListPreference) {
preference.setSummary(preference.getEntry())
preference.setOnPreferenceChangeListener(this)
}
private fun updateAutoSnoozeSummary(listPref: ListPreference, delay: String) {
val i = delay.toInt()
if (i == -1) {
listPref.setSummary(R.string.auto_silence_never)
} else {
listPref.setSummary(Utils.getNumberFormattedQuantityString(getActivity(),
R.plurals.auto_silence_summary, i))
}
}
}
companion object {
const val KEY_ALARM_SNOOZE = "snooze_duration"
const val KEY_ALARM_CRESCENDO = "alarm_crescendo_duration"
const val KEY_TIMER_CRESCENDO = "timer_crescendo_duration"
const val KEY_TIMER_RINGTONE = "timer_ringtone"
const val KEY_TIMER_VIBRATE = "timer_vibrate"
const val KEY_AUTO_SILENCE = "auto_silence"
const val KEY_CLOCK_STYLE = "clock_style"
const val KEY_CLOCK_DISPLAY_SECONDS = "display_clock_seconds"
const val KEY_HOME_TZ = "home_time_zone"
const val KEY_AUTO_HOME_CLOCK = "automatic_home_clock"
const val KEY_DATE_TIME = "date_time"
const val KEY_VOLUME_BUTTONS = "volume_button_setting"
const val KEY_WEEK_START = "week_start"
const val DEFAULT_VOLUME_BEHAVIOR = "0"
const val VOLUME_BEHAVIOR_SNOOZE = "1"
const val VOLUME_BEHAVIOR_DISMISS = "2"
const val PREFS_FRAGMENT_TAG = "prefs_fragment"
const val PREFERENCE_DIALOG_FRAGMENT_TAG = "preference_dialog"
}
}