summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Tate <ctate@google.com>2014-12-16 12:14:06 -0800
committerThe Android Automerger <android-build@android.com>2014-12-16 13:12:29 -0800
commit0ac9664a9ee2e6d1d3b68fe00c264ad94fe98966 (patch)
tree56e667a11133f3caf40c9df72b92c2e71abb1eb1
parenta6e7e6bf5923f427785d6946ac050ba4e4052dc5 (diff)
downloadbase-linaro_android_5.0.0.tar.gz
The man bent over his hourglass, A programmer of sorts. The day was green. They said, "You have a blue hourglass, You do not fire alarms when they're asked." The man replied, "Alarms as they're asked are changed within the blue hourglass." And they said then, "But fire, you must Alarms beyond us, yet themselves, Alarms within the blue hourglass That trigger exactly when they're asked." --- Fix the delivery-fuzzing semantics that had been introduced in 81f9882b5aadd6a2289c9f521a06a7af5f35ebf0. That patch turned out to be incomplete; in particular, alarms scheduled later might require the validity of an already-scheduled kernel alarm even if they did not affect the head alarm batch directly, and this was not being addressed. For now, roll back the fuzzed delivery logic entirely. (This is not a full revert because that patch also caused exact alarms to be considered standalone for batching purposes, and we need to preserve that new policy.) Bug 18726690 Bug 18765436 This is a 'git revert' of 81f9882b5aadd6a2289c9f521a06a7af5f35ebf0 *except* that this CL preserves the "exact alarms are treated as standalone" portion of the original patch. Change-Id: I54c763775877de5b6eeb5617544aa6100bb17526
-rw-r--r--services/core/java/com/android/server/AlarmManagerService.java84
1 files changed, 22 insertions, 62 deletions
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index ed8bc51f0de9..554393af3052 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -61,7 +61,6 @@ import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Locale;
-import java.util.Random;
import java.util.TimeZone;
import static android.app.AlarmManager.RTC_WAKEUP;
@@ -109,12 +108,8 @@ class AlarmManagerService extends SystemService {
final Object mLock = new Object();
long mNativeData;
-
- private final Random mFuzzer = new Random();
- private long mNextWakeupBatchStart; // nominal start of next wakeup's delivery window
- private long mNextWakeup; // actual scheduled next wakeup within that window
+ private long mNextWakeup;
private long mNextNonWakeup;
-
int mBroadcastRefCount = 0;
PowerManager.WakeLock mWakeLock;
boolean mLastWakeLockUnimportantForLogging;
@@ -366,27 +361,14 @@ class AlarmManagerService extends SystemService {
static class BatchTimeOrder implements Comparator<Batch> {
public int compare(Batch b1, Batch b2) {
- final long start1 = b1.start;
- final long start2 = b2.start;
- if (start1 > start2) {
- return 1;
- }
- if (start1 < start2) {
- return -1;
- }
-
- // Identical trigger times. As a secondary ordering, require that
- // the batch with the shorter allowable delivery window sorts first.
- final long interval1 = b1.end - b1.start;
- final long interval2 = b2.end - b2.start;
- if (interval1 > interval2) {
+ long when1 = b1.start;
+ long when2 = b2.start;
+ if (when1 - when2 > 0) {
return 1;
}
- if (interval2 < interval1) {
+ if (when1 - when2 < 0) {
return -1;
}
-
- // equal start + delivery window => they're identical
return 0;
}
}
@@ -609,7 +591,7 @@ class AlarmManagerService extends SystemService {
@Override
public void onStart() {
mNativeData = init();
- mNextWakeup = mNextWakeupBatchStart = mNextNonWakeup = 0;
+ mNextWakeup = mNextNonWakeup = 0;
// We have to set current TimeZone info to kernel
// because kernel doesn't keep this after reboot
@@ -804,7 +786,6 @@ class AlarmManagerService extends SystemService {
"AlarmManager.set");
}
- // Exact alarms are standalone; inexact get batched together
setImpl(type, triggerAtTime, windowLength, interval, operation,
windowLength == AlarmManager.WINDOW_EXACT, workSource, alarmClock);
}
@@ -877,7 +858,7 @@ class AlarmManagerService extends SystemService {
pw.print("nowRTC="); pw.print(nowRTC);
pw.print("="); pw.print(sdf.format(new Date(nowRTC)));
- pw.print(" nowELAPSED="); pw.print(nowELAPSED);
+ pw.print(" nowELAPSED="); TimeUtils.formatDuration(nowELAPSED, pw);
pw.println();
if (!mInteractive) {
pw.print("Time since non-interactive: ");
@@ -1083,6 +1064,17 @@ class AlarmManagerService extends SystemService {
return true;
}
+ private Batch findFirstWakeupBatchLocked() {
+ final int N = mAlarmBatches.size();
+ for (int i = 0; i < N; i++) {
+ Batch b = mAlarmBatches.get(i);
+ if (b.hasWakeups()) {
+ return b;
+ }
+ }
+ return null;
+ }
+
private AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) {
synchronized (mLock) {
return mNextAlarmClockForUser.get(userId);
@@ -1216,48 +1208,16 @@ class AlarmManagerService extends SystemService {
// prior to that which contains no wakeups, we schedule that as well.
long nextNonWakeup = 0;
if (mAlarmBatches.size() > 0) {
- // Find the first wakeup alarm and note the following batch as well. We'll be
- // choosing a fuzzed delivery time within the first's allowable interval but
- // ensuring that it does not encroach on the second's start time, to minimize
- // alarm reordering.
- Batch firstWakeup = null, nextAfterWakeup = null;
- final int N = mAlarmBatches.size();
- for (int i = 0; i < N; i++) {
- Batch b = mAlarmBatches.get(i);
- if (b.hasWakeups()) {
- firstWakeup = b;
- if (i < N-1) {
- nextAfterWakeup = mAlarmBatches.get(i+1);
- }
- break;
- }
- }
-
- // There's a subtlety here: we depend on the invariant that if two batches
- // exist with the same start time, the one with the shorter delivery window
- // is sorted before the other. This guarantees us that we need only look
- // at the first [relevant] batch in the queue in order to schedule an alarm
- // appropriately.
+ final Batch firstWakeup = findFirstWakeupBatchLocked();
final Batch firstBatch = mAlarmBatches.get(0);
- if (firstWakeup != null && mNextWakeupBatchStart != firstWakeup.start) {
- mNextWakeupBatchStart = mNextWakeup = firstWakeup.start;
- final long windowEnd = (nextAfterWakeup == null)
- ? firstWakeup.end
- : Math.min(firstWakeup.end, nextAfterWakeup.start);
- final long interval = windowEnd - firstWakeup.start;
- // if the interval is over maxint we're into crazy land anyway, but
- // just in case we check and don't fuzz if the conversion to int for
- // random-number purposes would blow up
- if (interval > 0 && interval < Integer.MAX_VALUE) {
- mNextWakeup += mFuzzer.nextInt((int) interval);
- }
- setLocked(ELAPSED_REALTIME_WAKEUP, mNextWakeup);
+ if (firstWakeup != null && mNextWakeup != firstWakeup.start) {
+ mNextWakeup = firstWakeup.start;
+ setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start);
}
if (firstBatch != firstWakeup) {
nextNonWakeup = firstBatch.start;
}
}
-
if (mPendingNonWakeupAlarms.size() > 0) {
if (nextNonWakeup == 0 || mNextNonWakeupDeliveryTime < nextNonWakeup) {
nextNonWakeup = mNextNonWakeupDeliveryTime;