summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java225
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java278
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmStore.java17
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java45
-rw-r--r--core/java/android/app/SystemServiceRegistry.java8
-rw-r--r--core/java/android/content/Context.java9
-rw-r--r--core/java/android/hardware/devicestate/DeviceStateManager.java38
-rw-r--r--core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java58
-rw-r--r--core/java/android/hardware/devicestate/IDeviceStateManager.aidl20
-rw-r--r--core/proto/android/app/settings_enums.proto5
-rw-r--r--location/java/com/android/internal/location/GpsNetInitiatedHandler.java3
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java13
-rw-r--r--services/core/java/com/android/server/devicestate/DeviceStateManagerService.java12
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java152
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java88
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java122
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/BackgroundRestrictedAlarmsTest.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/Constants.java22
-rw-r--r--services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java2
-rw-r--r--telecomm/java/android/telecom/CallerInfo.java3
-rw-r--r--telecomm/java/android/telecom/CallerInfoAsyncQuery.java4
21 files changed, 824 insertions, 302 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
index f672e4b711c4..45ea23321d15 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
@@ -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;
@@ -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;
@@ -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) {
@@ -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)
@@ -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);
@@ -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('}');
@@ -136,30 +209,46 @@ 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=");
+ ipw.print(" window=");
TimeUtils.formatDuration(windowLength, ipw);
ipw.print(" repeatInterval=");
ipw.print(repeatInterval);
@@ -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:");
@@ -177,9 +279,10 @@ class Alarm {
ipw.print(" showIntent=");
ipw.println(alarmClock.getShowIntent());
}
- ipw.print("operation=");
- ipw.println(operation);
-
+ if (operation != null) {
+ ipw.print("operation=");
+ ipw.println(operation);
+ }
if (listener != null) {
ipw.print("listener=");
ipw.println(listener.asBinder());
@@ -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);
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 05910a5b171e..82819dab0f69 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -26,6 +26,9 @@ import static android.app.AlarmManager.RTC_WAKEUP;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.os.UserHandle.USER_SYSTEM;
+import static com.android.server.alarm.Alarm.APP_STANDBY_POLICY_INDEX;
+import static com.android.server.alarm.Alarm.REQUESTER_POLICY_INDEX;
+
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.Activity;
@@ -727,9 +730,9 @@ public class AlarmManagerService extends SystemService {
}
// within each class, sort by nominal delivery time
- if (lhs.whenElapsed < rhs.whenElapsed) {
+ if (lhs.getWhenElapsed() < rhs.getWhenElapsed()) {
return -1;
- } else if (lhs.whenElapsed > rhs.whenElapsed) {
+ } else if (lhs.getWhenElapsed() > rhs.getWhenElapsed()) {
return 1;
}
@@ -798,9 +801,12 @@ public class AlarmManagerService extends SystemService {
this(context, new Injector(context));
}
+ private static boolean isRtc(int type) {
+ return (type == RTC || type == RTC_WAKEUP);
+ }
+
private long convertToElapsed(long when, int type) {
- final boolean isRtc = (type == RTC || type == RTC_WAKEUP);
- if (isRtc) {
+ if (isRtc(type)) {
when -= mInjector.getCurrentTimeMillis() - mInjector.getElapsedRealtime();
}
return when;
@@ -823,13 +829,29 @@ public class AlarmManagerService extends SystemService {
}
// The RTC clock has moved arbitrarily, so we need to recalculate all the RTC alarm deliveries.
- void reevaluateRtcAlarms(final long nowElapsed) {
+ void reevaluateRtcAlarms() {
synchronized (mLock) {
- final ArrayList<Alarm> rtcAlarms = mAlarmStore.remove(a -> (a.type == RTC
- || a.type == RTC_WAKEUP));
- for (final Alarm a : rtcAlarms) {
- restoreAlarmLocked(a, nowElapsed);
- setImplLocked(a);
+ boolean changed = mAlarmStore.updateAlarmDeliveries(a -> {
+ if (!isRtc(a.type)) {
+ return false;
+ }
+ return restoreRequestedTime(a);
+ });
+
+ if (mNextWakeFromIdle != null && isRtc(mNextWakeFromIdle.type)) {
+ // The next wake from idle got updated due to the rtc time change, implying we need
+ // to update the time we have to come out of idle too.
+ changed |= mAlarmStore.updateAlarmDeliveries(a -> {
+ if (a != mPendingIdleUntil) {
+ return false;
+ }
+ return adjustIdleUntilTime(a);
+ });
+ }
+
+ if (changed) {
+ rescheduleKernelAlarmsLocked();
+ // Only time shifted, so the next alarm clock will not change
}
}
}
@@ -844,7 +866,7 @@ public class AlarmManagerService extends SystemService {
boolean reorderAlarmsBasedOnStandbyBuckets(ArraySet<Pair<String, Integer>> targetPackages) {
final long start = mStatLogger.getTime();
- final boolean changed = mAlarmStore.recalculateAlarmDeliveries(a -> {
+ final boolean changed = mAlarmStore.updateAlarmDeliveries(a -> {
final Pair<String, Integer> packageUser =
Pair.create(a.sourcePackage, UserHandle.getUserId(a.creatorUid));
if (targetPackages != null && !targetPackages.contains(packageUser)) {
@@ -857,23 +879,8 @@ public class AlarmManagerService extends SystemService {
return changed;
}
- private void restoreAlarmLocked(Alarm a, long nowElapsed) {
- a.when = a.origWhen;
- long whenElapsed = convertToElapsed(a.when, a.type);
- final long maxElapsed;
- if (a.windowLength == AlarmManager.WINDOW_EXACT) {
- // Exact
- maxElapsed = whenElapsed;
- } else {
- // Not exact. Preserve any explicit window, otherwise recalculate
- // the window based on the alarm's new futurity. Note that this
- // reflects a policy of preferring timely to deferred delivery.
- maxElapsed = (a.windowLength > 0)
- ? clampPositive(whenElapsed + a.windowLength)
- : maxTriggerTime(nowElapsed, whenElapsed, a.repeatInterval);
- }
- a.expectedWhenElapsed = a.whenElapsed = whenElapsed;
- a.expectedMaxWhenElapsed = a.maxWhenElapsed = maxElapsed;
+ private boolean restoreRequestedTime(Alarm a) {
+ return a.setPolicyElapsed(REQUESTER_POLICY_INDEX, convertToElapsed(a.origWhen, a.type));
}
static long clampPositive(long val) {
@@ -973,14 +980,17 @@ public class AlarmManagerService extends SystemService {
// Recurring alarms may have passed several alarm intervals while the
// alarm was kept pending. Send the appropriate trigger count.
if (alarm.repeatInterval > 0) {
- alarm.count += (nowELAPSED - alarm.expectedWhenElapsed) / alarm.repeatInterval;
+ alarm.count += (nowELAPSED - alarm.getPolicyElapsed(REQUESTER_POLICY_INDEX))
+ / alarm.repeatInterval;
// Also schedule its next recurrence
final long delta = alarm.count * alarm.repeatInterval;
- final long nextElapsed = alarm.expectedWhenElapsed + delta;
- setImplLocked(alarm.type, alarm.when + delta, nextElapsed, alarm.windowLength,
- maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval),
- alarm.repeatInterval, alarm.operation, null, null, alarm.flags,
- alarm.workSource, alarm.alarmClock, alarm.uid, alarm.packageName);
+ final long nextElapsed = alarm.getPolicyElapsed(REQUESTER_POLICY_INDEX) + delta;
+ final long nextMaxElapsed = maxTriggerTime(nowELAPSED, nextElapsed,
+ alarm.repeatInterval);
+ setImplLocked(alarm.type, alarm.origWhen + delta, nextElapsed,
+ nextMaxElapsed - nextElapsed, alarm.repeatInterval, alarm.operation, null,
+ null, alarm.flags, alarm.workSource, alarm.alarmClock, alarm.uid,
+ alarm.packageName);
// Kernel alarms will be rescheduled as needed in setImplLocked
}
}
@@ -1026,18 +1036,10 @@ public class AlarmManagerService extends SystemService {
if (mPendingWhileIdleAlarms.size() > 0) {
ArrayList<Alarm> alarms = mPendingWhileIdleAlarms;
mPendingWhileIdleAlarms = new ArrayList<>();
- final long nowElapsed = mInjector.getElapsedRealtime();
for (int i = alarms.size() - 1; i >= 0; i--) {
- Alarm a = alarms.get(i);
- restoreAlarmLocked(a, nowElapsed);
- setImplLocked(a);
+ setImplLocked(alarms.get(i));
}
}
-
- // Reschedule everything.
- rescheduleKernelAlarmsLocked();
- updateNextAlarmClockLocked();
-
}
static final class InFlight {
@@ -1449,6 +1451,11 @@ public class AlarmManagerService extends SystemService {
}
}
+ if ((flags & AlarmManager.FLAG_IDLE_UNTIL) != 0) {
+ // Do not support windows for idle-until alarms.
+ windowLength = AlarmManager.WINDOW_EXACT;
+ }
+
// Sanity check the window length. This will catch people mistakenly
// trying to pass an end-of-window timestamp rather than a duration.
if (windowLength > AlarmManager.INTERVAL_HALF_DAY) {
@@ -1515,17 +1522,17 @@ public class AlarmManagerService extends SystemService {
Slog.w(TAG, errorMsg);
throw new IllegalStateException(errorMsg);
}
- setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, maxElapsed,
- interval, operation, directReceiver, listenerTag, flags, workSource,
- alarmClock, callingUid, callingPackage);
+ setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, interval, operation,
+ directReceiver, listenerTag, flags, workSource, alarmClock, callingUid,
+ callingPackage);
}
}
private void setImplLocked(int type, long when, long whenElapsed, long windowLength,
- long maxWhen, long interval, PendingIntent operation, IAlarmListener directReceiver,
+ long interval, PendingIntent operation, IAlarmListener directReceiver,
String listenerTag, int flags, WorkSource workSource,
AlarmManager.AlarmClockInfo alarmClock, int callingUid, String callingPackage) {
- Alarm a = new Alarm(type, when, whenElapsed, windowLength, maxWhen, interval,
+ final Alarm a = new Alarm(type, when, whenElapsed, windowLength, interval,
operation, directReceiver, listenerTag, workSource, flags, alarmClock,
callingUid, callingPackage);
if (mActivityManagerInternal.isAppStartModeDisabled(callingUid, callingPackage)) {
@@ -1560,72 +1567,55 @@ public class AlarmManagerService extends SystemService {
}
/**
- * Adjusts the idle-until alarm delivery time based on the upcoming wake-from-idle alarm.
+ * An alarm with {@link AlarmManager#FLAG_IDLE_UNTIL} is a special alarm that will put the
+ * system into idle until it goes off. We need to pull it earlier if there are existing alarms
+ * that have requested to bring us out of idle at an earlier time.
*
* @param alarm The alarm to adjust
* @return true if the alarm delivery time was updated.
*/
private boolean adjustIdleUntilTime(Alarm alarm) {
- if ((alarm.flags & AlarmManager.FLAG_IDLE_UNTIL) != 0) {
+ if ((alarm.flags & AlarmManager.FLAG_IDLE_UNTIL) == 0) {
return false;
}
- // This is a special alarm that will put the system into idle until it goes off.
- // The caller has given the time they want this to happen at, however we need
- // to pull that earlier if there are existing alarms that have requested to
- // bring us out of idle at an earlier time.
- if (mNextWakeFromIdle != null && alarm.whenElapsed > mNextWakeFromIdle.whenElapsed) {
- alarm.when = alarm.whenElapsed = alarm.maxWhenElapsed = mNextWakeFromIdle.whenElapsed;
+ restoreRequestedTime(alarm);
+ long triggerBeforeFuzz = alarm.getPolicyElapsed(REQUESTER_POLICY_INDEX);
+ if (mNextWakeFromIdle != null && triggerBeforeFuzz > mNextWakeFromIdle.getWhenElapsed()) {
+ triggerBeforeFuzz = mNextWakeFromIdle.getWhenElapsed();
}
// Add fuzz to make the alarm go off some time before the actual desired time.
- final long nowElapsed = mInjector.getElapsedRealtime();
- final int fuzz = fuzzForDuration(alarm.whenElapsed - nowElapsed);
+ final int fuzz = fuzzForDuration(alarm.getWhenElapsed() - mInjector.getElapsedRealtime());
+ final int delta;
if (fuzz > 0) {
if (mRandom == null) {
mRandom = new Random();
}
- final int delta = mRandom.nextInt(fuzz);
- alarm.whenElapsed -= delta;
- if (false) {
- Slog.d(TAG, "Alarm when: " + alarm.whenElapsed);
- Slog.d(TAG, "Delta until alarm: " + (alarm.whenElapsed - nowElapsed));
- Slog.d(TAG, "Applied fuzz: " + fuzz);
- Slog.d(TAG, "Final delta: " + delta);
- Slog.d(TAG, "Final when: " + alarm.whenElapsed);
- }
- alarm.when = alarm.maxWhenElapsed = alarm.whenElapsed;
+ delta = mRandom.nextInt(fuzz);
+ } else {
+ delta = 0;
}
+ alarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, triggerBeforeFuzz - delta);
return true;
}
/**
- * Adjusts the alarm delivery time based on the current app standby bucket.
+ * Adjusts the alarm's policy time for app_standby.
*
- * @param alarm The alarm to adjust
- * @return true if the alarm delivery time was updated.
+ * @param alarm The alarm to update.
+ * @return {@code true} if the actual delivery time of the given alarm was updated due to
+ * adjustments made in this call.
*/
private boolean adjustDeliveryTimeBasedOnBucketLocked(Alarm alarm) {
- if (isExemptFromAppStandby(alarm)) {
- return false;
- }
- if (mAppStandbyParole) {
- if (alarm.whenElapsed > alarm.expectedWhenElapsed) {
- // We did defer this alarm earlier, restore original requirements
- alarm.whenElapsed = alarm.expectedWhenElapsed;
- alarm.maxWhenElapsed = alarm.expectedMaxWhenElapsed;
- return true;
- }
- return false;
+ final long nowElapsed = mInjector.getElapsedRealtime();
+ if (isExemptFromAppStandby(alarm) || mAppStandbyParole) {
+ return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed);
}
- final long oldWhenElapsed = alarm.whenElapsed;
- final long oldMaxWhenElapsed = alarm.maxWhenElapsed;
final String sourcePackage = alarm.sourcePackage;
final int sourceUserId = UserHandle.getUserId(alarm.creatorUid);
final int standbyBucket = mUsageStatsManagerInternal.getAppStandbyBucket(
- sourcePackage, sourceUserId, mInjector.getElapsedRealtime());
+ sourcePackage, sourceUserId, nowElapsed);
- // Quota deferring implementation:
- boolean deferred = false;
final int wakeupsInWindow = mAppWakeupHistory.getTotalWakeupsInWindow(sourcePackage,
sourceUserId);
if (standbyBucket == UsageStatsManager.STANDBY_BUCKET_RESTRICTED) {
@@ -1635,14 +1625,9 @@ public class AlarmManagerService extends SystemService {
if (wakeupsInWindow > 0) {
final long lastWakeupTime = mAppWakeupHistory.getNthLastWakeupForPackage(
sourcePackage, sourceUserId, mConstants.APP_STANDBY_RESTRICTED_QUOTA);
- if (mInjector.getElapsedRealtime() - lastWakeupTime
- < mConstants.APP_STANDBY_RESTRICTED_WINDOW) {
- final long minElapsed =
- lastWakeupTime + mConstants.APP_STANDBY_RESTRICTED_WINDOW;
- if (alarm.expectedWhenElapsed < minElapsed) {
- alarm.whenElapsed = alarm.maxWhenElapsed = minElapsed;
- deferred = true;
- }
+ if ((nowElapsed - lastWakeupTime) < mConstants.APP_STANDBY_RESTRICTED_WINDOW) {
+ return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX,
+ lastWakeupTime + mConstants.APP_STANDBY_RESTRICTED_WINDOW);
}
}
} else {
@@ -1651,7 +1636,7 @@ public class AlarmManagerService extends SystemService {
final long minElapsed;
if (quotaForBucket <= 0) {
// Just keep deferring for a day till the quota changes
- minElapsed = mInjector.getElapsedRealtime() + MILLIS_IN_DAY;
+ minElapsed = nowElapsed + MILLIS_IN_DAY;
} else {
// Suppose the quota for window was q, and the qth last delivery time for this
// package was t(q) then the next delivery must be after t(q) + <window_size>
@@ -1659,19 +1644,11 @@ public class AlarmManagerService extends SystemService {
sourcePackage, sourceUserId, quotaForBucket);
minElapsed = t + mConstants.APP_STANDBY_WINDOW;
}
- if (alarm.expectedWhenElapsed < minElapsed) {
- alarm.whenElapsed = alarm.maxWhenElapsed = minElapsed;
- deferred = true;
- }
+ return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, minElapsed);
}
}
- if (!deferred) {
- // Restore original requirements in case they were changed earlier.
- alarm.whenElapsed = alarm.expectedWhenElapsed;
- alarm.maxWhenElapsed = alarm.expectedMaxWhenElapsed;
- }
-
- return (oldWhenElapsed != alarm.whenElapsed || oldMaxWhenElapsed != alarm.maxWhenElapsed);
+ // wakeupsInWindow are less than the permitted quota, hence no deferring is needed.
+ return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed);
}
private static boolean isAllowedWhileIdle(Alarm a) {
@@ -1691,7 +1668,7 @@ public class AlarmManagerService extends SystemService {
ent.tag = a.operation.getTag("");
ent.op = "SET";
ent.elapsedRealtime = mInjector.getElapsedRealtime();
- ent.argRealtime = a.whenElapsed;
+ ent.argRealtime = a.getWhenElapsed();
mAllowWhileIdleDispatches.add(ent);
if (mPendingIdleUntil == null) {
IdleDispatchEntry ent2 = new IdleDispatchEntry();
@@ -1704,6 +1681,7 @@ public class AlarmManagerService extends SystemService {
if ((mPendingIdleUntil != a) && (mPendingIdleUntil != null)) {
Slog.wtfStack(TAG, "setImplLocked: idle until changed from " + mPendingIdleUntil
+ " to " + a);
+ mAlarmStore.remove(mPendingIdleUntil::equals);
}
mPendingIdleUntil = a;
final ArrayList<Alarm> notAllowedWhileIdleAlarms = mAlarmStore.remove(
@@ -1718,18 +1696,16 @@ public class AlarmManagerService extends SystemService {
}
}
if ((a.flags & AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) {
- if (mNextWakeFromIdle == null || mNextWakeFromIdle.whenElapsed > a.whenElapsed) {
+ if (mNextWakeFromIdle == null || mNextWakeFromIdle.getWhenElapsed()
+ > a.getWhenElapsed()) {
mNextWakeFromIdle = a;
// If this wake from idle is earlier than whatever was previously scheduled,
- // and we are currently idling, then we need to rebatch alarms in case the idle
- // until time needs to be updated.
+ // and we are currently idling, then the idle-until time needs to be updated.
if (mPendingIdleUntil != null) {
- final long nowElapsed = mInjector.getElapsedRealtime();
- mAlarmStore.recalculateAlarmDeliveries(alarm -> {
+ mAlarmStore.updateAlarmDeliveries(alarm -> {
if (alarm != mPendingIdleUntil) {
return false;
}
- restoreAlarmLocked(alarm, nowElapsed);
return adjustIdleUntilTime(alarm);
});
}
@@ -2563,7 +2539,7 @@ public class AlarmManagerService extends SystemService {
long getNextWakeFromIdleTimeImpl() {
synchronized (mLock) {
- return mNextWakeFromIdle != null ? mNextWakeFromIdle.whenElapsed : Long.MAX_VALUE;
+ return mNextWakeFromIdle != null ? mNextWakeFromIdle.getWhenElapsed() : Long.MAX_VALUE;
}
}
@@ -2784,12 +2760,11 @@ public class AlarmManagerService extends SystemService {
restorePending = true;
}
if (mNextWakeFromIdle != null && mNextWakeFromIdle.matches(operation, directReceiver)) {
- mNextWakeFromIdle = null;
- mAlarmStore.recalculateAlarmDeliveries(alarm -> {
+ mNextWakeFromIdle = mAlarmStore.getNextWakeFromIdleAlarm();
+ mAlarmStore.updateAlarmDeliveries(alarm -> {
if (alarm != mPendingIdleUntil) {
return false;
}
- restoreAlarmLocked(alarm, mInjector.getElapsedRealtime());
return adjustIdleUntilTime(alarm);
});
}
@@ -2834,15 +2809,14 @@ public class AlarmManagerService extends SystemService {
mPendingBackgroundAlarms.removeAt(i);
}
}
- // If we're currently keying off of this app's alarms for doze transitions,
- // make sure to reset to other triggers.
+ // If we're currently using this app's alarms to come out of doze,
+ // make sure to reset to any remaining WAKE_FROM_IDLE alarms.
if (mNextWakeFromIdle != null && mNextWakeFromIdle.uid == uid) {
- mNextWakeFromIdle = null;
- mAlarmStore.recalculateAlarmDeliveries(alarm -> {
+ mNextWakeFromIdle = mAlarmStore.getNextWakeFromIdleAlarm();
+ mAlarmStore.updateAlarmDeliveries(alarm -> {
if (alarm != mPendingIdleUntil) {
return false;
}
- restoreAlarmLocked(alarm, mInjector.getElapsedRealtime());
return adjustIdleUntilTime(alarm);
});
}
@@ -2906,15 +2880,14 @@ public class AlarmManagerService extends SystemService {
mPendingBackgroundAlarms.removeAt(i);
}
}
- // If we're currently keying off of this app's alarms for doze transitions,
- // make sure to reset to other triggers.
+ // If we're currently using this app's alarms to come out of doze,
+ // make sure to reset to any remaining WAKE_FROM_IDLE alarms.
if (removedNextWakeFromIdle.value) {
- mNextWakeFromIdle = null;
- mAlarmStore.recalculateAlarmDeliveries(alarm -> {
+ mNextWakeFromIdle = mAlarmStore.getNextWakeFromIdleAlarm();
+ mAlarmStore.updateAlarmDeliveries(alarm -> {
if (alarm != mPendingIdleUntil) {
return false;
}
- restoreAlarmLocked(alarm, mInjector.getElapsedRealtime());
return adjustIdleUntilTime(alarm);
});
}
@@ -3071,20 +3044,6 @@ public class AlarmManagerService extends SystemService {
}
}
- private static final String labelForType(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";
- }
- return "--unknown--";
- }
-
private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list,
String prefix, long nowELAPSED, SimpleDateFormat sdf) {
final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, prefix, prefix);
@@ -3095,7 +3054,7 @@ public class AlarmManagerService extends SystemService {
long nowELAPSED, SimpleDateFormat sdf) {
for (int i = list.size() - 1; i >= 0; i--) {
final Alarm a = list.get(i);
- final String label = labelForType(a.type);
+ final String label = Alarm.typeToString(a.type);
ipw.print(label);
ipw.print(" #");
ipw.print(i);
@@ -3125,6 +3084,9 @@ public class AlarmManagerService extends SystemService {
}
final String sourcePackage = alarm.sourcePackage;
final int sourceUid = alarm.creatorUid;
+ if (UserHandle.isCore(sourceUid)) {
+ return false;
+ }
return (mAppStateTracker != null) &&
mAppStateTracker.areAlarmsRestricted(sourceUid, sourcePackage,
exemptOnBatterySaver);
@@ -3169,11 +3131,7 @@ public class AlarmManagerService extends SystemService {
// Whoops, it hasn't been long enough since the last ALLOW_WHILE_IDLE
// alarm went off for this app. Reschedule the alarm to be in the
// correct time period.
- alarm.expectedWhenElapsed = alarm.whenElapsed = minTime;
- if (alarm.maxWhenElapsed < minTime) {
- alarm.maxWhenElapsed = minTime;
- }
- alarm.expectedMaxWhenElapsed = alarm.maxWhenElapsed;
+ alarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, minTime);
if (RECORD_DEVICE_IDLE_ALARMS) {
IdleDispatchEntry ent = new IdleDispatchEntry();
ent.uid = alarm.uid;
@@ -3213,12 +3171,11 @@ public class AlarmManagerService extends SystemService {
restorePendingWhileIdleAlarmsLocked();
}
if (mNextWakeFromIdle == alarm) {
- mNextWakeFromIdle = null;
- mAlarmStore.recalculateAlarmDeliveries(a -> {
+ mNextWakeFromIdle = mAlarmStore.getNextWakeFromIdleAlarm();
+ mAlarmStore.updateAlarmDeliveries(a -> {
if (a != mPendingIdleUntil) {
return false;
}
- restoreAlarmLocked(a, nowELAPSED);
return adjustIdleUntilTime(a);
});
}
@@ -3228,14 +3185,17 @@ public class AlarmManagerService extends SystemService {
if (alarm.repeatInterval > 0) {
// this adjustment will be zero if we're late by
// less than one full repeat interval
- alarm.count += (nowELAPSED - alarm.expectedWhenElapsed) / alarm.repeatInterval;
+ alarm.count += (nowELAPSED - alarm.getPolicyElapsed(REQUESTER_POLICY_INDEX))
+ / alarm.repeatInterval;
// Also schedule its next recurrence
final long delta = alarm.count * alarm.repeatInterval;
- final long nextElapsed = alarm.expectedWhenElapsed + delta;
- setImplLocked(alarm.type, alarm.when + delta, nextElapsed, alarm.windowLength,
- maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval),
- alarm.repeatInterval, alarm.operation, null, null, alarm.flags,
- alarm.workSource, alarm.alarmClock, alarm.uid, alarm.packageName);
+ final long nextElapsed = alarm.getPolicyElapsed(REQUESTER_POLICY_INDEX) + delta;
+ final long nextMaxElapsed = maxTriggerTime(nowELAPSED, nextElapsed,
+ alarm.repeatInterval);
+ setImplLocked(alarm.type, alarm.origWhen + delta, nextElapsed,
+ nextMaxElapsed - nextElapsed, alarm.repeatInterval, alarm.operation, null,
+ null, alarm.flags, alarm.workSource, alarm.alarmClock, alarm.uid,
+ alarm.packageName);
}
if (alarm.wakeup) {
@@ -3277,7 +3237,7 @@ public class AlarmManagerService extends SystemService {
}
}
- static int fuzzForDuration(long duration) {
+ int fuzzForDuration(long duration) {
if (duration < 15 * 60 * 1000) {
// If the duration until the time is less than 15 minutes, the maximum fuzz
// is the duration.
@@ -3480,7 +3440,7 @@ public class AlarmManagerService extends SystemService {
FrameworkStatsLog.write(FrameworkStatsLog.WALL_CLOCK_TIME_SHIFTED, nowRTC);
removeImpl(null, mTimeTickTrigger);
removeImpl(mDateChangeSender, null);
- reevaluateRtcAlarms(nowELAPSED);
+ reevaluateRtcAlarms();
mClockReceiver.scheduleTimeTickEvent();
mClockReceiver.scheduleDateChangedEvent();
synchronized (mLock) {
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmStore.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmStore.java
index 9fdbb8bbffc7..7a846b9b82db 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmStore.java
@@ -48,6 +48,15 @@ public interface AlarmStore {
ArrayList<Alarm> remove(Predicate<Alarm> whichAlarms);
/**
+ * Gets the earliest alarm with the flag {@link android.app.AlarmManager#FLAG_WAKE_FROM_IDLE}
+ * based on {@link Alarm#getWhenElapsed()}.
+ *
+ * @return An alarm object matching the description above or {@code null} if no such alarm was
+ * found.
+ */
+ Alarm getNextWakeFromIdleAlarm();
+
+ /**
* Returns the total number of alarms in this store.
*/
int size();
@@ -71,7 +80,7 @@ public interface AlarmStore {
/**
* Removes all alarms that are pending delivery at the given time.
*
- * @param nowElapsed The time at which delivery eligibility is evaluated.
+ * @param nowElapsed The time at which delivery eligibility is evaluated.
* @return The list of alarms pending at the given time.
*/
ArrayList<Alarm> removePendingAlarms(long nowElapsed);
@@ -82,7 +91,7 @@ public interface AlarmStore {
*
* @return {@code true} if any of the alarm deliveries changed due to this call.
*/
- boolean recalculateAlarmDeliveries(AlarmDeliveryCalculator deliveryCalculator);
+ boolean updateAlarmDeliveries(AlarmDeliveryCalculator deliveryCalculator);
/**
* Returns all the alarms in the form of a list.
@@ -97,6 +106,7 @@ public interface AlarmStore {
* Primary useful for debugging. Can be called from the
* {@link android.os.Binder#dump(FileDescriptor PrintWriter, String[]) dump} method of the
* caller.
+ *
* @param ipw The {@link IndentingPrintWriter} to write to.
* @param nowElapsed the time when the dump is requested in the
* {@link SystemClock#elapsedRealtime()
@@ -112,7 +122,7 @@ public interface AlarmStore {
/**
* A functional interface used to update the alarm. Used to describe the update in
- * {@link #recalculateAlarmDeliveries(AlarmDeliveryCalculator)}
+ * {@link #updateAlarmDeliveries(AlarmDeliveryCalculator)}
*/
@FunctionalInterface
interface AlarmDeliveryCalculator {
@@ -125,3 +135,4 @@ public interface AlarmStore {
boolean updateAlarmDelivery(Alarm a);
}
}
+
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java b/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java
index 91c0c0579c69..cbfe80bdce24 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java
@@ -66,8 +66,8 @@ public class BatchingAlarmStore implements AlarmStore {
};
private static final Comparator<Alarm> sIncreasingTimeOrder = (a1, a2) -> {
- long when1 = a1.whenElapsed;
- long when2 = a2.whenElapsed;
+ long when1 = a1.getWhenElapsed();
+ long when2 = a2.getWhenElapsed();
if (when1 > when2) {
return 1;
}
@@ -99,11 +99,28 @@ public class BatchingAlarmStore implements AlarmStore {
}
if (!removed.isEmpty()) {
mSize -= removed.size();
+ // Not needed if only whole batches were removed, but keeping existing behavior.
rebatchAllAlarms();
}
return removed;
}
+ @Override
+ public Alarm getNextWakeFromIdleAlarm() {
+ for (final Batch batch : mAlarmBatches) {
+ if ((batch.mFlags & AlarmManager.FLAG_WAKE_FROM_IDLE) == 0) {
+ continue;
+ }
+ for (int i = 0; i < batch.size(); i++) {
+ final Alarm a = batch.get(i);
+ if ((a.flags & AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) {
+ return a;
+ }
+ }
+ }
+ return null;
+ }
+
private void rebatchAllAlarms() {
final long start = mStatLogger.getTime();
final ArrayList<Batch> oldBatches = (ArrayList<Batch>) mAlarmBatches.clone();
@@ -157,7 +174,7 @@ public class BatchingAlarmStore implements AlarmStore {
}
@Override
- public boolean recalculateAlarmDeliveries(AlarmDeliveryCalculator deliveryCalculator) {
+ public boolean updateAlarmDeliveries(AlarmDeliveryCalculator deliveryCalculator) {
boolean changed = false;
for (final Batch b : mAlarmBatches) {
for (int i = 0; i < b.size(); i++) {
@@ -204,7 +221,7 @@ public class BatchingAlarmStore implements AlarmStore {
private void insertAndBatchAlarm(Alarm alarm) {
final int whichBatch = ((alarm.flags & AlarmManager.FLAG_STANDALONE) != 0) ? -1
- : attemptCoalesce(alarm.whenElapsed, alarm.maxWhenElapsed);
+ : attemptCoalesce(alarm.getWhenElapsed(), alarm.getMaxWhenElapsed());
if (whichBatch < 0) {
addBatch(mAlarmBatches, new Batch(alarm));
@@ -247,8 +264,8 @@ public class BatchingAlarmStore implements AlarmStore {
final ArrayList<Alarm> mAlarms = new ArrayList<>();
Batch(Alarm seed) {
- mStart = seed.whenElapsed;
- mEnd = clampPositive(seed.maxWhenElapsed);
+ mStart = seed.getWhenElapsed();
+ mEnd = clampPositive(seed.getMaxWhenElapsed());
mFlags = seed.flags;
mAlarms.add(seed);
}
@@ -276,12 +293,12 @@ public class BatchingAlarmStore implements AlarmStore {
if (DEBUG_BATCH) {
Slog.v(TAG, "Adding " + alarm + " to " + this);
}
- if (alarm.whenElapsed > mStart) {
- mStart = alarm.whenElapsed;
+ if (alarm.getWhenElapsed() > mStart) {
+ mStart = alarm.getWhenElapsed();
newStart = true;
}
- if (alarm.maxWhenElapsed < mEnd) {
- mEnd = alarm.maxWhenElapsed;
+ if (alarm.getMaxWhenElapsed() < mEnd) {
+ mEnd = alarm.getMaxWhenElapsed();
}
mFlags |= alarm.flags;
@@ -309,11 +326,11 @@ public class BatchingAlarmStore implements AlarmStore {
Slog.wtf(TAG, "Removed TIME_TICK alarm");
}
} else {
- if (alarm.whenElapsed > newStart) {
- newStart = alarm.whenElapsed;
+ if (alarm.getWhenElapsed() > newStart) {
+ newStart = alarm.getWhenElapsed();
}
- if (alarm.maxWhenElapsed < newEnd) {
- newEnd = alarm.maxWhenElapsed;
+ if (alarm.getMaxWhenElapsed() < newEnd) {
+ newEnd = alarm.getMaxWhenElapsed();
}
newFlags |= alarm.flags;
i++;
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 90401ad53a93..b020c7044a00 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -81,6 +81,7 @@ import android.hardware.SystemSensorManager;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.IAuthService;
import android.hardware.camera2.CameraManager;
+import android.hardware.devicestate.DeviceStateManager;
import android.hardware.display.ColorDisplayManager;
import android.hardware.display.DisplayManager;
import android.hardware.face.FaceManager;
@@ -1348,6 +1349,12 @@ public final class SystemServiceRegistry {
throws ServiceNotFoundException {
return new DreamManager(ctx);
}});
+ registerService(Context.DEVICE_STATE_SERVICE, DeviceStateManager.class,
+ new CachedServiceFetcher<DeviceStateManager>() {
+ @Override
+ public DeviceStateManager createService(ContextImpl ctx) {
+ return new DeviceStateManager();
+ }});
sInitializing = true;
try {
@@ -1404,6 +1411,7 @@ public final class SystemServiceRegistry {
case Context.CONTENT_CAPTURE_MANAGER_SERVICE:
case Context.APP_PREDICTION_SERVICE:
case Context.INCREMENTAL_SERVICE:
+ case Context.ETHERNET_SERVICE:
return null;
}
Slog.wtf(TAG, "Manager wrapper not available: " + name);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 9c216a3ffd47..c4157cfe09ad 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3508,6 +3508,7 @@ public abstract class Context {
PERMISSION_SERVICE,
LIGHTS_SERVICE,
//@hide: PEOPLE_SERVICE,
+ //@hide: DEVICE_STATE_SERVICE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ServiceName {}
@@ -5246,6 +5247,14 @@ public abstract class Context {
public static final String PEOPLE_SERVICE = "people";
/**
+ * Use with {@link #getSystemService(String)} to access device state service.
+ *
+ * @see #getSystemService(String)
+ * @hide
+ */
+ public static final String DEVICE_STATE_SERVICE = "device_state";
+
+ /**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
*
diff --git a/core/java/android/hardware/devicestate/DeviceStateManager.java b/core/java/android/hardware/devicestate/DeviceStateManager.java
new file mode 100644
index 000000000000..a52f983ff2a7
--- /dev/null
+++ b/core/java/android/hardware/devicestate/DeviceStateManager.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.devicestate;
+
+import android.annotation.SystemService;
+import android.content.Context;
+
+/**
+ * Manages the state of the system for devices with user-configurable hardware like a foldable
+ * phone.
+ *
+ * @hide
+ */
+@SystemService(Context.DEVICE_STATE_SERVICE)
+public final class DeviceStateManager {
+ /** Invalid device state. */
+ public static final int INVALID_DEVICE_STATE = -1;
+
+ private DeviceStateManagerGlobal mGlobal;
+
+ public DeviceStateManager() {
+ mGlobal = DeviceStateManagerGlobal.getInstance();
+ }
+}
diff --git a/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java b/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java
new file mode 100644
index 000000000000..4e7cf4af118d
--- /dev/null
+++ b/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.devicestate;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.IBinder;
+import android.os.ServiceManager;
+
+/**
+ * Provides communication with the device state system service on behalf of applications.
+ *
+ * @see DeviceStateManager
+ * @hide
+ */
+final class DeviceStateManagerGlobal {
+ private static DeviceStateManagerGlobal sInstance;
+
+ /**
+ * Returns an instance of {@link DeviceStateManagerGlobal}. May return {@code null} if a
+ * connection with the device state service couldn't be established.
+ */
+ @Nullable
+ static DeviceStateManagerGlobal getInstance() {
+ synchronized (DeviceStateManagerGlobal.class) {
+ if (sInstance == null) {
+ IBinder b = ServiceManager.getService(Context.DEVICE_STATE_SERVICE);
+ if (b != null) {
+ sInstance = new DeviceStateManagerGlobal(IDeviceStateManager
+ .Stub.asInterface(b));
+ }
+ }
+ return sInstance;
+ }
+ }
+
+ @NonNull
+ private final IDeviceStateManager mDeviceStateManager;
+
+ private DeviceStateManagerGlobal(@NonNull IDeviceStateManager deviceStateManager) {
+ mDeviceStateManager = deviceStateManager;
+ }
+}
diff --git a/core/java/android/hardware/devicestate/IDeviceStateManager.aidl b/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
new file mode 100644
index 000000000000..24913e9b2d23
--- /dev/null
+++ b/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.devicestate;
+
+/** @hide */
+interface IDeviceStateManager {}
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 7fac615aa88d..32ce5e26e929 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2751,4 +2751,9 @@ enum PageId {
// OS: R QPR2
BLUETOOTH_PAIRING_RECEIVER = 1851;
+
+ // OPEN: Settings > Display > Screen timeout
+ // CATEGORY: SETTINGS
+ // OS: S
+ SCREEN_TIMEOUT = 1852;
}
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index eb2e23e1b5e1..4a095c9be053 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -28,7 +28,6 @@ import android.location.LocationManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
-import android.telephony.PhoneNumberUtils;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -161,7 +160,7 @@ public class GpsNetInitiatedHandler {
be set to true when the phone is having emergency call, and then will
be set to false by mPhoneStateListener when the emergency call ends.
*/
- mIsInEmergencyCall = PhoneNumberUtils.isEmergencyNumber(phoneNumber);
+ mIsInEmergencyCall = mTelephonyManager.isEmergencyNumber(phoneNumber);
if (DEBUG) Log.v(TAG, "ACTION_NEW_OUTGOING_CALL - " + getInEmergency());
} else if (action.equals(LocationManager.MODE_CHANGED_ACTION)) {
updateLocationMode();
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 9ddf7a4fb79b..d71b919818ea 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -941,10 +941,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
if (resolvedUserId != mCurrentUserId) {
return null;
}
- if (mA11yWindowManager.findA11yWindowInfoByIdLocked(windowId) == null) {
+ final AccessibilityWindowInfo accessibilityWindowInfo = mA11yWindowManager
+ .findA11yWindowInfoByIdLocked(windowId);
+ if (accessibilityWindowInfo == null) {
return null;
}
- return mA11yWindowManager.getWindowTokenForUserAndWindowIdLocked(userId, windowId);
+ // We use AccessibilityWindowInfo#getId instead of windowId. When the windowId comes
+ // from an embedded hierarchy, the system can't find correct window token because
+ // embedded hierarchy doesn't have windowInfo. Calling
+ // AccessibilityWindowManager#findA11yWindowInfoByIdLocked can look for its parent's
+ // windowInfo, so it is safer to use AccessibilityWindowInfo#getId
+ // to get window token to find real window.
+ return mA11yWindowManager.getWindowTokenForUserAndWindowIdLocked(userId,
+ accessibilityWindowInfo.getId());
}
}
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index 4cff5c013bda..7e3c1ab50ad5 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -16,8 +16,11 @@
package com.android.server.devicestate;
+import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
+
import android.annotation.NonNull;
import android.content.Context;
+import android.hardware.devicestate.IDeviceStateManager;
import android.util.IntArray;
import android.util.Slog;
@@ -49,9 +52,6 @@ import java.util.Arrays;
* @see DeviceStatePolicy
*/
public final class DeviceStateManagerService extends SystemService {
- /** Invalid device state. */
- public static final int INVALID_DEVICE_STATE = -1;
-
private static final String TAG = "DeviceStateManagerService";
private static final boolean DEBUG = false;
@@ -88,6 +88,7 @@ public final class DeviceStateManagerService extends SystemService {
@Override
public void onStart() {
mDeviceStatePolicy.getDeviceStateProvider().setListener(new DeviceStateProviderListener());
+ publishBinderService(Context.DEVICE_STATE_SERVICE, new BinderService());
}
/**
@@ -267,4 +268,9 @@ public final class DeviceStateManagerService extends SystemService {
requestState(state);
}
}
+
+ /** Implementation of {@link IDeviceStateManager} published as a binder service. */
+ private final class BinderService extends IDeviceStateManager.Stub {
+
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index d61783ef59d2..a5f083477863 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -48,10 +48,13 @@ import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_INT
import static com.android.server.alarm.AlarmManagerService.IS_WAKEUP_MASK;
import static com.android.server.alarm.AlarmManagerService.TIME_CHANGED_MASK;
import static com.android.server.alarm.AlarmManagerService.WORKING_INDEX;
+import static com.android.server.alarm.Constants.TEST_CALLING_PACKAGE;
+import static com.android.server.alarm.Constants.TEST_CALLING_UID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -82,6 +85,7 @@ import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.provider.DeviceConfig;
import android.provider.Settings;
+import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.SparseArray;
@@ -108,6 +112,8 @@ import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
import org.mockito.stubbing.Answer;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.Executor;
@@ -116,9 +122,7 @@ import java.util.concurrent.Executor;
@RunWith(AndroidJUnit4.class)
public class AlarmManagerServiceTest {
private static final String TAG = AlarmManagerServiceTest.class.getSimpleName();
- private static final String TEST_CALLING_PACKAGE = "com.android.framework.test-package";
private static final int SYSTEM_UI_UID = 12345;
- private static final int TEST_CALLING_UID = 67890;
private static final int TEST_CALLING_USER = UserHandle.getUserId(TEST_CALLING_UID);
private long mAppStandbyWindow;
@@ -350,19 +354,31 @@ public class AlarmManagerServiceTest {
}
private void setTestAlarm(int type, long triggerTime, PendingIntent operation) {
- setTestAlarm(type, triggerTime, operation, 0, TEST_CALLING_UID);
+ setTestAlarm(type, triggerTime, operation, 0, AlarmManager.FLAG_STANDALONE,
+ TEST_CALLING_UID);
}
private void setRepeatingTestAlarm(int type, long firstTrigger, long interval,
PendingIntent pi) {
- setTestAlarm(type, firstTrigger, pi, interval, TEST_CALLING_UID);
+ setTestAlarm(type, firstTrigger, pi, interval, AlarmManager.FLAG_STANDALONE,
+ TEST_CALLING_UID);
+ }
+
+ private void setIdleUntilAlarm(int type, long triggerTime, PendingIntent pi) {
+ setTestAlarm(type, triggerTime, pi, 0, AlarmManager.FLAG_IDLE_UNTIL, TEST_CALLING_UID);
+ }
+
+ private void setWakeFromIdle(int type, long triggerTime, PendingIntent pi) {
+ // Note: Only alarm clock alarms are allowed to include this flag in the actual service.
+ // But this is a unit test so we'll only test the flag for granularity and convenience.
+ setTestAlarm(type, triggerTime, pi, 0,
+ AlarmManager.FLAG_WAKE_FROM_IDLE | AlarmManager.FLAG_STANDALONE, TEST_CALLING_UID);
}
private void setTestAlarm(int type, long triggerTime, PendingIntent operation, long interval,
- int callingUid) {
- mService.setImpl(type, triggerTime, AlarmManager.WINDOW_EXACT, interval,
- operation, null, "test", AlarmManager.FLAG_STANDALONE, null, null,
- callingUid, TEST_CALLING_PACKAGE);
+ int flags, int callingUid) {
+ mService.setImpl(type, triggerTime, AlarmManager.WINDOW_EXACT, interval, operation, null,
+ "test", flags, null, null, callingUid, TEST_CALLING_PACKAGE);
}
private void setTestAlarmWithListener(int type, long triggerTime, IAlarmListener listener) {
@@ -1002,7 +1018,7 @@ public class AlarmManagerServiceTest {
for (int i = 0; i < numAlarms; i++) {
int mockUid = UserHandle.getUid(mockUserId, 1234 + i);
setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10,
- getNewMockPendingIntent(mockUid), 0, mockUid);
+ getNewMockPendingIntent(mockUid), 0, AlarmManager.FLAG_STANDALONE, mockUid);
}
assertEquals(numAlarms, mService.mAlarmsPerUid.size());
mService.removeUserLocked(mockUserId);
@@ -1142,6 +1158,116 @@ public class AlarmManagerServiceTest {
}
}
+ @Test
+ public void singleIdleUntil() {
+ doReturn(0).when(mService).fuzzForDuration(anyLong());
+
+ final PendingIntent idleUntilPi6 = getNewMockPendingIntent();
+ setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 6, idleUntilPi6);
+
+ assertTrue(mService.mPendingIdleUntil.matches(idleUntilPi6, null));
+ assertEquals(mNowElapsedTest + 6, mTestTimer.getElapsed());
+ assertEquals(mNowElapsedTest + 6, mService.mPendingIdleUntil.getWhenElapsed());
+
+ final PendingIntent idleUntilPi2 = getNewMockPendingIntent();
+ setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 2, idleUntilPi2);
+
+ // The same mPendingIdleUntil should get updated, even with a different PendingIntent.
+ assertTrue(mService.mPendingIdleUntil.matches(idleUntilPi2, null));
+ assertEquals(mNowElapsedTest + 2, mTestTimer.getElapsed());
+ assertEquals(1, mService.mAlarmStore.size());
+
+ final PendingIntent idleUntilPi10 = getNewMockPendingIntent();
+ setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 10, idleUntilPi10);
+
+ // The same thing should happen even when the new alarm is in farther in the future.
+ assertTrue(mService.mPendingIdleUntil.matches(idleUntilPi10, null));
+ assertEquals(mNowElapsedTest + 10, mTestTimer.getElapsed());
+ assertEquals(1, mService.mAlarmStore.size());
+ }
+
+ @Test
+ public void nextWakeFromIdle() throws Exception {
+ assertNull(mService.mNextWakeFromIdle);
+
+ final PendingIntent wakeFromIdle6 = getNewMockPendingIntent();
+ final long trigger6 = mNowElapsedTest + 6;
+ setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, trigger6, wakeFromIdle6);
+
+ assertTrue(mService.mNextWakeFromIdle.matches(wakeFromIdle6, null));
+ assertEquals(trigger6, mService.mNextWakeFromIdle.getWhenElapsed());
+ assertEquals(trigger6, mTestTimer.getElapsed());
+
+ final PendingIntent wakeFromIdle10 = getNewMockPendingIntent();
+ final long trigger10 = mNowElapsedTest + 10;
+ setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, trigger10, wakeFromIdle10);
+
+ // mNextWakeFromIdle should not get updated.
+ assertTrue(mService.mNextWakeFromIdle.matches(wakeFromIdle6, null));
+ assertEquals(trigger6, mTestTimer.getElapsed());
+ assertEquals(trigger6, mService.mNextWakeFromIdle.getWhenElapsed());
+
+ final PendingIntent wakeFromIdle3 = getNewMockPendingIntent();
+ final long trigger3 = mNowElapsedTest + 3;
+ setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, trigger3, wakeFromIdle3);
+
+ // mNextWakeFromIdle should always reflect the next earliest wake_from_idle alarm.
+ assertTrue(mService.mNextWakeFromIdle.matches(wakeFromIdle3, null));
+ assertEquals(trigger3, mTestTimer.getElapsed());
+ assertEquals(trigger3, mService.mNextWakeFromIdle.getWhenElapsed());
+
+ mNowElapsedTest = trigger3;
+ mTestTimer.expire();
+
+ assertTrue(mService.mNextWakeFromIdle.matches(wakeFromIdle6, null));
+ assertEquals(trigger6, mTestTimer.getElapsed());
+ assertEquals(trigger6, mService.mNextWakeFromIdle.getWhenElapsed());
+
+ mService.removeLocked(wakeFromIdle6, null);
+
+ assertTrue(mService.mNextWakeFromIdle.matches(wakeFromIdle10, null));
+ assertEquals(trigger10, mTestTimer.getElapsed());
+ assertEquals(trigger10, mService.mNextWakeFromIdle.getWhenElapsed());
+
+ mService.removeLocked(wakeFromIdle10, null);
+ assertNull(mService.mNextWakeFromIdle);
+ }
+
+ @Test
+ public void idleUntilBeforeWakeFromIdle() {
+ doReturn(0).when(mService).fuzzForDuration(anyLong());
+
+ final PendingIntent idleUntilPi = getNewMockPendingIntent();
+ final long requestedIdleUntil = mNowElapsedTest + 10;
+ setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, requestedIdleUntil, idleUntilPi);
+
+ assertEquals(requestedIdleUntil, mService.mPendingIdleUntil.getWhenElapsed());
+
+ final PendingIntent wakeFromIdle5 = getNewMockPendingIntent();
+ setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 5, wakeFromIdle5);
+ assertEquals(mNowElapsedTest + 5, mService.mPendingIdleUntil.getWhenElapsed());
+
+ final PendingIntent wakeFromIdle8 = getNewMockPendingIntent();
+ setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 8, wakeFromIdle8);
+ assertEquals(mNowElapsedTest + 5, mService.mPendingIdleUntil.getWhenElapsed());
+
+ final PendingIntent wakeFromIdle12 = getNewMockPendingIntent();
+ setWakeFromIdle(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 12, wakeFromIdle12);
+ assertEquals(mNowElapsedTest + 5, mService.mPendingIdleUntil.getWhenElapsed());
+
+ mService.removeLocked(wakeFromIdle5, null);
+ assertEquals(mNowElapsedTest + 8, mService.mPendingIdleUntil.getWhenElapsed());
+
+ mService.removeLocked(wakeFromIdle8, null);
+ assertEquals(requestedIdleUntil, mService.mPendingIdleUntil.getWhenElapsed());
+
+ mService.removeLocked(idleUntilPi, null);
+ assertNull(mService.mPendingIdleUntil);
+
+ setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 15, idleUntilPi);
+ assertEquals(mNowElapsedTest + 12, mService.mPendingIdleUntil.getWhenElapsed());
+ }
+
@After
public void tearDown() {
if (mMockingSession != null) {
@@ -1149,4 +1275,12 @@ public class AlarmManagerServiceTest {
}
LocalServices.removeServiceForTest(AlarmManagerInternal.class);
}
+
+ private void dumpAllAlarms(String tag, ArrayList<Alarm> alarms) {
+ System.out.println(tag + ": ");
+ IndentingPrintWriter ipw = new IndentingPrintWriter(new PrintWriter(System.out));
+ AlarmManagerService.dumpAlarmList(ipw, alarms, mNowElapsedTest,
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"));
+ ipw.close();
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
index 9e43b4ab9b5a..f0490ce469dd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
@@ -16,6 +16,9 @@
package com.android.server.alarm;
+import static com.android.server.alarm.Constants.TEST_CALLING_PACKAGE;
+import static com.android.server.alarm.Constants.TEST_CALLING_UID;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
@@ -35,9 +38,6 @@ import java.util.ArrayList;
@Presubmit
@RunWith(AndroidJUnit4.class)
public class AlarmStoreTest {
- private static final int TEST_CALLING_UID = 12345;
- private static final String TEST_CALLING_PACKAGE = "android.alarm.unit.test";
-
private AlarmStore mAlarmStore;
@Before
@@ -45,22 +45,22 @@ public class AlarmStoreTest {
mAlarmStore = new BatchingAlarmStore(null);
}
- private static Alarm createAlarm(long whenElapsed, long windowLength, PendingIntent mockPi,
+ private static Alarm createAlarm(long whenElapsed, long windowLength,
AlarmManager.AlarmClockInfo alarmClock) {
- return createAlarm(AlarmManager.ELAPSED_REALTIME, whenElapsed, windowLength, mockPi,
+ return createAlarm(AlarmManager.ELAPSED_REALTIME, whenElapsed, windowLength,
alarmClock);
}
private static Alarm createWakeupAlarm(long whenElapsed, long windowLength,
- PendingIntent mockPi, AlarmManager.AlarmClockInfo alarmClock) {
- return createAlarm(AlarmManager.ELAPSED_REALTIME_WAKEUP, whenElapsed, windowLength, mockPi,
+ AlarmManager.AlarmClockInfo alarmClock) {
+ return createAlarm(AlarmManager.ELAPSED_REALTIME_WAKEUP, whenElapsed, windowLength,
alarmClock);
}
private static Alarm createAlarm(int type, long whenElapsed, long windowLength,
- PendingIntent mockPi, AlarmManager.AlarmClockInfo alarmClock) {
- return new Alarm(type, whenElapsed, whenElapsed, windowLength, whenElapsed + windowLength,
- 0, mockPi, null, null, null, 0, alarmClock, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
+ AlarmManager.AlarmClockInfo alarmClock) {
+ return new Alarm(type, whenElapsed, whenElapsed, windowLength, 0, mock(PendingIntent.class),
+ null, null, null, 0, alarmClock, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
}
private void addAlarmsToStore(Alarm... alarms) {
@@ -71,11 +71,11 @@ public class AlarmStoreTest {
@Test
public void add() {
- final Alarm a1 = createAlarm(1, 0, mock(PendingIntent.class), null);
+ final Alarm a1 = createAlarm(1, 0, null);
mAlarmStore.add(a1);
assertEquals(1, mAlarmStore.size());
- final Alarm a2 = createAlarm(2, 0, mock(PendingIntent.class), null);
+ final Alarm a2 = createAlarm(2, 0, null);
mAlarmStore.add(a2);
assertEquals(2, mAlarmStore.size());
@@ -86,17 +86,17 @@ public class AlarmStoreTest {
@Test
public void remove() {
- final Alarm a1 = createAlarm(1, 0, mock(PendingIntent.class), null);
- final Alarm a2 = createAlarm(2, 0, mock(PendingIntent.class), null);
- final Alarm a5 = createAlarm(5, 0, mock(PendingIntent.class), null);
+ final Alarm a1 = createAlarm(1, 0, null);
+ final Alarm a2 = createAlarm(2, 0, null);
+ final Alarm a5 = createAlarm(5, 0, null);
addAlarmsToStore(a1, a2, a5);
- ArrayList<Alarm> removed = mAlarmStore.remove(a -> (a.whenElapsed < 4));
+ ArrayList<Alarm> removed = mAlarmStore.remove(a -> (a.getWhenElapsed() < 4));
assertEquals(2, removed.size());
assertEquals(1, mAlarmStore.size());
assertTrue(removed.contains(a1) && removed.contains(a2));
- final Alarm a8 = createAlarm(8, 0, mock(PendingIntent.class), null);
+ final Alarm a8 = createAlarm(8, 0, null);
addAlarmsToStore(a8, a2, a1);
removed = mAlarmStore.remove(unused -> false);
@@ -110,10 +110,10 @@ public class AlarmStoreTest {
@Test
public void removePendingAlarms() {
- final Alarm a1_11 = createAlarm(1, 10, mock(PendingIntent.class), null);
- final Alarm a2_5 = createAlarm(2, 3, mock(PendingIntent.class), null);
- final Alarm a6_9 = createAlarm(6, 3, mock(PendingIntent.class), null);
- addAlarmsToStore(a2_5, a6_9, a1_11);
+ final Alarm a1to11 = createAlarm(1, 10, null);
+ final Alarm a2to5 = createAlarm(2, 3, null);
+ final Alarm a6to9 = createAlarm(6, 3, null);
+ addAlarmsToStore(a2to5, a6to9, a1to11);
final ArrayList<Alarm> pendingAt0 = mAlarmStore.removePendingAlarms(0);
assertEquals(0, pendingAt0.size());
@@ -121,24 +121,24 @@ public class AlarmStoreTest {
final ArrayList<Alarm> pendingAt3 = mAlarmStore.removePendingAlarms(3);
assertEquals(2, pendingAt3.size());
- assertTrue(pendingAt3.contains(a1_11) && pendingAt3.contains(a2_5));
+ assertTrue(pendingAt3.contains(a1to11) && pendingAt3.contains(a2to5));
assertEquals(1, mAlarmStore.size());
- addAlarmsToStore(a2_5, a1_11);
+ addAlarmsToStore(a2to5, a1to11);
final ArrayList<Alarm> pendingAt7 = mAlarmStore.removePendingAlarms(7);
assertEquals(3, pendingAt7.size());
- assertTrue(pendingAt7.contains(a1_11) && pendingAt7.contains(a2_5) && pendingAt7.contains(
- a6_9));
+ assertTrue(pendingAt7.contains(a1to11) && pendingAt7.contains(a2to5) && pendingAt7.contains(
+ a6to9));
assertEquals(0, mAlarmStore.size());
}
@Test
public void getNextWakeupDeliveryTime() {
- final Alarm a1_10 = createAlarm(1, 9, mock(PendingIntent.class), null);
- final Alarm a3_8_wakeup = createWakeupAlarm(3, 5, mock(PendingIntent.class), null);
- final Alarm a6_wakeup = createWakeupAlarm(6, 0, mock(PendingIntent.class), null);
- final Alarm a5 = createAlarm(5, 0, mock(PendingIntent.class), null);
- addAlarmsToStore(a5, a6_wakeup, a3_8_wakeup, a1_10);
+ final Alarm a1to10 = createAlarm(1, 9, null);
+ final Alarm a3to8wakeup = createWakeupAlarm(3, 5, null);
+ final Alarm a6wakeup = createWakeupAlarm(6, 0, null);
+ final Alarm a5 = createAlarm(5, 0, null);
+ addAlarmsToStore(a5, a6wakeup, a3to8wakeup, a1to10);
// The wakeup alarms are [6] and [3, 8], hence 6 is the latest time till when we can
// defer delivering any wakeup alarm.
@@ -155,11 +155,11 @@ public class AlarmStoreTest {
@Test
public void getNextDeliveryTime() {
- final Alarm a1_10 = createAlarm(1, 9, mock(PendingIntent.class), null);
- final Alarm a3_8_wakeup = createWakeupAlarm(3, 5, mock(PendingIntent.class), null);
- final Alarm a6_wakeup = createWakeupAlarm(6, 0, mock(PendingIntent.class), null);
- final Alarm a5 = createAlarm(5, 0, mock(PendingIntent.class), null);
- addAlarmsToStore(a5, a6_wakeup, a3_8_wakeup, a1_10);
+ final Alarm a1to10 = createAlarm(1, 9, null);
+ final Alarm a3to8wakeup = createWakeupAlarm(3, 5, null);
+ final Alarm a6wakeup = createWakeupAlarm(6, 0, null);
+ final Alarm a5 = createAlarm(5, 0, null);
+ addAlarmsToStore(a5, a6wakeup, a3to8wakeup, a1to10);
assertTrue(mAlarmStore.getNextDeliveryTime() <= 5);
@@ -168,24 +168,22 @@ public class AlarmStoreTest {
}
@Test
- public void recalculateAlarmDeliveries() {
- final Alarm a5 = createAlarm(5, 0, mock(PendingIntent.class), null);
- final Alarm a8 = createAlarm(8, 0, mock(PendingIntent.class), null);
- final Alarm a10 = createAlarm(10, 0, mock(PendingIntent.class), null);
+ public void updateAlarmDeliveries() {
+ final Alarm a5 = createAlarm(5, 0, null);
+ final Alarm a8 = createAlarm(8, 0, null);
+ final Alarm a10 = createAlarm(10, 0, null);
addAlarmsToStore(a8, a10, a5);
assertEquals(5, mAlarmStore.getNextDeliveryTime());
- mAlarmStore.recalculateAlarmDeliveries(a -> {
- a.whenElapsed += 3;
- a.maxWhenElapsed = a.whenElapsed;
+ mAlarmStore.updateAlarmDeliveries(a -> {
+ a.setPolicyElapsed(Alarm.REQUESTER_POLICY_INDEX, a.getWhenElapsed() + 3);
return true;
});
assertEquals(8, mAlarmStore.getNextDeliveryTime());
- mAlarmStore.recalculateAlarmDeliveries(a -> {
- a.whenElapsed = 20 - a.whenElapsed;
- a.maxWhenElapsed = a.whenElapsed;
+ mAlarmStore.updateAlarmDeliveries(a -> {
+ a.setPolicyElapsed(Alarm.REQUESTER_POLICY_INDEX, 20 - a.getWhenElapsed());
return true;
});
assertEquals(7, mAlarmStore.getNextDeliveryTime());
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java
new file mode 100644
index 000000000000..efcfae38c3d3
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.alarm;
+
+import static android.app.AlarmManager.ELAPSED_REALTIME;
+
+import static com.android.server.alarm.Alarm.APP_STANDBY_POLICY_INDEX;
+import static com.android.server.alarm.Alarm.REQUESTER_POLICY_INDEX;
+import static com.android.server.alarm.Constants.TEST_CALLING_PACKAGE;
+import static com.android.server.alarm.Constants.TEST_CALLING_UID;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import android.app.PendingIntent;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class AlarmTest {
+
+ private Alarm createDefaultAlarm(long requestedElapsed, long windowLength) {
+ return new Alarm(ELAPSED_REALTIME, 0, requestedElapsed, windowLength, 0,
+ mock(PendingIntent.class), null, null, null, 0, null, TEST_CALLING_UID,
+ TEST_CALLING_PACKAGE);
+ }
+
+ @Test
+ public void initSetsOnlyRequesterPolicy() {
+ final Alarm a = createDefaultAlarm(4567, 2);
+ assertEquals(4567, a.getPolicyElapsed(REQUESTER_POLICY_INDEX));
+ assertEquals(0, a.getPolicyElapsed(APP_STANDBY_POLICY_INDEX));
+ }
+
+ @Test
+ public void whenElapsed() {
+ final Alarm a = createDefaultAlarm(0, 0);
+
+ a.setPolicyElapsed(REQUESTER_POLICY_INDEX, 4);
+ a.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 10);
+ assertEquals(10, a.getWhenElapsed());
+
+ a.setPolicyElapsed(REQUESTER_POLICY_INDEX, 12);
+ assertEquals(12, a.getWhenElapsed());
+
+ a.setPolicyElapsed(REQUESTER_POLICY_INDEX, 7);
+ assertEquals(10, a.getWhenElapsed());
+
+ a.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 2);
+ assertEquals(7, a.getWhenElapsed());
+
+ a.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 7);
+ assertEquals(7, a.getWhenElapsed());
+ }
+
+ @Test
+ public void maxWhenElapsed() {
+ final Alarm a = createDefaultAlarm(10, 12);
+ assertEquals(22, a.getMaxWhenElapsed());
+
+ a.setPolicyElapsed(REQUESTER_POLICY_INDEX, 15);
+ assertEquals(27, a.getMaxWhenElapsed());
+
+ a.setPolicyElapsed(REQUESTER_POLICY_INDEX, 2);
+ assertEquals(14, a.getMaxWhenElapsed());
+
+ a.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 5);
+ assertEquals(14, a.getMaxWhenElapsed());
+
+ a.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 16);
+ assertEquals(16, a.getMaxWhenElapsed());
+
+ a.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 12);
+ assertEquals(14, a.getMaxWhenElapsed());
+ }
+
+ @Test
+ public void setPolicyElapsed() {
+ final Alarm exactAlarm = createDefaultAlarm(10, 0);
+
+ assertTrue(exactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 4));
+ assertTrue(exactAlarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 10));
+
+ assertFalse(exactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 8));
+ assertFalse(exactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 10));
+ assertFalse(exactAlarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 8));
+
+ assertTrue(exactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 7));
+
+ final Alarm inexactAlarm = createDefaultAlarm(10, 5);
+
+ assertTrue(inexactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 4));
+ assertTrue(inexactAlarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 10));
+
+ // whenElapsed won't change, but maxWhenElapsed will.
+ assertTrue(inexactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 8));
+ assertTrue(inexactAlarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, 10));
+
+ assertFalse(inexactAlarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 8));
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/BackgroundRestrictedAlarmsTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/BackgroundRestrictedAlarmsTest.java
index 6465739f6822..5bb6a42b2604 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/BackgroundRestrictedAlarmsTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/BackgroundRestrictedAlarmsTest.java
@@ -45,7 +45,7 @@ public class BackgroundRestrictedAlarmsTest {
}
uidAlarms.add(new Alarm(
removeIt ? RTC : RTC_WAKEUP,
- 0, 0, 0, 0, 0, null, null, null, null, 0, null, uid, name));
+ 0, 0, 0, 0, null, null, null, null, 0, null, uid, name));
return all;
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/Constants.java b/services/tests/mockingservicestests/src/com/android/server/alarm/Constants.java
new file mode 100644
index 000000000000..2552db8a310a
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/Constants.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.alarm;
+
+public interface Constants {
+ String TEST_CALLING_PACKAGE = "com.android.framework.test-package";
+ int TEST_CALLING_UID = 67890;
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
index 59d4e2ae6ae4..058794a3b9e9 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -16,7 +16,7 @@
package com.android.server.devicestate;
-import static com.android.server.devicestate.DeviceStateManagerService.INVALID_DEVICE_STATE;
+import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertThrows;
diff --git a/telecomm/java/android/telecom/CallerInfo.java b/telecomm/java/android/telecom/CallerInfo.java
index fb6f99405759..aff2f0183a3b 100644
--- a/telecomm/java/android/telecom/CallerInfo.java
+++ b/telecomm/java/android/telecom/CallerInfo.java
@@ -405,7 +405,8 @@ public class CallerInfo {
// Change the callerInfo number ONLY if it is an emergency number
// or if it is the voicemail number. If it is either, take a
// shortcut and skip the query.
- if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) {
+ TelephonyManager tm = context.getSystemService(TelephonyManager.class);
+ if (tm.isEmergencyNumber(number)) {
return new CallerInfo().markAsEmergency(context);
} else if (PhoneNumberUtils.isVoiceMailNumber(null, subId, number)) {
return new CallerInfo().markAsVoiceMail(context, subId);
diff --git a/telecomm/java/android/telecom/CallerInfoAsyncQuery.java b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
index 4a81a8eea5cf..a9e1a8fc1952 100644
--- a/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
+++ b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
@@ -34,6 +34,7 @@ import android.os.UserManager;
import android.provider.ContactsContract.PhoneLookup;
import android.telephony.PhoneNumberUtils;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import java.util.ArrayList;
@@ -481,7 +482,8 @@ public class CallerInfoAsyncQuery {
cw.subId = subId;
// check to see if these are recognized numbers, and use shortcuts if we can.
- if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) {
+ TelephonyManager tm = context.getSystemService(TelephonyManager.class);
+ if (tm.isEmergencyNumber(number)) {
cw.event = EVENT_EMERGENCY_NUMBER;
} else if (PhoneNumberUtils.isVoiceMailNumber(context, subId, number)) {
cw.event = EVENT_VOICEMAIL_NUMBER;