Merge "Flip the protection level for SCHEDULE_EXACT_ALARM" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
59b2fbe0df
@@ -30,6 +30,9 @@ 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;
|
||||
import static android.content.PermissionChecker.PERMISSION_GRANTED;
|
||||
import static android.content.PermissionChecker.PID_UNKNOWN;
|
||||
import static android.content.PermissionChecker.checkPermissionForPreflight;
|
||||
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
|
||||
import static android.os.PowerExemptionManager.REASON_ALARM_MANAGER_ALARM_CLOCK;
|
||||
import static android.os.PowerExemptionManager.REASON_DENIED;
|
||||
@@ -87,11 +90,9 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.PermissionChecker;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.content.pm.UserPackage;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.BatteryStatsInternal;
|
||||
@@ -182,7 +183,6 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
@@ -269,7 +269,8 @@ public class AlarmManagerService extends SystemService {
|
||||
|
||||
/**
|
||||
* A map from uid to the last op-mode we have seen for
|
||||
* {@link AppOpsManager#OP_SCHEDULE_EXACT_ALARM}
|
||||
* {@link AppOpsManager#OP_SCHEDULE_EXACT_ALARM}. Used for evaluating permission state change
|
||||
* when the denylist changes.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
@GuardedBy("mLock")
|
||||
@@ -2097,20 +2098,31 @@ public class AlarmManagerService extends SystemService {
|
||||
if (oldMode == newMode) {
|
||||
return;
|
||||
}
|
||||
final boolean allowedByDefault =
|
||||
isScheduleExactAlarmAllowedByDefault(packageName, uid);
|
||||
final boolean deniedByDefault = isScheduleExactAlarmDeniedByDefault(
|
||||
packageName, UserHandle.getUserId(uid));
|
||||
|
||||
final boolean hadPermission;
|
||||
if (oldMode != AppOpsManager.MODE_DEFAULT) {
|
||||
hadPermission = (oldMode == AppOpsManager.MODE_ALLOWED);
|
||||
} else {
|
||||
hadPermission = allowedByDefault;
|
||||
}
|
||||
final boolean hasPermission;
|
||||
if (newMode != AppOpsManager.MODE_DEFAULT) {
|
||||
hasPermission = (newMode == AppOpsManager.MODE_ALLOWED);
|
||||
|
||||
if (deniedByDefault) {
|
||||
final boolean permissionState = getContext().checkPermission(
|
||||
Manifest.permission.SCHEDULE_EXACT_ALARM, PID_UNKNOWN,
|
||||
uid) == PackageManager.PERMISSION_GRANTED;
|
||||
hadPermission = (oldMode == AppOpsManager.MODE_DEFAULT)
|
||||
? permissionState
|
||||
: (oldMode == AppOpsManager.MODE_ALLOWED);
|
||||
hasPermission = (newMode == AppOpsManager.MODE_DEFAULT)
|
||||
? permissionState
|
||||
: (newMode == AppOpsManager.MODE_ALLOWED);
|
||||
} else {
|
||||
hasPermission = allowedByDefault;
|
||||
final boolean allowedByDefault =
|
||||
!mConstants.EXACT_ALARM_DENY_LIST.contains(packageName);
|
||||
hadPermission = (oldMode == AppOpsManager.MODE_DEFAULT)
|
||||
? allowedByDefault
|
||||
: (oldMode == AppOpsManager.MODE_ALLOWED);
|
||||
hasPermission = (newMode == AppOpsManager.MODE_DEFAULT)
|
||||
? allowedByDefault
|
||||
: (newMode == AppOpsManager.MODE_ALLOWED);
|
||||
}
|
||||
|
||||
if (hadPermission && !hasPermission) {
|
||||
@@ -2754,41 +2766,13 @@ public class AlarmManagerService extends SystemService {
|
||||
|
||||
boolean hasUseExactAlarmInternal(String packageName, int uid) {
|
||||
return isUseExactAlarmEnabled(packageName, UserHandle.getUserId(uid))
|
||||
&& (PermissionChecker.checkPermissionForPreflight(getContext(),
|
||||
Manifest.permission.USE_EXACT_ALARM, PermissionChecker.PID_UNKNOWN, uid,
|
||||
packageName) == PermissionChecker.PERMISSION_GRANTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether SCHEDULE_EXACT_ALARM is allowed by default.
|
||||
*/
|
||||
boolean isScheduleExactAlarmAllowedByDefault(String packageName, int uid) {
|
||||
if (isScheduleExactAlarmDeniedByDefault(packageName, UserHandle.getUserId(uid))) {
|
||||
|
||||
// This is essentially like changing the protection level of the permission to
|
||||
// (privileged|signature|role|appop), but have to implement this logic to maintain
|
||||
// compatibility for older apps.
|
||||
if (mPackageManagerInternal.isPlatformSigned(packageName)
|
||||
|| mPackageManagerInternal.isUidPrivileged(uid)) {
|
||||
return true;
|
||||
}
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
final List<String> wellbeingHolders = (mRoleManager != null)
|
||||
? mRoleManager.getRoleHolders(RoleManager.ROLE_SYSTEM_WELLBEING)
|
||||
: Collections.emptyList();
|
||||
return wellbeingHolders.contains(packageName);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
return !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName);
|
||||
&& (checkPermissionForPreflight(getContext(), Manifest.permission.USE_EXACT_ALARM,
|
||||
PID_UNKNOWN, uid, packageName) == PERMISSION_GRANTED);
|
||||
}
|
||||
|
||||
boolean hasScheduleExactAlarmInternal(String packageName, int uid) {
|
||||
final long start = mStatLogger.getTime();
|
||||
|
||||
// Not using getScheduleExactAlarmState as this can avoid some calls to AppOpsService.
|
||||
// Not using #mLastOpScheduleExactAlarm as it may contain stale values.
|
||||
// No locking needed as all internal containers being queried are immutable.
|
||||
final boolean hasPermission;
|
||||
@@ -2796,11 +2780,16 @@ public class AlarmManagerService extends SystemService {
|
||||
hasPermission = false;
|
||||
} else if (!isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) {
|
||||
hasPermission = false;
|
||||
} else if (isScheduleExactAlarmDeniedByDefault(packageName, UserHandle.getUserId(uid))) {
|
||||
hasPermission = (checkPermissionForPreflight(getContext(),
|
||||
Manifest.permission.SCHEDULE_EXACT_ALARM, PID_UNKNOWN, uid, packageName)
|
||||
== PERMISSION_GRANTED);
|
||||
} else {
|
||||
// Compatibility permission check for older apps.
|
||||
final int mode = mAppOps.checkOpNoThrow(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, uid,
|
||||
packageName);
|
||||
if (mode == AppOpsManager.MODE_DEFAULT) {
|
||||
hasPermission = isScheduleExactAlarmAllowedByDefault(packageName, uid);
|
||||
hasPermission = !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName);
|
||||
} else {
|
||||
hasPermission = (mode == AppOpsManager.MODE_ALLOWED);
|
||||
}
|
||||
@@ -4685,10 +4674,6 @@ public class AlarmManagerService extends SystemService {
|
||||
return service.new ClockReceiver();
|
||||
}
|
||||
|
||||
void registerContentObserver(ContentObserver contentObserver, Uri uri) {
|
||||
mContext.getContentResolver().registerContentObserver(uri, false, contentObserver);
|
||||
}
|
||||
|
||||
void registerDeviceConfigListener(DeviceConfig.OnPropertiesChangedListener listener) {
|
||||
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ALARM_MANAGER,
|
||||
AppSchedulingModuleThread.getExecutor(), listener);
|
||||
|
||||
@@ -5303,12 +5303,12 @@
|
||||
{@link android.Manifest.permission#USE_EXACT_ALARM} once it targets API
|
||||
{@link android.os.Build.VERSION_CODES#TIRAMISU}. All apps using exact alarms for secondary
|
||||
features (which should still be user facing) should continue using this permission.
|
||||
<p>Protection level: appop
|
||||
<p>Protection level: signature|privileged|appop
|
||||
-->
|
||||
<permission android:name="android.permission.SCHEDULE_EXACT_ALARM"
|
||||
android:label="@string/permlab_schedule_exact_alarm"
|
||||
android:description="@string/permdesc_schedule_exact_alarm"
|
||||
android:protectionLevel="normal|appop"/>
|
||||
android:protectionLevel="signature|privileged|appop"/>
|
||||
|
||||
<!-- Allows apps to use exact alarms just like with {@link
|
||||
android.Manifest.permission#SCHEDULE_EXACT_ALARM} but without needing to request this
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<permission name="android.permission.CALL_PRIVILEGED"/>
|
||||
<permission name="android.permission.MANAGE_USERS"/>
|
||||
<permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
|
||||
<permission name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
<permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
|
||||
<!-- Required to update emergency gesture settings -->
|
||||
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
|
||||
|
||||
@@ -321,6 +321,7 @@ applications that come with the platform
|
||||
<permission name="android.permission.REGISTER_CONNECTION_MANAGER"/>
|
||||
<permission name="android.permission.REGISTER_SIM_SUBSCRIPTION"/>
|
||||
<permission name="android.permission.RETRIEVE_WINDOW_CONTENT"/>
|
||||
<permission name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
<permission name="android.permission.SET_ALWAYS_FINISH"/>
|
||||
<permission name="android.permission.SET_ANIMATION_SCALE"/>
|
||||
<permission name="android.permission.SET_DEBUG_APP"/>
|
||||
|
||||
@@ -28,7 +28,6 @@ import static android.app.AlarmManager.FLAG_STANDALONE;
|
||||
import static android.app.AlarmManager.FLAG_WAKE_FROM_IDLE;
|
||||
import static android.app.AlarmManager.RTC;
|
||||
import static android.app.AlarmManager.RTC_WAKEUP;
|
||||
import static android.app.AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT;
|
||||
import static android.app.AlarmManager.WINDOW_EXACT;
|
||||
import static android.app.AlarmManager.WINDOW_HEURISTIC;
|
||||
import static android.app.AppOpsManager.MODE_ALLOWED;
|
||||
@@ -126,7 +125,6 @@ import android.app.IAlarmListener;
|
||||
import android.app.IAlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.compat.CompatChanges;
|
||||
import android.app.role.RoleManager;
|
||||
import android.app.tare.EconomyManager;
|
||||
import android.app.usage.UsageStatsManagerInternal;
|
||||
import android.content.ContentResolver;
|
||||
@@ -134,7 +132,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.PermissionChecker;
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Bundle;
|
||||
@@ -192,7 +189,6 @@ import org.mockito.quality.Strictness;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -246,8 +242,6 @@ public final class AlarmManagerServiceTest {
|
||||
@Mock
|
||||
private PackageManagerInternal mPackageManagerInternal;
|
||||
@Mock
|
||||
private RoleManager mRoleManager;
|
||||
@Mock
|
||||
private AppStateTrackerImpl mAppStateTracker;
|
||||
@Mock
|
||||
private AlarmManagerService.ClockReceiver mClockReceiver;
|
||||
@@ -392,11 +386,6 @@ public final class AlarmManagerServiceTest {
|
||||
return mWakeLock;
|
||||
}
|
||||
|
||||
@Override
|
||||
void registerContentObserver(ContentObserver observer, Uri uri) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
void registerDeviceConfigListener(DeviceConfig.OnPropertiesChangedListener listener) {
|
||||
// Do nothing.
|
||||
@@ -484,10 +473,12 @@ public final class AlarmManagerServiceTest {
|
||||
doReturn(PermissionChecker.PERMISSION_HARD_DENIED).when(
|
||||
() -> PermissionChecker.checkPermissionForPreflight(any(),
|
||||
eq(Manifest.permission.USE_EXACT_ALARM), anyInt(), anyInt(), anyString()));
|
||||
doReturn(PermissionChecker.PERMISSION_HARD_DENIED).when(
|
||||
() -> PermissionChecker.checkPermissionForPreflight(any(), eq(SCHEDULE_EXACT_ALARM),
|
||||
anyInt(), anyInt(), anyString()));
|
||||
|
||||
when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
|
||||
when(mMockContext.getSystemService(BatteryManager.class)).thenReturn(mBatteryManager);
|
||||
when(mMockContext.getSystemService(RoleManager.class)).thenReturn(mRoleManager);
|
||||
|
||||
registerAppIds(new String[]{TEST_CALLING_PACKAGE},
|
||||
new Integer[]{UserHandle.getAppId(TEST_CALLING_UID)});
|
||||
@@ -2181,40 +2172,6 @@ public final class AlarmManagerServiceTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasScheduleExactAlarmBinderCallNotDenyListed() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
|
||||
mockScheduleExactAlarmState(true, false, MODE_DEFAULT);
|
||||
assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
|
||||
assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmState(true, false, MODE_IGNORED);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasScheduleExactAlarmBinderCallDenyListed() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
|
||||
mockScheduleExactAlarmState(true, true, MODE_ERRORED);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmState(true, true, MODE_DEFAULT);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmState(true, true, MODE_IGNORED);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmState(true, true, MODE_ALLOWED);
|
||||
assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
}
|
||||
|
||||
private void mockChangeEnabled(long changeId, boolean enabled) {
|
||||
doReturn(enabled).when(() -> CompatChanges.isChangeEnabled(eq(changeId), anyString(),
|
||||
any(UserHandle.class)));
|
||||
@@ -2222,16 +2179,62 @@ public final class AlarmManagerServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasScheduleExactAlarmBinderCallNotDeclared() throws RemoteException {
|
||||
public void hasScheduleExactAlarmBinderCall() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
|
||||
|
||||
mockScheduleExactAlarmState(true);
|
||||
assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmState(false);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasScheduleExactAlarmBinderCallNotDenyListedPreT() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
|
||||
mockScheduleExactAlarmState(false, false, MODE_DEFAULT);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_DEFAULT);
|
||||
assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
|
||||
assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmState(false, false, MODE_ALLOWED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_IGNORED);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasScheduleExactAlarmBinderCallDenyListedPreT() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
|
||||
mockScheduleExactAlarmStatePreT(true, true, MODE_ERRORED);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmState(false, true, MODE_ALLOWED);
|
||||
mockScheduleExactAlarmStatePreT(true, true, MODE_DEFAULT);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmStatePreT(true, true, MODE_IGNORED);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmStatePreT(true, true, MODE_ALLOWED);
|
||||
assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasScheduleExactAlarmBinderCallNotDeclaredPreT() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
|
||||
mockScheduleExactAlarmStatePreT(false, false, MODE_DEFAULT);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmStatePreT(false, false, MODE_ALLOWED);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
|
||||
mockScheduleExactAlarmStatePreT(false, true, MODE_ALLOWED);
|
||||
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
|
||||
}
|
||||
|
||||
@@ -2240,61 +2243,94 @@ public final class AlarmManagerServiceTest {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
|
||||
|
||||
// canScheduleExactAlarms should be true regardless of any permission state.
|
||||
mockUseExactAlarmState(true);
|
||||
// Both SEA and UEA are denied in setUp.
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
mockUseExactAlarmState(false);
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
mockScheduleExactAlarmState(false, true, MODE_DEFAULT);
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmState(false);
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canScheduleExactAlarmsBinderCall() throws RemoteException {
|
||||
public void canScheduleExactAlarmsBinderCallPreT() throws RemoteException {
|
||||
// Policy permission is denied in setUp().
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
|
||||
|
||||
// No permission, no exemption.
|
||||
mockScheduleExactAlarmState(true, true, MODE_DEFAULT);
|
||||
mockScheduleExactAlarmStatePreT(true, true, MODE_DEFAULT);
|
||||
assertFalse(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
// No permission, no exemption.
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
assertFalse(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
// Policy permission only, no exemption.
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
mockUseExactAlarmState(true);
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
mockUseExactAlarmState(false);
|
||||
|
||||
// User permission only, no exemption.
|
||||
mockScheduleExactAlarmState(true, false, MODE_DEFAULT);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_DEFAULT);
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
// User permission only, no exemption.
|
||||
mockScheduleExactAlarmState(true, true, MODE_ALLOWED);
|
||||
mockScheduleExactAlarmStatePreT(true, true, MODE_ALLOWED);
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
// No permission, exemption.
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
when(mDeviceIdleInternal.isAppOnWhitelist(TEST_CALLING_UID)).thenReturn(true);
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
// No permission, exemption.
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
when(mDeviceIdleInternal.isAppOnWhitelist(TEST_CALLING_UID)).thenReturn(false);
|
||||
doReturn(true).when(() -> UserHandle.isCore(TEST_CALLING_UID));
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
// Both permissions and exemption.
|
||||
mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
|
||||
mockUseExactAlarmState(true);
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canScheduleExactAlarmsBinderCall() throws RemoteException {
|
||||
// Both permissions are denied in setUp().
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
|
||||
mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
|
||||
|
||||
// No permission, no exemption.
|
||||
assertFalse(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
// Policy permission only, no exemption.
|
||||
mockUseExactAlarmState(true);
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
mockUseExactAlarmState(false);
|
||||
|
||||
// User permission only, no exemption.
|
||||
mockScheduleExactAlarmState(true);
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
// No permission, exemption.
|
||||
mockScheduleExactAlarmState(false);
|
||||
when(mDeviceIdleInternal.isAppOnWhitelist(TEST_CALLING_UID)).thenReturn(true);
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
// No permission, core uid exemption.
|
||||
when(mDeviceIdleInternal.isAppOnWhitelist(TEST_CALLING_UID)).thenReturn(false);
|
||||
doReturn(true).when(() -> UserHandle.isCore(TEST_CALLING_UID));
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
|
||||
// Both permissions and core uid exemption.
|
||||
mockScheduleExactAlarmState(true);
|
||||
mockUseExactAlarmState(true);
|
||||
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
|
||||
}
|
||||
@@ -2404,8 +2440,9 @@ public final class AlarmManagerServiceTest {
|
||||
@Test
|
||||
public void alarmClockBinderCallWithSEAPermission() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
|
||||
|
||||
mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
|
||||
mockScheduleExactAlarmState(true);
|
||||
|
||||
final PendingIntent alarmPi = getNewMockPendingIntent();
|
||||
final AlarmManager.AlarmClockInfo alarmClock = mock(AlarmManager.AlarmClockInfo.class);
|
||||
@@ -2431,9 +2468,10 @@ public final class AlarmManagerServiceTest {
|
||||
public void alarmClockBinderCallWithUEAPermission() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
|
||||
mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
|
||||
|
||||
mockUseExactAlarmState(true);
|
||||
mockScheduleExactAlarmState(false, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmState(false);
|
||||
|
||||
final PendingIntent alarmPi = getNewMockPendingIntent();
|
||||
final AlarmManager.AlarmClockInfo alarmClock = mock(AlarmManager.AlarmClockInfo.class);
|
||||
@@ -2455,7 +2493,7 @@ public final class AlarmManagerServiceTest {
|
||||
assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type);
|
||||
}
|
||||
|
||||
private void mockScheduleExactAlarmState(boolean declared, boolean denyList, int mode) {
|
||||
private void mockScheduleExactAlarmStatePreT(boolean declared, boolean denyList, int mode) {
|
||||
String[] requesters = declared ? new String[]{TEST_CALLING_PACKAGE} : EmptyArray.STRING;
|
||||
when(mPermissionManagerInternal.getAppOpPermissionPackages(SCHEDULE_EXACT_ALARM))
|
||||
.thenReturn(requesters);
|
||||
@@ -2470,6 +2508,20 @@ public final class AlarmManagerServiceTest {
|
||||
TEST_CALLING_PACKAGE)).thenReturn(mode);
|
||||
}
|
||||
|
||||
private void mockScheduleExactAlarmState(boolean granted) {
|
||||
String[] requesters = granted ? new String[]{TEST_CALLING_PACKAGE} : EmptyArray.STRING;
|
||||
when(mPermissionManagerInternal.getAppOpPermissionPackages(SCHEDULE_EXACT_ALARM))
|
||||
.thenReturn(requesters);
|
||||
mService.refreshExactAlarmCandidates();
|
||||
|
||||
final int result = granted ? PermissionChecker.PERMISSION_GRANTED
|
||||
: PermissionChecker.PERMISSION_HARD_DENIED;
|
||||
doReturn(result).when(
|
||||
() -> PermissionChecker.checkPermissionForPreflight(eq(mMockContext),
|
||||
eq(SCHEDULE_EXACT_ALARM), anyInt(), eq(TEST_CALLING_UID),
|
||||
eq(TEST_CALLING_PACKAGE)));
|
||||
}
|
||||
|
||||
private void mockUseExactAlarmState(boolean granted) {
|
||||
final int result = granted ? PermissionChecker.PERMISSION_GRANTED
|
||||
: PermissionChecker.PERMISSION_HARD_DENIED;
|
||||
@@ -2483,7 +2535,7 @@ public final class AlarmManagerServiceTest {
|
||||
public void alarmClockBinderCallWithoutPermission() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true);
|
||||
|
||||
final PendingIntent alarmPi = getNewMockPendingIntent();
|
||||
@@ -2504,8 +2556,9 @@ public final class AlarmManagerServiceTest {
|
||||
@Test
|
||||
public void exactBinderCallWithSEAPermission() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
|
||||
|
||||
mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
|
||||
mockScheduleExactAlarmState(true);
|
||||
final PendingIntent alarmPi = getNewMockPendingIntent();
|
||||
mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
|
||||
0, alarmPi, null, null, null, null);
|
||||
@@ -2529,9 +2582,10 @@ public final class AlarmManagerServiceTest {
|
||||
public void exactBinderCallWithUEAPermission() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
|
||||
mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
|
||||
|
||||
mockUseExactAlarmState(true);
|
||||
mockScheduleExactAlarmState(false, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmState(false);
|
||||
final PendingIntent alarmPi = getNewMockPendingIntent();
|
||||
mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
|
||||
0, alarmPi, null, null, null, null);
|
||||
@@ -2555,7 +2609,7 @@ public final class AlarmManagerServiceTest {
|
||||
public void exactBinderCallWithAllowlist() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
// If permission is denied, only then allowlist will be checked.
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true);
|
||||
|
||||
final PendingIntent alarmPi = getNewMockPendingIntent();
|
||||
@@ -2575,7 +2629,7 @@ public final class AlarmManagerServiceTest {
|
||||
public void exactAllowWhileIdleBinderCallWithSEAPermission() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
|
||||
mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
|
||||
final PendingIntent alarmPi = getNewMockPendingIntent();
|
||||
mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
|
||||
FLAG_ALLOW_WHILE_IDLE, alarmPi, null, null, null, null);
|
||||
@@ -2601,7 +2655,7 @@ public final class AlarmManagerServiceTest {
|
||||
mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
|
||||
|
||||
mockUseExactAlarmState(true);
|
||||
mockScheduleExactAlarmState(false, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(false, false, MODE_ERRORED);
|
||||
final PendingIntent alarmPi = getNewMockPendingIntent();
|
||||
mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
|
||||
FLAG_ALLOW_WHILE_IDLE, alarmPi, null, null, null, null);
|
||||
@@ -2625,7 +2679,7 @@ public final class AlarmManagerServiceTest {
|
||||
public void exactAllowWhileIdleBinderCallWithAllowlist() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
// If permission is denied, only then allowlist will be checked.
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true);
|
||||
|
||||
final PendingIntent alarmPi = getNewMockPendingIntent();
|
||||
@@ -2651,7 +2705,7 @@ public final class AlarmManagerServiceTest {
|
||||
public void exactBinderCallsWithoutPermissionWithoutAllowlist() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(false);
|
||||
|
||||
final PendingIntent alarmPi = getNewMockPendingIntent();
|
||||
@@ -2701,7 +2755,7 @@ public final class AlarmManagerServiceTest {
|
||||
public void binderCallWithUserAllowlist() throws RemoteException {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true);
|
||||
when(mAppStateTracker.isUidPowerSaveUserExempt(TEST_CALLING_UID)).thenReturn(true);
|
||||
|
||||
@@ -3026,7 +3080,7 @@ public final class AlarmManagerServiceTest {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
|
||||
mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ALLOWED);
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
|
||||
mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
|
||||
assertAndHandleMessageSync(REMOVE_EXACT_ALARMS);
|
||||
@@ -3039,7 +3093,7 @@ public final class AlarmManagerServiceTest {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
|
||||
|
||||
mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ALLOWED);
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
|
||||
mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
|
||||
|
||||
@@ -3052,7 +3106,7 @@ public final class AlarmManagerServiceTest {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
|
||||
|
||||
mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ERRORED);
|
||||
mockScheduleExactAlarmState(true, true, MODE_DEFAULT);
|
||||
mockScheduleExactAlarmStatePreT(true, true, MODE_DEFAULT);
|
||||
|
||||
mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
|
||||
|
||||
@@ -3068,7 +3122,7 @@ public final class AlarmManagerServiceTest {
|
||||
when(mActivityManagerInternal.getBootTimeTempAllowListDuration()).thenReturn(durationMs);
|
||||
|
||||
mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ERRORED);
|
||||
mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
|
||||
mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
|
||||
|
||||
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
|
||||
@@ -3328,7 +3382,7 @@ public final class AlarmManagerServiceTest {
|
||||
.putExtra(Intent.EXTRA_REPLACING, true);
|
||||
|
||||
mockUseExactAlarmState(false);
|
||||
mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
|
||||
mPackageChangesReceiver.onReceive(mMockContext, packageReplacedIntent);
|
||||
assertAndHandleMessageSync(CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE);
|
||||
|
||||
@@ -3336,7 +3390,7 @@ public final class AlarmManagerServiceTest {
|
||||
assertEquals(5, mService.mAlarmStore.size());
|
||||
|
||||
mockUseExactAlarmState(true);
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
mPackageChangesReceiver.onReceive(mMockContext, packageReplacedIntent);
|
||||
assertAndHandleMessageSync(CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE);
|
||||
|
||||
@@ -3344,7 +3398,7 @@ public final class AlarmManagerServiceTest {
|
||||
assertEquals(5, mService.mAlarmStore.size());
|
||||
|
||||
mockUseExactAlarmState(false);
|
||||
mockScheduleExactAlarmState(true, false, MODE_ERRORED);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
mPackageChangesReceiver.onReceive(mMockContext, packageReplacedIntent);
|
||||
assertAndHandleMessageSync(CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE);
|
||||
|
||||
@@ -3362,55 +3416,6 @@ public final class AlarmManagerServiceTest {
|
||||
assertEquals(0, remaining.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isScheduleExactAlarmAllowedByDefault() {
|
||||
final String package1 = "priv";
|
||||
final String package2 = "signed";
|
||||
final String package3 = "normal";
|
||||
final String package4 = "wellbeing";
|
||||
final int uid1 = 1294;
|
||||
final int uid2 = 8321;
|
||||
final int uid3 = 3412;
|
||||
final int uid4 = 4591;
|
||||
|
||||
when(mPackageManagerInternal.isUidPrivileged(uid1)).thenReturn(true);
|
||||
when(mPackageManagerInternal.isUidPrivileged(uid2)).thenReturn(false);
|
||||
when(mPackageManagerInternal.isUidPrivileged(uid3)).thenReturn(false);
|
||||
when(mPackageManagerInternal.isUidPrivileged(uid4)).thenReturn(false);
|
||||
|
||||
when(mPackageManagerInternal.isPlatformSigned(package1)).thenReturn(false);
|
||||
when(mPackageManagerInternal.isPlatformSigned(package2)).thenReturn(true);
|
||||
when(mPackageManagerInternal.isPlatformSigned(package3)).thenReturn(false);
|
||||
when(mPackageManagerInternal.isPlatformSigned(package4)).thenReturn(false);
|
||||
|
||||
when(mRoleManager.getRoleHolders(RoleManager.ROLE_SYSTEM_WELLBEING)).thenReturn(
|
||||
Arrays.asList(package4));
|
||||
|
||||
mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, false);
|
||||
mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[]{
|
||||
package1,
|
||||
package3,
|
||||
});
|
||||
|
||||
// Deny listed packages will be false.
|
||||
assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package1, uid1));
|
||||
assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package2, uid2));
|
||||
assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package3, uid3));
|
||||
assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package4, uid4));
|
||||
|
||||
mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
|
||||
mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[]{
|
||||
package1,
|
||||
package3,
|
||||
});
|
||||
|
||||
// Deny list doesn't matter now, only exemptions should be true.
|
||||
assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package1, uid1));
|
||||
assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package2, uid2));
|
||||
assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package3, uid3));
|
||||
assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package4, uid4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void alarmScheduledAtomPushed() {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
@@ -3510,7 +3515,7 @@ public final class AlarmManagerServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasUseExactAlarmPermission() {
|
||||
public void hasUseExactAlarmInternal() {
|
||||
mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
|
||||
|
||||
mockUseExactAlarmState(true);
|
||||
@@ -3521,7 +3526,7 @@ public final class AlarmManagerServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasUseExactAlarmPermissionChangeDisabled() {
|
||||
public void hasUseExactAlarmInternalChangeDisabled() {
|
||||
mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, false);
|
||||
|
||||
mockUseExactAlarmState(true);
|
||||
@@ -3531,6 +3536,49 @@ public final class AlarmManagerServiceTest {
|
||||
assertFalse(mService.hasUseExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasScheduleExactAlarmInternal() {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
|
||||
|
||||
mockScheduleExactAlarmState(false);
|
||||
assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
|
||||
|
||||
mockScheduleExactAlarmState(true);
|
||||
assertTrue(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasScheduleExactAlarmInternalPreT() {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
|
||||
mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, false);
|
||||
|
||||
mockScheduleExactAlarmStatePreT(true, true, MODE_DEFAULT);
|
||||
assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
|
||||
|
||||
mockScheduleExactAlarmStatePreT(false, false, MODE_ALLOWED);
|
||||
assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
|
||||
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
|
||||
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
|
||||
assertTrue(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasScheduleExactAlarmInternalPreS() {
|
||||
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
|
||||
|
||||
mockScheduleExactAlarmState(true);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
|
||||
assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
|
||||
|
||||
mockScheduleExactAlarmState(false);
|
||||
mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
|
||||
assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void temporaryQuotaReserve_hasQuota() {
|
||||
final int quotaToFill = 5;
|
||||
|
||||
Reference in New Issue
Block a user