Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c352722e authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Ignore small time changes in alarm manager.

It turns out switching to the new kernel alarm
reporting causes lots and lots of spurious flags
that the clock has changed.  The alarm manager
would blindly trust these, thinking the world has
changed on it and recomputing everything and reporting
this to everyone else.  This was expensive.

We now verify that the time has changed sufficiently
that it is worth caring about.  This is basically the
same algorithm that battery stats was using to avoid
recording small clock changes, so we are really just
pushing this down into the alarm manager and can now
remove that from battery stats.

Also since we are getting these so much, make use of
the other information in about the wakeup that tells us
if an alarm went off to avoid doing anything if it didn't.

Change-Id: I6f4f4226db6eb2b38ca73860786e7cf7c9136cc3
parent e3a6a69a
Loading
Loading
Loading
Loading
+0 −25
Original line number Diff line number Diff line
@@ -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;
+94 −62
Original line number Diff line number Diff line
@@ -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,7 +1962,23 @@ class AlarmManagerService extends SystemService {

                triggerList.clear();

                final long nowRTC = System.currentTimeMillis();
                final long nowELAPSED = SystemClock.elapsedRealtime();

                if ((result & TIME_CHANGED_MASK) != 0) {
                    // 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) {
                        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");
                        }
@@ -1964,16 +1987,24 @@ class AlarmManagerService extends SystemService {
                        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;
                    }
                }

                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) {
                    final long nowRTC = System.currentTimeMillis();
                    final long nowELAPSED = SystemClock.elapsedRealtime();
                        if (localLOGV) Slog.v(
                            TAG, "Checking for alarms... rtc=" + nowRTC
                            + ", elapsed=" + nowELAPSED);
@@ -2031,6 +2062,7 @@ class AlarmManagerService extends SystemService {
                }
            }
        }
    }

    /**
     * Attribute blame for a WakeLock.