summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Lemieux <jplemieux@google.com>2016-02-12 17:24:12 -0800
committerJames Lemieux <jplemieux@google.com>2016-02-12 18:08:49 -0800
commitf8e562f69dd6547f7386956eea2edab361913cc0 (patch)
tree4e2696ff809eb1f7720166182a2b0003720bbfe4
parent8633847bede6b3ae4b3d958b16fe844387e9206d (diff)
downloadandroid_packages_apps_DeskClock-f8e562f69dd6547f7386956eea2edab361913cc0.tar.gz
android_packages_apps_DeskClock-f8e562f69dd6547f7386956eea2edab361913cc0.tar.bz2
android_packages_apps_DeskClock-f8e562f69dd6547f7386956eea2edab361913cc0.zip
Do not assume current stopwatch lap has positive duration
Bug: 27171498 After a device reboot the realtime clock is reset. Because of this, the app is notified of the BOOT_COMPLETE and resets the stopwatch. There exists about a 10 second window of opportunity before the BOOT_COMPLETE broadcast in which the app may be opened and the realtime clock information may be used to compute stopwatch laptimes which would be negative. This case is now handled gracefully rather than crashing on a sanity check. Change-Id: I0eb4da0a9a55b5abc8d6abaa5a2e046821d39a2e
-rw-r--r--src/com/android/deskclock/data/Stopwatch.java11
-rw-r--r--src/com/android/deskclock/data/StopwatchModel.java20
2 files changed, 15 insertions, 16 deletions
diff --git a/src/com/android/deskclock/data/Stopwatch.java b/src/com/android/deskclock/data/Stopwatch.java
index 9eb2b9cf2..a08cc1f0d 100644
--- a/src/com/android/deskclock/data/Stopwatch.java
+++ b/src/com/android/deskclock/data/Stopwatch.java
@@ -61,7 +61,11 @@ public final class Stopwatch {
return mAccumulatedTime;
}
- return mAccumulatedTime + (now() - mLastStartTime);
+ // In practice, "now" can be any value due to device reboots. When the real-time clock
+ // is reset, there is no more guarantee that "now" falls after the last start time. To
+ // ensure the stopwatch is monotonically increasing, normalize negative time segments to 0,
+ final long timeSinceStart = now() - mLastStartTime;
+ return mAccumulatedTime + Math.max(0, timeSinceStart);
}
/**
@@ -79,7 +83,7 @@ public final class Stopwatch {
return this;
}
- return new Stopwatch(RUNNING, now(), mAccumulatedTime);
+ return new Stopwatch(RUNNING, now(), getTotalTime());
}
/**
@@ -90,8 +94,7 @@ public final class Stopwatch {
return this;
}
- final long accumulatedTime = mAccumulatedTime + (now() - mLastStartTime);
- return new Stopwatch(PAUSED, Long.MIN_VALUE, accumulatedTime);
+ return new Stopwatch(PAUSED, Long.MIN_VALUE, getTotalTime());
}
/**
diff --git a/src/com/android/deskclock/data/StopwatchModel.java b/src/com/android/deskclock/data/StopwatchModel.java
index 217a83016..a536c1fb4 100644
--- a/src/com/android/deskclock/data/StopwatchModel.java
+++ b/src/com/android/deskclock/data/StopwatchModel.java
@@ -175,21 +175,17 @@ final class StopwatchModel {
}
/**
- * @param time a point in time after the end of the last lap
- * @return the elapsed time between the given {@code time} and the end of the previous lap
+ * In practice, {@code time} can be any value due to device reboots. When the real-time clock is
+ * reset, there is no more guarantee that this time falls after the last recorded lap.
+ *
+ * @param time a point in time expected, but not required, to be after the end of the prior lap
+ * @return the elapsed time between the given {@code time} and the end of the prior lap;
+ * negative elapsed times are normalized to {@code 0}
*/
long getCurrentLapTime(long time) {
final Lap previousLap = getLaps().get(0);
-
- final long last = previousLap.getAccumulatedTime();
- final long lapTime = time - last;
-
- if (lapTime < 0) {
- final String message = String.format("time (%d) must exceed last lap (%d)", time, last);
- throw new IllegalArgumentException(message);
- }
-
- return lapTime;
+ final long currentLapTime = time - previousLap.getAccumulatedTime();
+ return Math.max(0, currentLapTime);
}
/**