/** * Determine whether it is a good time to kill, crash, or otherwise plunder the current situation * for the overall long-term benefit of the world. * * @param curTime The current system time. * @return Returns null if this is a good time, else a String with the text of why it is not a * good time. */ String shouldWeBeBrutalLocked(long curTime) { if (mBattery == null || !mBattery.isPowered()) { return "battery"; } if (mMinScreenOff >= 0 && (mPower == null || mPower.timeSinceScreenOn() < mMinScreenOff)) { return "screen"; } if (mMinAlarm >= 0 && (mAlarm == null || mAlarm.timeToNextAlarm() < mMinAlarm)) { return "alarm"; } return null; }
void checkReboot(boolean fromAlarm) { int rebootInterval = mReqRebootInterval >= 0 ? mReqRebootInterval : Settings.Secure.getInt( mResolver, Settings.Secure.REBOOT_INTERVAL, REBOOT_DEFAULT_INTERVAL); mRebootInterval = rebootInterval; if (rebootInterval <= 0) { // No reboot interval requested. if (localLOGV) Slog.v(TAG, "No need to schedule a reboot alarm!"); mAlarm.remove(mRebootIntent); return; } long rebootStartTime = mReqRebootStartTime >= 0 ? mReqRebootStartTime : Settings.Secure.getLong( mResolver, Settings.Secure.REBOOT_START_TIME, REBOOT_DEFAULT_START_TIME); long rebootWindowMillis = (mReqRebootWindow >= 0 ? mReqRebootWindow : Settings.Secure.getLong( mResolver, Settings.Secure.REBOOT_WINDOW, REBOOT_DEFAULT_WINDOW)) * 1000; long recheckInterval = (mReqRecheckInterval >= 0 ? mReqRecheckInterval : Settings.Secure.getLong( mResolver, Settings.Secure.MEMCHECK_RECHECK_INTERVAL, MEMCHECK_DEFAULT_RECHECK_INTERVAL)) * 1000; retrieveBrutalityAmount(); long realStartTime; long now; synchronized (this) { now = System.currentTimeMillis(); realStartTime = computeCalendarTime(mCalendar, now, rebootStartTime); long rebootIntervalMillis = rebootInterval * 24 * 60 * 60 * 1000; if (DB || mReqRebootNoWait || (now - mBootTime) >= (rebootIntervalMillis - rebootWindowMillis)) { if (fromAlarm && rebootWindowMillis <= 0) { // No reboot window -- just immediately reboot. EventLog.writeEvent( EventLogTags.WATCHDOG_SCHEDULED_REBOOT, now, (int) rebootIntervalMillis, (int) rebootStartTime * 1000, (int) rebootWindowMillis, ""); rebootSystem("Checkin scheduled forced"); return; } // Are we within the reboot window? if (now < realStartTime) { // Schedule alarm for next check interval. realStartTime = computeCalendarTime(mCalendar, now, rebootStartTime); } else if (now < (realStartTime + rebootWindowMillis)) { String doit = shouldWeBeBrutalLocked(now); EventLog.writeEvent( EventLogTags.WATCHDOG_SCHEDULED_REBOOT, now, (int) rebootInterval, (int) rebootStartTime * 1000, (int) rebootWindowMillis, doit != null ? doit : ""); if (doit == null) { rebootSystem("Checked scheduled range"); return; } // Schedule next alarm either within the window or in the // next interval. if ((now + recheckInterval) >= (realStartTime + rebootWindowMillis)) { realStartTime = computeCalendarTime(mCalendar, now + rebootIntervalMillis, rebootStartTime); } else { realStartTime = now + recheckInterval; } } else { // Schedule alarm for next check interval. realStartTime = computeCalendarTime(mCalendar, now + rebootIntervalMillis, rebootStartTime); } } } if (localLOGV) Slog.v( TAG, "Scheduling next reboot alarm for " + ((realStartTime - now) / 1000 / 60) + "m from now"); mAlarm.remove(mRebootIntent); mAlarm.set(AlarmManager.RTC_WAKEUP, realStartTime, mRebootIntent); }