Merge "Support ignoring orientation request on DisplayArea level"
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 7c44f16..8ac9842 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -122,7 +122,6 @@
droidstubs {
name: "api-stubs-docs",
defaults: ["metalava-full-api-stubs-default"],
- removed_dex_api_filename: "removed-dex.txt",
arg_files: [
"core/res/AndroidManifest.xml",
],
@@ -183,7 +182,6 @@
droidstubs {
name: "system-api-stubs-docs",
defaults: ["metalava-full-api-stubs-default"],
- removed_dex_api_filename: "system-removed-dex.txt",
arg_files: [
"core/res/AndroidManifest.xml",
],
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 f672e4b..45ea233 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.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 05910a5..82819da 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.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 @@
}
// 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 @@
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 @@
}
// 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 @@
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 @@
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 @@
// 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 @@
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 @@
}
}
+ 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 @@
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 @@
}
/**
- * 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;
+ final long nowElapsed = mInjector.getElapsedRealtime();
+ if (isExemptFromAppStandby(alarm) || mAppStandbyParole) {
+ return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed);
}
- 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 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
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 @@
long getNextWakeFromIdleTimeImpl() {
synchronized (mLock) {
- return mNextWakeFromIdle != null ? mNextWakeFromIdle.whenElapsed : Long.MAX_VALUE;
+ return mNextWakeFromIdle != null ? mNextWakeFromIdle.getWhenElapsed() : Long.MAX_VALUE;
}
}
@@ -2784,12 +2760,11 @@
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 @@
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 @@
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 @@
}
}
- 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 @@
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 @@
}
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 @@
// 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 @@
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 @@
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 @@
}
}
- 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 @@
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 9fdbb8b..7a846b9 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 @@
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 @@
/**
* 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 @@
*
* @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 @@
* 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 @@
/**
* 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 @@
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 91c0c05..cbfe80b 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 @@
};
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 @@
}
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 @@
}
@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 @@
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 @@
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 @@
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 @@
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/api/test-current.txt b/api/test-current.txt
index 9069eea..e7c6445 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3485,6 +3485,7 @@
field public static final String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD = "dynamic_power_savings_disable_threshold";
field public static final String DYNAMIC_POWER_SAVINGS_ENABLED = "dynamic_power_savings_enabled";
field public static final String HIDDEN_API_BLACKLIST_EXEMPTIONS = "hidden_api_blacklist_exemptions";
+ field public static final String HIDDEN_API_POLICY = "hidden_api_policy";
field public static final String HIDE_ERROR_DIALOGS = "hide_error_dialogs";
field public static final String LOCATION_GLOBAL_KILL_SWITCH = "location_global_kill_switch";
field public static final String LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST = "location_ignore_settings_package_whitelist";
diff --git a/api/test-lint-baseline.txt b/api/test-lint-baseline.txt
index a314702..0440d1a 100644
--- a/api/test-lint-baseline.txt
+++ b/api/test-lint-baseline.txt
@@ -2511,6 +2511,8 @@
NoSettingsProvider: android.provider.Settings.Global#HIDDEN_API_BLACKLIST_EXEMPTIONS:
+NoSettingsProvider: android.provider.Settings.Global#HIDDEN_API_POLICY:
+
NoSettingsProvider: android.provider.Settings.Global#HIDE_ERROR_DIALOGS:
NoSettingsProvider: android.provider.Settings.Global#LOCATION_GLOBAL_KILL_SWITCH:
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index e5dbb42..091e9a7 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -3834,6 +3834,12 @@
// App startup time (until call to Activity#reportFullyDrawn()).
optional int64 app_startup_time_millis = 6;
+ // The compiler filter used when when the package was optimized.
+ optional int32 package_optimization_compilation_filter = 7;
+
+ // The reason why the package was optimized.
+ optional int32 package_optimization_compilation_reason = 8;
+
enum SourceType {
UNAVAILABLE = 0;
LAUNCHER = 1;
@@ -3841,11 +3847,11 @@
LOCKSCREEN = 3;
}
// The type of the startup source.
- optional SourceType source_type = 7;
+ optional SourceType source_type = 9;
// The time from the startup source to the beginning of handling the startup event.
// -1 means not available.
- optional int32 source_event_delay_millis = 8;
+ optional int32 source_event_delay_millis = 10;
}
/**
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 90401ad..b020c70 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -81,6 +81,7 @@
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 @@
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 @@
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/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index 79f05a3..eedf958 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -852,15 +852,6 @@
}
/**
- * Returns true if this container may be scaled without resizing, and windows within may need
- * to be configured as such.
- * @hide
- */
- public boolean windowsAreScaleable() {
- return mWindowingMode == WINDOWING_MODE_PINNED;
- }
-
- /**
* Returns true if windows in this container should be given move animations by default.
* @hide
*/
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 9c216a3..c4157cf 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3508,6 +3508,7 @@
PERMISSION_SERVICE,
LIGHTS_SERVICE,
//@hide: PEOPLE_SERVICE,
+ //@hide: DEVICE_STATE_SERVICE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ServiceName {}
@@ -5246,6 +5247,14 @@
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 0000000..a52f983
--- /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 0000000..4e7cf4a
--- /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 0000000..24913e9
--- /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/java/android/net/NetworkProvider.java b/core/java/android/net/NetworkProvider.java
index 75086cf..d31218d 100644
--- a/core/java/android/net/NetworkProvider.java
+++ b/core/java/android/net/NetworkProvider.java
@@ -30,7 +30,7 @@
/**
* Base class for network providers such as telephony or Wi-Fi. NetworkProviders connect the device
- * to networks and makes them available to to the core network stack by creating
+ * to networks and makes them available to the core network stack by creating
* {@link NetworkAgent}s. The networks can then provide connectivity to apps and can be interacted
* with via networking APIs such as {@link ConnectivityManager}.
*
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 8ad7669..b133bcd 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -13412,6 +13412,7 @@
*
* @hide
*/
+ @TestApi
public static final String HIDDEN_API_POLICY = "hidden_api_policy";
/**
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 5b0d950..0847a17 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -739,7 +739,7 @@
* Set the scaling mode to be used for this surfaces buffers
* @hide
*/
- void setScalingMode(@ScalingMode int scalingMode) {
+ public void setScalingMode(@ScalingMode int scalingMode) {
synchronized (mLock) {
checkNotReleasedLocked();
int err = nativeSetScalingMode(mNativeObject, scalingMode);
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index ed9deec..566ebf3 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -187,8 +187,6 @@
private static native void nativeReparent(long transactionObj, long nativeObject,
long newParentNativeObject);
private static native void nativeSeverChildren(long transactionObj, long nativeObject);
- private static native void nativeSetOverrideScalingMode(long transactionObj, long nativeObject,
- int scalingMode);
private static native Display.HdrCapabilities nativeGetHdrCapabilities(IBinder displayToken);
@@ -1521,16 +1519,6 @@
/**
* @hide
*/
- public void setOverrideScalingMode(int scalingMode) {
- checkNotReleased();
- synchronized(SurfaceControl.class) {
- sGlobalTransaction.setOverrideScalingMode(this, scalingMode);
- }
- }
-
- /**
- * @hide
- */
@UnsupportedAppUsage
public void setLayer(int zorder) {
checkNotReleased();
@@ -2989,16 +2977,6 @@
}
/**
- * @hide
- */
- public Transaction setOverrideScalingMode(SurfaceControl sc, int overrideScalingMode) {
- checkPreconditions(sc);
- nativeSetOverrideScalingMode(mNativeObject, sc.mNativeObject,
- overrideScalingMode);
- return this;
- }
-
- /**
* Fills the surface with the specified color.
* @param color A float array with three values to represent r, g, b in range [0..1]. An
* invalid color will remove the color fill.
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 1419855..a61903d 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -1360,15 +1360,6 @@
transaction->detachChildren(ctrl);
}
-static void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong transactionObj,
- jlong nativeObject,
- jint scalingMode) {
- auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
-
- auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
- transaction->setOverrideScalingMode(ctrl, scalingMode);
-}
-
static jobject nativeGetHdrCapabilities(JNIEnv* env, jclass clazz, jobject tokenObject) {
sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
if (token == NULL) return NULL;
@@ -1694,8 +1685,6 @@
(void*)nativeReparent },
{"nativeSeverChildren", "(JJ)V",
(void*)nativeSeverChildren } ,
- {"nativeSetOverrideScalingMode", "(JJI)V",
- (void*)nativeSetOverrideScalingMode },
{"nativeCaptureDisplay",
"(Landroid/view/SurfaceControl$DisplayCaptureArgs;Landroid/view/SurfaceControl$ScreenCaptureListener;)I",
(void*)nativeCaptureDisplay },
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 7fac615..32ce5e2 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2751,4 +2751,9 @@
// OS: R QPR2
BLUETOOTH_PAIRING_RECEIVER = 1851;
+
+ // OPEN: Settings > Display > Screen timeout
+ // CATEGORY: SETTINGS
+ // OS: S
+ SCREEN_TIMEOUT = 1852;
}
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 7057b844..012acf5 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1206,7 +1206,7 @@
<string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ичинен <xliff:g id="NUMBER_0">%1$d</xliff:g> колдонмо ыңгайлаштырылууда."</string>
<string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> даярдалууда."</string>
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Колдонмолорду иштетип баштоо"</string>
- <string name="android_upgrading_complete" msgid="409800058018374746">"Жүктөө аякталууда."</string>
+ <string name="android_upgrading_complete" msgid="409800058018374746">"Жүктөлүүдө"</string>
<string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> иштеп жатат"</string>
<string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Оюнга кайтуу үчүн таптаңыз"</string>
<string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Оюн тандоо"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 1418248..2183d010 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -957,18 +957,18 @@
<string name="autofill_parish" msgid="6847960518334530198">"Мөргөлч"</string>
<string name="autofill_area" msgid="8289022370678448983">"Хэсэг"</string>
<string name="autofill_emirate" msgid="2544082046790551168">"Эмират"</string>
- <string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"өөрийн Вэб хавчуурга болон түүхийг унших"</string>
+ <string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"өөрийн Веб хавчуурга болон түүхийг унших"</string>
<string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"Апп нь Хөтчийн зочилж байсан бүх URL-н түүх болон Хөтчийн бүх хавчуургыг унших боломжтой. Анхаар: Энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вебээр хөтөчлөх чадавхтай аппликейшнүүдэд ашиглагдахгүй байх боломжтой."</string>
- <string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"вэб хавчуурга болон түүхийг бичих"</string>
+ <string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"веб хавчуурга болон түүхийг бичих"</string>
<string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Апп нь таны таблет дээр хадгалагдсан Хөтчийн түүх эсвэл хавчуургыг өөрчлөх боломжтой. Энэ нь апп-д Хөтчийн датаг арилгах эсвэл өөрчлөх боломжийг олгоно. Анхаар: Энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вебээр хөтөчлөх чадвартай аппликейшнд ажиллахгүй байх боломжтой."</string>
- <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Аппад таны Android TV төхөөрөмжид хадгалсан Хөтчийн түүх эсвэл хавчуургыг өөрчлөхийг зөвшөөрнө. Энэ нь аппад Хөтчийн өгөгдлийг устгах эсвэл өөрчлөхийг зөвшөөрч болзошгүй. Санамж: энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вэб хөтчийн чадамжтай бусад аппад хэрэгжихгүй байж болзошгүй."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Аппад таны Android TV төхөөрөмжид хадгалсан Хөтчийн түүх эсвэл хавчуургыг өөрчлөхийг зөвшөөрнө. Энэ нь аппад Хөтчийн өгөгдлийг устгах эсвэл өөрчлөхийг зөвшөөрч болзошгүй. Санамж: энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл веб хөтчийн чадамжтай бусад аппад хэрэгжихгүй байж болзошгүй."</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Апп нь таны утсан дээр хадгалагдсан Хөтчийн түүх эсвэл хавчуургыг өөрчлөх боломжтой. Энэ нь апп-д Хөтчийн датаг арилгах эсвэл өөрчлөх боломжийг олгоно. Анхаар: Энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вебээр хөтөчлөх чадвартай аппликейшнд ажиллахгүй байх боломжтой."</string>
<string name="permlab_setAlarm" msgid="1158001610254173567">"сэрүүлэг тохируулах"</string>
<string name="permdesc_setAlarm" msgid="2185033720060109640">"Апп нь суулгагдсан сэрүүлэгний апп дээр сэрүүлэг тохируулах боломжтой. Зарим сэрүүлэгний апп нь энэ функцийг дэмжихгүй байж болзошгүй."</string>
<string name="permlab_addVoicemail" msgid="4770245808840814471">"дуут шуудан нэмэх"</string>
<string name="permdesc_addVoicemail" msgid="5470312139820074324">"Таны дуут шуудангийн ирсэн мэйлд зурвас нэмэхийг апп-д зөвшөөрөх."</string>
<string name="permlab_writeGeolocationPermissions" msgid="8605631647492879449">"Хөтчийн геобайршлын зөвшөөрлийг өөрчлөх"</string>
- <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"Апп нь Хөтчийн гео байршлын зөвшөөрлийг өөрчлөх боломжтой. Хортой апп нь энийг ашиглан дурын вэб хуудасруу байршлын мэдээллийг илгээх боломжтой."</string>
+ <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"Апп нь Хөтчийн гео байршлын зөвшөөрлийг өөрчлөх боломжтой. Хортой апп нь энийг ашиглан дурын веб хуудасруу байршлын мэдээллийг илгээх боломжтой."</string>
<string name="save_password_message" msgid="2146409467245462965">"Та хөтчид энэ нууц үгийг сануулах уу?"</string>
<string name="save_password_notnow" msgid="2878327088951240061">"Одоо биш"</string>
<string name="save_password_remember" msgid="6490888932657708341">"Санах"</string>
@@ -1459,7 +1459,7 @@
<string name="progress_erasing" msgid="6891435992721028004">"Хуваалцсан хадгалах санг устгаж байна…"</string>
<string name="share" msgid="4157615043345227321">"Хуваалцах"</string>
<string name="find" msgid="5015737188624767706">"Олох"</string>
- <string name="websearch" msgid="5624340204512793290">"Вэб хайлт"</string>
+ <string name="websearch" msgid="5624340204512793290">"Веб хайлт"</string>
<string name="find_next" msgid="5341217051549648153">"Дараагийнхыг хайх"</string>
<string name="find_previous" msgid="4405898398141275532">"Өмнөхөөс олох"</string>
<string name="gpsNotifTicker" msgid="3207361857637620780">"<xliff:g id="NAME">%s</xliff:g>-н байршлын хүсэлт"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 2cdf709..092686b 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1389,7 +1389,7 @@
<string name="ext_media_status_unmountable" msgid="7043574843541087748">"बिग्रेको"</string>
<string name="ext_media_status_unsupported" msgid="5460509911660539317">"असमर्थित"</string>
<string name="ext_media_status_ejecting" msgid="7532403368044013797">"निकाल्दै..."</string>
- <string name="ext_media_status_formatting" msgid="774148701503179906">"फरम्याट गर्दै…"</string>
+ <string name="ext_media_status_formatting" msgid="774148701503179906">"फर्म्याट गर्दै…"</string>
<string name="ext_media_status_missing" msgid="6520746443048867314">"सम्मिलित छैन"</string>
<string name="activity_list_empty" msgid="4219430010716034252">"कुनै मिल्ने गतिविधि पाइएन।"</string>
<string name="permlab_route_media_output" msgid="8048124531439513118">"मिडिया निकास दिशानिर्देश गराउनुहोस्"</string>
diff --git a/core/tests/coretests/src/android/text/TextShaperTest.java b/core/tests/coretests/src/android/text/TextShaperTest.java
new file mode 100644
index 0000000..f92ea99
--- /dev/null
+++ b/core/tests/coretests/src/android/text/TextShaperTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.text;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.graphics.text.PositionedGlyphs;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TextShaperTest {
+
+ @Test
+ public void testFontWithPath() {
+ TextPaint p = new TextPaint();
+ p.setFontFeatureSettings("'wght' 900");
+ List<PositionedGlyphs> glyphs = StyledTextShaper.shapeText("a", 0, 1,
+ TextDirectionHeuristics.LTR, p);
+ assertThat(glyphs.size()).isEqualTo(1);
+ // This test only passes if the font of the Latin font is variable font.
+ assertThat(glyphs.get(0).getFont(0).getFile()).isNotNull();
+
+ }
+}
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index 21b8fc6..97cd8ab 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -687,7 +687,9 @@
charBuffer[3] = (char) ((packedAxis & 0x0000_00FF_0000_0000L) >> 32);
axes[i] = new FontVariationAxis(new String(charBuffer), value);
}
- Font.Builder builder = new Font.Builder(buffer)
+ String path = nGetFontPath(ptr);
+ File file = (path == null) ? null : new File(path);
+ Font.Builder builder = new Font.Builder(buffer, file, "")
.setWeight(weight)
.setSlant(italic ? FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT)
.setTtcIndex(ttcIndex)
@@ -712,6 +714,9 @@
private static native long nGetAxisInfo(long ptr, int i);
@FastNative
+ private static native String nGetFontPath(long ptr);
+
+ @FastNative
private static native float nGetGlyphBounds(long font, int glyphId, long paint, RectF rect);
@FastNative
diff --git a/libs/hwui/jni/fonts/Font.cpp b/libs/hwui/jni/fonts/Font.cpp
index 6bc318d..aeb096d 100644
--- a/libs/hwui/jni/fonts/Font.cpp
+++ b/libs/hwui/jni/fonts/Font.cpp
@@ -221,6 +221,17 @@
return (static_cast<uint64_t>(var.axisTag) << 32) | static_cast<uint64_t>(floatBinary);
}
+// FastNative
+static jstring Font_getFontPath(JNIEnv* env, jobject, jlong fontHandle) {
+ const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle);
+ MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get());
+ const std::string& filePath = minikinSkia->getFilePath();
+ if (filePath.empty()) {
+ return nullptr;
+ }
+ return env->NewStringUTF(filePath.c_str());
+}
+
// Critical Native
static jlong Font_getNativeFontPtr(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) {
FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle);
@@ -274,6 +285,7 @@
{ "nGetFontMetrics", "(JJLandroid/graphics/Paint$FontMetrics;)F", (void*) Font_getFontMetrics },
{ "nGetFontInfo", "(J)J", (void*) Font_getFontInfo },
{ "nGetAxisInfo", "(JI)J", (void*) Font_getAxisInfo },
+ { "nGetFontPath", "(J)Ljava/lang/String;", (void*) Font_getFontPath },
{ "nGetNativeFontPtr", "(J)J", (void*) Font_getNativeFontPtr },
};
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index eb2e23e..4a095c9 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.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 @@
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/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index f1727ec..094e866 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -124,6 +124,7 @@
private float mAppearAnimationTranslation;
private int mNormalColor;
private boolean mIsBelowSpeedBump;
+ private long mLastActionUpTime;
private float mNormalBackgroundVisibilityAmount;
private float mDimmedBackgroundFadeInAmount = -1;
@@ -225,6 +226,22 @@
return super.onInterceptTouchEvent(ev);
}
+ /** Sets the last action up time this view was touched. */
+ void setLastActionUpTime(long eventTime) {
+ mLastActionUpTime = eventTime;
+ }
+
+ /**
+ * Returns the last action up time. The last time will also be cleared because the source of
+ * action is not only from touch event. That prevents the caller from utilizing the time with
+ * unrelated event. The time can be 0 if the event is unavailable.
+ */
+ public long getAndResetLastActionUpTime() {
+ long lastActionUpTime = mLastActionUpTime;
+ mLastActionUpTime = 0;
+ return lastActionUpTime;
+ }
+
protected boolean disallowSingleClick(MotionEvent ev) {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
index dd30c89..41ce51c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.row;
+import android.os.SystemClock;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
@@ -92,6 +93,9 @@
mBlockNextTouch = false;
return true;
}
+ if (ev.getAction() == MotionEvent.ACTION_UP) {
+ mView.setLastActionUpTime(SystemClock.uptimeMillis());
+ }
if (mNeedsDimming && !mAccessibilityManager.isTouchExplorationEnabled()
&& mView.isInteractive()) {
if (mNeedsDimming && !mView.isDimmed()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 456e99c..873d40f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -4282,6 +4282,19 @@
}
public static Bundle getActivityOptions(@Nullable RemoteAnimationAdapter animationAdapter) {
+ return getDefaultActivityOptions(animationAdapter).toBundle();
+ }
+
+ public static Bundle getActivityOptions(@Nullable RemoteAnimationAdapter animationAdapter,
+ boolean isKeyguardShowing, long eventTime) {
+ ActivityOptions options = getDefaultActivityOptions(animationAdapter);
+ options.setSourceInfo(isKeyguardShowing ? ActivityOptions.SourceInfo.TYPE_LOCKSCREEN
+ : ActivityOptions.SourceInfo.TYPE_NOTIFICATION, eventTime);
+ return options.toBundle();
+ }
+
+ public static ActivityOptions getDefaultActivityOptions(
+ @Nullable RemoteAnimationAdapter animationAdapter) {
ActivityOptions options;
if (animationAdapter != null) {
options = ActivityOptions.makeRemoteAnimation(animationAdapter);
@@ -4291,7 +4304,7 @@
// Anything launched from the notification shade should always go into the secondary
// split-screen windowing mode.
options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
- return options.toBundle();
+ return options;
}
void visibilityChanged(boolean visible) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index aa01642..256ee20 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -30,6 +30,7 @@
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
@@ -40,7 +41,6 @@
import android.text.TextUtils;
import android.util.EventLog;
import android.view.RemoteAnimationAdapter;
-import android.view.View;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.NotificationVisibility;
@@ -402,7 +402,7 @@
PendingIntent intent,
Intent fillInIntent,
NotificationEntry entry,
- View row,
+ ExpandableNotificationRow row,
boolean wasOccluded,
boolean isActivityIntent) {
RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation(row,
@@ -414,8 +414,11 @@
.registerRemoteAnimationForNextActivityStart(
intent.getCreatorPackage(), adapter);
}
+ long eventTime = row.getAndResetLastActionUpTime();
+ Bundle options = eventTime > 0 ? getActivityOptions(adapter,
+ mKeyguardStateController.isShowing(), eventTime) : getActivityOptions(adapter);
int launchResult = intent.sendAndReturnResult(mContext, 0, fillInIntent, null,
- null, null, getActivityOptions(adapter));
+ null, null, options);
mMainThreadHandler.post(() -> {
mActivityLaunchAnimator.setLaunchResult(launchResult, isActivityIntent);
});
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 9ddf7a4..d71b919 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 @@
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 4cff5c0..7e3c1ab 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 @@
* @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 @@
@Override
public void onStart() {
mDeviceStatePolicy.getDeviceStateProvider().setListener(new DeviceStateProviderListener());
+ publishBinderService(Context.DEVICE_STATE_SERVICE, new BinderService());
}
/**
@@ -267,4 +268,9 @@
requestState(state);
}
}
+
+ /** Implementation of {@link IDeviceStateManager} published as a binder service. */
+ private final class BinderService extends IDeviceStateManager.Stub {
+
+ }
}
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index eb2c7e6..93cada7 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -208,7 +208,6 @@
private PackageManager mPackageManager;
private Context mContext;
- private DisplayDeviceConfig mDisplayDeviceConfig;
private final Injector mInjector;
AutomaticBrightnessController(Callbacks callbacks, Looper looper,
@@ -217,14 +216,13 @@
float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate,
long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
- HysteresisLevels screenBrightnessThresholds, Context context, DisplayDeviceConfig
- displayDeviceConfig) {
+ HysteresisLevels screenBrightnessThresholds, Context context) {
this(new Injector(), callbacks, looper, sensorManager, lightSensor, mapper,
lightSensorWarmUpTime, brightnessMin, brightnessMax, dozeScaleFactor,
lightSensorRate, initialLightSensorRate, brighteningLightDebounceConfig,
darkeningLightDebounceConfig, resetAmbientLuxAfterWarmUpConfig,
- ambientBrightnessThresholds, screenBrightnessThresholds, context,
- displayDeviceConfig);
+ ambientBrightnessThresholds, screenBrightnessThresholds, context
+ );
}
@VisibleForTesting
@@ -234,8 +232,7 @@
float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate,
long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
- HysteresisLevels screenBrightnessThresholds, Context context, DisplayDeviceConfig
- displayDeviceConfig) {
+ HysteresisLevels screenBrightnessThresholds, Context context) {
mInjector = injector;
mContext = context;
mCallbacks = callbacks;
@@ -257,7 +254,6 @@
mScreenBrightnessThresholds = screenBrightnessThresholds;
mShortTermModelValid = true;
mShortTermModelAnchor = -1;
- mDisplayDeviceConfig = displayDeviceConfig;
mHandler = new AutomaticBrightnessHandler(looper);
mAmbientLightRingBuffer =
new AmbientLightRingBuffer(mNormalLightSensorRate, mAmbientLightHorizon);
diff --git a/services/core/java/com/android/server/display/DisplayBlanker.java b/services/core/java/com/android/server/display/DisplayBlanker.java
index d294898..e2129ba 100644
--- a/services/core/java/com/android/server/display/DisplayBlanker.java
+++ b/services/core/java/com/android/server/display/DisplayBlanker.java
@@ -20,5 +20,5 @@
* Interface used to update the actual display state.
*/
public interface DisplayBlanker {
- void requestDisplayState(int state, float brightness);
+ void requestDisplayState(int displayId, int state, float brightness);
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index ca94efc..ffce3be 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -2382,7 +2382,7 @@
synchronized (mSyncRoot) {
DisplayBlanker blanker = new DisplayBlanker() {
@Override
- public void requestDisplayState(int state, float brightness) {
+ public void requestDisplayState(int displayId, int state, float brightness) {
// The order of operations is important for legacy reasons.
if (state == Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness);
@@ -2395,11 +2395,9 @@
}
}
};
- LogicalDisplay defaultDisplay =
- mLogicalDisplayMapper.getLocked(Display.DEFAULT_DISPLAY);
- DisplayDevice defaultDevice = defaultDisplay.getPrimaryDisplayDeviceLocked();
mDisplayPowerController = new DisplayPowerController(
- mContext, callbacks, handler, sensorManager, blanker, defaultDevice);
+ mContext, callbacks, handler, sensorManager, blanker,
+ Display.DEFAULT_DISPLAY);
mSensorManager = sensorManager;
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 58ef9d1..0211876 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -163,8 +163,8 @@
// The display blanker.
private final DisplayBlanker mBlanker;
- // The display device.
- private final DisplayDevice mDisplayDevice;
+ // The ID of the LogicalDisplay tied to this DisplayPowerController.
+ private final int mDisplayId;
// Tracker for brightness changes.
private final BrightnessTracker mBrightnessTracker;
@@ -406,7 +406,7 @@
*/
public DisplayPowerController(Context context,
DisplayPowerCallbacks callbacks, Handler handler,
- SensorManager sensorManager, DisplayBlanker blanker, DisplayDevice displayDevice) {
+ SensorManager sensorManager, DisplayBlanker blanker, int displayId) {
mHandler = new DisplayControllerHandler(handler.getLooper());
mBrightnessTracker = new BrightnessTracker(context, null);
mSettingsObserver = new SettingsObserver(mHandler);
@@ -417,10 +417,9 @@
mBlanker = blanker;
mContext = context;
mBrightnessSynchronizer = new BrightnessSynchronizer(context);
- mDisplayDevice = displayDevice;
+ mDisplayId = displayId;
PowerManager pm = context.getSystemService(PowerManager.class);
- DisplayDeviceConfig displayDeviceConfig = mDisplayDevice.getDisplayDeviceConfig();
final Resources resources = context.getResources();
@@ -515,7 +514,7 @@
mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds,
- screenBrightnessThresholds, context, displayDeviceConfig);
+ screenBrightnessThresholds, context);
} else {
mUseSoftwareAutoBrightnessConfig = false;
}
@@ -684,7 +683,7 @@
// Initialize the power state object for the default display.
// In the future, we might manage multiple displays independently.
mPowerState = new DisplayPowerState(mBlanker,
- mColorFadeEnabled ? new ColorFade(Display.DEFAULT_DISPLAY) : null);
+ mColorFadeEnabled ? new ColorFade(mDisplayId) : null, mDisplayId);
if (mColorFadeEnabled) {
mColorFadeOnAnimator = ObjectAnimator.ofFloat(
@@ -1153,7 +1152,7 @@
if (ready && state != Display.STATE_OFF
&& mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
- mWindowManagerPolicy.screenTurnedOn();
+ mWindowManagerPolicy.screenTurnedOn(mDisplayId);
}
// Grab a wake lock if we have unfinished business.
@@ -1277,7 +1276,7 @@
if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
blockScreenOff();
- mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker);
+ mWindowManagerPolicy.screenTurningOff(mDisplayId, mPendingScreenOffUnblocker);
unblockScreenOff();
} else if (mPendingScreenOffUnblocker != null) {
// Abort doing the state change until screen off is unblocked.
@@ -1309,14 +1308,14 @@
&& !mScreenOffBecauseOfProximity) {
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
unblockScreenOn();
- mWindowManagerPolicy.screenTurnedOff();
+ mWindowManagerPolicy.screenTurnedOff(mDisplayId);
} else if (!isOff
&& mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {
// We told policy already that screen was turning off, but now we changed our minds.
// Complete the full state transition on -> turningOff -> off.
unblockScreenOff();
- mWindowManagerPolicy.screenTurnedOff();
+ mWindowManagerPolicy.screenTurnedOff(mDisplayId);
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
}
if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
@@ -1326,7 +1325,7 @@
} else {
unblockScreenOn();
}
- mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
+ mWindowManagerPolicy.screenTurningOn(mDisplayId, mPendingScreenOnUnblocker);
}
// Return true if the screen isn't blocked.
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index 4b6430d..54f30a9 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -58,6 +58,7 @@
private final DisplayBlanker mBlanker;
private final ColorFade mColorFade;
private final PhotonicModulator mPhotonicModulator;
+ private final int mDisplayId;
private int mScreenState;
private float mScreenBrightness;
@@ -71,13 +72,14 @@
private Runnable mCleanListener;
- public DisplayPowerState(DisplayBlanker blanker, ColorFade colorFade) {
+ public DisplayPowerState(DisplayBlanker blanker, ColorFade colorFade, int displayId) {
mHandler = new Handler(true /*async*/);
mChoreographer = Choreographer.getInstance();
mBlanker = blanker;
mColorFade = colorFade;
mPhotonicModulator = new PhotonicModulator();
mPhotonicModulator.start();
+ mDisplayId = displayId;
// At boot time, we know that the screen is on and the electron beam
// animation is not playing. We don't know the screen's brightness though,
@@ -434,10 +436,10 @@
// Apply pending change.
if (DEBUG) {
- Slog.d(TAG, "Updating screen state: state="
+ Slog.d(TAG, "Updating screen state: id=" + mDisplayId + ", state="
+ Display.stateToString(state) + ", backlight=" + brightnessState);
}
- mBlanker.requestDisplayState(state, brightnessState);
+ mBlanker.requestDisplayState(mDisplayId, state, brightnessState);
}
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index df283e2..0313aae 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4506,7 +4506,11 @@
// Called on the DisplayManager's DisplayPowerController thread.
@Override
- public void screenTurnedOff() {
+ public void screenTurnedOff(int displayId) {
+ if (displayId != DEFAULT_DISPLAY) {
+ return;
+ }
+
if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turned off...");
updateScreenOffSleepToken(true);
@@ -4529,7 +4533,11 @@
// Called on the DisplayManager's DisplayPowerController thread.
@Override
- public void screenTurningOn(final ScreenOnListener screenOnListener) {
+ public void screenTurningOn(int displayId, final ScreenOnListener screenOnListener) {
+ if (displayId != DEFAULT_DISPLAY) {
+ return;
+ }
+
if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...");
Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn", 0 /* cookie */);
@@ -4552,7 +4560,11 @@
// Called on the DisplayManager's DisplayPowerController thread.
@Override
- public void screenTurnedOn() {
+ public void screenTurnedOn(int displayId) {
+ if (displayId != DEFAULT_DISPLAY) {
+ return;
+ }
+
synchronized (mLock) {
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onScreenTurnedOn();
@@ -4562,7 +4574,11 @@
}
@Override
- public void screenTurningOff(ScreenOffListener screenOffListener) {
+ public void screenTurningOff(int displayId, ScreenOffListener screenOffListener) {
+ if (displayId != DEFAULT_DISPLAY) {
+ return;
+ }
+
mWindowManagerFuncs.screenTurningOff(screenOffListener);
synchronized (mLock) {
if (mKeyguardDelegate != null) {
@@ -4824,8 +4840,8 @@
}
startedWakingUp(ON_BECAUSE_OF_UNKNOWN);
finishedWakingUp(ON_BECAUSE_OF_UNKNOWN);
- screenTurningOn(null);
- screenTurnedOn();
+ screenTurningOn(DEFAULT_DISPLAY, null);
+ screenTurnedOn(DEFAULT_DISPLAY);
}
@Override
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index b96d65c..0d8d347 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -831,7 +831,7 @@
public void finishedGoingToSleep(int why);
/**
- * Called when the device is about to turn on the screen to show content.
+ * Called when the display is about to turn on to show content.
* When waking up, this method will be called once after the call to wakingUp().
* When dozing, the method will be called sometime after the call to goingToSleep() and
* may be called repeatedly in the case where the screen is pulsing on and off.
@@ -839,13 +839,13 @@
* Must call back on the listener to tell it when the higher-level system
* is ready for the screen to go on (i.e. the lock screen is shown).
*/
- public void screenTurningOn(ScreenOnListener screenOnListener);
+ public void screenTurningOn(int displayId, ScreenOnListener screenOnListener);
/**
- * Called when the device has actually turned on the screen, i.e. the display power state has
- * been set to ON and the screen is unblocked.
+ * Called when the display has actually turned on, i.e. the display power state has been set to
+ * ON and the screen is unblocked.
*/
- public void screenTurnedOn();
+ public void screenTurnedOn(int displayId);
/**
* Called when the display would like to be turned off. This gives policy a chance to do some
@@ -854,12 +854,12 @@
* @param screenOffListener Must be called to tell that the display power state can actually be
* changed now after policy has done its work.
*/
- public void screenTurningOff(ScreenOffListener screenOffListener);
+ public void screenTurningOff(int displayId, ScreenOffListener screenOffListener);
/**
- * Called when the device has turned the screen off.
+ * Called when the display has turned off.
*/
- public void screenTurnedOff();
+ public void screenTurnedOff(int displayId);
public interface ScreenOnListener {
void onScreenOn();
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index fb06a9c..9d08b1b 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -397,6 +397,13 @@
return -1;
}
}
+
+ PackageOptimizationInfo getPackageOptimizationInfo(ArtManagerInternal artManagerInternal) {
+ return artManagerInternal == null || launchedActivityAppRecordRequiredAbi == null
+ ? PackageOptimizationInfo.createWithNoInfo()
+ : artManagerInternal.getPackageOptimizationInfo(applicationInfo,
+ launchedActivityAppRecordRequiredAbi, launchedActivityName);
+ }
}
ActivityMetricsLogger(ActivityStackSupervisor supervisor, Looper looper) {
@@ -857,14 +864,8 @@
info.bindApplicationDelayMs);
}
builder.addTaggedData(APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS, info.windowsDrawnDelayMs);
- final ArtManagerInternal artManagerInternal = getArtManagerInternal();
final PackageOptimizationInfo packageOptimizationInfo =
- (artManagerInternal == null) || (info.launchedActivityAppRecordRequiredAbi == null)
- ? PackageOptimizationInfo.createWithNoInfo()
- : artManagerInternal.getPackageOptimizationInfo(
- info.applicationInfo,
- info.launchedActivityAppRecordRequiredAbi,
- info.launchedActivityName);
+ info.getPackageOptimizationInfo(getArtManagerInternal());
builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_REASON,
packageOptimizationInfo.getCompilationReason());
builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_FILTER,
@@ -985,6 +986,8 @@
builder.addTaggedData(APP_TRANSITION_PROCESS_RUNNING,
info.mProcessRunning ? 1 : 0);
mMetricsLogger.write(builder);
+ final PackageOptimizationInfo packageOptimizationInfo =
+ infoSnapshot.getPackageOptimizationInfo(getArtManagerInternal());
FrameworkStatsLog.write(
FrameworkStatsLog.APP_START_FULLY_DRAWN,
info.mLastLaunchedActivity.info.applicationInfo.uid,
@@ -995,6 +998,8 @@
info.mLastLaunchedActivity.info.name,
info.mProcessRunning,
startupTimeMs,
+ packageOptimizationInfo.getCompilationReason(),
+ packageOptimizationInfo.getCompilationFilter(),
info.mSourceType,
info.mSourceEventDelayMs);
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 25732e7..7ed22a1 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -203,16 +203,14 @@
.setCallsite("ScreenRotationAnimation")
.build();
- // In case display bounds change, screenshot buffer and surface may mismatch so set a
- // scaling mode.
- SurfaceControl.Transaction t2 = mService.mTransactionFactory.get();
- t2.setOverrideScalingMode(mScreenshotLayer, Surface.SCALING_MODE_SCALE_TO_WINDOW);
- t2.apply(true /* sync */);
-
// Capture a screenshot into the surface we just created.
final int displayId = displayContent.getDisplayId();
final Surface surface = mService.mSurfaceFactory.get();
+ // In case display bounds change, screenshot buffer and surface may mismatch so set a
+ // scaling mode.
surface.copyFrom(mScreenshotLayer);
+ surface.setScalingMode(Surface.SCALING_MODE_SCALE_TO_WINDOW);
+
SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
mService.mDisplayManagerInternal.systemScreenshot(displayId);
if (screenshotBuffer != null) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 249fe03..0077182 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1474,14 +1474,6 @@
// Update task bounds if needed.
adjustBoundsForDisplayChangeIfNeeded(getDisplayContent());
- if (getWindowConfiguration().windowsAreScaleable()) {
- // We force windows out of SCALING_MODE_FREEZE so that we can continue to animate them
- // while a resize is pending.
- forceWindowsScaleable(true /* force */);
- } else {
- forceWindowsScaleable(false /* force */);
- }
-
mRootWindowContainer.updateUIDsPresentOnDisplay();
// Resume next focusable stack after reparenting to another display if we aren't removing
@@ -3780,17 +3772,6 @@
positionChildAt(position, child, false /* includeParents */);
}
- void forceWindowsScaleable(boolean force) {
- mWmService.openSurfaceTransaction();
- try {
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- mChildren.get(i).forceWindowsScaleableInTransaction(force);
- }
- } finally {
- mWmService.closeSurfaceTransaction("forceWindowsScaleable");
- }
- }
-
void setTaskDescription(TaskDescription taskDescription) {
mTaskDescription = taskDescription;
}
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 95d8662..0edaa1d 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -861,13 +861,6 @@
}
}
- void forceWindowsScaleableInTransaction(boolean force) {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final WindowContainer wc = mChildren.get(i);
- wc.forceWindowsScaleableInTransaction(force);
- }
- }
-
/**
* @return {@code true} when an application can override an app transition animation on this
* container.
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 0b53bf6..3b79241 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2172,16 +2172,7 @@
}
}
- @Override
- void forceWindowsScaleableInTransaction(boolean force) {
- if (mWinAnimator != null && mWinAnimator.hasSurface()) {
- mWinAnimator.mSurfaceController.forceScaleableInTransaction(force);
- }
-
- super.forceWindowsScaleableInTransaction(force);
- }
-
- @Override
+ @Override
void removeImmediately() {
super.removeImmediately();
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index f342976..6349e6d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -971,10 +971,6 @@
* @return Returns true if the surface was successfully shown.
*/
private boolean showSurfaceRobustlyLocked() {
- if (mWin.getWindowConfiguration().windowsAreScaleable()) {
- mSurfaceController.forceScaleableInTransaction(true);
- }
-
boolean shown = mSurfaceController.showRobustlyInTransaction();
if (!shown)
return false;
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index cbe0a42..d2c36e2 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -342,11 +342,9 @@
return false;
}
- void forceScaleableInTransaction(boolean force) {
- // -1 means we don't override the default or client specified
- // scaling mode.
- int scalingMode = force ? SCALING_MODE_SCALE_TO_WINDOW : -1;
- mSurfaceControl.setOverrideScalingMode(scalingMode);
+ void deferTransactionUntil(SurfaceControl barrier, long frame) {
+ // TODO: Logging
+ mSurfaceControl.deferTransactionUntil(barrier, frame);
}
boolean clearWindowContentFrameStats() {
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 d61783e..a5f0834 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.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.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.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 @@
@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 @@
}
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 @@
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 @@
}
}
+ @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 @@
}
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 9e43b4a..f0490ce 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 @@
@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 @@
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 @@
@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 @@
@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 @@
@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 @@
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 @@
@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 @@
}
@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 0000000..efcfae3
--- /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 6465739..5bb6a42 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 @@
}
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 0000000..2552db8
--- /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 59d4e2a..058794a 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/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
index b69cc47..ec747ac 100644
--- a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
@@ -83,8 +83,8 @@
BRIGHTNESS_MAX_FLOAT, DOZE_SCALE_FACTOR, LIGHT_SENSOR_RATE,
INITIAL_LIGHT_SENSOR_RATE, BRIGHTENING_LIGHT_DEBOUNCE_CONFIG,
DARKENING_LIGHT_DEBOUNCE_CONFIG, RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG,
- mAmbientBrightnessThresholds, mScreenBrightnessThresholds, mContext,
- mDisplayDeviceConfig);
+ mAmbientBrightnessThresholds, mScreenBrightnessThresholds, mContext
+ );
controller.setLoggingEnabled(true);
// Configure the brightness controller and grab an instance of the sensor listener,
diff --git a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
index d0a5644..ecbfac8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
+++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
@@ -163,12 +163,6 @@
}
@Override
- public SurfaceControl.Transaction setOverrideScalingMode(SurfaceControl sc,
- int overrideScalingMode) {
- return this;
- }
-
- @Override
public SurfaceControl.Transaction setColor(SurfaceControl sc, float[] color) {
return this;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index dc85904..db5c796 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -197,19 +197,19 @@
}
@Override
- public void screenTurningOn(ScreenOnListener screenOnListener) {
+ public void screenTurningOn(int displayId, ScreenOnListener screenOnListener) {
}
@Override
- public void screenTurnedOn() {
+ public void screenTurnedOn(int displayId) {
}
@Override
- public void screenTurningOff(ScreenOffListener screenOffListener) {
+ public void screenTurningOff(int displayId, ScreenOffListener screenOffListener) {
}
@Override
- public void screenTurnedOff() {
+ public void screenTurnedOff(int displayId) {
}
@Override
diff --git a/telecomm/java/android/telecom/CallerInfo.java b/telecomm/java/android/telecom/CallerInfo.java
index fb6f994..aff2f01 100644
--- a/telecomm/java/android/telecom/CallerInfo.java
+++ b/telecomm/java/android/telecom/CallerInfo.java
@@ -405,7 +405,8 @@
// 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 4a81a8e..a9e1a8f 100644
--- a/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
+++ b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
@@ -34,6 +34,7 @@
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 @@
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;
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index 9bf6b6f..6662b0e 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -27,6 +27,7 @@
import static org.junit.Assume.assumeTrue;
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.ddmlib.Log;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.IFileEntry;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -53,6 +54,7 @@
*/
@RunWith(DeviceJUnit4ClassRunner.class)
public class StagedRollbackTest extends BaseHostJUnit4Test {
+ private static final String TAG = "StagedRollbackTest";
private static final int NATIVE_CRASHES_THRESHOLD = 5;
/**
@@ -556,16 +558,18 @@
return String.format("/data/user_de/%d/%s", userId, apexName);
}
- private List<String> getSnapshotDirectories(String baseDir) {
- try {
- return getDevice().getFileEntry(baseDir).getChildren(false)
- .stream().filter(entry -> entry.getName().matches("\\d+(-prerestore)?"))
- .map(entry -> entry.getFullPath())
- .collect(Collectors.toList());
- } catch (Exception e) {
- // Return an empty list if any error
+ private List<String> getSnapshotDirectories(String baseDir) throws Exception {
+ IFileEntry f = getDevice().getFileEntry(baseDir);
+ if (f == null) {
+ Log.d(TAG, "baseDir doesn't exist: " + baseDir);
return Collections.EMPTY_LIST;
}
+ List<String> list = f.getChildren(false)
+ .stream().filter(entry -> entry.getName().matches("\\d+(-prerestore)?"))
+ .map(entry -> entry.getFullPath())
+ .collect(Collectors.toList());
+ Log.d(TAG, "getSnapshotDirectories=" + list);
+ return list;
}
private void assertDirectoryIsEmpty(String path) {