Merge "Separating quota window for pre-S apps" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
219aea8c64
@@ -24,6 +24,7 @@ import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_COMPAT;
|
||||
import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
|
||||
import static android.app.AlarmManager.FLAG_IDLE_UNTIL;
|
||||
import static android.app.AlarmManager.FLAG_WAKE_FROM_IDLE;
|
||||
import static android.app.AlarmManager.INTERVAL_DAY;
|
||||
import static android.app.AlarmManager.INTERVAL_HOUR;
|
||||
import static android.app.AlarmManager.RTC;
|
||||
import static android.app.AlarmManager.RTC_WAKEUP;
|
||||
@@ -88,7 +89,6 @@ import android.provider.Settings;
|
||||
import android.system.Os;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateFormat;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.IndentingPrintWriter;
|
||||
@@ -168,8 +168,7 @@ public class AlarmManagerService extends SystemService {
|
||||
static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
|
||||
|
||||
static final int TICK_HISTORY_DEPTH = 10;
|
||||
static final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||
static final long INDEFINITE_DELAY = 365 * MILLIS_IN_DAY;
|
||||
static final long INDEFINITE_DELAY = 365 * INTERVAL_DAY;
|
||||
|
||||
// Indices into the KEYS_APP_STANDBY_QUOTAS array.
|
||||
static final int ACTIVE_INDEX = 0;
|
||||
@@ -423,13 +422,17 @@ public class AlarmManagerService extends SystemService {
|
||||
|
||||
@VisibleForTesting
|
||||
static final String KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA = "allow_while_idle_compat_quota";
|
||||
private static final String KEY_ALLOW_WHILE_IDLE_WINDOW = "allow_while_idle_window";
|
||||
|
||||
@VisibleForTesting
|
||||
static final String KEY_ALLOW_WHILE_IDLE_WINDOW = "allow_while_idle_window";
|
||||
@VisibleForTesting
|
||||
static final String KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW = "allow_while_idle_compat_window";
|
||||
|
||||
private static final String KEY_CRASH_NON_CLOCK_APPS = "crash_non_clock_apps";
|
||||
|
||||
private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
|
||||
private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
|
||||
private static final long DEFAULT_MAX_INTERVAL = 365 * DateUtils.DAY_IN_MILLIS;
|
||||
private static final long DEFAULT_MAX_INTERVAL = 365 * INTERVAL_DAY;
|
||||
private static final long DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION = 10 * 1000;
|
||||
private static final long DEFAULT_LISTENER_TIMEOUT = 5 * 1000;
|
||||
private static final int DEFAULT_MAX_ALARMS_PER_UID = 500;
|
||||
@@ -445,19 +448,21 @@ public class AlarmManagerService extends SystemService {
|
||||
0 // Never
|
||||
};
|
||||
private static final int DEFAULT_APP_STANDBY_RESTRICTED_QUOTA = 1;
|
||||
private static final long DEFAULT_APP_STANDBY_RESTRICTED_WINDOW = MILLIS_IN_DAY;
|
||||
private static final long DEFAULT_APP_STANDBY_RESTRICTED_WINDOW = INTERVAL_DAY;
|
||||
|
||||
private static final boolean DEFAULT_LAZY_BATCHING = true;
|
||||
private static final boolean DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE = true;
|
||||
|
||||
/**
|
||||
* Default quota for pre-S apps. Enough to accommodate the existing policy of an alarm
|
||||
* Default quota for pre-S apps. The same as allowing an alarm slot once
|
||||
* every ALLOW_WHILE_IDLE_LONG_DELAY, which was 9 minutes.
|
||||
*/
|
||||
private static final int DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA = 7;
|
||||
private static final int DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA = 1;
|
||||
private static final int DEFAULT_ALLOW_WHILE_IDLE_QUOTA = 72;
|
||||
|
||||
private static final long DEFAULT_ALLOW_WHILE_IDLE_WINDOW = 60 * 60 * 1000; // 1 hour.
|
||||
private static final long DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW = 9 * 60 * 1000; // 9 mins.
|
||||
|
||||
// TODO (b/171306433): Change to true by default.
|
||||
private static final boolean DEFAULT_CRASH_NON_CLOCK_APPS = false;
|
||||
|
||||
@@ -495,9 +500,14 @@ public class AlarmManagerService extends SystemService {
|
||||
public int ALLOW_WHILE_IDLE_COMPAT_QUOTA = DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA;
|
||||
|
||||
/**
|
||||
* The window used for enforcing {@link #ALLOW_WHILE_IDLE_QUOTA} and
|
||||
* {@link #ALLOW_WHILE_IDLE_COMPAT_QUOTA}. Can be configured, but only recommended for
|
||||
* testing.
|
||||
* The window used for enforcing {@link #ALLOW_WHILE_IDLE_COMPAT_QUOTA}.
|
||||
* Can be configured, but only recommended for testing.
|
||||
*/
|
||||
public long ALLOW_WHILE_IDLE_COMPAT_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW;
|
||||
|
||||
/**
|
||||
* The window used for enforcing {@link #ALLOW_WHILE_IDLE_COMPAT_QUOTA}.
|
||||
* Can be configured, but only recommended for testing.
|
||||
*/
|
||||
public long ALLOW_WHILE_IDLE_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_WINDOW;
|
||||
|
||||
@@ -561,7 +571,7 @@ public class AlarmManagerService extends SystemService {
|
||||
ALLOW_WHILE_IDLE_QUOTA = properties.getInt(KEY_ALLOW_WHILE_IDLE_QUOTA,
|
||||
DEFAULT_ALLOW_WHILE_IDLE_QUOTA);
|
||||
if (ALLOW_WHILE_IDLE_QUOTA <= 0) {
|
||||
Slog.w(TAG, "Cannot have allow-while-idle quota lower than 1.");
|
||||
Slog.w(TAG, "Must have positive allow_while_idle quota");
|
||||
ALLOW_WHILE_IDLE_QUOTA = 1;
|
||||
}
|
||||
break;
|
||||
@@ -570,22 +580,38 @@ public class AlarmManagerService extends SystemService {
|
||||
KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA,
|
||||
DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA);
|
||||
if (ALLOW_WHILE_IDLE_COMPAT_QUOTA <= 0) {
|
||||
Slog.w(TAG, "Cannot have quota lower than 1.");
|
||||
Slog.w(TAG, "Must have positive allow_while_idle_compat quota");
|
||||
ALLOW_WHILE_IDLE_COMPAT_QUOTA = 1;
|
||||
}
|
||||
break;
|
||||
case KEY_ALLOW_WHILE_IDLE_WINDOW:
|
||||
ALLOW_WHILE_IDLE_WINDOW = properties.getLong(
|
||||
KEY_ALLOW_WHILE_IDLE_WINDOW, DEFAULT_ALLOW_WHILE_IDLE_WINDOW);
|
||||
if (ALLOW_WHILE_IDLE_WINDOW > DEFAULT_ALLOW_WHILE_IDLE_WINDOW) {
|
||||
|
||||
if (ALLOW_WHILE_IDLE_WINDOW > INTERVAL_HOUR) {
|
||||
Slog.w(TAG, "Cannot have allow_while_idle_window > "
|
||||
+ DEFAULT_ALLOW_WHILE_IDLE_WINDOW);
|
||||
ALLOW_WHILE_IDLE_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_WINDOW;
|
||||
} else if (ALLOW_WHILE_IDLE_WINDOW < DEFAULT_ALLOW_WHILE_IDLE_WINDOW) {
|
||||
+ INTERVAL_HOUR);
|
||||
ALLOW_WHILE_IDLE_WINDOW = INTERVAL_HOUR;
|
||||
} else if (ALLOW_WHILE_IDLE_WINDOW != DEFAULT_ALLOW_WHILE_IDLE_WINDOW) {
|
||||
Slog.w(TAG, "Using a non-default allow_while_idle_window = "
|
||||
+ ALLOW_WHILE_IDLE_WINDOW);
|
||||
}
|
||||
break;
|
||||
case KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW:
|
||||
ALLOW_WHILE_IDLE_COMPAT_WINDOW = properties.getLong(
|
||||
KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW,
|
||||
DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW);
|
||||
|
||||
if (ALLOW_WHILE_IDLE_COMPAT_WINDOW > INTERVAL_HOUR) {
|
||||
Slog.w(TAG, "Cannot have allow_while_idle_compat_window > "
|
||||
+ INTERVAL_HOUR);
|
||||
ALLOW_WHILE_IDLE_COMPAT_WINDOW = INTERVAL_HOUR;
|
||||
} else if (ALLOW_WHILE_IDLE_COMPAT_WINDOW
|
||||
!= DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW) {
|
||||
Slog.w(TAG, "Using a non-default allow_while_idle_compat_window = "
|
||||
+ ALLOW_WHILE_IDLE_COMPAT_WINDOW);
|
||||
}
|
||||
break;
|
||||
case KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION:
|
||||
ALLOW_WHILE_IDLE_WHITELIST_DURATION = properties.getLong(
|
||||
KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION,
|
||||
@@ -717,6 +743,9 @@ public class AlarmManagerService extends SystemService {
|
||||
TimeUtils.formatDuration(LISTENER_TIMEOUT, pw);
|
||||
pw.println();
|
||||
|
||||
pw.print(KEY_ALLOW_WHILE_IDLE_QUOTA, ALLOW_WHILE_IDLE_QUOTA);
|
||||
pw.println();
|
||||
|
||||
pw.print(KEY_ALLOW_WHILE_IDLE_WINDOW);
|
||||
pw.print("=");
|
||||
TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WINDOW, pw);
|
||||
@@ -725,7 +754,9 @@ public class AlarmManagerService extends SystemService {
|
||||
pw.print(KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, ALLOW_WHILE_IDLE_COMPAT_QUOTA);
|
||||
pw.println();
|
||||
|
||||
pw.print(KEY_ALLOW_WHILE_IDLE_QUOTA, ALLOW_WHILE_IDLE_QUOTA);
|
||||
pw.print(KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW);
|
||||
pw.print("=");
|
||||
TimeUtils.formatDuration(ALLOW_WHILE_IDLE_COMPAT_WINDOW, pw);
|
||||
pw.println();
|
||||
|
||||
pw.print(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION);
|
||||
@@ -1330,8 +1361,7 @@ public class AlarmManagerService extends SystemService {
|
||||
mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater);
|
||||
|
||||
mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW);
|
||||
mAllowWhileIdleHistory = new AppWakeupHistory(
|
||||
Constants.DEFAULT_ALLOW_WHILE_IDLE_WINDOW);
|
||||
mAllowWhileIdleHistory = new AppWakeupHistory(INTERVAL_HOUR);
|
||||
|
||||
mNextWakeup = mNextNonWakeup = 0;
|
||||
|
||||
@@ -1730,9 +1760,15 @@ public class AlarmManagerService extends SystemService {
|
||||
} else if (isAllowedWhileIdleRestricted(alarm)) {
|
||||
// Allowed but limited.
|
||||
final int userId = UserHandle.getUserId(alarm.creatorUid);
|
||||
final int quota = ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0)
|
||||
? mConstants.ALLOW_WHILE_IDLE_QUOTA
|
||||
: mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
|
||||
final int quota;
|
||||
final long window;
|
||||
if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) {
|
||||
quota = mConstants.ALLOW_WHILE_IDLE_QUOTA;
|
||||
window = mConstants.ALLOW_WHILE_IDLE_WINDOW;
|
||||
} else {
|
||||
quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
|
||||
window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW;
|
||||
}
|
||||
final int dispatchesInWindow = mAllowWhileIdleHistory.getTotalWakeupsInWindow(
|
||||
alarm.sourcePackage, userId);
|
||||
if (dispatchesInWindow < quota) {
|
||||
@@ -1740,7 +1776,7 @@ public class AlarmManagerService extends SystemService {
|
||||
batterySaverPolicyElapsed = nowElapsed;
|
||||
} else {
|
||||
batterySaverPolicyElapsed = mAllowWhileIdleHistory.getNthLastWakeupForPackage(
|
||||
alarm.sourcePackage, userId, quota) + mConstants.ALLOW_WHILE_IDLE_WINDOW;
|
||||
alarm.sourcePackage, userId, quota) + window;
|
||||
}
|
||||
} else {
|
||||
// Not allowed.
|
||||
@@ -1778,9 +1814,15 @@ public class AlarmManagerService extends SystemService {
|
||||
} else if (isAllowedWhileIdleRestricted(alarm)) {
|
||||
// Allowed but limited.
|
||||
final int userId = UserHandle.getUserId(alarm.creatorUid);
|
||||
final int quota = ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0)
|
||||
? mConstants.ALLOW_WHILE_IDLE_QUOTA
|
||||
: mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
|
||||
final int quota;
|
||||
final long window;
|
||||
if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) {
|
||||
quota = mConstants.ALLOW_WHILE_IDLE_QUOTA;
|
||||
window = mConstants.ALLOW_WHILE_IDLE_WINDOW;
|
||||
} else {
|
||||
quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
|
||||
window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW;
|
||||
}
|
||||
final int dispatchesInWindow = mAllowWhileIdleHistory.getTotalWakeupsInWindow(
|
||||
alarm.sourcePackage, userId);
|
||||
if (dispatchesInWindow < quota) {
|
||||
@@ -1788,7 +1830,7 @@ public class AlarmManagerService extends SystemService {
|
||||
deviceIdlePolicyTime = nowElapsed;
|
||||
} else {
|
||||
final long whenInQuota = mAllowWhileIdleHistory.getNthLastWakeupForPackage(
|
||||
alarm.sourcePackage, userId, quota) + mConstants.ALLOW_WHILE_IDLE_WINDOW;
|
||||
alarm.sourcePackage, userId, quota) + window;
|
||||
deviceIdlePolicyTime = Math.min(whenInQuota, mPendingIdleUntil.getWhenElapsed());
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -49,8 +49,10 @@ import static com.android.server.alarm.AlarmManagerService.AlarmHandler.APP_STAN
|
||||
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.CHARGING_STATUS_CHANGED;
|
||||
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_FOR_CANCELED;
|
||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA;
|
||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW;
|
||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_QUOTA;
|
||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION;
|
||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WINDOW;
|
||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LAZY_BATCHING;
|
||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LISTENER_TIMEOUT;
|
||||
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MAX_INTERVAL;
|
||||
@@ -566,17 +568,23 @@ public class AlarmManagerServiceTest {
|
||||
setDeviceConfigLong(KEY_MAX_INTERVAL, 15);
|
||||
setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_QUOTA, 20);
|
||||
setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, 25);
|
||||
setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION, 30);
|
||||
setDeviceConfigLong(KEY_LISTENER_TIMEOUT, 35);
|
||||
setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_WINDOW, 30);
|
||||
setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW, 35);
|
||||
setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION, 40);
|
||||
setDeviceConfigLong(KEY_LISTENER_TIMEOUT, 45);
|
||||
assertEquals(5, mService.mConstants.MIN_FUTURITY);
|
||||
assertEquals(10, mService.mConstants.MIN_INTERVAL);
|
||||
assertEquals(15, mService.mConstants.MAX_INTERVAL);
|
||||
assertEquals(20, mService.mConstants.ALLOW_WHILE_IDLE_QUOTA);
|
||||
assertEquals(25, mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA);
|
||||
assertEquals(30, mService.mConstants.ALLOW_WHILE_IDLE_WHITELIST_DURATION);
|
||||
assertEquals(35, mService.mConstants.LISTENER_TIMEOUT);
|
||||
assertEquals(30, mService.mConstants.ALLOW_WHILE_IDLE_WINDOW);
|
||||
assertEquals(35, mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW);
|
||||
assertEquals(40, mService.mConstants.ALLOW_WHILE_IDLE_WHITELIST_DURATION);
|
||||
assertEquals(45, mService.mConstants.LISTENER_TIMEOUT);
|
||||
}
|
||||
|
||||
// Test safeguards.
|
||||
@Test
|
||||
public void positiveWhileIdleQuotas() {
|
||||
setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_QUOTA, -3);
|
||||
assertEquals(1, mService.mConstants.ALLOW_WHILE_IDLE_QUOTA);
|
||||
setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_QUOTA, 0);
|
||||
@@ -588,6 +596,21 @@ public class AlarmManagerServiceTest {
|
||||
assertEquals(1, mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whileIdleWindowsDontExceedAnHour() {
|
||||
setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_WINDOW, AlarmManager.INTERVAL_DAY);
|
||||
assertEquals(AlarmManager.INTERVAL_HOUR, mService.mConstants.ALLOW_WHILE_IDLE_WINDOW);
|
||||
setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_WINDOW, AlarmManager.INTERVAL_HOUR + 1);
|
||||
assertEquals(AlarmManager.INTERVAL_HOUR, mService.mConstants.ALLOW_WHILE_IDLE_WINDOW);
|
||||
|
||||
setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW, AlarmManager.INTERVAL_DAY);
|
||||
assertEquals(AlarmManager.INTERVAL_HOUR,
|
||||
mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW);
|
||||
setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW, AlarmManager.INTERVAL_HOUR + 1);
|
||||
assertEquals(AlarmManager.INTERVAL_HOUR,
|
||||
mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMinFuturity() {
|
||||
setDeviceConfigLong(KEY_MIN_FUTURITY, 10L);
|
||||
|
||||
Reference in New Issue
Block a user