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