• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 
17 package com.android.deskclock.alarms
18 
19 import android.content.Context
20 import android.content.Intent
21 import android.os.Bundle
22 import android.os.Vibrator
23 import androidx.fragment.app.Fragment
24 
25 import com.android.deskclock.AlarmClockFragment
26 import com.android.deskclock.LabelDialogFragment
27 import com.android.deskclock.LogUtils
28 import com.android.deskclock.R
29 import com.android.deskclock.alarms.dataadapter.AlarmItemHolder
30 import com.android.deskclock.data.DataModel
31 import com.android.deskclock.data.Weekdays
32 import com.android.deskclock.events.Events
33 import com.android.deskclock.provider.Alarm
34 import com.android.deskclock.provider.AlarmInstance
35 import com.android.deskclock.provider.ClockContract.InstancesColumns
36 import com.android.deskclock.ringtone.RingtonePickerActivity
37 
38 import java.util.Calendar
39 
40 /**
41  * Click handler for an alarm time item.
42  */
43 class AlarmTimeClickHandler(
44     private val mFragment: Fragment,
45     savedState: Bundle?,
46     private val mAlarmUpdateHandler: AlarmUpdateHandler,
47     private val mScrollHandler: ScrollHandler
48 ) {
49 
50     private val mContext: Context = mFragment.requireActivity().getApplicationContext()
51     private var mSelectedAlarm: Alarm? = null
52     private var mPreviousDaysOfWeekMap: Bundle? = null
53 
54     init {
55         if (savedState != null) {
56             mPreviousDaysOfWeekMap = savedState.getBundle(KEY_PREVIOUS_DAY_MAP)
57         }
58         if (mPreviousDaysOfWeekMap == null) {
59             mPreviousDaysOfWeekMap = Bundle()
60         }
61     }
62 
setSelectedAlarmnull63     fun setSelectedAlarm(selectedAlarm: Alarm?) {
64         mSelectedAlarm = selectedAlarm
65     }
66 
saveInstancenull67     fun saveInstance(outState: Bundle) {
68         outState.putBundle(KEY_PREVIOUS_DAY_MAP, mPreviousDaysOfWeekMap)
69     }
70 
setAlarmEnablednull71     fun setAlarmEnabled(alarm: Alarm, newState: Boolean) {
72         if (newState != alarm.enabled) {
73             alarm.enabled = newState
74             Events.sendAlarmEvent(if (newState) R.string.action_enable else R.string.action_disable,
75                     R.string.label_deskclock)
76             mAlarmUpdateHandler.asyncUpdateAlarm(alarm, alarm.enabled, minorUpdate = false)
77             LOGGER.d("Updating alarm enabled state to $newState")
78         }
79     }
80 
setAlarmVibrationEnablednull81     fun setAlarmVibrationEnabled(alarm: Alarm, newState: Boolean) {
82         if (newState != alarm.vibrate) {
83             alarm.vibrate = newState
84             Events.sendAlarmEvent(R.string.action_toggle_vibrate, R.string.label_deskclock)
85             mAlarmUpdateHandler.asyncUpdateAlarm(alarm, popToast = false, minorUpdate = true)
86             LOGGER.d("Updating vibrate state to $newState")
87 
88             if (newState) {
89                 // Buzz the vibrator to preview the alarm firing behavior.
90                 val v: Vibrator = mContext.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
91                 if (v.hasVibrator()) {
92                     v.vibrate(300)
93                 }
94             }
95         }
96     }
97 
setAlarmRepeatEnablednull98     fun setAlarmRepeatEnabled(alarm: Alarm, isEnabled: Boolean) {
99         val now = Calendar.getInstance()
100         val oldNextAlarmTime = alarm.getNextAlarmTime(now)
101         val alarmId = alarm.id.toString()
102         if (isEnabled) {
103             // Set all previously set days
104             // or
105             // Set all days if no previous.
106             val bitSet: Int = mPreviousDaysOfWeekMap!!.getInt(alarmId)
107             alarm.daysOfWeek = Weekdays.fromBits(bitSet)
108             if (!alarm.daysOfWeek.isRepeating) {
109                 alarm.daysOfWeek = Weekdays.ALL
110             }
111         } else {
112             // Remember the set days in case the user wants it back.
113             val bitSet = alarm.daysOfWeek.bits
114             mPreviousDaysOfWeekMap!!.putInt(alarmId, bitSet)
115 
116             // Remove all repeat days
117             alarm.daysOfWeek = Weekdays.NONE
118         }
119 
120         // if the change altered the next scheduled alarm time, tell the user
121         val newNextAlarmTime = alarm.getNextAlarmTime(now)
122         val popupToast = oldNextAlarmTime != newNextAlarmTime
123         Events.sendAlarmEvent(R.string.action_toggle_repeat_days, R.string.label_deskclock)
124         mAlarmUpdateHandler.asyncUpdateAlarm(alarm, popupToast, minorUpdate = false)
125     }
126 
setDayOfWeekEnablednull127     fun setDayOfWeekEnabled(alarm: Alarm, checked: Boolean, index: Int) {
128         val now = Calendar.getInstance()
129         val oldNextAlarmTime = alarm.getNextAlarmTime(now)
130 
131         val weekday = DataModel.dataModel.weekdayOrder.calendarDays[index]
132         alarm.daysOfWeek = alarm.daysOfWeek.setBit(weekday, checked)
133 
134         // if the change altered the next scheduled alarm time, tell the user
135         val newNextAlarmTime = alarm.getNextAlarmTime(now)
136         val popupToast = oldNextAlarmTime != newNextAlarmTime
137         mAlarmUpdateHandler.asyncUpdateAlarm(alarm, popupToast, minorUpdate = false)
138     }
139 
onDeleteClickednull140     fun onDeleteClicked(itemHolder: AlarmItemHolder) {
141         if (mFragment is AlarmClockFragment) {
142             (mFragment as AlarmClockFragment).removeItem(itemHolder)
143         }
144         val alarm = itemHolder.item
145         Events.sendAlarmEvent(R.string.action_delete, R.string.label_deskclock)
146         mAlarmUpdateHandler.asyncDeleteAlarm(alarm)
147         LOGGER.d("Deleting alarm.")
148     }
149 
onClockClickednull150     fun onClockClicked(alarm: Alarm) {
151         mSelectedAlarm = alarm
152         Events.sendAlarmEvent(R.string.action_set_time, R.string.label_deskclock)
153         TimePickerDialogFragment.show(mFragment, alarm.hour, alarm.minutes)
154     }
155 
dismissAlarmInstancenull156     fun dismissAlarmInstance(alarmInstance: AlarmInstance) {
157         val dismissIntent: Intent = AlarmStateManager.createStateChangeIntent(
158                 mContext, AlarmStateManager.ALARM_DISMISS_TAG, alarmInstance,
159                 InstancesColumns.PREDISMISSED_STATE)
160         mContext.startService(dismissIntent)
161         mAlarmUpdateHandler.showPredismissToast(alarmInstance)
162     }
163 
onRingtoneClickednull164     fun onRingtoneClicked(context: Context, alarm: Alarm) {
165         mSelectedAlarm = alarm
166         Events.sendAlarmEvent(R.string.action_set_ringtone, R.string.label_deskclock)
167 
168         val intent: Intent = RingtonePickerActivity.createAlarmRingtonePickerIntent(context, alarm)
169         context.startActivity(intent)
170     }
171 
onEditLabelClickednull172     fun onEditLabelClicked(alarm: Alarm) {
173         Events.sendAlarmEvent(R.string.action_set_label, R.string.label_deskclock)
174         val fragment = LabelDialogFragment.newInstance(alarm, alarm.label, mFragment.getTag())
175         LabelDialogFragment.show(mFragment.getFragmentManager(), fragment)
176     }
177 
onTimeSetnull178     fun onTimeSet(hourOfDay: Int, minute: Int) {
179         if (mSelectedAlarm == null) {
180             // If mSelectedAlarm is null then we're creating a new alarm.
181             val a = Alarm()
182             a.hour = hourOfDay
183             a.minutes = minute
184             a.enabled = true
185             mAlarmUpdateHandler.asyncAddAlarm(a)
186         } else {
187             mSelectedAlarm!!.hour = hourOfDay
188             mSelectedAlarm!!.minutes = minute
189             mSelectedAlarm!!.enabled = true
190             mScrollHandler.setSmoothScrollStableId(mSelectedAlarm!!.id)
191             mAlarmUpdateHandler
192                     .asyncUpdateAlarm(mSelectedAlarm!!, popToast = true, minorUpdate = false)
193             mSelectedAlarm = null
194         }
195     }
196 
197     companion object {
198         private val LOGGER = LogUtils.Logger("AlarmTimeClickHandler")
199 
200         private const val KEY_PREVIOUS_DAY_MAP = "previousDayMap"
201     }
202 }