* commit '8fb320717510e0703e99299f7df4543fbafcab02': Ignore small time changes in alarm manager.
This commit is contained in:
@@ -302,9 +302,6 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
String mStartPlatformVersion;
|
||||
String mEndPlatformVersion;
|
||||
|
||||
long mLastRecordedClockTime;
|
||||
long mLastRecordedClockRealtime;
|
||||
|
||||
long mUptime;
|
||||
long mUptimeStart;
|
||||
long mRealtime;
|
||||
@@ -2329,8 +2326,6 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
if (dataSize == 0) {
|
||||
// The history is currently empty; we need it to start with a time stamp.
|
||||
cur.currentTime = System.currentTimeMillis();
|
||||
mLastRecordedClockTime = cur.currentTime;
|
||||
mLastRecordedClockRealtime = elapsedRealtimeMs;
|
||||
addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_RESET, cur);
|
||||
}
|
||||
addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
|
||||
@@ -2503,8 +2498,6 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
mHistoryOverflow = false;
|
||||
mActiveHistoryStates = 0xffffffff;
|
||||
mActiveHistoryStates2 = 0xffffffff;
|
||||
mLastRecordedClockTime = 0;
|
||||
mLastRecordedClockRealtime = 0;
|
||||
}
|
||||
|
||||
public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime,
|
||||
@@ -2554,18 +2547,6 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
final long elapsedRealtime = SystemClock.elapsedRealtime();
|
||||
final long uptime = SystemClock.uptimeMillis();
|
||||
if (isStartClockTimeValid()) {
|
||||
// Has the time changed sufficiently that it is really worth recording?
|
||||
if (mLastRecordedClockTime != 0) {
|
||||
long expectedClockTime = mLastRecordedClockTime
|
||||
+ (elapsedRealtime - mLastRecordedClockRealtime);
|
||||
if (currentTime >= (expectedClockTime-500)
|
||||
&& currentTime <= (expectedClockTime+500)) {
|
||||
// Not sufficiently changed, skip!
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime);
|
||||
if (isStartClockTimeValid()) {
|
||||
mStartClockTime = currentTime;
|
||||
@@ -7941,8 +7922,6 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
boolean reset) {
|
||||
mRecordingHistory = true;
|
||||
mHistoryCur.currentTime = System.currentTimeMillis();
|
||||
mLastRecordedClockTime = mHistoryCur.currentTime;
|
||||
mLastRecordedClockRealtime = elapsedRealtimeMs;
|
||||
addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs,
|
||||
reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
|
||||
mHistoryCur);
|
||||
@@ -7956,8 +7935,6 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
final long uptimeMs) {
|
||||
if (mRecordingHistory) {
|
||||
mHistoryCur.currentTime = currentTime;
|
||||
mLastRecordedClockTime = currentTime;
|
||||
mLastRecordedClockRealtime = elapsedRealtimeMs;
|
||||
addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME,
|
||||
mHistoryCur);
|
||||
mHistoryCur.currentTime = 0;
|
||||
@@ -7967,8 +7944,6 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) {
|
||||
if (mRecordingHistory) {
|
||||
mHistoryCur.currentTime = System.currentTimeMillis();
|
||||
mLastRecordedClockTime = mHistoryCur.currentTime;
|
||||
mLastRecordedClockRealtime = elapsedRealtimeMs;
|
||||
addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_SHUTDOWN,
|
||||
mHistoryCur);
|
||||
mHistoryCur.currentTime = 0;
|
||||
|
||||
@@ -138,6 +138,8 @@ class AlarmManagerService extends SystemService {
|
||||
long mLastAlarmDeliveryTime;
|
||||
long mStartCurrentDelayTime;
|
||||
long mNextNonWakeupDeliveryTime;
|
||||
long mLastTimeChangeClockTime;
|
||||
long mLastTimeChangeRealtime;
|
||||
int mNumTimeChanged;
|
||||
|
||||
private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser =
|
||||
@@ -1024,6 +1026,11 @@ class AlarmManagerService extends SystemService {
|
||||
pw.print("="); pw.print(sdf.format(new Date(nowRTC)));
|
||||
pw.print(" nowELAPSED="); TimeUtils.formatDuration(nowELAPSED, pw);
|
||||
pw.println();
|
||||
pw.print("mLastTimeChangeClockTime="); pw.print(mLastTimeChangeClockTime);
|
||||
pw.print("="); pw.println(sdf.format(new Date(mLastTimeChangeClockTime)));
|
||||
pw.print("mLastTimeChangeRealtime=");
|
||||
TimeUtils.formatDuration(mLastTimeChangeRealtime, pw);
|
||||
pw.println();
|
||||
if (!mInteractive) {
|
||||
pw.print("Time since non-interactive: ");
|
||||
TimeUtils.formatDuration(nowELAPSED - mNonInteractiveStartTime, pw);
|
||||
@@ -1955,77 +1962,102 @@ class AlarmManagerService extends SystemService {
|
||||
|
||||
triggerList.clear();
|
||||
|
||||
final long nowRTC = System.currentTimeMillis();
|
||||
final long nowELAPSED = SystemClock.elapsedRealtime();
|
||||
|
||||
if ((result & TIME_CHANGED_MASK) != 0) {
|
||||
if (DEBUG_BATCH) {
|
||||
Slog.v(TAG, "Time changed notification from kernel; rebatching");
|
||||
}
|
||||
removeImpl(mTimeTickSender);
|
||||
rebatchAllAlarms();
|
||||
mClockReceiver.scheduleTimeTickEvent();
|
||||
// The kernel can give us spurious time change notifications due to
|
||||
// small adjustments it makes internally; we want to filter those out.
|
||||
final long lastTimeChangeClockTime;
|
||||
final long expectedClockTime;
|
||||
synchronized (mLock) {
|
||||
mNumTimeChanged++;
|
||||
lastTimeChangeClockTime = mLastTimeChangeClockTime;
|
||||
expectedClockTime = lastTimeChangeClockTime
|
||||
+ (nowELAPSED - mLastTimeChangeRealtime);
|
||||
}
|
||||
if (lastTimeChangeClockTime == 0 || nowRTC < (expectedClockTime-500)
|
||||
|| nowRTC > (expectedClockTime+500)) {
|
||||
// The change is by at least +/- 500 ms (or this is the first change),
|
||||
// let's do it!
|
||||
if (DEBUG_BATCH) {
|
||||
Slog.v(TAG, "Time changed notification from kernel; rebatching");
|
||||
}
|
||||
removeImpl(mTimeTickSender);
|
||||
rebatchAllAlarms();
|
||||
mClockReceiver.scheduleTimeTickEvent();
|
||||
synchronized (mLock) {
|
||||
mNumTimeChanged++;
|
||||
mLastTimeChangeClockTime = nowRTC;
|
||||
mLastTimeChangeRealtime = nowELAPSED;
|
||||
}
|
||||
Intent intent = new Intent(Intent.ACTION_TIME_CHANGED);
|
||||
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
|
||||
| Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
|
||||
getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
|
||||
|
||||
// The world has changed on us, so we need to re-evaluate alarms
|
||||
// regardless of whether the kernel has told us one went off.
|
||||
result |= IS_WAKEUP_MASK;
|
||||
}
|
||||
Intent intent = new Intent(Intent.ACTION_TIME_CHANGED);
|
||||
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
|
||||
| Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
|
||||
getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
final long nowRTC = System.currentTimeMillis();
|
||||
final long nowELAPSED = SystemClock.elapsedRealtime();
|
||||
if (localLOGV) Slog.v(
|
||||
TAG, "Checking for alarms... rtc=" + nowRTC
|
||||
+ ", elapsed=" + nowELAPSED);
|
||||
|
||||
if (WAKEUP_STATS) {
|
||||
if ((result & IS_WAKEUP_MASK) != 0) {
|
||||
long newEarliest = nowRTC - RECENT_WAKEUP_PERIOD;
|
||||
int n = 0;
|
||||
for (WakeupEvent event : mRecentWakeups) {
|
||||
if (event.when > newEarliest) break;
|
||||
n++; // number of now-stale entries at the list head
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
mRecentWakeups.remove();
|
||||
}
|
||||
if (result != TIME_CHANGED_MASK) {
|
||||
// If this was anything besides just a time change, then figure what if
|
||||
// anything to do about alarms.
|
||||
synchronized (mLock) {
|
||||
if (localLOGV) Slog.v(
|
||||
TAG, "Checking for alarms... rtc=" + nowRTC
|
||||
+ ", elapsed=" + nowELAPSED);
|
||||
|
||||
recordWakeupAlarms(mAlarmBatches, nowELAPSED, nowRTC);
|
||||
}
|
||||
}
|
||||
if (WAKEUP_STATS) {
|
||||
if ((result & IS_WAKEUP_MASK) != 0) {
|
||||
long newEarliest = nowRTC - RECENT_WAKEUP_PERIOD;
|
||||
int n = 0;
|
||||
for (WakeupEvent event : mRecentWakeups) {
|
||||
if (event.when > newEarliest) break;
|
||||
n++; // number of now-stale entries at the list head
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
mRecentWakeups.remove();
|
||||
}
|
||||
|
||||
boolean hasWakeup = triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC);
|
||||
if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) {
|
||||
// if there are no wakeup alarms and the screen is off, we can
|
||||
// delay what we have so far until the future.
|
||||
if (mPendingNonWakeupAlarms.size() == 0) {
|
||||
mStartCurrentDelayTime = nowELAPSED;
|
||||
mNextNonWakeupDeliveryTime = nowELAPSED
|
||||
+ ((currentNonWakeupFuzzLocked(nowELAPSED)*3)/2);
|
||||
}
|
||||
mPendingNonWakeupAlarms.addAll(triggerList);
|
||||
mNumDelayedAlarms += triggerList.size();
|
||||
rescheduleKernelAlarmsLocked();
|
||||
updateNextAlarmClockLocked();
|
||||
} else {
|
||||
// now deliver the alarm intents; if there are pending non-wakeup
|
||||
// alarms, we need to merge them in to the list. note we don't
|
||||
// just deliver them first because we generally want non-wakeup
|
||||
// alarms delivered after wakeup alarms.
|
||||
rescheduleKernelAlarmsLocked();
|
||||
updateNextAlarmClockLocked();
|
||||
if (mPendingNonWakeupAlarms.size() > 0) {
|
||||
calculateDeliveryPriorities(mPendingNonWakeupAlarms);
|
||||
triggerList.addAll(mPendingNonWakeupAlarms);
|
||||
Collections.sort(triggerList, mAlarmDispatchComparator);
|
||||
final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime;
|
||||
mTotalDelayTime += thisDelayTime;
|
||||
if (mMaxDelayTime < thisDelayTime) {
|
||||
mMaxDelayTime = thisDelayTime;
|
||||
recordWakeupAlarms(mAlarmBatches, nowELAPSED, nowRTC);
|
||||
}
|
||||
mPendingNonWakeupAlarms.clear();
|
||||
}
|
||||
deliverAlarmsLocked(triggerList, nowELAPSED);
|
||||
|
||||
boolean hasWakeup = triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC);
|
||||
if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) {
|
||||
// if there are no wakeup alarms and the screen is off, we can
|
||||
// delay what we have so far until the future.
|
||||
if (mPendingNonWakeupAlarms.size() == 0) {
|
||||
mStartCurrentDelayTime = nowELAPSED;
|
||||
mNextNonWakeupDeliveryTime = nowELAPSED
|
||||
+ ((currentNonWakeupFuzzLocked(nowELAPSED)*3)/2);
|
||||
}
|
||||
mPendingNonWakeupAlarms.addAll(triggerList);
|
||||
mNumDelayedAlarms += triggerList.size();
|
||||
rescheduleKernelAlarmsLocked();
|
||||
updateNextAlarmClockLocked();
|
||||
} else {
|
||||
// now deliver the alarm intents; if there are pending non-wakeup
|
||||
// alarms, we need to merge them in to the list. note we don't
|
||||
// just deliver them first because we generally want non-wakeup
|
||||
// alarms delivered after wakeup alarms.
|
||||
rescheduleKernelAlarmsLocked();
|
||||
updateNextAlarmClockLocked();
|
||||
if (mPendingNonWakeupAlarms.size() > 0) {
|
||||
calculateDeliveryPriorities(mPendingNonWakeupAlarms);
|
||||
triggerList.addAll(mPendingNonWakeupAlarms);
|
||||
Collections.sort(triggerList, mAlarmDispatchComparator);
|
||||
final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime;
|
||||
mTotalDelayTime += thisDelayTime;
|
||||
if (mMaxDelayTime < thisDelayTime) {
|
||||
mMaxDelayTime = thisDelayTime;
|
||||
}
|
||||
mPendingNonWakeupAlarms.clear();
|
||||
}
|
||||
deliverAlarmsLocked(triggerList, nowELAPSED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user