1287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
2287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinpackage com.android.deskclock.stopwatch;
3287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
4287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.app.Notification;
5287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.app.NotificationManager;
6287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.app.PendingIntent;
7287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.app.Service;
8287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.content.Context;
9287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.content.Intent;
10287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.content.SharedPreferences;
11287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.os.IBinder;
12287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.preference.PreferenceManager;
13287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.view.View;
14287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport android.widget.RemoteViews;
15287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
16287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport com.android.deskclock.CircleTimerView;
17287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport com.android.deskclock.DeskClock;
18287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport com.android.deskclock.R;
19287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinimport com.android.deskclock.Utils;
20287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
21287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein/**
22287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein * TODO: Insert description here. (generated by sblitz)
23287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein */
24287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzsteinpublic class StopwatchService extends Service {
25287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    // Member fields
26287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private int mNumLaps;
27287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private long mElapsedTime;
28287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private long mStartTime;
29287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private boolean mLoadApp;
30287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private NotificationManager mNotificationManager;
31287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
32287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    // Constants for intent information
3358c329f52d7952597ae7a4e88fc2ec9e15ddd93aRobyn Coultas    // Make this a large number to avoid the alarm ID's which seem to be 1, 2, ...
3458c329f52d7952597ae7a4e88fc2ec9e15ddd93aRobyn Coultas    // Must also be different than TimerReceiver.IN_USE_NOTIFICATION_ID
3558c329f52d7952597ae7a4e88fc2ec9e15ddd93aRobyn Coultas    private static final int NOTIFICATION_ID = Integer.MAX_VALUE - 1;
36287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
37287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    @Override
38287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    public IBinder onBind(Intent intent) {
39287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        return null;
40287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
41287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
42287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    @Override
43287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    public void onCreate() {
44287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        mNumLaps = 0;
45287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        mElapsedTime = 0;
46287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        mStartTime = 0;
47287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        mLoadApp = false;
48287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
49287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
50287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
51287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    @Override
52287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    public int onStartCommand(Intent intent, int flags, int startId) {
53287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (intent == null) {
54287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            return Service.START_NOT_STICKY;
55287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
56287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
57287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (mStartTime == 0 || mElapsedTime == 0 || mNumLaps == 0) {
58287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            // May not have the most recent values.
59287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            readFromSharedPrefs();
60287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
61287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
62287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        String actionType = intent.getAction();
63287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        long actionTime = intent.getLongExtra(Stopwatches.MESSAGE_TIME, Utils.getTimeNow());
64287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        boolean showNotif = intent.getBooleanExtra(Stopwatches.SHOW_NOTIF, true);
65287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        boolean updateCircle = showNotif; // Don't save updates to the cirle if we're in the app.
66287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (actionType.equals(Stopwatches.START_STOPWATCH)) {
67287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            mStartTime = actionTime;
68287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            writeSharedPrefsStarted(mStartTime, updateCircle);
69287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            if (showNotif) {
70287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                setNotification(mStartTime - mElapsedTime, true, mNumLaps);
71287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            } else {
72287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                saveNotification(mStartTime - mElapsedTime, true, mNumLaps);
73287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            }
74287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        } else if (actionType.equals(Stopwatches.LAP_STOPWATCH)) {
75287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            mNumLaps++;
76287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            long lapTimeElapsed = actionTime - mStartTime + mElapsedTime;
77287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            writeSharedPrefsLap(lapTimeElapsed, updateCircle);
78287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            if (showNotif) {
79287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                setNotification(mStartTime - mElapsedTime, true, mNumLaps);
80287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            } else {
81287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                saveNotification(mStartTime - mElapsedTime, true, mNumLaps);
82287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            }
83287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        } else if (actionType.equals(Stopwatches.STOP_STOPWATCH)) {
84287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            mElapsedTime = mElapsedTime + (actionTime - mStartTime);
85287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            writeSharedPrefsStopped(mElapsedTime, updateCircle);
86287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            if (showNotif) {
87287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                setNotification(actionTime - mElapsedTime, false, mNumLaps);
88287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            } else {
89287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                saveNotification(mElapsedTime, false, mNumLaps);
90287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            }
91287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        } else if (actionType.equals(Stopwatches.RESET_STOPWATCH)) {
924eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein            mLoadApp = false;
934eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein            writeSharedPrefsReset(updateCircle);
944eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein            clearSavedNotification();
954eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein            stopSelf();
964eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein        } else if (actionType.equals(Stopwatches.RESET_AND_LAUNCH_STOPWATCH)) {
974eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein            mLoadApp = true;
98287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            writeSharedPrefsReset(updateCircle);
99287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            clearSavedNotification();
100287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            closeNotificationShade();
101287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            stopSelf();
102287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        } else if (actionType.equals(Stopwatches.SHARE_STOPWATCH)) {
103287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            closeNotificationShade();
104287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
105287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            shareIntent.setType("text/plain");
106287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            shareIntent.putExtra(
107287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    Intent.EXTRA_SUBJECT, Stopwatches.getShareTitle(getApplicationContext()));
108287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            shareIntent.putExtra(Intent.EXTRA_TEXT, Stopwatches.buildShareResults(
109287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    getApplicationContext(), mElapsedTime, readLapsFromPrefs()));
110287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            Intent chooserIntent = Intent.createChooser(shareIntent, null);
111287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
112287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            getApplication().startActivity(chooserIntent);
113287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        } else if (actionType.equals(Stopwatches.SHOW_NOTIF)) {
11444f3415c62f7420c21605c9af14bf2dc4ca44573Robyn Coultas            // SHOW_NOTIF sent from the DeskClock.onPause
11544f3415c62f7420c21605c9af14bf2dc4ca44573Robyn Coultas            // If a notification is not displayed, this service's work is over
11644f3415c62f7420c21605c9af14bf2dc4ca44573Robyn Coultas            if (!showSavedNotification()) {
11744f3415c62f7420c21605c9af14bf2dc4ca44573Robyn Coultas                stopSelf();
11844f3415c62f7420c21605c9af14bf2dc4ca44573Robyn Coultas            }
119287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        } else if (actionType.equals(Stopwatches.KILL_NOTIF)) {
120287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            mNotificationManager.cancel(NOTIFICATION_ID);
121287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
122287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
123287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        // We want this service to continue running until it is explicitly
124287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        // stopped, so return sticky.
125287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        return START_STICKY;
126287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
127287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
128287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    @Override
129287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    public void onDestroy() {
130287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        mNotificationManager.cancel(NOTIFICATION_ID);
131287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        clearSavedNotification();
132287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        mNumLaps = 0;
133287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        mElapsedTime = 0;
134287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        mStartTime = 0;
135287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (mLoadApp) {
136287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            Intent activityIntent = new Intent(getApplicationContext(), DeskClock.class);
137287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
138287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            activityIntent.putExtra(
139287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    DeskClock.SELECT_TAB_INTENT_EXTRA, DeskClock.STOPWATCH_TAB_INDEX);
140287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            startActivity(activityIntent);
141287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            mLoadApp = false;
142287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
143287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
144287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
145287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private void setNotification(long clockBaseTime, boolean clockRunning, int numLaps) {
146287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        Context context = getApplicationContext();
147287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        // Intent to load the app for a non-button click.
148287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        Intent intent = new Intent(context, DeskClock.class);
149287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
150287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        intent.putExtra(DeskClock.SELECT_TAB_INTENT_EXTRA, DeskClock.STOPWATCH_TAB_INDEX);
1515b986600a3b458123555107f7845331fecafc0e7Isaac Katzenelson        // add category to distinguish between stopwatch intents and timer intents
1525b986600a3b458123555107f7845331fecafc0e7Isaac Katzenelson        intent.addCategory("stopwatch");
153287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,
154287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT);
155287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
156287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        // Set up remoteviews for the notification.
157287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        RemoteViews remoteViewsCollapsed = new RemoteViews(getPackageName(),
158287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                R.layout.stopwatch_notif_collapsed);
159287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        remoteViewsCollapsed.setOnClickPendingIntent(R.id.swn_collapsed_hitspace, pendingIntent);
160287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        remoteViewsCollapsed.setChronometer(
161287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                R.id.swn_collapsed_chronometer, clockBaseTime, null, clockRunning);
1629d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas        remoteViewsCollapsed.
1639d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas                setImageViewResource(R.id.notification_icon, R.drawable.stat_notify_stopwatch);
164287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        RemoteViews remoteViewsExpanded = new RemoteViews(getPackageName(),
165287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                R.layout.stopwatch_notif_expanded);
166287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        remoteViewsExpanded.setOnClickPendingIntent(R.id.swn_expanded_hitspace, pendingIntent);
167287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        remoteViewsExpanded.setChronometer(
168287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                R.id.swn_expanded_chronometer, clockBaseTime, null, clockRunning);
1699d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas        remoteViewsExpanded.
1709d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas                setImageViewResource(R.id.notification_icon, R.drawable.stat_notify_stopwatch);
171287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
172287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (clockRunning) {
173287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            // Left button: lap
174287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            remoteViewsExpanded.setTextViewText(
175287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    R.id.swn_left_button, getResources().getText(R.string.sw_lap_button));
176287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            Intent leftButtonIntent = new Intent(context, StopwatchService.class);
177287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            leftButtonIntent.setAction(Stopwatches.LAP_STOPWATCH);
178287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            remoteViewsExpanded.setOnClickPendingIntent(R.id.swn_left_button,
179287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    PendingIntent.getService(context, 0, leftButtonIntent, 0));
1809d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas            remoteViewsExpanded.
1819d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas                    setTextViewCompoundDrawablesRelative(R.id.swn_left_button,
1829d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas                            R.drawable.ic_notify_lap, 0, 0, 0);
183287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
184287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            // Right button: stop clock
185287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            remoteViewsExpanded.setTextViewText(
186287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    R.id.swn_right_button, getResources().getText(R.string.sw_stop_button));
187287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            Intent rightButtonIntent = new Intent(context, StopwatchService.class);
188287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            rightButtonIntent.setAction(Stopwatches.STOP_STOPWATCH);
189287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            remoteViewsExpanded.setOnClickPendingIntent(R.id.swn_right_button,
190287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    PendingIntent.getService(context, 0, rightButtonIntent, 0));
1919d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas            remoteViewsExpanded.
1929d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas                    setTextViewCompoundDrawablesRelative(R.id.swn_right_button,
1939d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas                            R.drawable.ic_notify_stop, 0, 0, 0);
1944eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein
1954eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein            // Show the laps if applicable.
1964eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein            if (numLaps > 0) {
1974eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                String lapText = String.format(
1984eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                        context.getString(R.string.sw_notification_lap_number), numLaps);
1994eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                remoteViewsCollapsed.setTextViewText(R.id.swn_collapsed_laps, lapText);
2004eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                remoteViewsCollapsed.setViewVisibility(R.id.swn_collapsed_laps, View.VISIBLE);
2014eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                remoteViewsExpanded.setTextViewText(R.id.swn_expanded_laps, lapText);
2024eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                remoteViewsExpanded.setViewVisibility(R.id.swn_expanded_laps, View.VISIBLE);
2034eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein            } else {
2044eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                remoteViewsCollapsed.setViewVisibility(R.id.swn_collapsed_laps, View.GONE);
2054eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                remoteViewsExpanded.setViewVisibility(R.id.swn_expanded_laps, View.GONE);
2064eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein            }
207287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        } else {
208287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            // Left button: reset clock
209287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            remoteViewsExpanded.setTextViewText(
210287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    R.id.swn_left_button, getResources().getText(R.string.sw_reset_button));
211287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            Intent leftButtonIntent = new Intent(context, StopwatchService.class);
2124eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein            leftButtonIntent.setAction(Stopwatches.RESET_AND_LAUNCH_STOPWATCH);
213287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            remoteViewsExpanded.setOnClickPendingIntent(R.id.swn_left_button,
214287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    PendingIntent.getService(context, 0, leftButtonIntent, 0));
2159d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas            remoteViewsExpanded.
2169d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas                    setTextViewCompoundDrawablesRelative(R.id.swn_left_button,
2179d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas                            R.drawable.ic_notify_reset, 0, 0, 0);
218287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
219287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            // Right button: start clock
220287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            remoteViewsExpanded.setTextViewText(
221287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    R.id.swn_right_button, getResources().getText(R.string.sw_start_button));
222287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            Intent rightButtonIntent = new Intent(context, StopwatchService.class);
223287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            rightButtonIntent.setAction(Stopwatches.START_STOPWATCH);
224287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            remoteViewsExpanded.setOnClickPendingIntent(R.id.swn_right_button,
225287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    PendingIntent.getService(context, 0, rightButtonIntent, 0));
2269d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas            remoteViewsExpanded.
2279d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas                    setTextViewCompoundDrawablesRelative(R.id.swn_right_button,
2289d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas                            R.drawable.ic_notify_start, 0, 0, 0);
229287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
2304eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein            // Show stopped string.
2319d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas            remoteViewsCollapsed.
2329d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas                    setTextViewText(R.id.swn_collapsed_laps, getString(R.string.swn_stopped));
2334eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein            remoteViewsCollapsed.setViewVisibility(R.id.swn_collapsed_laps, View.VISIBLE);
2349d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas            remoteViewsExpanded.
2359d815e84d50207f0846f2ef486e5c2d62ebdb0fdRobyn Coultas                    setTextViewText(R.id.swn_expanded_laps, getString(R.string.swn_stopped));
2364eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein            remoteViewsExpanded.setViewVisibility(R.id.swn_expanded_laps, View.VISIBLE);
237287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
238287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
2394eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein        Intent dismissIntent = new Intent(context, StopwatchService.class);
2404eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein        dismissIntent.setAction(Stopwatches.RESET_STOPWATCH);
2414eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein
242287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        Notification notification = new Notification.Builder(context)
2434eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                .setAutoCancel(!clockRunning)
2444eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                .setContent(remoteViewsCollapsed)
2454eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                .setOngoing(clockRunning)
2464eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                .setDeleteIntent(PendingIntent.getService(context, 0, dismissIntent, 0))
2474eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                .setSmallIcon(R.drawable.ic_tab_stopwatch_activated)
2484eee155f772c68e390716e6409fcb8414851d6cbSam Blitzstein                .setPriority(Notification.PRIORITY_MAX).build();
249287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        notification.bigContentView = remoteViewsExpanded;
250287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        mNotificationManager.notify(NOTIFICATION_ID, notification);
251287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
252287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
253287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    /** Save the notification to be shown when the app is closed. **/
254287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private void saveNotification(long clockTime, boolean clockRunning, int numLaps) {
255287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
256287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                getApplicationContext());
257287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        SharedPreferences.Editor editor = prefs.edit();
258287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (clockRunning) {
259287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putLong(Stopwatches.NOTIF_CLOCK_BASE, clockTime);
260287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putLong(Stopwatches.NOTIF_CLOCK_ELAPSED, -1);
261287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putBoolean(Stopwatches.NOTIF_CLOCK_RUNNING, true);
262287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        } else {
263287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putLong(Stopwatches.NOTIF_CLOCK_ELAPSED, clockTime);
264287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putLong(Stopwatches.NOTIF_CLOCK_BASE, -1);
265287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putBoolean(Stopwatches.NOTIF_CLOCK_RUNNING, false);
266287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
267287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        editor.putBoolean(Stopwatches.PREF_UPDATE_CIRCLE, false);
268287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        editor.apply();
269287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
270287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
271287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    /** Show the most recently saved notification. **/
27244f3415c62f7420c21605c9af14bf2dc4ca44573Robyn Coultas    private boolean showSavedNotification() {
273287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
274287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                getApplicationContext());
275287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        long clockBaseTime = prefs.getLong(Stopwatches.NOTIF_CLOCK_BASE, -1);
276287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        long clockElapsedTime = prefs.getLong(Stopwatches.NOTIF_CLOCK_ELAPSED, -1);
277287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        boolean clockRunning = prefs.getBoolean(Stopwatches.NOTIF_CLOCK_RUNNING, false);
278287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        int numLaps = prefs.getInt(Stopwatches.PREF_LAP_NUM, -1);
279287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (clockBaseTime == -1) {
280287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            if (clockElapsedTime == -1) {
28144f3415c62f7420c21605c9af14bf2dc4ca44573Robyn Coultas                return false;
282287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            } else {
283287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                // We don't have a clock base time, so the clock is stopped.
284287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                // Use the elapsed time to figure out what time to show.
285287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                mElapsedTime = clockElapsedTime;
286287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                clockBaseTime = Utils.getTimeNow() - clockElapsedTime;
287287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            }
288287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
289287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        setNotification(clockBaseTime, clockRunning, numLaps);
29044f3415c62f7420c21605c9af14bf2dc4ca44573Robyn Coultas        return true;
291287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
292287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
293287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private void clearSavedNotification() {
294287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
295287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                getApplicationContext());
296287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        SharedPreferences.Editor editor = prefs.edit();
297287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        editor.remove(Stopwatches.NOTIF_CLOCK_BASE);
298287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        editor.remove(Stopwatches.NOTIF_CLOCK_RUNNING);
299287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        editor.remove(Stopwatches.NOTIF_CLOCK_ELAPSED);
300287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        editor.apply();
301287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
302287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
303287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private void closeNotificationShade() {
304287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        Intent intent = new Intent();
305287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        intent.setAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
306287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        sendBroadcast(intent);
307287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
308287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
309287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private void readFromSharedPrefs() {
310287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
311287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                getApplicationContext());
312287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        mStartTime = prefs.getLong(Stopwatches.PREF_START_TIME, 0);
313287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        mElapsedTime = prefs.getLong(Stopwatches.PREF_ACCUM_TIME, 0);
314287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        mNumLaps = prefs.getInt(Stopwatches.PREF_LAP_NUM, Stopwatches.STOPWATCH_RESET);
315287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
316287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
317287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private long[] readLapsFromPrefs() {
318287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
319287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                getApplicationContext());
320287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        int numLaps = prefs.getInt(Stopwatches.PREF_LAP_NUM, Stopwatches.STOPWATCH_RESET);
321287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        long[] laps = new long[numLaps];
322287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        long prevLapElapsedTime = 0;
323287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        for (int lap_i = 0; lap_i < numLaps; lap_i++) {
324287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            String key = Stopwatches.PREF_LAP_TIME + Integer.toString(lap_i + 1);
325287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            long lap = prefs.getLong(key, 0);
326287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            if (lap == prevLapElapsedTime && lap_i == numLaps - 1) {
327287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                lap = mElapsedTime;
328287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            }
329287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            laps[numLaps - lap_i - 1] = lap - prevLapElapsedTime;
330287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            prevLapElapsedTime = lap;
331287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
332287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        return laps;
333287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
334287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
335287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private void writeToSharedPrefs(Long startTime, Long lapTimeElapsed, Long elapsedTime,
336287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            Integer state, boolean updateCircle) {
337287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
338287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                getApplicationContext());
339287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        SharedPreferences.Editor editor = prefs.edit();
340287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (startTime != null) {
341287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putLong(Stopwatches.PREF_START_TIME, startTime);
342287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            mStartTime = startTime;
343287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
344287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (lapTimeElapsed != null) {
345287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            int numLaps = prefs.getInt(Stopwatches.PREF_LAP_NUM, 0);
346287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            if (numLaps == 0) {
347287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                mNumLaps++;
348287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                numLaps++;
349287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            }
350287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putLong(Stopwatches.PREF_LAP_TIME + Integer.toString(numLaps), lapTimeElapsed);
351287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            numLaps++;
352287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putLong(Stopwatches.PREF_LAP_TIME + Integer.toString(numLaps), lapTimeElapsed);
353287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putInt(Stopwatches.PREF_LAP_NUM, numLaps);
354287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
355287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (elapsedTime != null) {
356287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putLong(Stopwatches.PREF_ACCUM_TIME, elapsedTime);
357287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            mElapsedTime = elapsedTime;
358287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
359287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (state != null) {
360287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            if (state == Stopwatches.STOPWATCH_RESET) {
361287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                editor.putInt(Stopwatches.PREF_STATE, Stopwatches.STOPWATCH_RESET);
362287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            } else if (state == Stopwatches.STOPWATCH_RUNNING) {
363287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                editor.putInt(Stopwatches.PREF_STATE, Stopwatches.STOPWATCH_RUNNING);
364287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            } else if (state == Stopwatches.STOPWATCH_STOPPED) {
365287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                editor.putInt(Stopwatches.PREF_STATE, Stopwatches.STOPWATCH_STOPPED);
366287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            }
367287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
368287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        editor.putBoolean(Stopwatches.PREF_UPDATE_CIRCLE, updateCircle);
369287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        editor.apply();
370287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
371287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
372287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private void writeSharedPrefsStarted(long startTime, boolean updateCircle) {
373287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        writeToSharedPrefs(startTime, null, null, Stopwatches.STOPWATCH_RUNNING, updateCircle);
374287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (updateCircle) {
375287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            long time = Utils.getTimeNow();
376287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
377287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    getApplicationContext());
378287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            long intervalStartTime = prefs.getLong(
379287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    Stopwatches.KEY + CircleTimerView.PREF_CTV_INTERVAL_START, -1);
380287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            if (intervalStartTime != -1) {
381287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                intervalStartTime = time;
382287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                SharedPreferences.Editor editor = prefs.edit();
383287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_INTERVAL_START,
384287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                        intervalStartTime);
385287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                editor.putBoolean(Stopwatches.KEY + CircleTimerView.PREF_CTV_PAUSED, false);
386287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                editor.apply();
387287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            }
388287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
389287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
390287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
391287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private void writeSharedPrefsLap(long lapTimeElapsed, boolean updateCircle) {
392287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        writeToSharedPrefs(null, lapTimeElapsed, null, null, updateCircle);
393287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (updateCircle) {
394287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            long time = Utils.getTimeNow();
395287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
396287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    getApplicationContext());
397287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            SharedPreferences.Editor editor = prefs.edit();
398287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            long laps[] = readLapsFromPrefs();
399287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            int numLaps = laps.length;
400287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            long lapTime = laps[1];
401287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            if (numLaps == 2) { // Have only hit lap once.
402287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_INTERVAL, lapTime);
403287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            } else {
404287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_MARKER_TIME, lapTime);
405287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            }
406287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_ACCUM_TIME, 0);
407287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            if (numLaps < Stopwatches.MAX_LAPS) {
408287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_INTERVAL_START, time);
409287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                editor.putBoolean(Stopwatches.KEY + CircleTimerView.PREF_CTV_PAUSED, false);
410287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            } else {
411287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_INTERVAL_START, -1);
412287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            }
413287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.apply();
414287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
415287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
416287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
417287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private void writeSharedPrefsStopped(long elapsedTime, boolean updateCircle) {
418287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        writeToSharedPrefs(null, null, elapsedTime, Stopwatches.STOPWATCH_STOPPED, updateCircle);
419287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        if (updateCircle) {
420287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            long time = Utils.getTimeNow();
421287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
422287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    getApplicationContext());
423287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            long accumulatedTime = prefs.getLong(
424287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    Stopwatches.KEY + CircleTimerView.PREF_CTV_ACCUM_TIME, 0);
425287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            long intervalStartTime = prefs.getLong(
426287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    Stopwatches.KEY + CircleTimerView.PREF_CTV_INTERVAL_START, -1);
427287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            accumulatedTime += time - intervalStartTime;
428287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            SharedPreferences.Editor editor = prefs.edit();
429287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_ACCUM_TIME, accumulatedTime);
430287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putBoolean(Stopwatches.KEY + CircleTimerView.PREF_CTV_PAUSED, true);
431287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.putLong(
432287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein                    Stopwatches.KEY + CircleTimerView.PREF_CTV_CURRENT_INTERVAL, accumulatedTime);
433287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein            editor.apply();
434287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        }
435287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
436287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein
437287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    private void writeSharedPrefsReset(boolean updateCircle) {
438287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein        writeToSharedPrefs(null, null, null, Stopwatches.STOPWATCH_RESET, updateCircle);
439287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein    }
440287f2d82aaf91d881f5de50a133d21684a8d4821Sam Blitzstein}
441