diff --git a/api/current.txt b/api/current.txt index 6b8c453e80cbb..6bfc9c54e7b55 100644 --- a/api/current.txt +++ b/api/current.txt @@ -3763,7 +3763,9 @@ package android.app { method public android.app.AlarmManager.AlarmClockInfo getNextAlarmClock(); method public void set(int, long, android.app.PendingIntent); method public void setAlarmClock(android.app.AlarmManager.AlarmClockInfo, android.app.PendingIntent); + method public void setAndAllowWhileIdle(int, long, android.app.PendingIntent); method public void setExact(int, long, android.app.PendingIntent); + method public void setExactAndAllowWhileIdle(int, long, android.app.PendingIntent); method public void setInexactRepeating(int, long, long, android.app.PendingIntent); method public void setRepeating(int, long, long, android.app.PendingIntent); method public void setTime(long); diff --git a/api/system-current.txt b/api/system-current.txt index 19e0e6b4980d4..081e2727e0663 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3853,7 +3853,9 @@ package android.app { method public void set(int, long, android.app.PendingIntent); method public void set(int, long, long, long, android.app.PendingIntent, android.os.WorkSource); method public void setAlarmClock(android.app.AlarmManager.AlarmClockInfo, android.app.PendingIntent); + method public void setAndAllowWhileIdle(int, long, android.app.PendingIntent); method public void setExact(int, long, android.app.PendingIntent); + method public void setExactAndAllowWhileIdle(int, long, android.app.PendingIntent); method public void setInexactRepeating(int, long, long, android.app.PendingIntent); method public void setRepeating(int, long, long, android.app.PendingIntent); method public void setTime(long); diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java index b0fda9c251908..5e7bd0dc39f8e 100644 --- a/core/java/android/app/AlarmManager.java +++ b/core/java/android/app/AlarmManager.java @@ -71,10 +71,7 @@ import java.io.IOException; * {@link android.content.Context#getSystemService * Context.getSystemService(Context.ALARM_SERVICE)}. */ -public class AlarmManager -{ - private static final String TAG = "AlarmManager"; - +public class AlarmManager { /** * Alarm time in {@link System#currentTimeMillis System.currentTimeMillis()} * (wall clock time in UTC), which will wake up the device when @@ -558,7 +555,93 @@ public class AlarmManager long intervalMillis, PendingIntent operation) { setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, intervalMillis, 0, operation, null, null); } - + + /** + * Like {@link #set(int, long, PendingIntent)}, but this alarm will be allowed to execute + * even when the system is in low-power idle modes. This type of alarm must only + * be used for situations where it is actually required that the alarm go off while in + * idle -- a reasonable example would be for a calendar notification that should make a + * sound so the user is aware of it. These alarms can significantly impact the power use + * of the device when idle (and thus cause significant battery blame to the app scheduling + * them), so they should be used with care. + * + *
Unlike other alarms, the system is free to reschedule this type of alarm to happen + * out of order with any other alarms, even those from the same app. This will clearly happen + * when the device is idle (since this alarm can go off while idle, when any other alarms + * from the app will be held until later), but may also happen even when not idle.
+ * + *Regardless of the app's target SDK version, this call always allows batching of the + * alarm.
+ * + * @param type One of {@link #ELAPSED_REALTIME}, {@link #ELAPSED_REALTIME_WAKEUP}, + * {@link #RTC}, or {@link #RTC_WAKEUP}. + * @param triggerAtMillis time in milliseconds that the alarm should go + * off, using the appropriate clock (depending on the alarm type). + * @param operation Action to perform when the alarm goes off; + * typically comes from {@link PendingIntent#getBroadcast + * IntentSender.getBroadcast()}. + * + * @see #set(int, long, PendingIntent) + * @see #setExactAndAllowWhileIdle + * @see #cancel + * @see android.content.Context#sendBroadcast + * @see android.content.Context#registerReceiver + * @see android.content.Intent#filterEquals + * @see #ELAPSED_REALTIME + * @see #ELAPSED_REALTIME_WAKEUP + * @see #RTC + * @see #RTC_WAKEUP + */ + public void setAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation) { + setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, 0, FLAG_ALLOW_WHILE_IDLE, operation, + null, null); + } + + /** + * Like {@link #setExact(int, long, PendingIntent)}, but this alarm will be allowed to execute + * even when the system is in low-power idle modes. If you don't need exact scheduling of + * the alarm but still need to execute while idle, consider using + * {@link #setAndAllowWhileIdle}. This type of alarm must only + * be used for situations where it is actually required that the alarm go off while in + * idle -- a reasonable example would be for a calendar notification that should make a + * sound so the user is aware of it. These alarms can significantly impact the power use + * of the device when idle (and thus cause significant battery blame to the app scheduling + * them), so they should be used with care. + * + *Unlike other alarms, the system is free to reschedule this type of alarm to happen + * out of order with any other alarms, even those from the same app. This will clearly happen + * when the device is idle (since this alarm can go off while idle, when any other alarms + * from the app will be held until later), but may also happen even when not idle. + * Note that the OS will allow itself more flexibility for scheduling these alarms than + * regular exact alarms, since the application has opted into this behavior. When the + * device is idle it may take even more liberties with scheduling in order to optimize + * for battery life.
+ * + * @param type One of {@link #ELAPSED_REALTIME}, {@link #ELAPSED_REALTIME_WAKEUP}, + * {@link #RTC}, or {@link #RTC_WAKEUP}. + * @param triggerAtMillis time in milliseconds that the alarm should go + * off, using the appropriate clock (depending on the alarm type). + * @param operation Action to perform when the alarm goes off; + * typically comes from {@link PendingIntent#getBroadcast + * IntentSender.getBroadcast()}. + * + * @see #set + * @see #setRepeating + * @see #setWindow + * @see #cancel + * @see android.content.Context#sendBroadcast + * @see android.content.Context#registerReceiver + * @see android.content.Intent#filterEquals + * @see #ELAPSED_REALTIME + * @see #ELAPSED_REALTIME_WAKEUP + * @see #RTC + * @see #RTC_WAKEUP + */ + public void setExactAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation) { + setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, FLAG_ALLOW_WHILE_IDLE, operation, + null, null); + } + /** * Remove any alarms with a matching {@link Intent}. * Any alarm, of any type, whose Intent matches this one (as defined by diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java index 00ab262fda4e8..9a0d0d094d25f 100644 --- a/core/java/android/os/PowerManagerInternal.java +++ b/core/java/android/os/PowerManagerInternal.java @@ -134,4 +134,6 @@ public abstract class PowerManagerInternal { } public abstract void setDeviceIdleMode(boolean enabled); + + public abstract void setDeviceIdleWhitelist(int[] appids); } diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index b7bc0f02ea4f6..76465d45a180c 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -142,6 +142,7 @@ public class DeviceIdleController extends SystemService { private PendingIntent mAlarmIntent; private Intent mIdleIntent; private Display mCurDisplay; + private boolean mIdleDisabled; private boolean mScreenOn; private boolean mCharging; private boolean mSigMotionActive; @@ -187,10 +188,16 @@ public class DeviceIdleController extends SystemService { private final ArrayMap