1 /* 2 * Copyright (C) 2015 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.app.Fragment; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.os.Bundle; 23 import android.os.Vibrator; 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.ringtone.RingtonePickerActivity; 36 37 import java.util.Calendar; 38 39 /** 40 * Click handler for an alarm time item. 41 */ 42 public final class AlarmTimeClickHandler { 43 44 private static final LogUtils.Logger LOGGER = new LogUtils.Logger("AlarmTimeClickHandler"); 45 46 private static final String KEY_PREVIOUS_DAY_MAP = "previousDayMap"; 47 48 private final Fragment mFragment; 49 private final Context mContext; 50 private final AlarmUpdateHandler mAlarmUpdateHandler; 51 private final ScrollHandler mScrollHandler; 52 53 private Alarm mSelectedAlarm; 54 private Bundle mPreviousDaysOfWeekMap; 55 AlarmTimeClickHandler(Fragment fragment, Bundle savedState, AlarmUpdateHandler alarmUpdateHandler, ScrollHandler smoothScrollController)56 public AlarmTimeClickHandler(Fragment fragment, Bundle savedState, 57 AlarmUpdateHandler alarmUpdateHandler, ScrollHandler smoothScrollController) { 58 mFragment = fragment; 59 mContext = mFragment.getActivity().getApplicationContext(); 60 mAlarmUpdateHandler = alarmUpdateHandler; 61 mScrollHandler = smoothScrollController; 62 if (savedState != null) { 63 mPreviousDaysOfWeekMap = savedState.getBundle(KEY_PREVIOUS_DAY_MAP); 64 } 65 if (mPreviousDaysOfWeekMap == null) { 66 mPreviousDaysOfWeekMap = new Bundle(); 67 } 68 } 69 setSelectedAlarm(Alarm selectedAlarm)70 public void setSelectedAlarm(Alarm selectedAlarm) { 71 mSelectedAlarm = selectedAlarm; 72 } 73 saveInstance(Bundle outState)74 public void saveInstance(Bundle outState) { 75 outState.putBundle(KEY_PREVIOUS_DAY_MAP, mPreviousDaysOfWeekMap); 76 } 77 setAlarmEnabled(Alarm alarm, boolean newState)78 public void setAlarmEnabled(Alarm alarm, boolean newState) { 79 if (newState != alarm.enabled) { 80 alarm.enabled = newState; 81 Events.sendAlarmEvent(newState ? R.string.action_enable : R.string.action_disable, 82 R.string.label_deskclock); 83 mAlarmUpdateHandler.asyncUpdateAlarm(alarm, alarm.enabled, false); 84 LOGGER.d("Updating alarm enabled state to " + newState); 85 } 86 } 87 setAlarmVibrationEnabled(Alarm alarm, boolean newState)88 public void setAlarmVibrationEnabled(Alarm alarm, boolean newState) { 89 if (newState != alarm.vibrate) { 90 alarm.vibrate = newState; 91 Events.sendAlarmEvent(R.string.action_toggle_vibrate, R.string.label_deskclock); 92 mAlarmUpdateHandler.asyncUpdateAlarm(alarm, false, true); 93 LOGGER.d("Updating vibrate state to " + newState); 94 95 if (newState) { 96 // Buzz the vibrator to preview the alarm firing behavior. 97 final Vibrator v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); 98 if (v.hasVibrator()) { 99 v.vibrate(300); 100 } 101 } 102 } 103 } 104 setAlarmRepeatEnabled(Alarm alarm, boolean isEnabled)105 public void setAlarmRepeatEnabled(Alarm alarm, boolean isEnabled) { 106 final Calendar now = Calendar.getInstance(); 107 final Calendar oldNextAlarmTime = alarm.getNextAlarmTime(now); 108 final String alarmId = String.valueOf(alarm.id); 109 if (isEnabled) { 110 // Set all previously set days 111 // or 112 // Set all days if no previous. 113 final int bitSet = mPreviousDaysOfWeekMap.getInt(alarmId); 114 alarm.daysOfWeek = Weekdays.fromBits(bitSet); 115 if (!alarm.daysOfWeek.isRepeating()) { 116 alarm.daysOfWeek = Weekdays.ALL; 117 } 118 } else { 119 // Remember the set days in case the user wants it back. 120 final int bitSet = alarm.daysOfWeek.getBits(); 121 mPreviousDaysOfWeekMap.putInt(alarmId, bitSet); 122 123 // Remove all repeat days 124 alarm.daysOfWeek = Weekdays.NONE; 125 } 126 127 // if the change altered the next scheduled alarm time, tell the user 128 final Calendar newNextAlarmTime = alarm.getNextAlarmTime(now); 129 final boolean popupToast = !oldNextAlarmTime.equals(newNextAlarmTime); 130 131 Events.sendAlarmEvent(R.string.action_toggle_repeat_days, R.string.label_deskclock); 132 mAlarmUpdateHandler.asyncUpdateAlarm(alarm, popupToast, false); 133 } 134 setDayOfWeekEnabled(Alarm alarm, boolean checked, int index)135 public void setDayOfWeekEnabled(Alarm alarm, boolean checked, int index) { 136 final Calendar now = Calendar.getInstance(); 137 final Calendar oldNextAlarmTime = alarm.getNextAlarmTime(now); 138 139 final int weekday = DataModel.getDataModel().getWeekdayOrder().getCalendarDays().get(index); 140 alarm.daysOfWeek = alarm.daysOfWeek.setBit(weekday, checked); 141 142 // if the change altered the next scheduled alarm time, tell the user 143 final Calendar newNextAlarmTime = alarm.getNextAlarmTime(now); 144 final boolean popupToast = !oldNextAlarmTime.equals(newNextAlarmTime); 145 mAlarmUpdateHandler.asyncUpdateAlarm(alarm, popupToast, false); 146 } 147 onDeleteClicked(AlarmItemHolder itemHolder)148 public void onDeleteClicked(AlarmItemHolder itemHolder) { 149 if (mFragment instanceof AlarmClockFragment) { 150 ((AlarmClockFragment) mFragment).removeItem(itemHolder); 151 } 152 final Alarm alarm = itemHolder.item; 153 Events.sendAlarmEvent(R.string.action_delete, R.string.label_deskclock); 154 mAlarmUpdateHandler.asyncDeleteAlarm(alarm); 155 LOGGER.d("Deleting alarm."); 156 } 157 onClockClicked(Alarm alarm)158 public void onClockClicked(Alarm alarm) { 159 mSelectedAlarm = alarm; 160 Events.sendAlarmEvent(R.string.action_set_time, R.string.label_deskclock); 161 TimePickerDialogFragment.show(mFragment, alarm.hour, alarm.minutes); 162 } 163 dismissAlarmInstance(AlarmInstance alarmInstance)164 public void dismissAlarmInstance(AlarmInstance alarmInstance) { 165 final Intent dismissIntent = AlarmStateManager.createStateChangeIntent( 166 mContext, AlarmStateManager.ALARM_DISMISS_TAG, alarmInstance, 167 AlarmInstance.PREDISMISSED_STATE); 168 mContext.startService(dismissIntent); 169 mAlarmUpdateHandler.showPredismissToast(alarmInstance); 170 } 171 onRingtoneClicked(Context context, Alarm alarm)172 public void onRingtoneClicked(Context context, Alarm alarm) { 173 mSelectedAlarm = alarm; 174 Events.sendAlarmEvent(R.string.action_set_ringtone, R.string.label_deskclock); 175 176 final Intent intent = 177 RingtonePickerActivity.createAlarmRingtonePickerIntent(context, alarm); 178 context.startActivity(intent); 179 } 180 onEditLabelClicked(Alarm alarm)181 public void onEditLabelClicked(Alarm alarm) { 182 Events.sendAlarmEvent(R.string.action_set_label, R.string.label_deskclock); 183 final LabelDialogFragment fragment = 184 LabelDialogFragment.newInstance(alarm, alarm.label, mFragment.getTag()); 185 LabelDialogFragment.show(mFragment.getFragmentManager(), fragment); 186 } 187 onTimeSet(int hourOfDay, int minute)188 public void onTimeSet(int hourOfDay, int minute) { 189 if (mSelectedAlarm == null) { 190 // If mSelectedAlarm is null then we're creating a new alarm. 191 final Alarm a = new Alarm(); 192 a.hour = hourOfDay; 193 a.minutes = minute; 194 a.enabled = true; 195 mAlarmUpdateHandler.asyncAddAlarm(a); 196 } else { 197 mSelectedAlarm.hour = hourOfDay; 198 mSelectedAlarm.minutes = minute; 199 mSelectedAlarm.enabled = true; 200 mScrollHandler.setSmoothScrollStableId(mSelectedAlarm.id); 201 mAlarmUpdateHandler.asyncUpdateAlarm(mSelectedAlarm, true, false); 202 mSelectedAlarm = null; 203 } 204 } 205 }