Loading apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java +164 −61 Original line number Diff line number Diff line Loading @@ -16,10 +16,13 @@ package com.android.server.alarm; import static android.app.AlarmManager.ELAPSED_REALTIME; import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; import static android.app.AlarmManager.RTC; import static android.app.AlarmManager.RTC_WAKEUP; import static com.android.server.alarm.AlarmManagerService.clampPositive; import android.app.AlarmManager; import android.app.IAlarmListener; import android.app.PendingIntent; Loading @@ -32,8 +35,28 @@ import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; /** * Class to describe an alarm that is used to the set the kernel timer that returns when the timer * expires. The timer will wake up the device if the alarm is a "wakeup" alarm. */ class Alarm { private static final int NUM_POLICIES = 2; /** * Index used to store the time the alarm was requested to expire. To be used with * {@link #setPolicyElapsed(int, long)} */ public static final int REQUESTER_POLICY_INDEX = 0; /** * Index used to store the earliest time the alarm can expire based on app-standby policy. * To be used with {@link #setPolicyElapsed(int, long)} */ public static final int APP_STANDBY_POLICY_INDEX = 1; public final int type; /** * The original trigger time supplied by the caller. This can be in the elapsed or rtc time base * depending on the type of this alarm */ public final long origWhen; public final boolean wakeup; public final PendingIntent operation; Loading @@ -47,42 +70,40 @@ class Alarm { public final int creatorUid; public final String packageName; public final String sourcePackage; public final long windowLength; public final long repeatInterval; public int count; public long when; public long windowLength; public long whenElapsed; // 'when' in the elapsed time base public long maxWhenElapsed; // also in the elapsed time base // Expected alarm expiry time before app standby deferring is applied. public long expectedWhenElapsed; public long expectedMaxWhenElapsed; public long repeatInterval; /** The earliest time this alarm is eligible to fire according to each policy */ private long[] mPolicyWhenElapsed; /** The ultimate delivery time to be used for this alarm */ private long mWhenElapsed; private long mMaxWhenElapsed; public AlarmManagerService.PriorityClass priorityClass; Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen, long _interval, PendingIntent _op, IAlarmListener _rec, String _listenerTag, WorkSource _ws, int _flags, AlarmManager.AlarmClockInfo _info, int _uid, String _pkgName) { type = _type; origWhen = _when; wakeup = _type == AlarmManager.ELAPSED_REALTIME_WAKEUP || _type == AlarmManager.RTC_WAKEUP; when = _when; whenElapsed = _whenElapsed; expectedWhenElapsed = _whenElapsed; windowLength = _windowLength; maxWhenElapsed = expectedMaxWhenElapsed = AlarmManagerService.clampPositive(_maxWhen); repeatInterval = _interval; operation = _op; listener = _rec; listenerTag = _listenerTag; statsTag = makeTag(_op, _listenerTag, _type); workSource = _ws; flags = _flags; alarmClock = _info; uid = _uid; packageName = _pkgName; Alarm(int type, long when, long requestedWhenElapsed, long windowLength, long interval, PendingIntent op, IAlarmListener rec, String listenerTag, WorkSource ws, int flags, AlarmManager.AlarmClockInfo info, int uid, String pkgName) { this.type = type; origWhen = when; wakeup = type == AlarmManager.ELAPSED_REALTIME_WAKEUP || type == AlarmManager.RTC_WAKEUP; mPolicyWhenElapsed = new long[NUM_POLICIES]; mPolicyWhenElapsed[REQUESTER_POLICY_INDEX] = requestedWhenElapsed; mWhenElapsed = requestedWhenElapsed; this.windowLength = windowLength; mMaxWhenElapsed = clampPositive(requestedWhenElapsed + windowLength); repeatInterval = interval; operation = op; listener = rec; this.listenerTag = listenerTag; statsTag = makeTag(op, listenerTag, type); workSource = ws; this.flags = flags; alarmClock = info; this.uid = uid; packageName = pkgName; sourcePackage = (operation != null) ? operation.getCreatorPackage() : packageName; creatorUid = (operation != null) ? operation.getCreatorUid() : uid; creatorUid = (operation != null) ? operation.getCreatorUid() : this.uid; } public static String makeTag(PendingIntent pi, String tag, int type) { Loading @@ -91,13 +112,6 @@ class Alarm { return (pi != null) ? pi.getTag(alarmString) : (alarmString + tag); } public AlarmManagerService.WakeupEvent makeWakeupEvent(long nowRTC) { return new AlarmManagerService.WakeupEvent(nowRTC, creatorUid, (operation != null) ? operation.getIntent().getAction() : ("<listener>:" + listenerTag)); } // Returns true if either matches public boolean matches(PendingIntent pi, IAlarmListener rec) { return (operation != null) Loading @@ -109,6 +123,65 @@ class Alarm { return packageName.equals(sourcePackage); } /** * Get the earliest time this alarm is allowed to expire based on the given policy. * * @param policyIndex The index of the policy. One of [{@link #REQUESTER_POLICY_INDEX}, * {@link #APP_STANDBY_POLICY_INDEX}]. */ public long getPolicyElapsed(int policyIndex) { return mPolicyWhenElapsed[policyIndex]; } /** * Get the earliest time that this alarm should be delivered to the requesting app. */ public long getWhenElapsed() { return mWhenElapsed; } /** * Get the latest time that this alarm should be delivered to the requesting app. Will be equal * to {@link #getWhenElapsed()} in case this is an exact alarm. */ public long getMaxWhenElapsed() { return mMaxWhenElapsed; } /** * Set the earliest time this alarm can expire based on the passed policy index. * * @return {@code true} if this change resulted in a change in the ultimate delivery time (or * time window in the case of inexact alarms) of this alarm. * @see #getWhenElapsed() * @see #getMaxWhenElapsed() * @see #getPolicyElapsed(int) */ public boolean setPolicyElapsed(int policyIndex, long policyElapsed) { mPolicyWhenElapsed[policyIndex] = policyElapsed; return updateWhenElapsed(); } /** * @return {@code true} if either {@link #mWhenElapsed} or {@link #mMaxWhenElapsed} changes * due to this call. */ private boolean updateWhenElapsed() { final long oldWhenElapsed = mWhenElapsed; mWhenElapsed = 0; for (int i = 0; i < NUM_POLICIES; i++) { mWhenElapsed = Math.max(mWhenElapsed, mPolicyWhenElapsed[i]); } final long oldMaxWhenElapsed = mMaxWhenElapsed; // windowLength should always be >= 0 here. final long maxRequestedElapsed = clampPositive( mPolicyWhenElapsed[REQUESTER_POLICY_INDEX] + windowLength); mMaxWhenElapsed = Math.max(maxRequestedElapsed, mWhenElapsed); return (oldWhenElapsed != mWhenElapsed) || (oldMaxWhenElapsed != mMaxWhenElapsed); } @Override public String toString() { StringBuilder sb = new StringBuilder(128); Loading @@ -116,11 +189,11 @@ class Alarm { sb.append(Integer.toHexString(System.identityHashCode(this))); sb.append(" type "); sb.append(type); sb.append(" when "); sb.append(when); sb.append(" origWhen "); sb.append(origWhen); sb.append(" "); sb.append(" whenElapsed "); sb.append(whenElapsed); sb.append(getWhenElapsed()); sb.append(" "); sb.append(sourcePackage); sb.append('}'); Loading @@ -136,29 +209,45 @@ class Alarm { dump(ipw, nowELAPSED, sdf); } private static String policyIndexToString(int index) { switch (index) { case REQUESTER_POLICY_INDEX: return "requester"; case APP_STANDBY_POLICY_INDEX: return "app_standby"; default: return "unknown"; } } public static String typeToString(int type) { switch (type) { case RTC: return "RTC"; case RTC_WAKEUP: return "RTC_WAKEUP"; case ELAPSED_REALTIME: return "ELAPSED"; case ELAPSED_REALTIME_WAKEUP: return "ELAPSED_WAKEUP"; default: return "--unknown--"; } } public void dump(IndentingPrintWriter ipw, long nowELAPSED, SimpleDateFormat sdf) { final boolean isRtc = (type == RTC || type == RTC_WAKEUP); ipw.print("tag="); ipw.println(statsTag); ipw.print("type="); ipw.print(type); ipw.print(" expectedWhenElapsed="); TimeUtils.formatDuration(expectedWhenElapsed, nowELAPSED, ipw); ipw.print(" expectedMaxWhenElapsed="); TimeUtils.formatDuration(expectedMaxWhenElapsed, nowELAPSED, ipw); ipw.print(" whenElapsed="); TimeUtils.formatDuration(whenElapsed, nowELAPSED, ipw); ipw.print(" maxWhenElapsed="); TimeUtils.formatDuration(maxWhenElapsed, nowELAPSED, ipw); ipw.print(" when="); ipw.print(typeToString(type)); ipw.print(" origWhen="); if (isRtc) { ipw.print(sdf.format(new Date(when))); ipw.print(sdf.format(new Date(origWhen))); } else { TimeUtils.formatDuration(when, nowELAPSED, ipw); TimeUtils.formatDuration(origWhen, nowELAPSED, ipw); } ipw.println(); ipw.print(" window="); TimeUtils.formatDuration(windowLength, ipw); ipw.print(" repeatInterval="); Loading @@ -168,6 +257,19 @@ class Alarm { ipw.print(" flags=0x"); ipw.println(Integer.toHexString(flags)); ipw.print("policyWhenElapsed:"); for (int i = 0; i < NUM_POLICIES; i++) { ipw.print(" " + policyIndexToString(i) + "="); TimeUtils.formatDuration(mPolicyWhenElapsed[i], nowELAPSED, ipw); } ipw.println(); ipw.print("whenElapsed="); TimeUtils.formatDuration(getWhenElapsed(), nowELAPSED, ipw); ipw.print(" maxWhenElapsed="); TimeUtils.formatDuration(mMaxWhenElapsed, nowELAPSED, ipw); ipw.println(); if (alarmClock != null) { ipw.println("Alarm clock:"); Loading @@ -177,9 +279,10 @@ class Alarm { ipw.print(" showIntent="); ipw.println(alarmClock.getShowIntent()); } if (operation != null) { ipw.print("operation="); ipw.println(operation); } if (listener != null) { ipw.print("listener="); ipw.println(listener.asBinder()); Loading @@ -191,7 +294,7 @@ class Alarm { proto.write(AlarmProto.TAG, statsTag); proto.write(AlarmProto.TYPE, type); proto.write(AlarmProto.TIME_UNTIL_WHEN_ELAPSED_MS, whenElapsed - nowElapsed); proto.write(AlarmProto.TIME_UNTIL_WHEN_ELAPSED_MS, getWhenElapsed() - nowElapsed); proto.write(AlarmProto.WINDOW_LENGTH_MS, windowLength); proto.write(AlarmProto.REPEAT_INTERVAL_MS, repeatInterval); proto.write(AlarmProto.COUNT, count); Loading Loading
apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java +164 −61 Original line number Diff line number Diff line Loading @@ -16,10 +16,13 @@ package com.android.server.alarm; import static android.app.AlarmManager.ELAPSED_REALTIME; import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; import static android.app.AlarmManager.RTC; import static android.app.AlarmManager.RTC_WAKEUP; import static com.android.server.alarm.AlarmManagerService.clampPositive; import android.app.AlarmManager; import android.app.IAlarmListener; import android.app.PendingIntent; Loading @@ -32,8 +35,28 @@ import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; /** * Class to describe an alarm that is used to the set the kernel timer that returns when the timer * expires. The timer will wake up the device if the alarm is a "wakeup" alarm. */ class Alarm { private static final int NUM_POLICIES = 2; /** * Index used to store the time the alarm was requested to expire. To be used with * {@link #setPolicyElapsed(int, long)} */ public static final int REQUESTER_POLICY_INDEX = 0; /** * Index used to store the earliest time the alarm can expire based on app-standby policy. * To be used with {@link #setPolicyElapsed(int, long)} */ public static final int APP_STANDBY_POLICY_INDEX = 1; public final int type; /** * The original trigger time supplied by the caller. This can be in the elapsed or rtc time base * depending on the type of this alarm */ public final long origWhen; public final boolean wakeup; public final PendingIntent operation; Loading @@ -47,42 +70,40 @@ class Alarm { public final int creatorUid; public final String packageName; public final String sourcePackage; public final long windowLength; public final long repeatInterval; public int count; public long when; public long windowLength; public long whenElapsed; // 'when' in the elapsed time base public long maxWhenElapsed; // also in the elapsed time base // Expected alarm expiry time before app standby deferring is applied. public long expectedWhenElapsed; public long expectedMaxWhenElapsed; public long repeatInterval; /** The earliest time this alarm is eligible to fire according to each policy */ private long[] mPolicyWhenElapsed; /** The ultimate delivery time to be used for this alarm */ private long mWhenElapsed; private long mMaxWhenElapsed; public AlarmManagerService.PriorityClass priorityClass; Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen, long _interval, PendingIntent _op, IAlarmListener _rec, String _listenerTag, WorkSource _ws, int _flags, AlarmManager.AlarmClockInfo _info, int _uid, String _pkgName) { type = _type; origWhen = _when; wakeup = _type == AlarmManager.ELAPSED_REALTIME_WAKEUP || _type == AlarmManager.RTC_WAKEUP; when = _when; whenElapsed = _whenElapsed; expectedWhenElapsed = _whenElapsed; windowLength = _windowLength; maxWhenElapsed = expectedMaxWhenElapsed = AlarmManagerService.clampPositive(_maxWhen); repeatInterval = _interval; operation = _op; listener = _rec; listenerTag = _listenerTag; statsTag = makeTag(_op, _listenerTag, _type); workSource = _ws; flags = _flags; alarmClock = _info; uid = _uid; packageName = _pkgName; Alarm(int type, long when, long requestedWhenElapsed, long windowLength, long interval, PendingIntent op, IAlarmListener rec, String listenerTag, WorkSource ws, int flags, AlarmManager.AlarmClockInfo info, int uid, String pkgName) { this.type = type; origWhen = when; wakeup = type == AlarmManager.ELAPSED_REALTIME_WAKEUP || type == AlarmManager.RTC_WAKEUP; mPolicyWhenElapsed = new long[NUM_POLICIES]; mPolicyWhenElapsed[REQUESTER_POLICY_INDEX] = requestedWhenElapsed; mWhenElapsed = requestedWhenElapsed; this.windowLength = windowLength; mMaxWhenElapsed = clampPositive(requestedWhenElapsed + windowLength); repeatInterval = interval; operation = op; listener = rec; this.listenerTag = listenerTag; statsTag = makeTag(op, listenerTag, type); workSource = ws; this.flags = flags; alarmClock = info; this.uid = uid; packageName = pkgName; sourcePackage = (operation != null) ? operation.getCreatorPackage() : packageName; creatorUid = (operation != null) ? operation.getCreatorUid() : uid; creatorUid = (operation != null) ? operation.getCreatorUid() : this.uid; } public static String makeTag(PendingIntent pi, String tag, int type) { Loading @@ -91,13 +112,6 @@ class Alarm { return (pi != null) ? pi.getTag(alarmString) : (alarmString + tag); } public AlarmManagerService.WakeupEvent makeWakeupEvent(long nowRTC) { return new AlarmManagerService.WakeupEvent(nowRTC, creatorUid, (operation != null) ? operation.getIntent().getAction() : ("<listener>:" + listenerTag)); } // Returns true if either matches public boolean matches(PendingIntent pi, IAlarmListener rec) { return (operation != null) Loading @@ -109,6 +123,65 @@ class Alarm { return packageName.equals(sourcePackage); } /** * Get the earliest time this alarm is allowed to expire based on the given policy. * * @param policyIndex The index of the policy. One of [{@link #REQUESTER_POLICY_INDEX}, * {@link #APP_STANDBY_POLICY_INDEX}]. */ public long getPolicyElapsed(int policyIndex) { return mPolicyWhenElapsed[policyIndex]; } /** * Get the earliest time that this alarm should be delivered to the requesting app. */ public long getWhenElapsed() { return mWhenElapsed; } /** * Get the latest time that this alarm should be delivered to the requesting app. Will be equal * to {@link #getWhenElapsed()} in case this is an exact alarm. */ public long getMaxWhenElapsed() { return mMaxWhenElapsed; } /** * Set the earliest time this alarm can expire based on the passed policy index. * * @return {@code true} if this change resulted in a change in the ultimate delivery time (or * time window in the case of inexact alarms) of this alarm. * @see #getWhenElapsed() * @see #getMaxWhenElapsed() * @see #getPolicyElapsed(int) */ public boolean setPolicyElapsed(int policyIndex, long policyElapsed) { mPolicyWhenElapsed[policyIndex] = policyElapsed; return updateWhenElapsed(); } /** * @return {@code true} if either {@link #mWhenElapsed} or {@link #mMaxWhenElapsed} changes * due to this call. */ private boolean updateWhenElapsed() { final long oldWhenElapsed = mWhenElapsed; mWhenElapsed = 0; for (int i = 0; i < NUM_POLICIES; i++) { mWhenElapsed = Math.max(mWhenElapsed, mPolicyWhenElapsed[i]); } final long oldMaxWhenElapsed = mMaxWhenElapsed; // windowLength should always be >= 0 here. final long maxRequestedElapsed = clampPositive( mPolicyWhenElapsed[REQUESTER_POLICY_INDEX] + windowLength); mMaxWhenElapsed = Math.max(maxRequestedElapsed, mWhenElapsed); return (oldWhenElapsed != mWhenElapsed) || (oldMaxWhenElapsed != mMaxWhenElapsed); } @Override public String toString() { StringBuilder sb = new StringBuilder(128); Loading @@ -116,11 +189,11 @@ class Alarm { sb.append(Integer.toHexString(System.identityHashCode(this))); sb.append(" type "); sb.append(type); sb.append(" when "); sb.append(when); sb.append(" origWhen "); sb.append(origWhen); sb.append(" "); sb.append(" whenElapsed "); sb.append(whenElapsed); sb.append(getWhenElapsed()); sb.append(" "); sb.append(sourcePackage); sb.append('}'); Loading @@ -136,29 +209,45 @@ class Alarm { dump(ipw, nowELAPSED, sdf); } private static String policyIndexToString(int index) { switch (index) { case REQUESTER_POLICY_INDEX: return "requester"; case APP_STANDBY_POLICY_INDEX: return "app_standby"; default: return "unknown"; } } public static String typeToString(int type) { switch (type) { case RTC: return "RTC"; case RTC_WAKEUP: return "RTC_WAKEUP"; case ELAPSED_REALTIME: return "ELAPSED"; case ELAPSED_REALTIME_WAKEUP: return "ELAPSED_WAKEUP"; default: return "--unknown--"; } } public void dump(IndentingPrintWriter ipw, long nowELAPSED, SimpleDateFormat sdf) { final boolean isRtc = (type == RTC || type == RTC_WAKEUP); ipw.print("tag="); ipw.println(statsTag); ipw.print("type="); ipw.print(type); ipw.print(" expectedWhenElapsed="); TimeUtils.formatDuration(expectedWhenElapsed, nowELAPSED, ipw); ipw.print(" expectedMaxWhenElapsed="); TimeUtils.formatDuration(expectedMaxWhenElapsed, nowELAPSED, ipw); ipw.print(" whenElapsed="); TimeUtils.formatDuration(whenElapsed, nowELAPSED, ipw); ipw.print(" maxWhenElapsed="); TimeUtils.formatDuration(maxWhenElapsed, nowELAPSED, ipw); ipw.print(" when="); ipw.print(typeToString(type)); ipw.print(" origWhen="); if (isRtc) { ipw.print(sdf.format(new Date(when))); ipw.print(sdf.format(new Date(origWhen))); } else { TimeUtils.formatDuration(when, nowELAPSED, ipw); TimeUtils.formatDuration(origWhen, nowELAPSED, ipw); } ipw.println(); ipw.print(" window="); TimeUtils.formatDuration(windowLength, ipw); ipw.print(" repeatInterval="); Loading @@ -168,6 +257,19 @@ class Alarm { ipw.print(" flags=0x"); ipw.println(Integer.toHexString(flags)); ipw.print("policyWhenElapsed:"); for (int i = 0; i < NUM_POLICIES; i++) { ipw.print(" " + policyIndexToString(i) + "="); TimeUtils.formatDuration(mPolicyWhenElapsed[i], nowELAPSED, ipw); } ipw.println(); ipw.print("whenElapsed="); TimeUtils.formatDuration(getWhenElapsed(), nowELAPSED, ipw); ipw.print(" maxWhenElapsed="); TimeUtils.formatDuration(mMaxWhenElapsed, nowELAPSED, ipw); ipw.println(); if (alarmClock != null) { ipw.println("Alarm clock:"); Loading @@ -177,9 +279,10 @@ class Alarm { ipw.print(" showIntent="); ipw.println(alarmClock.getShowIntent()); } if (operation != null) { ipw.print("operation="); ipw.println(operation); } if (listener != null) { ipw.print("listener="); ipw.println(listener.asBinder()); Loading @@ -191,7 +294,7 @@ class Alarm { proto.write(AlarmProto.TAG, statsTag); proto.write(AlarmProto.TYPE, type); proto.write(AlarmProto.TIME_UNTIL_WHEN_ELAPSED_MS, whenElapsed - nowElapsed); proto.write(AlarmProto.TIME_UNTIL_WHEN_ELAPSED_MS, getWhenElapsed() - nowElapsed); proto.write(AlarmProto.WINDOW_LENGTH_MS, windowLength); proto.write(AlarmProto.REPEAT_INTERVAL_MS, repeatInterval); proto.write(AlarmProto.COUNT, count); Loading