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.app.FragmentTransaction; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.media.RingtoneManager; 24 import android.net.Uri; 25 import android.os.Bundle; 26 import android.os.Vibrator; 27 import android.text.format.DateFormat; 28 29 import com.android.deskclock.LabelDialogFragment; 30 import com.android.deskclock.LogUtils; 31 import com.android.deskclock.R; 32 import com.android.deskclock.alarms.utils.DayOrderUtils; 33 import com.android.deskclock.provider.Alarm; 34 import com.android.deskclock.provider.AlarmInstance; 35 36 import java.util.Calendar; 37 38 /** 39 * Click handler for an alarm time item. 40 */ 41 public final class AlarmTimeClickHandler { 42 43 private static final String TAG = "AlarmTimeClickHandler"; 44 private static final String KEY_PREVIOUS_DAY_MAP = "previousDayMap"; 45 46 private final Fragment mFragment; 47 private final AlarmUpdateHandler mAlarmUpdateHandler; 48 private final ScrollHandler mScrollHandler; 49 50 private Alarm mSelectedAlarm; 51 private Bundle mPreviousDaysOfWeekMap; 52 private int[] mDayOrder; 53 AlarmTimeClickHandler(Fragment fragment, Bundle savedState, AlarmUpdateHandler alarmUpdateHandler, ScrollHandler smoothScrollController)54 public AlarmTimeClickHandler(Fragment fragment, Bundle savedState, 55 AlarmUpdateHandler alarmUpdateHandler, ScrollHandler smoothScrollController) { 56 mFragment = fragment; 57 mAlarmUpdateHandler = alarmUpdateHandler; 58 mScrollHandler = smoothScrollController; 59 if (savedState != null) { 60 mPreviousDaysOfWeekMap = savedState.getBundle(KEY_PREVIOUS_DAY_MAP); 61 } 62 if (mPreviousDaysOfWeekMap == null) { 63 mPreviousDaysOfWeekMap = new Bundle(); 64 } 65 mDayOrder = DayOrderUtils.getDayOrder(fragment.getActivity()); 66 } 67 getSelectedAlarm()68 public Alarm getSelectedAlarm() { 69 return mSelectedAlarm; 70 } 71 clearSelectedAlarm()72 public void clearSelectedAlarm() { 73 mSelectedAlarm = null; 74 } 75 saveInstance(Bundle outState)76 public void saveInstance(Bundle outState) { 77 outState.putBundle(KEY_PREVIOUS_DAY_MAP, mPreviousDaysOfWeekMap); 78 } 79 setAlarmEnabled(Alarm alarm, boolean newState)80 public void setAlarmEnabled(Alarm alarm, boolean newState) { 81 if (newState != alarm.enabled) { 82 alarm.enabled = newState; 83 mAlarmUpdateHandler.asyncUpdateAlarm(alarm, alarm.enabled, false); 84 LogUtils.d(TAG, "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 mAlarmUpdateHandler.asyncUpdateAlarm(alarm, false, true); 92 LogUtils.d(TAG, "Updating vibrate state to " + newState); 93 94 if (newState) { 95 // Buzz the vibrator to preview the alarm firing behavior. 96 final Context context = mFragment.getActivity(); 97 final Vibrator v = (Vibrator) context.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.setBitSet(bitSet); 115 if (!alarm.daysOfWeek.isRepeating()) { 116 alarm.daysOfWeek.setDaysOfWeek(true, mDayOrder); 117 } 118 } else { 119 // Remember the set days in case the user wants it back. 120 final int bitSet = alarm.daysOfWeek.getBitSet(); 121 mPreviousDaysOfWeekMap.putInt(alarmId, bitSet); 122 123 // Remove all repeat days 124 alarm.daysOfWeek.clearAllDays(); 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 mAlarmUpdateHandler.asyncUpdateAlarm(alarm, popupToast, false); 132 } 133 setDayOfWeekEnabled(Alarm alarm, boolean checked, int index)134 public void setDayOfWeekEnabled(Alarm alarm, boolean checked, int index) { 135 final Calendar now = Calendar.getInstance(); 136 final Calendar oldNextAlarmTime = alarm.getNextAlarmTime(now); 137 alarm.daysOfWeek.setDaysOfWeek(checked, mDayOrder[index]); 138 // if the change altered the next scheduled alarm time, tell the user 139 final Calendar newNextAlarmTime = alarm.getNextAlarmTime(now); 140 final boolean popupToast = !oldNextAlarmTime.equals(newNextAlarmTime); 141 mAlarmUpdateHandler.asyncUpdateAlarm(alarm, popupToast, false); 142 } 143 onDeleteClicked(Alarm alarm)144 public void onDeleteClicked(Alarm alarm) { 145 mAlarmUpdateHandler.asyncDeleteAlarm(alarm); 146 LogUtils.d(TAG, "Deleting alarm."); 147 } 148 onClockClicked(Alarm alarm)149 public void onClockClicked(Alarm alarm) { 150 mSelectedAlarm = alarm; 151 TimePickerCompat.showTimeEditDialog(mFragment, alarm, 152 DateFormat.is24HourFormat(mFragment.getActivity())); 153 } 154 dismissAlarmInstance(AlarmInstance alarmInstance)155 public void dismissAlarmInstance(AlarmInstance alarmInstance) { 156 final Context context = mFragment.getActivity().getApplicationContext(); 157 final Intent dismissIntent = AlarmStateManager.createStateChangeIntent( 158 context, AlarmStateManager.ALARM_DISMISS_TAG, alarmInstance, 159 AlarmInstance.PREDISMISSED_STATE); 160 context.startService(dismissIntent); 161 mAlarmUpdateHandler.showPredismissToast(alarmInstance); 162 } 163 onRingtoneClicked(Alarm alarm)164 public void onRingtoneClicked(Alarm alarm) { 165 mSelectedAlarm = alarm; 166 final Uri oldRingtone = Alarm.NO_RINGTONE_URI.equals(alarm.alert) ? null : alarm.alert; 167 final Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); 168 intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, oldRingtone); 169 intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_ALARM); 170 intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false); 171 LogUtils.d(TAG, "Showing ringtone picker."); 172 mFragment.startActivityForResult(intent, R.id.request_code_ringtone); 173 } 174 onEditLabelClicked(Alarm alarm)175 public void onEditLabelClicked(Alarm alarm) { 176 final FragmentTransaction ft = mFragment.getFragmentManager().beginTransaction(); 177 final Fragment prev = mFragment.getFragmentManager().findFragmentByTag("label_dialog"); 178 if (prev != null) { 179 ft.remove(prev); 180 } 181 ft.addToBackStack(null); 182 183 // Create and show the dialog. 184 final LabelDialogFragment newFragment = 185 LabelDialogFragment.newInstance(alarm, alarm.label, mFragment.getTag()); 186 newFragment.show(ft, "label_dialog"); 187 } 188 processTimeSet(int hourOfDay, int minute)189 public void processTimeSet(int hourOfDay, int minute) { 190 if (mSelectedAlarm == null) { 191 // If mSelectedAlarm is null then we're creating a new alarm. 192 final Alarm a = new Alarm(); 193 a.hour = hourOfDay; 194 a.minutes = minute; 195 a.enabled = true; 196 mAlarmUpdateHandler.asyncAddAlarm(a); 197 } else { 198 mSelectedAlarm.hour = hourOfDay; 199 mSelectedAlarm.minutes = minute; 200 mSelectedAlarm.enabled = true; 201 mScrollHandler.setSmoothScrollStableId(mSelectedAlarm.id); 202 mAlarmUpdateHandler.asyncUpdateAlarm(mSelectedAlarm, true, false); 203 mSelectedAlarm = null; 204 } 205 } 206 } 207