Loading core/java/android/app/AlarmManager.java +6 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,12 @@ public class AlarmManager * wakes up. */ public static final int ELAPSED_REALTIME = 3; /** @hide * Alarm time in {@link System#currentTimeMillis System.currentTimeMillis()} * (wall clock time in UTC), which will wake up the device when * it goes off. And it will power on the devices when it shuts down. */ public static final int RTC_POWEROFF_WAKEUP = 4; /** @hide */ public static final long WINDOW_EXACT = 0; Loading services/java/com/android/server/AlarmManagerService.java +38 −5 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ import static android.app.AlarmManager.RTC_WAKEUP; import static android.app.AlarmManager.RTC; import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; import static android.app.AlarmManager.ELAPSED_REALTIME; import static android.app.AlarmManager.RTC_POWEROFF_WAKEUP; import com.android.internal.util.LocalLog; Loading @@ -75,6 +76,7 @@ class AlarmManagerService extends IAlarmManager.Stub { private static final int RTC_MASK = 1 << RTC; private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP; private static final int ELAPSED_REALTIME_MASK = 1 << ELAPSED_REALTIME; private static final int RTC_POWEROFF_WAKEUP_MASK = 1 << RTC_POWEROFF_WAKEUP; private static final int TIME_CHANGED_MASK = 1 << 16; private static final int IS_WAKEUP_MASK = RTC_WAKEUP_MASK|ELAPSED_REALTIME_WAKEUP_MASK; Loading Loading @@ -106,6 +108,7 @@ class AlarmManagerService extends IAlarmManager.Stub { private int mDescriptor; private long mNextWakeup; private long mNextRtcWakeup; private long mNextNonWakeup; private int mBroadcastRefCount = 0; private PowerManager.WakeLock mWakeLock; Loading Loading @@ -292,6 +295,18 @@ class AlarmManagerService extends IAlarmManager.Stub { return false; } boolean isRtcPowerOffWakeup() { final int N = alarms.size(); for (int i = 0; i < N; i++) { Alarm a = alarms.get(i); // non-wakeup alarms are types 1 and 3, i.e. have the low bit set if (a.type == RTC_POWEROFF_WAKEUP) { return true; } } return false; } @Override public String toString() { StringBuilder b = new StringBuilder(40); Loading Loading @@ -327,7 +342,7 @@ class AlarmManagerService extends IAlarmManager.Stub { private final ArrayList<Batch> mAlarmBatches = new ArrayList<Batch>(); static long convertToElapsed(long when, int type) { final boolean isRtc = (type == RTC || type == RTC_WAKEUP); final boolean isRtc = (type == RTC || type == RTC_WAKEUP || type == RTC_POWEROFF_WAKEUP); if (isRtc) { when -= System.currentTimeMillis() - SystemClock.elapsedRealtime(); } Loading Loading @@ -470,7 +485,7 @@ class AlarmManagerService extends IAlarmManager.Stub { public AlarmManagerService(Context context) { mContext = context; mDescriptor = init(); mNextWakeup = mNextNonWakeup = 0; mNextWakeup = mNextRtcWakeup = mNextNonWakeup = 0; // We have to set current TimeZone info to kernel // because kernel doesn't keep this after reboot Loading Loading @@ -540,7 +555,7 @@ class AlarmManagerService extends IAlarmManager.Stub { windowLength = AlarmManager.INTERVAL_HOUR; } if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) { if (type < RTC_WAKEUP || type > RTC_POWEROFF_WAKEUP) { throw new IllegalArgumentException("Invalid alarm type " + type); } Loading Loading @@ -656,6 +671,17 @@ class AlarmManagerService extends IAlarmManager.Stub { } return null; } private Batch findFirstRtcWakeupBatchLocked() { final int N = mAlarmBatches.size(); for (int i = 0; i < N; i++) { Batch b = mAlarmBatches.get(i); if (b.isRtcPowerOffWakeup()) { return b; } } return null; } private void rescheduleKernelAlarmsLocked() { // Schedule the next upcoming wakeup alarm. If there is a deliverable batch Loading @@ -663,6 +689,7 @@ class AlarmManagerService extends IAlarmManager.Stub { if (mAlarmBatches.size() > 0) { final Batch firstWakeup = findFirstWakeupBatchLocked(); final Batch firstBatch = mAlarmBatches.get(0); final Batch firstRtcWakeup = findFirstRtcWakeupBatchLocked(); if (firstWakeup != null && mNextWakeup != firstWakeup.start) { mNextWakeup = firstWakeup.start; setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start); Loading @@ -671,6 +698,11 @@ class AlarmManagerService extends IAlarmManager.Stub { mNextNonWakeup = firstBatch.start; setLocked(ELAPSED_REALTIME, firstBatch.start); } if (firstRtcWakeup != null && mNextRtcWakeup != firstRtcWakeup.start) { mNextRtcWakeup = firstRtcWakeup.start; setLocked(RTC_POWEROFF_WAKEUP, firstRtcWakeup.start - SystemClock.elapsedRealtime()); } } } Loading Loading @@ -1046,6 +1078,7 @@ class AlarmManagerService extends IAlarmManager.Stub { case RTC_WAKEUP : return "RTC_WAKEUP"; case ELAPSED_REALTIME : return "ELAPSED"; case ELAPSED_REALTIME_WAKEUP: return "ELAPSED_WAKEUP"; case RTC_POWEROFF_WAKEUP : return "RTC_POWEROFF_WAKEUP"; default: break; } Loading Loading @@ -1252,7 +1285,6 @@ class AlarmManagerService extends IAlarmManager.Stub { recordWakeupAlarms(mAlarmBatches, nowELAPSED, nowRTC); } } triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC); rescheduleKernelAlarmsLocked(); Loading Loading @@ -1293,7 +1325,8 @@ class AlarmManagerService extends IAlarmManager.Stub { fs.nesting++; } if (alarm.type == ELAPSED_REALTIME_WAKEUP || alarm.type == RTC_WAKEUP) { || alarm.type == RTC_WAKEUP || alarm.type == RTC_POWEROFF_WAKEUP) { bs.numWakeup++; fs.numWakeup++; ActivityManagerNative.noteWakeupAlarm( Loading Loading
core/java/android/app/AlarmManager.java +6 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,12 @@ public class AlarmManager * wakes up. */ public static final int ELAPSED_REALTIME = 3; /** @hide * Alarm time in {@link System#currentTimeMillis System.currentTimeMillis()} * (wall clock time in UTC), which will wake up the device when * it goes off. And it will power on the devices when it shuts down. */ public static final int RTC_POWEROFF_WAKEUP = 4; /** @hide */ public static final long WINDOW_EXACT = 0; Loading
services/java/com/android/server/AlarmManagerService.java +38 −5 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ import static android.app.AlarmManager.RTC_WAKEUP; import static android.app.AlarmManager.RTC; import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; import static android.app.AlarmManager.ELAPSED_REALTIME; import static android.app.AlarmManager.RTC_POWEROFF_WAKEUP; import com.android.internal.util.LocalLog; Loading @@ -75,6 +76,7 @@ class AlarmManagerService extends IAlarmManager.Stub { private static final int RTC_MASK = 1 << RTC; private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP; private static final int ELAPSED_REALTIME_MASK = 1 << ELAPSED_REALTIME; private static final int RTC_POWEROFF_WAKEUP_MASK = 1 << RTC_POWEROFF_WAKEUP; private static final int TIME_CHANGED_MASK = 1 << 16; private static final int IS_WAKEUP_MASK = RTC_WAKEUP_MASK|ELAPSED_REALTIME_WAKEUP_MASK; Loading Loading @@ -106,6 +108,7 @@ class AlarmManagerService extends IAlarmManager.Stub { private int mDescriptor; private long mNextWakeup; private long mNextRtcWakeup; private long mNextNonWakeup; private int mBroadcastRefCount = 0; private PowerManager.WakeLock mWakeLock; Loading Loading @@ -292,6 +295,18 @@ class AlarmManagerService extends IAlarmManager.Stub { return false; } boolean isRtcPowerOffWakeup() { final int N = alarms.size(); for (int i = 0; i < N; i++) { Alarm a = alarms.get(i); // non-wakeup alarms are types 1 and 3, i.e. have the low bit set if (a.type == RTC_POWEROFF_WAKEUP) { return true; } } return false; } @Override public String toString() { StringBuilder b = new StringBuilder(40); Loading Loading @@ -327,7 +342,7 @@ class AlarmManagerService extends IAlarmManager.Stub { private final ArrayList<Batch> mAlarmBatches = new ArrayList<Batch>(); static long convertToElapsed(long when, int type) { final boolean isRtc = (type == RTC || type == RTC_WAKEUP); final boolean isRtc = (type == RTC || type == RTC_WAKEUP || type == RTC_POWEROFF_WAKEUP); if (isRtc) { when -= System.currentTimeMillis() - SystemClock.elapsedRealtime(); } Loading Loading @@ -470,7 +485,7 @@ class AlarmManagerService extends IAlarmManager.Stub { public AlarmManagerService(Context context) { mContext = context; mDescriptor = init(); mNextWakeup = mNextNonWakeup = 0; mNextWakeup = mNextRtcWakeup = mNextNonWakeup = 0; // We have to set current TimeZone info to kernel // because kernel doesn't keep this after reboot Loading Loading @@ -540,7 +555,7 @@ class AlarmManagerService extends IAlarmManager.Stub { windowLength = AlarmManager.INTERVAL_HOUR; } if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) { if (type < RTC_WAKEUP || type > RTC_POWEROFF_WAKEUP) { throw new IllegalArgumentException("Invalid alarm type " + type); } Loading Loading @@ -656,6 +671,17 @@ class AlarmManagerService extends IAlarmManager.Stub { } return null; } private Batch findFirstRtcWakeupBatchLocked() { final int N = mAlarmBatches.size(); for (int i = 0; i < N; i++) { Batch b = mAlarmBatches.get(i); if (b.isRtcPowerOffWakeup()) { return b; } } return null; } private void rescheduleKernelAlarmsLocked() { // Schedule the next upcoming wakeup alarm. If there is a deliverable batch Loading @@ -663,6 +689,7 @@ class AlarmManagerService extends IAlarmManager.Stub { if (mAlarmBatches.size() > 0) { final Batch firstWakeup = findFirstWakeupBatchLocked(); final Batch firstBatch = mAlarmBatches.get(0); final Batch firstRtcWakeup = findFirstRtcWakeupBatchLocked(); if (firstWakeup != null && mNextWakeup != firstWakeup.start) { mNextWakeup = firstWakeup.start; setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start); Loading @@ -671,6 +698,11 @@ class AlarmManagerService extends IAlarmManager.Stub { mNextNonWakeup = firstBatch.start; setLocked(ELAPSED_REALTIME, firstBatch.start); } if (firstRtcWakeup != null && mNextRtcWakeup != firstRtcWakeup.start) { mNextRtcWakeup = firstRtcWakeup.start; setLocked(RTC_POWEROFF_WAKEUP, firstRtcWakeup.start - SystemClock.elapsedRealtime()); } } } Loading Loading @@ -1046,6 +1078,7 @@ class AlarmManagerService extends IAlarmManager.Stub { case RTC_WAKEUP : return "RTC_WAKEUP"; case ELAPSED_REALTIME : return "ELAPSED"; case ELAPSED_REALTIME_WAKEUP: return "ELAPSED_WAKEUP"; case RTC_POWEROFF_WAKEUP : return "RTC_POWEROFF_WAKEUP"; default: break; } Loading Loading @@ -1252,7 +1285,6 @@ class AlarmManagerService extends IAlarmManager.Stub { recordWakeupAlarms(mAlarmBatches, nowELAPSED, nowRTC); } } triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC); rescheduleKernelAlarmsLocked(); Loading Loading @@ -1293,7 +1325,8 @@ class AlarmManagerService extends IAlarmManager.Stub { fs.nesting++; } if (alarm.type == ELAPSED_REALTIME_WAKEUP || alarm.type == RTC_WAKEUP) { || alarm.type == RTC_WAKEUP || alarm.type == RTC_POWEROFF_WAKEUP) { bs.numWakeup++; fs.numWakeup++; ActivityManagerNative.noteWakeupAlarm( Loading