124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux/* 224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * Copyright (C) 2015 The Android Open Source Project 324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * 424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * Licensed under the Apache License, Version 2.0 (the "License"); 524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * you may not use this file except in compliance with the License. 624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * You may obtain a copy of the License at 724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * 824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * http://www.apache.org/licenses/LICENSE-2.0 924a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * 1024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * Unless required by applicable law or agreed to in writing, software 1124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * distributed under the License is distributed on an "AS IS" BASIS, 1224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * See the License for the specific language governing permissions and 1424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * limitations under the License. 1524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux */ 1624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 17287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinpackage com.android.deskclock.stopwatch; 18287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 19287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.app.Service; 20287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.content.Intent; 21287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.os.IBinder; 22287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 23ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassenimport com.android.deskclock.DeskClock; 24287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport com.android.deskclock.R; 2524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieuximport com.android.deskclock.data.DataModel; 2624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieuximport com.android.deskclock.events.Events; 27ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassenimport com.android.deskclock.uidata.UiDataModel; 28ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen 29ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassenimport static com.android.deskclock.uidata.UiDataModel.Tab.STOPWATCH; 30287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 31287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein/** 32437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux * This service exists solely to allow the stopwatch notification to alter the state of the 3324a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * stopwatch without disturbing the notification shade. If an activity were used instead (even one 3424a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux * that is not displayed) the notification manager implicitly closes the notification shade which 356d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux * clashes with the use case of starting/pausing/lapping/resetting the stopwatch without 36437da3b08ce9ce1b32f4e544816cb3431ceb8d4eJames Lemieux * disturbing the notification shade. 37287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein */ 3824a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieuxpublic final class StopwatchService extends Service { 39287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 40ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen private static final String ACTION_PREFIX = "com.android.deskclock.action."; 41ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen 42ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen // shows the tab with the stopwatch 43ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen public static final String ACTION_SHOW_STOPWATCH = ACTION_PREFIX + "SHOW_STOPWATCH"; 44ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen // starts the current stopwatch 45ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen public static final String ACTION_START_STOPWATCH = ACTION_PREFIX + "START_STOPWATCH"; 46ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen // pauses the current stopwatch that's currently running 47ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen public static final String ACTION_PAUSE_STOPWATCH = ACTION_PREFIX + "PAUSE_STOPWATCH"; 48ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen // laps the stopwatch that's currently running 49ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen public static final String ACTION_LAP_STOPWATCH = ACTION_PREFIX + "LAP_STOPWATCH"; 50ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen // resets the stopwatch if it's stopped 51ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen public static final String ACTION_RESET_STOPWATCH = ACTION_PREFIX + "RESET_STOPWATCH"; 52ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen 53287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein @Override 54287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein public IBinder onBind(Intent intent) { 55287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein return null; 56287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 57287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 58287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein @Override 59287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein public int onStartCommand(Intent intent, int flags, int startId) { 60ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen final String action = intent.getAction(); 61ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen final int label = intent.getIntExtra(Events.EXTRA_EVENT_LABEL, R.string.label_intent); 62ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen switch (action) { 63ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen case ACTION_SHOW_STOPWATCH: { 64ba27a4ded731598feb18a49818110815c1998114Justin Klaassen Events.sendStopwatchEvent(R.string.action_show, label); 65ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen 66ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen // Open DeskClock positioned on the stopwatch tab. 67ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen UiDataModel.getUiDataModel().setSelectedTab(STOPWATCH); 68fe4f416602026b464c94268a90b62677d5de2582Sean Stout final Intent showStopwatch = new Intent(this, DeskClock.class) 69fe4f416602026b464c94268a90b62677d5de2582Sean Stout .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 70fe4f416602026b464c94268a90b62677d5de2582Sean Stout startActivity(showStopwatch); 71ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen break; 72ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen } 73ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen case ACTION_START_STOPWATCH: { 74ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen Events.sendStopwatchEvent(R.string.action_start, label); 7524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux DataModel.getDataModel().startStopwatch(); 765f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova break; 7724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 78ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen case ACTION_PAUSE_STOPWATCH: { 79ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen Events.sendStopwatchEvent(R.string.action_pause, label); 8024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux DataModel.getDataModel().pauseStopwatch(); 815f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova break; 8224a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 83ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen case ACTION_RESET_STOPWATCH: { 84ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen Events.sendStopwatchEvent(R.string.action_reset, label); 8524a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux DataModel.getDataModel().resetStopwatch(); 865f594531901d5f562c0c6a8e1d4ffd2e57709764Daria Evdokimova break; 874eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein } 88ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen case ACTION_LAP_STOPWATCH: { 89ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen Events.sendStopwatchEvent(R.string.action_lap, label); 909042b0b548db623f7f465767008a27d305299aa9James Lemieux DataModel.getDataModel().addLap(); 919042b0b548db623f7f465767008a27d305299aa9James Lemieux break; 929042b0b548db623f7f465767008a27d305299aa9James Lemieux } 93287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 94287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein 959042b0b548db623f7f465767008a27d305299aa9James Lemieux return START_NOT_STICKY; 96287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein } 97ab6a8e1f3e21977b0fddfa03ee0ba942830dc00aJustin Klaassen} 98