Loading api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -3761,7 +3761,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); api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -3851,7 +3851,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); core/java/android/app/AlarmManager.java +88 −5 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -559,6 +556,92 @@ public class AlarmManager 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 <b>only</b> * 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. * * <p>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.</p> * * <p>Regardless of the app's target SDK version, this call always allows batching of the * alarm.</p> * * @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 <b>only</b> * 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. * * <p>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.</p> * * @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 Loading core/java/android/os/PowerManagerInternal.java +2 −0 Original line number Diff line number Diff line Loading @@ -134,4 +134,6 @@ public abstract class PowerManagerInternal { } public abstract void setDeviceIdleMode(boolean enabled); public abstract void setDeviceIdleWhitelist(int[] appids); } services/core/java/com/android/server/DeviceIdleController.java +46 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -187,10 +188,16 @@ public class DeviceIdleController extends SystemService { private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>(); /** * UIDs that have been white-listed to opt out of power save restrictions. * App IDs that have been white-listed to opt out of power save restrictions. */ private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray(); /** * Current app IDs that are in the complete power save white list. This array can * be shared with others because it will not be modified once set. */ private int[] mPowerSaveWhitelistAppIdArray = new int[0]; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) { Loading Loading @@ -381,6 +388,8 @@ public class DeviceIdleController extends SystemService { filter.addAction(ACTION_STEP_IDLE_STATE); getContext().registerReceiver(mReceiver, filter); mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAppIdArray); mDisplayManager.registerDisplayListener(mDisplayListener, null); updateDisplayLocked(); } Loading Loading @@ -445,12 +454,7 @@ public class DeviceIdleController extends SystemService { public int[] getAppIdWhitelistInternal() { synchronized (this) { int size = mPowerSaveWhitelistAppIds.size(); int[] appids = new int[size]; for (int i = 0; i < size; i++) { appids[i] = mPowerSaveWhitelistAppIds.keyAt(i); } return appids; return mPowerSaveWhitelistAppIdArray; } } Loading Loading @@ -499,7 +503,7 @@ public class DeviceIdleController extends SystemService { } void becomeInactiveIfAppropriateLocked() { if (!mScreenOn && !mCharging && mState == STATE_ACTIVE) { if (!mScreenOn && !mCharging && !mIdleDisabled && mState == STATE_ACTIVE) { // Screen has turned off; we are now going to become inactive and start // waiting to see if we will ultimately go idle. mState = STATE_INACTIVE; Loading Loading @@ -625,6 +629,15 @@ public class DeviceIdleController extends SystemService { for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) { mPowerSaveWhitelistAppIds.put(mPowerSaveWhitelistUserApps.valueAt(i), true); } int size = mPowerSaveWhitelistAppIds.size(); int[] appids = new int[size]; for (int i = 0; i < size; i++) { appids[i] = mPowerSaveWhitelistAppIds.keyAt(i); } mPowerSaveWhitelistAppIdArray = appids; if (mLocalPowerManager != null) { mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAppIdArray); } } private void reportPowerSaveWhitelistChangedLocked() { Loading Loading @@ -763,6 +776,10 @@ public class DeviceIdleController extends SystemService { pw.println("Commands:"); pw.println(" step"); pw.println(" Immediately step to next state, without waiting for alarm."); pw.println(" disable"); pw.println(" Completely disable device idle mode."); pw.println(" enable"); pw.println(" Re-enable device idle mode after it had previously been disabled."); pw.println(" whitelist"); pw.println(" Add (prefix with +) or remove (prefix with -) packages."); } Loading @@ -782,12 +799,32 @@ public class DeviceIdleController extends SystemService { if ("-h".equals(arg)) { dumpHelp(pw); return; } else if ("-a".equals(arg)) { // Ignore, we always dump all. } else if ("step".equals(arg)) { synchronized (this) { stepIdleStateLocked(); pw.print("Stepped to: "); pw.println(stateToString(mState)); } return; } else if ("disable".equals(arg)) { synchronized (this) { if (!mIdleDisabled) { mIdleDisabled = true; becomeActiveLocked("disabled"); pw.println("Idle mode disabled"); } } return; } else if ("enable".equals(arg)) { synchronized (this) { if (mIdleDisabled) { mIdleDisabled = false; becomeInactiveIfAppropriateLocked(); pw.println("Idle mode enabled"); } } return; } else if ("whitelist".equals(arg)) { i++; while (i < args.length) { Loading Loading @@ -853,6 +890,7 @@ public class DeviceIdleController extends SystemService { } pw.print(" mSigMotionSensor="); pw.println(mSigMotionSensor); pw.print(" mCurDisplay="); pw.println(mCurDisplay); pw.print(" mIdleDisabled="); pw.println(mIdleDisabled); pw.print(" mScreenOn="); pw.println(mScreenOn); pw.print(" mCharging="); pw.println(mCharging); pw.print(" mSigMotionActive="); pw.println(mSigMotionActive); Loading Loading
api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -3761,7 +3761,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);
api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -3851,7 +3851,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);
core/java/android/app/AlarmManager.java +88 −5 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -559,6 +556,92 @@ public class AlarmManager 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 <b>only</b> * 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. * * <p>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.</p> * * <p>Regardless of the app's target SDK version, this call always allows batching of the * alarm.</p> * * @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 <b>only</b> * 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. * * <p>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.</p> * * @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 Loading
core/java/android/os/PowerManagerInternal.java +2 −0 Original line number Diff line number Diff line Loading @@ -134,4 +134,6 @@ public abstract class PowerManagerInternal { } public abstract void setDeviceIdleMode(boolean enabled); public abstract void setDeviceIdleWhitelist(int[] appids); }
services/core/java/com/android/server/DeviceIdleController.java +46 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -187,10 +188,16 @@ public class DeviceIdleController extends SystemService { private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>(); /** * UIDs that have been white-listed to opt out of power save restrictions. * App IDs that have been white-listed to opt out of power save restrictions. */ private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray(); /** * Current app IDs that are in the complete power save white list. This array can * be shared with others because it will not be modified once set. */ private int[] mPowerSaveWhitelistAppIdArray = new int[0]; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) { Loading Loading @@ -381,6 +388,8 @@ public class DeviceIdleController extends SystemService { filter.addAction(ACTION_STEP_IDLE_STATE); getContext().registerReceiver(mReceiver, filter); mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAppIdArray); mDisplayManager.registerDisplayListener(mDisplayListener, null); updateDisplayLocked(); } Loading Loading @@ -445,12 +454,7 @@ public class DeviceIdleController extends SystemService { public int[] getAppIdWhitelistInternal() { synchronized (this) { int size = mPowerSaveWhitelistAppIds.size(); int[] appids = new int[size]; for (int i = 0; i < size; i++) { appids[i] = mPowerSaveWhitelistAppIds.keyAt(i); } return appids; return mPowerSaveWhitelistAppIdArray; } } Loading Loading @@ -499,7 +503,7 @@ public class DeviceIdleController extends SystemService { } void becomeInactiveIfAppropriateLocked() { if (!mScreenOn && !mCharging && mState == STATE_ACTIVE) { if (!mScreenOn && !mCharging && !mIdleDisabled && mState == STATE_ACTIVE) { // Screen has turned off; we are now going to become inactive and start // waiting to see if we will ultimately go idle. mState = STATE_INACTIVE; Loading Loading @@ -625,6 +629,15 @@ public class DeviceIdleController extends SystemService { for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) { mPowerSaveWhitelistAppIds.put(mPowerSaveWhitelistUserApps.valueAt(i), true); } int size = mPowerSaveWhitelistAppIds.size(); int[] appids = new int[size]; for (int i = 0; i < size; i++) { appids[i] = mPowerSaveWhitelistAppIds.keyAt(i); } mPowerSaveWhitelistAppIdArray = appids; if (mLocalPowerManager != null) { mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAppIdArray); } } private void reportPowerSaveWhitelistChangedLocked() { Loading Loading @@ -763,6 +776,10 @@ public class DeviceIdleController extends SystemService { pw.println("Commands:"); pw.println(" step"); pw.println(" Immediately step to next state, without waiting for alarm."); pw.println(" disable"); pw.println(" Completely disable device idle mode."); pw.println(" enable"); pw.println(" Re-enable device idle mode after it had previously been disabled."); pw.println(" whitelist"); pw.println(" Add (prefix with +) or remove (prefix with -) packages."); } Loading @@ -782,12 +799,32 @@ public class DeviceIdleController extends SystemService { if ("-h".equals(arg)) { dumpHelp(pw); return; } else if ("-a".equals(arg)) { // Ignore, we always dump all. } else if ("step".equals(arg)) { synchronized (this) { stepIdleStateLocked(); pw.print("Stepped to: "); pw.println(stateToString(mState)); } return; } else if ("disable".equals(arg)) { synchronized (this) { if (!mIdleDisabled) { mIdleDisabled = true; becomeActiveLocked("disabled"); pw.println("Idle mode disabled"); } } return; } else if ("enable".equals(arg)) { synchronized (this) { if (mIdleDisabled) { mIdleDisabled = false; becomeInactiveIfAppropriateLocked(); pw.println("Idle mode enabled"); } } return; } else if ("whitelist".equals(arg)) { i++; while (i < args.length) { Loading Loading @@ -853,6 +890,7 @@ public class DeviceIdleController extends SystemService { } pw.print(" mSigMotionSensor="); pw.println(mSigMotionSensor); pw.print(" mCurDisplay="); pw.println(mCurDisplay); pw.print(" mIdleDisabled="); pw.println(mIdleDisabled); pw.print(" mScreenOn="); pw.println(mScreenOn); pw.print(" mCharging="); pw.println(mCharging); pw.print(" mSigMotionActive="); pw.println(mSigMotionActive); Loading