Merge "Avoid alarm lock when calling outside" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
48d602a8a6
@@ -2637,15 +2637,18 @@ public class AlarmManagerService extends SystemService {
|
|||||||
* Returns true if the given uid can set window to be as small as it wants.
|
* Returns true if the given uid can set window to be as small as it wants.
|
||||||
*/
|
*/
|
||||||
boolean isExemptFromMinWindowRestrictions(int uid) {
|
boolean isExemptFromMinWindowRestrictions(int uid) {
|
||||||
return isExemptFromExactAlarmPermission(uid);
|
return isExemptFromExactAlarmPermissionNoLock(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given uid does not require SCHEDULE_EXACT_ALARM to set exact,
|
* Returns true if the given uid does not require SCHEDULE_EXACT_ALARM to set exact,
|
||||||
* allow-while-idle alarms.
|
* allow-while-idle alarms.
|
||||||
* Note: It is ok to call this method without the lock {@link #mLock} held.
|
* <b> Note: This should not be called with {@link #mLock} held.</b>
|
||||||
*/
|
*/
|
||||||
boolean isExemptFromExactAlarmPermission(int uid) {
|
boolean isExemptFromExactAlarmPermissionNoLock(int uid) {
|
||||||
|
if (Build.IS_DEBUGGABLE && Thread.holdsLock(mLock)) {
|
||||||
|
Slog.wtfStack(TAG, "Alarm lock held while calling into DeviceIdleController");
|
||||||
|
}
|
||||||
return (UserHandle.isSameApp(mSystemUiUid, uid)
|
return (UserHandle.isSameApp(mSystemUiUid, uid)
|
||||||
|| UserHandle.isCore(uid)
|
|| UserHandle.isCore(uid)
|
||||||
|| mLocalDeviceIdleController == null
|
|| mLocalDeviceIdleController == null
|
||||||
@@ -2747,7 +2750,7 @@ public class AlarmManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
if (needsPermission && !hasScheduleExactAlarmInternal(callingPackage, callingUid)
|
if (needsPermission && !hasScheduleExactAlarmInternal(callingPackage, callingUid)
|
||||||
&& !hasUseExactAlarmInternal(callingPackage, callingUid)) {
|
&& !hasUseExactAlarmInternal(callingPackage, callingUid)) {
|
||||||
if (!isExemptFromExactAlarmPermission(callingUid)) {
|
if (!isExemptFromExactAlarmPermissionNoLock(callingUid)) {
|
||||||
final String errorMessage = "Caller " + callingPackage + " 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 "
|
||||||
+ "exact alarms.";
|
+ "exact alarms.";
|
||||||
@@ -2810,7 +2813,7 @@ public class AlarmManagerService extends SystemService {
|
|||||||
if (!isExactAlarmChangeEnabled(packageName, userId)) {
|
if (!isExactAlarmChangeEnabled(packageName, userId)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return isExemptFromExactAlarmPermission(packageUid)
|
return isExemptFromExactAlarmPermissionNoLock(packageUid)
|
||||||
|| hasScheduleExactAlarmInternal(packageName, packageUid)
|
|| hasScheduleExactAlarmInternal(packageName, packageUid)
|
||||||
|| hasUseExactAlarmInternal(packageName, packageUid);
|
|| hasUseExactAlarmInternal(packageName, packageUid);
|
||||||
}
|
}
|
||||||
@@ -3862,10 +3865,7 @@ public class AlarmManagerService extends SystemService {
|
|||||||
// added: true => package was added to the deny list
|
// added: true => package was added to the deny list
|
||||||
// added: false => package was removed from the deny list
|
// added: false => package was removed from the deny list
|
||||||
if (added) {
|
if (added) {
|
||||||
synchronized (mLock) {
|
removeExactAlarmsOnPermissionRevoked(uid, changedPackage, /*killUid = */ true);
|
||||||
removeExactAlarmsOnPermissionRevokedLocked(uid,
|
|
||||||
changedPackage, /*killUid = */ true);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
sendScheduleExactAlarmPermissionStateChangedBroadcast(changedPackage, userId);
|
sendScheduleExactAlarmPermissionStateChangedBroadcast(changedPackage, userId);
|
||||||
}
|
}
|
||||||
@@ -3880,9 +3880,8 @@ public class AlarmManagerService extends SystemService {
|
|||||||
*
|
*
|
||||||
* This is not expected to get called frequently.
|
* This is not expected to get called frequently.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
void removeExactAlarmsOnPermissionRevoked(int uid, String packageName, boolean killUid) {
|
||||||
void removeExactAlarmsOnPermissionRevokedLocked(int uid, String packageName, boolean killUid) {
|
if (isExemptFromExactAlarmPermissionNoLock(uid)
|
||||||
if (isExemptFromExactAlarmPermission(uid)
|
|
||||||
|| !isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) {
|
|| !isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3891,7 +3890,9 @@ public class AlarmManagerService extends SystemService {
|
|||||||
|
|
||||||
final Predicate<Alarm> whichAlarms = a -> (a.uid == uid && a.packageName.equals(packageName)
|
final Predicate<Alarm> whichAlarms = a -> (a.uid == uid && a.packageName.equals(packageName)
|
||||||
&& a.windowLength == 0);
|
&& a.windowLength == 0);
|
||||||
removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_EXACT_PERMISSION_REVOKED);
|
synchronized (mLock) {
|
||||||
|
removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_EXACT_PERMISSION_REVOKED);
|
||||||
|
}
|
||||||
|
|
||||||
if (killUid && mConstants.KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED) {
|
if (killUid && mConstants.KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED) {
|
||||||
PermissionManagerService.killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
|
PermissionManagerService.killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
|
||||||
@@ -4807,10 +4808,7 @@ public class AlarmManagerService extends SystemService {
|
|||||||
case REMOVE_EXACT_ALARMS:
|
case REMOVE_EXACT_ALARMS:
|
||||||
int uid = msg.arg1;
|
int uid = msg.arg1;
|
||||||
String packageName = (String) msg.obj;
|
String packageName = (String) msg.obj;
|
||||||
synchronized (mLock) {
|
removeExactAlarmsOnPermissionRevoked(uid, packageName, /*killUid = */true);
|
||||||
removeExactAlarmsOnPermissionRevokedLocked(uid, packageName, /*killUid = */
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case EXACT_ALARM_DENY_LIST_PACKAGES_ADDED:
|
case EXACT_ALARM_DENY_LIST_PACKAGES_ADDED:
|
||||||
handleChangesToExactAlarmDenyList((ArraySet<String>) msg.obj, true);
|
handleChangesToExactAlarmDenyList((ArraySet<String>) msg.obj, true);
|
||||||
@@ -4826,10 +4824,7 @@ public class AlarmManagerService extends SystemService {
|
|||||||
uid = msg.arg1;
|
uid = msg.arg1;
|
||||||
if (!hasScheduleExactAlarmInternal(packageName, uid)
|
if (!hasScheduleExactAlarmInternal(packageName, uid)
|
||||||
&& !hasUseExactAlarmInternal(packageName, uid)) {
|
&& !hasUseExactAlarmInternal(packageName, uid)) {
|
||||||
synchronized (mLock) {
|
removeExactAlarmsOnPermissionRevoked(uid, packageName, /*killUid = */false);
|
||||||
removeExactAlarmsOnPermissionRevokedLocked(uid,
|
|
||||||
packageName, /*killUid = */false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CHECK_EXACT_ALARM_PERMISSION_ON_FEATURE_TOGGLE:
|
case CHECK_EXACT_ALARM_PERMISSION_ON_FEATURE_TOGGLE:
|
||||||
@@ -4849,10 +4844,7 @@ public class AlarmManagerService extends SystemService {
|
|||||||
if (defaultDenied) {
|
if (defaultDenied) {
|
||||||
if (!hasScheduleExactAlarmInternal(pkg, uid)
|
if (!hasScheduleExactAlarmInternal(pkg, uid)
|
||||||
&& !hasUseExactAlarmInternal(pkg, uid)) {
|
&& !hasUseExactAlarmInternal(pkg, uid)) {
|
||||||
synchronized (mLock) {
|
removeExactAlarmsOnPermissionRevoked(uid, pkg, true);
|
||||||
removeExactAlarmsOnPermissionRevokedLocked(uid, pkg,
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (hasScheduleExactAlarmInternal(pkg, uid)) {
|
} else if (hasScheduleExactAlarmInternal(pkg, uid)) {
|
||||||
sendScheduleExactAlarmPermissionStateChangedBroadcast(pkg,
|
sendScheduleExactAlarmPermissionStateChangedBroadcast(pkg,
|
||||||
|
|||||||
@@ -2758,7 +2758,7 @@ public class AlarmManagerServiceTest {
|
|||||||
mService.handleChangesToExactAlarmDenyList(new ArraySet<>(packages), false);
|
mService.handleChangesToExactAlarmDenyList(new ArraySet<>(packages), false);
|
||||||
|
|
||||||
// No permission revoked.
|
// No permission revoked.
|
||||||
verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked(anyInt(), anyString(),
|
verify(mService, never()).removeExactAlarmsOnPermissionRevoked(anyInt(), anyString(),
|
||||||
anyBoolean());
|
anyBoolean());
|
||||||
|
|
||||||
// Permission got granted only for (appId1, userId2).
|
// Permission got granted only for (appId1, userId2).
|
||||||
@@ -2813,14 +2813,14 @@ public class AlarmManagerServiceTest {
|
|||||||
mService.handleChangesToExactAlarmDenyList(new ArraySet<>(packages), true);
|
mService.handleChangesToExactAlarmDenyList(new ArraySet<>(packages), true);
|
||||||
|
|
||||||
// Permission got revoked only for (appId1, userId2)
|
// Permission got revoked only for (appId1, userId2)
|
||||||
verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked(
|
verify(mService, never()).removeExactAlarmsOnPermissionRevoked(
|
||||||
eq(UserHandle.getUid(userId1, appId1)), eq(packages[0]), eq(true));
|
eq(UserHandle.getUid(userId1, appId1)), eq(packages[0]), eq(true));
|
||||||
verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked(
|
verify(mService, never()).removeExactAlarmsOnPermissionRevoked(
|
||||||
eq(UserHandle.getUid(userId1, appId2)), eq(packages[1]), eq(true));
|
eq(UserHandle.getUid(userId1, appId2)), eq(packages[1]), eq(true));
|
||||||
verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked(
|
verify(mService, never()).removeExactAlarmsOnPermissionRevoked(
|
||||||
eq(UserHandle.getUid(userId2, appId2)), eq(packages[1]), eq(true));
|
eq(UserHandle.getUid(userId2, appId2)), eq(packages[1]), eq(true));
|
||||||
|
|
||||||
verify(mService).removeExactAlarmsOnPermissionRevokedLocked(
|
verify(mService).removeExactAlarmsOnPermissionRevoked(
|
||||||
eq(UserHandle.getUid(userId2, appId1)), eq(packages[0]), eq(true));
|
eq(UserHandle.getUid(userId2, appId1)), eq(packages[0]), eq(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2833,7 +2833,7 @@ public class AlarmManagerServiceTest {
|
|||||||
|
|
||||||
mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
|
mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
|
||||||
assertAndHandleMessageSync(REMOVE_EXACT_ALARMS);
|
assertAndHandleMessageSync(REMOVE_EXACT_ALARMS);
|
||||||
verify(mService).removeExactAlarmsOnPermissionRevokedLocked(TEST_CALLING_UID,
|
verify(mService).removeExactAlarmsOnPermissionRevoked(TEST_CALLING_UID,
|
||||||
TEST_CALLING_PACKAGE, true);
|
TEST_CALLING_PACKAGE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2919,7 +2919,7 @@ public class AlarmManagerServiceTest {
|
|||||||
null);
|
null);
|
||||||
assertEquals(6, mService.mAlarmStore.size());
|
assertEquals(6, mService.mAlarmStore.size());
|
||||||
|
|
||||||
mService.removeExactAlarmsOnPermissionRevokedLocked(TEST_CALLING_UID, TEST_CALLING_PACKAGE,
|
mService.removeExactAlarmsOnPermissionRevoked(TEST_CALLING_UID, TEST_CALLING_PACKAGE,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
final ArrayList<Alarm> remaining = mService.mAlarmStore.asList();
|
final ArrayList<Alarm> remaining = mService.mAlarmStore.asList();
|
||||||
|
|||||||
Reference in New Issue
Block a user