Merge "Enable alarm permission with a soft failure mode" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
dabf447720
@@ -23,7 +23,7 @@ import android.annotation.SdkConstant;
|
|||||||
import android.annotation.SystemApi;
|
import android.annotation.SystemApi;
|
||||||
import android.annotation.SystemService;
|
import android.annotation.SystemService;
|
||||||
import android.compat.annotation.ChangeId;
|
import android.compat.annotation.ChangeId;
|
||||||
import android.compat.annotation.Disabled;
|
import android.compat.annotation.EnabledSince;
|
||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -202,7 +202,7 @@ public class AlarmManager {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@ChangeId
|
@ChangeId
|
||||||
@Disabled // TODO (b/171306433): Enable starting S.
|
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
|
||||||
public static final long REQUIRE_EXACT_ALARM_PERMISSION = 171306433L;
|
public static final long REQUIRE_EXACT_ALARM_PERMISSION = 171306433L;
|
||||||
|
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
|
|||||||
@@ -423,6 +423,8 @@ public class AlarmManagerService extends SystemService {
|
|||||||
static final String KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA = "allow_while_idle_compat_quota";
|
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";
|
private static final String KEY_ALLOW_WHILE_IDLE_WINDOW = "allow_while_idle_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_FUTURITY = 5 * 1000;
|
||||||
private static final long DEFAULT_MIN_INTERVAL = 60 * 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 * DateUtils.DAY_IN_MILLIS;
|
||||||
@@ -454,6 +456,8 @@ public class AlarmManagerService extends SystemService {
|
|||||||
private static final int DEFAULT_ALLOW_WHILE_IDLE_QUOTA = 72;
|
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_WINDOW = 60 * 60 * 1000; // 1 hour.
|
||||||
|
// TODO (b/171306433): Change to true by default.
|
||||||
|
private static final boolean DEFAULT_CRASH_NON_CLOCK_APPS = false;
|
||||||
|
|
||||||
// Minimum futurity of a new alarm
|
// Minimum futurity of a new alarm
|
||||||
public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
|
public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
|
||||||
@@ -495,6 +499,13 @@ public class AlarmManagerService extends SystemService {
|
|||||||
*/
|
*/
|
||||||
public long ALLOW_WHILE_IDLE_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_WINDOW;
|
public long ALLOW_WHILE_IDLE_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_WINDOW;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not to crash callers that use setExactAndAllowWhileIdle or setAlarmClock
|
||||||
|
* but don't hold the required permission. This is useful to catch broken
|
||||||
|
* apps and reverting to a softer failure in case of broken apps.
|
||||||
|
*/
|
||||||
|
public boolean CRASH_NON_CLOCK_APPS = DEFAULT_CRASH_NON_CLOCK_APPS;
|
||||||
|
|
||||||
private long mLastAllowWhileIdleWhitelistDuration = -1;
|
private long mLastAllowWhileIdleWhitelistDuration = -1;
|
||||||
|
|
||||||
Constants() {
|
Constants() {
|
||||||
@@ -607,6 +618,10 @@ public class AlarmManagerService extends SystemService {
|
|||||||
KEY_TIME_TICK_ALLOWED_WHILE_IDLE,
|
KEY_TIME_TICK_ALLOWED_WHILE_IDLE,
|
||||||
DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE);
|
DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE);
|
||||||
break;
|
break;
|
||||||
|
case KEY_CRASH_NON_CLOCK_APPS:
|
||||||
|
CRASH_NON_CLOCK_APPS = properties.getBoolean(KEY_CRASH_NON_CLOCK_APPS,
|
||||||
|
DEFAULT_CRASH_NON_CLOCK_APPS);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) {
|
if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) {
|
||||||
// The quotas need to be updated in order, so we can't just rely
|
// The quotas need to be updated in order, so we can't just rely
|
||||||
@@ -741,6 +756,9 @@ public class AlarmManagerService extends SystemService {
|
|||||||
pw.print(KEY_TIME_TICK_ALLOWED_WHILE_IDLE, TIME_TICK_ALLOWED_WHILE_IDLE);
|
pw.print(KEY_TIME_TICK_ALLOWED_WHILE_IDLE, TIME_TICK_ALLOWED_WHILE_IDLE);
|
||||||
pw.println();
|
pw.println();
|
||||||
|
|
||||||
|
pw.print(KEY_CRASH_NON_CLOCK_APPS, CRASH_NON_CLOCK_APPS);
|
||||||
|
pw.println();
|
||||||
|
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1914,11 +1932,12 @@ public class AlarmManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given uid is on the system or user's power save exclusion list.
|
* Returns true if the given uid does not require SCHEDULE_EXACT_ALARM to set exact,
|
||||||
|
* allow-while-idle alarms.
|
||||||
*/
|
*/
|
||||||
boolean isWhitelisted(int uid) {
|
boolean isExemptFromPermission(int uid) {
|
||||||
return (mLocalDeviceIdleController == null || mLocalDeviceIdleController.isAppOnWhitelist(
|
return (UserHandle.isSameApp(mSystemUiUid, uid) || mLocalDeviceIdleController == null
|
||||||
UserHandle.getAppId(uid)));
|
|| mLocalDeviceIdleController.isAppOnWhitelist(UserHandle.getAppId(uid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1949,7 +1968,7 @@ public class AlarmManagerService extends SystemService {
|
|||||||
if (windowLength != AlarmManager.WINDOW_EXACT) {
|
if (windowLength != AlarmManager.WINDOW_EXACT) {
|
||||||
needsPermission = false;
|
needsPermission = false;
|
||||||
lowQuota = true;
|
lowQuota = true;
|
||||||
idleOptions = isWhitelisted(callingUid) ? mOptsWithFgs.toBundle()
|
idleOptions = isExemptFromPermission(callingUid) ? mOptsWithFgs.toBundle()
|
||||||
: mOptsWithoutFgs.toBundle();
|
: mOptsWithoutFgs.toBundle();
|
||||||
} else if (alarmClock != null) {
|
} else if (alarmClock != null) {
|
||||||
needsPermission = true;
|
needsPermission = true;
|
||||||
@@ -1966,16 +1985,22 @@ public class AlarmManagerService extends SystemService {
|
|||||||
idleOptions = allowWhileIdle ? mOptsWithFgs.toBundle() : null;
|
idleOptions = allowWhileIdle ? mOptsWithFgs.toBundle() : null;
|
||||||
}
|
}
|
||||||
if (needsPermission && !canScheduleExactAlarms()) {
|
if (needsPermission && !canScheduleExactAlarms()) {
|
||||||
if (alarmClock == null && isWhitelisted(callingUid)) {
|
if (alarmClock == null && isExemptFromPermission(callingUid)) {
|
||||||
// If the app is on the full system allow-list (not except-idle), we still
|
// If the app is on the full system allow-list (not except-idle), we still
|
||||||
// allow the alarms, but with a lower quota to keep pre-S compatibility.
|
// allow the alarms, but with a lower quota to keep pre-S compatibility.
|
||||||
lowQuota = true;
|
lowQuota = true;
|
||||||
} else {
|
} else {
|
||||||
final String errorMessage = "Caller needs to hold "
|
final String errorMessage = "Caller " + callingPackage + " needs to hold "
|
||||||
+ Manifest.permission.SCHEDULE_EXACT_ALARM + " to set "
|
+ Manifest.permission.SCHEDULE_EXACT_ALARM + " to set "
|
||||||
+ ((allowWhileIdle) ? "exact, allow-while-idle" : "alarm-clock")
|
+ ((allowWhileIdle) ? "exact, allow-while-idle" : "alarm-clock")
|
||||||
+ " alarms.";
|
+ " alarms.";
|
||||||
throw new SecurityException(errorMessage);
|
if (mConstants.CRASH_NON_CLOCK_APPS) {
|
||||||
|
throw new SecurityException(errorMessage);
|
||||||
|
} else {
|
||||||
|
Slog.wtf(TAG, errorMessage);
|
||||||
|
idleOptions = mOptsWithoutFgs.toBundle();
|
||||||
|
lowQuota = allowWhileIdle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lowQuota) {
|
if (lowQuota) {
|
||||||
@@ -2933,7 +2958,7 @@ public class AlarmManagerService extends SystemService {
|
|||||||
if (UserHandle.isCore(uid) || uid == mSystemUiUid) {
|
if (UserHandle.isCore(uid) || uid == mSystemUiUid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isWhitelisted(uid)) {
|
if (isExemptFromPermission(uid)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!CompatChanges.isChangeEnabled(
|
if (!CompatChanges.isChangeEnabled(
|
||||||
|
|||||||
Reference in New Issue
Block a user