summaryrefslogtreecommitdiffstats
path: root/src/com/android/deskclock/data/StopwatchDAO.java
blob: 823ab63fd832b1ba6a7c77c5bc3d604f8f94e424 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.deskclock.data;

import android.content.SharedPreferences;

import com.android.deskclock.data.Stopwatch.State;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static com.android.deskclock.data.Stopwatch.State.RESET;

/**
 * This class encapsulates the transfer of data between {@link Stopwatch} and {@link Lap} domain
 * objects and their permanent storage in {@link SharedPreferences}.
 */
final class StopwatchDAO {

    /** Key to a preference that stores the state of the stopwatch. */
    private static final String STATE = "sw_state";

    /** Key to a preference that stores the last start time of the stopwatch. */
    private static final String LAST_START_TIME = "sw_start_time";

    /** Key to a preference that stores the epoch time when the stopwatch last started. */
    private static final String LAST_WALL_CLOCK_TIME = "sw_wall_clock_time";

    /** Key to a preference that stores the accumulated elapsed time of the stopwatch. */
    private static final String ACCUMULATED_TIME = "sw_accum_time";

    /** Prefix for a key to a preference that stores the number of recorded laps. */
    private static final String LAP_COUNT = "sw_lap_num";

    /** Prefix for a key to a preference that stores accumulated time at the end of a lap. */
    private static final String LAP_ACCUMULATED_TIME = "sw_lap_time_";

    private StopwatchDAO() {}

    /**
     * @return the stopwatch from permanent storage or a reset stopwatch if none exists
     */
    static Stopwatch getStopwatch(SharedPreferences prefs) {
        final int stateIndex = prefs.getInt(STATE, RESET.ordinal());
        final State state = State.values()[stateIndex];
        final long lastStartTime = prefs.getLong(LAST_START_TIME, Stopwatch.UNUSED);
        final long lastWallClockTime = prefs.getLong(LAST_WALL_CLOCK_TIME, Stopwatch.UNUSED);
        final long accumulatedTime = prefs.getLong(ACCUMULATED_TIME, 0);
        return new Stopwatch(state, lastStartTime, lastWallClockTime, accumulatedTime);
    }

    /**
     * @param stopwatch the last state of the stopwatch
     */
    static void setStopwatch(SharedPreferences prefs, Stopwatch stopwatch) {
        final SharedPreferences.Editor editor = prefs.edit();

        if (stopwatch.isReset()) {
            editor.remove(STATE)
                    .remove(LAST_START_TIME)
                    .remove(LAST_WALL_CLOCK_TIME)
                    .remove(ACCUMULATED_TIME);
        } else {
            editor.putInt(STATE, stopwatch.getState().ordinal())
                    .putLong(LAST_START_TIME, stopwatch.getLastStartTime())
                    .putLong(LAST_WALL_CLOCK_TIME, stopwatch.getLastWallClockTime())
                    .putLong(ACCUMULATED_TIME, stopwatch.getAccumulatedTime());
        }

        editor.apply();
    }

    /**
     * @return a list of recorded laps for the stopwatch
     */
    static List<Lap> getLaps(SharedPreferences prefs) {
        // Prepare the container to be filled with laps.
        final int lapCount = prefs.getInt(LAP_COUNT, 0);
        final List<Lap> laps = new ArrayList<>(lapCount);

        long prevAccumulatedTime = 0;

        // Lap numbers are 1-based and so the are corresponding shared preference keys.
        for (int lapNumber = 1; lapNumber <= lapCount; lapNumber++) {
            // Look up the accumulated time for the lap.
            final String lapAccumulatedTimeKey = LAP_ACCUMULATED_TIME + lapNumber;
            final long accumulatedTime = prefs.getLong(lapAccumulatedTimeKey, 0);

            // Lap time is the delta between accumulated time of this lap and prior lap.
            final long lapTime = accumulatedTime - prevAccumulatedTime;

            // Create the lap instance from the data.
            laps.add(new Lap(lapNumber, lapTime, accumulatedTime));

            // Update the accumulated time of the previous lap.
            prevAccumulatedTime = accumulatedTime;
        }

        // Laps are stored in the order they were recorded; display order is the reverse.
        Collections.reverse(laps);

        return laps;
    }

    /**
     * @param newLapCount the number of laps including the new lap
     * @param accumulatedTime the amount of time accumulate by the stopwatch at the end of the lap
     */
    static void addLap(SharedPreferences prefs, int newLapCount, long accumulatedTime) {
        prefs.edit()
                .putInt(LAP_COUNT, newLapCount)
                .putLong(LAP_ACCUMULATED_TIME + newLapCount, accumulatedTime)
                .apply();
    }

    /**
     * Remove the recorded laps for the stopwatch
     */
    static void clearLaps(SharedPreferences prefs) {
        final SharedPreferences.Editor editor = prefs.edit();

        final int lapCount = prefs.getInt(LAP_COUNT, 0);
        for (int lapNumber = 1; lapNumber <= lapCount; lapNumber++) {
            editor.remove(LAP_ACCUMULATED_TIME + lapNumber);
        }
        editor.remove(LAP_COUNT);

        editor.apply();
    }
}