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

Commit 4870e9d5 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

More work on device idle mode and other power stuff.

Add idle mode support to the alarm manager.  Introduce
a new concept of flags associated with alarms to tell
the alarm manager how to treat the alarm -- they allow
everything from the alarm that will bring us out of idle
mode, to alarms that are allowed when idle or should
also bring us out of idle.  The standalone boolean is
now also a flag.

(Note there is currently no protection from user space
setting the flags however it wants; I will be working
on that in a follow-up change.)

When in idle mode, the alarm manager pushes all alarms
that shouldn't execute during that time over to a
separate list that is not executed until out of idle.
To help with this, I reworked a bit how Alarm objects
are managed, so that when rebatching or moving between
lists we don't have to allocated new objects but can
just use the same existing instance.

Also tweaked the sync manager to deal with idle mode,
which currently just means doing the same thing as when
low on storage -- turning off sync.

Add new ACTION_CHARGING and ACTION_DISCHARGING broadcasts
that apps can listen for to know when the device is actively
charging and discharging.  These are better than the old
POWER_CONNECTED and POWER_DISCONNECTED ones because we only
report charging when we actually see that there is enough
power being provided to charge the battery (and will report
discharging if there is not enough power).

The job controller uses these new actions for scheduling
jobs that want to run while plugged in.  Removed the
"stable charging" stuff while doing so, since the new
charging state serves as an even better signal for that.

Introduced two new process states: FOREGROUND_SERVICE and
TOP_SLEEPING.  This will allow us to treat foreground services
specially (such as still allowing network access to them for
background music playback) while not mixing them together with
whatever happens to be the top activity while the device is
asleep.

Also some other small cleanup here and there.

Change-Id: I7a9808b578bad6f50deb8e1baf919298512a0d3a
parent 7c6a34e6
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -22247,6 +22247,9 @@ package android.os {
  public class BatteryManager {
    method public int getIntProperty(int);
    method public long getLongProperty(int);
    method public boolean isCharging();
    field public static final java.lang.String ACTION_CHARGING = "android.os.action.CHARGING";
    field public static final java.lang.String ACTION_DISCHARGING = "android.os.action.DISCHARGING";
    field public static final int BATTERY_HEALTH_COLD = 7; // 0x7
    field public static final int BATTERY_HEALTH_DEAD = 4; // 0x4
    field public static final int BATTERY_HEALTH_GOOD = 2; // 0x2
+3 −0
Original line number Diff line number Diff line
@@ -24118,6 +24118,9 @@ package android.os {
  public class BatteryManager {
    method public int getIntProperty(int);
    method public long getLongProperty(int);
    method public boolean isCharging();
    field public static final java.lang.String ACTION_CHARGING = "android.os.action.CHARGING";
    field public static final java.lang.String ACTION_DISCHARGING = "android.os.action.DISCHARGING";
    field public static final int BATTERY_HEALTH_COLD = 7; // 0x7
    field public static final int BATTERY_HEALTH_DEAD = 4; // 0x4
    field public static final int BATTERY_HEALTH_GOOD = 2; // 0x2
+18 −12
Original line number Diff line number Diff line
@@ -269,45 +269,51 @@ public class ActivityManager {
     * all activities that are visible to the user. */
    public static final int PROCESS_STATE_TOP = 2;

    /** @hide Process is hosting a foreground service. */
    public static final int PROCESS_STATE_FOREGROUND_SERVICE = 3;

    /** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */
    public static final int PROCESS_STATE_TOP_SLEEPING = 4;

    /** @hide Process is important to the user, and something they are aware of. */
    public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 3;
    public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 5;

    /** @hide Process is important to the user, but not something they are aware of. */
    public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 4;
    public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 6;

    /** @hide Process is in the background running a backup/restore operation. */
    public static final int PROCESS_STATE_BACKUP = 5;
    public static final int PROCESS_STATE_BACKUP = 7;

    /** @hide Process is in the background, but it can't restore its state so we want
     * to try to avoid killing it. */
    public static final int PROCESS_STATE_HEAVY_WEIGHT = 6;
    public static final int PROCESS_STATE_HEAVY_WEIGHT = 8;

    /** @hide Process is in the background running a service.  Unlike oom_adj, this level
     * is used for both the normal running in background state and the executing
     * operations state. */
    public static final int PROCESS_STATE_SERVICE = 7;
    public static final int PROCESS_STATE_SERVICE = 9;

    /** @hide Process is in the background running a receiver.   Note that from the
     * perspective of oom_adj receivers run at a higher foreground level, but for our
     * prioritization here that is not necessary and putting them below services means
     * many fewer changes in some process states as they receive broadcasts. */
    public static final int PROCESS_STATE_RECEIVER = 8;
    public static final int PROCESS_STATE_RECEIVER = 10;

    /** @hide Process is in the background but hosts the home activity. */
    public static final int PROCESS_STATE_HOME = 9;
    public static final int PROCESS_STATE_HOME = 11;

    /** @hide Process is in the background but hosts the last shown activity. */
    public static final int PROCESS_STATE_LAST_ACTIVITY = 10;
    public static final int PROCESS_STATE_LAST_ACTIVITY = 12;

    /** @hide Process is being cached for later use and contains activities. */
    public static final int PROCESS_STATE_CACHED_ACTIVITY = 11;
    public static final int PROCESS_STATE_CACHED_ACTIVITY = 13;

    /** @hide Process is being cached for later use and is a client of another cached
     * process that contains activities. */
    public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 12;
    public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 14;

    /** @hide Process is being cached for later use and is empty. */
    public static final int PROCESS_STATE_CACHED_EMPTY = 13;
    public static final int PROCESS_STATE_CACHED_EMPTY = 15;

    /** @hide requestType for assist context: only basic information. */
    public static final int ASSIST_CONTEXT_BASIC = 0;
@@ -2064,7 +2070,7 @@ public class ActivityManager {
                return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
            } else if (procState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
                return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
            } else if (procState >= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
            } else if (procState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
                return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
            } else {
                return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+54 −9
Original line number Diff line number Diff line
@@ -115,6 +115,40 @@ public class AlarmManager
    /** @hide */
    public static final long WINDOW_HEURISTIC = -1;

    /**
     * Flag for alarms: this is to be a stand-alone alarm, that should not be batched with
     * other alarms.
     * @hide
     */
    public static final int FLAG_STANDALONE = 1<<0;

    /**
     * Flag for alarms: this alarm would like to wake the device even if it is idle.  This
     * is, for example, an alarm for an alarm clock.
     * @hide
     */
    public static final int FLAG_WAKE_FROM_IDLE = 1<<1;

    /**
     * Flag for alarms: this alarm would like to still execute even if the device is
     * idle.  This won't bring the device out of idle, just allow this specific alarm to
     * run.  Note that this means the actual time this alarm goes off can be inconsistent
     * with the time of non-allow-while-idle alarms (it could go earlier than the time
     * requested by another alarm).
     *
     * @hide
     */
    public static final int FLAG_ALLOW_WHILE_IDLE = 1<<2;

    /**
     * Flag for alarms: this alarm marks the point where we would like to come out of idle
     * mode.  It may be moved by the alarm manager to match the first wake-from-idle alarm.
     * Scheduling an alarm with this flag puts the alarm manager in to idle mode, where it
     * avoids scheduling any further alarms until the marker alarm is executed.
     * @hide
     */
    public static final int FLAG_IDLE_UNTIL = 1<<3;

    private final IAlarmManager mService;
    private final boolean mAlwaysExact;

@@ -204,7 +238,7 @@ public class AlarmManager
     * @see #RTC_WAKEUP
     */
    public void set(int type, long triggerAtMillis, PendingIntent operation) {
        setImpl(type, triggerAtMillis, legacyExactLength(), 0, operation, null, null);
        setImpl(type, triggerAtMillis, legacyExactLength(), 0, 0, operation, null, null);
    }

    /**
@@ -265,7 +299,8 @@ public class AlarmManager
     */
    public void setRepeating(int type, long triggerAtMillis,
            long intervalMillis, PendingIntent operation) {
        setImpl(type, triggerAtMillis, legacyExactLength(), intervalMillis, operation, null, null);
        setImpl(type, triggerAtMillis, legacyExactLength(), intervalMillis, 0, operation, null,
                null);
    }

    /**
@@ -315,7 +350,7 @@ public class AlarmManager
     */
    public void setWindow(int type, long windowStartMillis, long windowLengthMillis,
            PendingIntent operation) {
        setImpl(type, windowStartMillis, windowLengthMillis, 0, operation, null, null);
        setImpl(type, windowStartMillis, windowLengthMillis, 0, 0, operation, null, null);
    }

    /**
@@ -353,7 +388,16 @@ public class AlarmManager
     * @see #RTC_WAKEUP
     */
    public void setExact(int type, long triggerAtMillis, PendingIntent operation) {
        setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, operation, null, null);
        setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, 0, operation, null, null);
    }

    /**
     * Schedule an idle-until alarm, which will keep the alarm manager idle until
     * the given time.
     * @hide
     */
    public void setIdleUntil(int type, long triggerAtMillis, PendingIntent operation) {
        setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, FLAG_IDLE_UNTIL, operation, null, null);
    }

    /**
@@ -381,18 +425,19 @@ public class AlarmManager
     * @see android.content.Intent#filterEquals
     */
    public void setAlarmClock(AlarmClockInfo info, PendingIntent operation) {
        setImpl(RTC_WAKEUP, info.getTriggerTime(), WINDOW_EXACT, 0, operation, null, info);
        setImpl(RTC_WAKEUP, info.getTriggerTime(), WINDOW_EXACT, 0, 0, operation, null, info);
    }

    /** @hide */
    @SystemApi
    public void set(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
            PendingIntent operation, WorkSource workSource) {
        setImpl(type, triggerAtMillis, windowMillis, intervalMillis, operation, workSource, null);
        setImpl(type, triggerAtMillis, windowMillis, intervalMillis, 0, operation, workSource,
                null);
    }

    private void setImpl(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
            PendingIntent operation, WorkSource workSource, AlarmClockInfo alarmClock) {
            int flags, PendingIntent operation, WorkSource workSource, AlarmClockInfo alarmClock) {
        if (triggerAtMillis < 0) {
            /* NOTYET
            if (mAlwaysExact) {
@@ -405,7 +450,7 @@ public class AlarmManager
        }

        try {
            mService.set(type, triggerAtMillis, windowMillis, intervalMillis, operation,
            mService.set(type, triggerAtMillis, windowMillis, intervalMillis, flags, operation,
                    workSource, alarmClock);
        } catch (RemoteException ex) {
        }
@@ -506,7 +551,7 @@ public class AlarmManager
     */
    public void setInexactRepeating(int type, long triggerAtMillis,
            long intervalMillis, PendingIntent operation) {
        setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, intervalMillis, operation, null, null);
        setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, intervalMillis, 0, operation, null, null);
    }
    
    /**
+1 −1
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ import android.os.WorkSource;
interface IAlarmManager {
	/** windowLength == 0 means exact; windowLength < 0 means the let the OS decide */
    void set(int type, long triggerAtTime, long windowLength,
            long interval, in PendingIntent operation, in WorkSource workSource,
            long interval, int flags, in PendingIntent operation, in WorkSource workSource,
            in AlarmManager.AlarmClockInfo alarmClock);
    boolean setTime(long millis);
    void setTimeZone(String zone);
Loading