15f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova/* 25f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova * Copyright (C) 2015 The Android Open Source Project 35f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova * 45f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova * Licensed under the Apache License, Version 2.0 (the "License"); 55f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova * you may not use this file except in compliance with the License. 65f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova * You may obtain a copy of the License at 75f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova * 85f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova * http://www.apache.org/licenses/LICENSE-2.0 95f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova * 105f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova * Unless required by applicable law or agreed to in writing, software 115f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova * distributed under the License is distributed on an "AS IS" BASIS, 125f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova * See the License for the specific language governing permissions and 145f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova * limitations under the License. 155f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova */ 165f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 17972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimovapackage com.android.deskclock; 185f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 195f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimovaimport android.app.Activity; 205f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimovaimport android.content.Context; 215f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimovaimport android.content.Intent; 225f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimovaimport android.os.Bundle; 23972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova 2434142b1d0f2445bbd606bb490dfef6c078c630eaJames Lemieuximport com.android.deskclock.data.City; 2534142b1d0f2445bbd606bb490dfef6c078c630eaJames Lemieuximport com.android.deskclock.data.DataModel; 266d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieuximport com.android.deskclock.data.Timer; 275f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimovaimport com.android.deskclock.events.Events; 2834142b1d0f2445bbd606bb490dfef6c078c630eaJames Lemieuximport com.android.deskclock.worldclock.CitySelectionActivity; 295f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 305f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimovaimport java.util.List; 3137fb8c747190e0657fbde31ff1d920f3eca42432Daria Evdokimovaimport java.util.Set; 325f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 33972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimovapublic class HandleDeskClockApiCalls extends Activity { 3449b6cba9468fe3ccc91ec0efad26810085a8cae7Daria Evdokimova private Context mAppContext; 3549b6cba9468fe3ccc91ec0efad26810085a8cae7Daria Evdokimova 365f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova private static final String ACTION_PREFIX = "com.android.deskclock.action."; 375f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 385f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova // shows the tab with world clocks 39972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova public static final String ACTION_SHOW_CLOCK = ACTION_PREFIX + "SHOW_CLOCK"; 4034142b1d0f2445bbd606bb490dfef6c078c630eaJames Lemieux // extra for ACTION_SHOW_CLOCK indicating the clock is being displayed from tapping the widget 4134142b1d0f2445bbd606bb490dfef6c078c630eaJames Lemieux public static final String EXTRA_FROM_WIDGET = "com.android.deskclock.extra.clock.FROM_WIDGET"; 425f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova // add a clock of a selected city, if no city is specified opens the city selection screen 43972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova public static final String ACTION_ADD_CLOCK = ACTION_PREFIX + "ADD_CLOCK"; 4449b6cba9468fe3ccc91ec0efad26810085a8cae7Daria Evdokimova // delete a clock of a selected city, if no city is specified shows CitiesActivity for the user 4549b6cba9468fe3ccc91ec0efad26810085a8cae7Daria Evdokimova // to choose a city 46972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova public static final String ACTION_DELETE_CLOCK = ACTION_PREFIX + "DELETE_CLOCK"; 47972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova // extra for ACTION_ADD_CLOCK and ACTION_DELETE_CLOCK 485f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova public static final String EXTRA_CITY = "com.android.deskclock.extra.clock.CITY"; 495f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 505f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova // shows the tab with the stopwatch 51972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova public static final String ACTION_SHOW_STOPWATCH = ACTION_PREFIX + "SHOW_STOPWATCH"; 525f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova // starts the current stopwatch 53972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova public static final String ACTION_START_STOPWATCH = ACTION_PREFIX + "START_STOPWATCH"; 5424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux // pauses the current stopwatch that's currently running 5524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux public static final String ACTION_PAUSE_STOPWATCH = ACTION_PREFIX + "PAUSE_STOPWATCH"; 565f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova // laps the stopwatch that's currently running 57972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova public static final String ACTION_LAP_STOPWATCH = ACTION_PREFIX + "LAP_STOPWATCH"; 585f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova // resets the stopwatch if it's stopped 59972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova public static final String ACTION_RESET_STOPWATCH = ACTION_PREFIX + "RESET_STOPWATCH"; 605f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 616d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux // shows the tab with timers; optionally scrolls to a specific timer 62972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova public static final String ACTION_SHOW_TIMERS = ACTION_PREFIX + "SHOW_TIMERS"; 6306a5775de256f1238909789406ae7bec593b5b42James Lemieux // pauses running timers; resets expired timers 646d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux public static final String ACTION_PAUSE_TIMER = ACTION_PREFIX + "PAUSE_TIMER"; 6506a5775de256f1238909789406ae7bec593b5b42James Lemieux // starts the sole timer 66972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova public static final String ACTION_START_TIMER = ACTION_PREFIX + "START_TIMER"; 6706a5775de256f1238909789406ae7bec593b5b42James Lemieux // resets the timer 68972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova public static final String ACTION_RESET_TIMER = ACTION_PREFIX + "RESET_TIMER"; 6906a5775de256f1238909789406ae7bec593b5b42James Lemieux // adds an extra minute to the timer 706d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux public static final String ACTION_ADD_MINUTE_TIMER = ACTION_PREFIX + "ADD_MINUTE_TIMER"; 716d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux 726d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux // extra for many actions specific to a given timer 736d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux public static final String EXTRA_TIMER_ID = 746d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux "com.android.deskclock.extra.TIMER_ID"; 755f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 76437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux // Describes the entity responsible for the action being performed. 77437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux public static final String EXTRA_EVENT_LABEL = "com.android.deskclock.extra.EVENT_LABEL"; 7824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 795f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova @Override 805f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova protected void onCreate(Bundle icicle) { 8173b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova try { 8273b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova super.onCreate(icicle); 8349b6cba9468fe3ccc91ec0efad26810085a8cae7Daria Evdokimova mAppContext = getApplicationContext(); 845f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 8573b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova final Intent intent = getIntent(); 8673b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova if (intent == null) { 8773b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova return; 8873b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova } 8973b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova 9073b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova final String action = intent.getAction(); 9124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux LogUtils.i("HandleDeskClockApiCalls " + action); 9224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 9373b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova switch (action) { 94972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova case ACTION_START_STOPWATCH: 9524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux case ACTION_PAUSE_STOPWATCH: 96972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova case ACTION_LAP_STOPWATCH: 97972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova case ACTION_SHOW_STOPWATCH: 98972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova case ACTION_RESET_STOPWATCH: 9924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux handleStopwatchIntent(intent); 10073b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova break; 101972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova case ACTION_SHOW_TIMERS: 102972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova case ACTION_RESET_TIMER: 1036d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux case ACTION_PAUSE_TIMER: 104972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova case ACTION_START_TIMER: 1056d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux handleTimerIntent(intent); 10673b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova break; 107972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova case ACTION_SHOW_CLOCK: 108972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova case ACTION_ADD_CLOCK: 109972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova case ACTION_DELETE_CLOCK: 11024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux handleClockIntent(intent); 11173b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova break; 11273b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova } 11373b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova } finally { 11473b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova finish(); 1155f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova } 1165f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova } 1175f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 11824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux private void handleStopwatchIntent(Intent intent) { 11924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux final String action = intent.getAction(); 1205f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 12124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux // Determine where this intent originated. 122437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux final int eventLabel = intent.getIntExtra(EXTRA_EVENT_LABEL, R.string.label_intent); 12395d226e9785c7608923f05be54211fe0d415a3f6Daria Evdokimova 12424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux if (ACTION_SHOW_STOPWATCH.equals(action)) { 125437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux Events.sendStopwatchEvent(R.string.action_show, eventLabel); 12624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } else { 12724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux final String reason; 12824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux boolean fail = false; 12924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux switch (action) { 13024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux case ACTION_START_STOPWATCH: { 131437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux DataModel.getDataModel().startStopwatch(); 132437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux Events.sendStopwatchEvent(R.string.action_start, eventLabel); 1336d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux reason = getString(R.string.stopwatch_started); 13424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux break; 13524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 13624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux case ACTION_PAUSE_STOPWATCH: { 137437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux DataModel.getDataModel().pauseStopwatch(); 138437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux Events.sendStopwatchEvent(R.string.action_pause, eventLabel); 1396d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux reason = getString(R.string.stopwatch_paused); 1406d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux break; 1416d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } 1426d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux case ACTION_RESET_STOPWATCH: { 143437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux DataModel.getDataModel().clearLaps(); 144437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux DataModel.getDataModel().resetStopwatch(); 145437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux Events.sendStopwatchEvent(R.string.action_reset, eventLabel); 1466d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux reason = getString(R.string.stopwatch_reset); 14724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux break; 14824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 14924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux case ACTION_LAP_STOPWATCH: { 150437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux if (!DataModel.getDataModel().getStopwatch().isRunning()) { 15124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux fail = true; 15224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux reason = getString(R.string.stopwatch_isnt_running); 15324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } else { 154437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux DataModel.getDataModel().addLap(); 155437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux Events.sendStopwatchEvent(R.string.action_lap, eventLabel); 15624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux reason = getString(R.string.stopwatch_lapped); 15724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 15824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux break; 15924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 16024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux default: 16124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux throw new IllegalArgumentException("unknown stopwatch action: " + action); 16273b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova } 16324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 16424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux if (fail) { 16597149ea89a5c0e057f25b89b87eef6224b82a777Daria Evdokimova Voice.notifyFailure(this, reason); 16624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } else { 16724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux Voice.notifySuccess(this, reason); 16873b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova } 16924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux LogUtils.i(reason); 17049b6cba9468fe3ccc91ec0efad26810085a8cae7Daria Evdokimova } 17173b6275353eaf0e2b29b10113e3ef85dc9de686bDaria Evdokimova 17224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux // Open the UI to the stopwatch. 17324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux final Intent stopwatchIntent = new Intent(mAppContext, DeskClock.class) 17424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux .putExtra(DeskClock.SELECT_TAB_INTENT_EXTRA, DeskClock.STOPWATCH_TAB_INDEX); 17524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux startActivity(stopwatchIntent); 1765f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova } 1775f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 1786d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux private void handleTimerIntent(Intent intent) { 1796d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux final String action = intent.getAction(); 1806d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux 1816d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux // Determine where this intent originated. 182437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux final int eventLabel = intent.getIntExtra(EXTRA_EVENT_LABEL, R.string.label_intent); 183437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux int timerId = intent.getIntExtra(EXTRA_TIMER_ID, -1); 1846d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux Timer timer = null; 1855f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 186972fca903a5272631c2cfbe5f111adc8edeace51Daria Evdokimova if (ACTION_SHOW_TIMERS.equals(action)) { 187437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux Events.sendTimerEvent(R.string.action_show, eventLabel); 1886d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } else { 1896d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux String reason = null; 1906d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux if (timerId == -1) { 1916d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux // No timer id was given explicitly, so check if only one timer exists. 1926d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux final List<Timer> timers = DataModel.getDataModel().getTimers(); 1936d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux if (timers.isEmpty()) { 1946d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux // No timers exist to control. 1956d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux reason = getString(R.string.no_timers_exist); 1966d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } else if (timers.size() > 1) { 1976d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux // Many timers exist so the control command is ambiguous. 1986d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux reason = getString(R.string.too_many_timers_exist); 1996d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } else { 2006d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux timer = timers.get(0); 2016d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } 2026d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } else { 2036d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux // Verify that the given timer does exist. 2046d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux timer = DataModel.getDataModel().getTimer(timerId); 2056d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux if (timer == null) { 2066d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux reason = getString(R.string.timer_does_not_exist); 2076d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } 2086d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } 2096d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux 2106d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux if (timer == null) { 2116d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux Voice.notifyFailure(this, reason); 2126d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } else { 213692ccc4aaf2d6f605ac59235b7774b656847ab07James Lemieux timerId = timer.getId(); 214692ccc4aaf2d6f605ac59235b7774b656847ab07James Lemieux 2156d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux // Otherwise the control command can be honored. 2166d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux switch (action) { 2176d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux case ACTION_RESET_TIMER: { 218437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux DataModel.getDataModel().resetOrDeleteTimer(timer, eventLabel); 219437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux if (timer.isExpired() && timer.getDeleteAfterUse()) { 220692ccc4aaf2d6f605ac59235b7774b656847ab07James Lemieux timerId = -1; 2216d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux reason = getString(R.string.timer_deleted); 2226d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } else { 2236d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux reason = getString(R.string.timer_was_reset); 2246d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } 2256d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux break; 2266d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } 2276d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux case ACTION_START_TIMER: { 228437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux DataModel.getDataModel().startTimer(timer); 229437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux Events.sendTimerEvent(R.string.action_start, eventLabel); 2306d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux reason = getString(R.string.timer_started); 2316d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux break; 2326d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } 2336d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux case ACTION_PAUSE_TIMER: { 234437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux DataModel.getDataModel().pauseTimer(timer); 235437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux Events.sendTimerEvent(R.string.action_pause, eventLabel); 2366d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux reason = getString(R.string.timer_paused); 2376d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux break; 2386d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } 2396d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux default: 2406d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux throw new IllegalArgumentException("unknown timer action: " + action); 2416d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } 2426d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux 2436d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux Voice.notifySuccess(this, reason); 2446d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux } 2456d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux 2466d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux LogUtils.i(reason); 2475f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova } 2486d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux 2496d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux // Open the UI to the timers. 250692ccc4aaf2d6f605ac59235b7774b656847ab07James Lemieux final Intent showTimers = new Intent(mAppContext, DeskClock.class) 251692ccc4aaf2d6f605ac59235b7774b656847ab07James Lemieux .putExtra(DeskClock.SELECT_TAB_INTENT_EXTRA, DeskClock.TIMER_TAB_INDEX); 252692ccc4aaf2d6f605ac59235b7774b656847ab07James Lemieux if (timerId != -1) { 253692ccc4aaf2d6f605ac59235b7774b656847ab07James Lemieux showTimers.putExtra(EXTRA_TIMER_ID, timerId); 254692ccc4aaf2d6f605ac59235b7774b656847ab07James Lemieux } 255692ccc4aaf2d6f605ac59235b7774b656847ab07James Lemieux startActivity(showTimers); 25649b6cba9468fe3ccc91ec0efad26810085a8cae7Daria Evdokimova } 2575f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova 25824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux private void handleClockIntent(Intent intent) { 25924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux final String action = intent.getAction(); 26024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 26124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux if (ACTION_SHOW_CLOCK.equals(action)) { 26224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux final boolean fromWidget = intent.getBooleanExtra(EXTRA_FROM_WIDGET, false); 26324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux final int label = fromWidget ? R.string.label_widget : R.string.label_intent; 26424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux Events.sendClockEvent(R.string.action_show, label); 26524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } else { 26624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux final String cityName = intent.getStringExtra(EXTRA_CITY); 26724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 26824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux final String reason; 26924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux boolean fail = false; 27024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 27124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux // If no city was given, start the city chooser. 27224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux if (cityName == null) { 27324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux reason = getString(R.string.no_city_selected); 27424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux LogUtils.i(reason); 27524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux Voice.notifySuccess(this, reason); 27624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux startActivity(new Intent(this, CitySelectionActivity.class) 27724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 27824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux switch (action) { 27924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux case ACTION_ADD_CLOCK: 28024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux Events.sendClockEvent(R.string.action_add, R.string.label_intent); 28124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux break; 28224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux case ACTION_DELETE_CLOCK: 28324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux Events.sendClockEvent(R.string.action_delete, R.string.label_intent); 28424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux break; 28524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 28624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux return; 28724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 28824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 28924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux // If a city was given, ensure it can be located. 29024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux final City city = DataModel.getDataModel().getCity(cityName); 29124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux if (city == null) { 29224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux reason = getString(R.string.the_city_you_specified_is_not_available); 29324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux LogUtils.i(reason); 29424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux Voice.notifyFailure(this, reason); 29524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux switch (action) { 29624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux case ACTION_ADD_CLOCK: 29724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux Events.sendClockEvent(R.string.action_add, R.string.label_intent); 29824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux break; 29924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux case ACTION_DELETE_CLOCK: 30024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux Events.sendClockEvent(R.string.action_delete, R.string.label_intent); 30124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux break; 30224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 30324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux return; 30424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 30524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 30624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux final Set<City> selectedCities = 30724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux Utils.newArraySet(DataModel.getDataModel().getSelectedCities()); 30824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 30924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux switch (action) { 31024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux case ACTION_ADD_CLOCK: { 31124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux // Fail if the city is already present. 31224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux if (!selectedCities.add(city)) { 31324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux fail = true; 31424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux reason = getString(R.string.the_city_already_added); 31524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux break; 31624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 31724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 31824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux // Otherwise report the success. 31924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux DataModel.getDataModel().setSelectedCities(selectedCities); 32024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux reason = getString(R.string.city_added, city.getName()); 32124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux Events.sendClockEvent(R.string.action_add, R.string.label_intent); 32224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux break; 32324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 32424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux case ACTION_DELETE_CLOCK: { 32524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux // Fail if the city is not present. 32624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux if (!selectedCities.remove(city)) { 32724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux fail = true; 32824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux reason = getString(R.string.the_city_you_specified_is_not_available); 32924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux break; 33024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 33124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 33224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux // Otherwise report the success. 33324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux DataModel.getDataModel().setSelectedCities(selectedCities); 33424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux reason = getString(R.string.city_deleted, city.getName()); 33524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux Events.sendClockEvent(R.string.action_delete, R.string.label_intent); 33624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux break; 33724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 33824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux default: 33924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux throw new IllegalArgumentException("unknown clock action: " + action); 34024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 34124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 34224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux if (fail) { 34324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux Voice.notifyFailure(this, reason); 34424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } else { 34524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux Voice.notifySuccess(this, reason); 34624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 34724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux LogUtils.i(reason); 34824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 34924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 35049b6cba9468fe3ccc91ec0efad26810085a8cae7Daria Evdokimova // Opens the UI for clocks 35124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux final Intent clockIntent = new Intent(mAppContext, DeskClock.class) 35249b6cba9468fe3ccc91ec0efad26810085a8cae7Daria Evdokimova .setAction(action) 35349b6cba9468fe3ccc91ec0efad26810085a8cae7Daria Evdokimova .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 35449b6cba9468fe3ccc91ec0efad26810085a8cae7Daria Evdokimova .putExtra(DeskClock.SELECT_TAB_INTENT_EXTRA, DeskClock.CLOCK_TAB_INDEX); 35524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux startActivity(clockIntent); 35649b6cba9468fe3ccc91ec0efad26810085a8cae7Daria Evdokimova } 3576d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux}