diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index af33cbc0ac1c8..38b9647c15b44 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -285,14 +285,21 @@ class AlarmManagerService extends SystemService { @VisibleForTesting final class Constants extends ContentObserver { // Key names stored in the settings value. - private static final String KEY_MIN_FUTURITY = "min_futurity"; - private static final String KEY_MIN_INTERVAL = "min_interval"; - private static final String KEY_MAX_INTERVAL = "max_interval"; - private static final String KEY_ALLOW_WHILE_IDLE_SHORT_TIME = "allow_while_idle_short_time"; - private static final String KEY_ALLOW_WHILE_IDLE_LONG_TIME = "allow_while_idle_long_time"; - private static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION + @VisibleForTesting + static final String KEY_MIN_FUTURITY = "min_futurity"; + @VisibleForTesting + static final String KEY_MIN_INTERVAL = "min_interval"; + @VisibleForTesting + static final String KEY_MAX_INTERVAL = "max_interval"; + @VisibleForTesting + static final String KEY_ALLOW_WHILE_IDLE_SHORT_TIME = "allow_while_idle_short_time"; + @VisibleForTesting + static final String KEY_ALLOW_WHILE_IDLE_LONG_TIME = "allow_while_idle_long_time"; + @VisibleForTesting + static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION = "allow_while_idle_whitelist_duration"; - private static final String KEY_LISTENER_TIMEOUT = "listener_timeout"; + @VisibleForTesting + static final String KEY_LISTENER_TIMEOUT = "listener_timeout"; // Keys for specifying throttling delay based on app standby bucketing private final String[] KEYS_APP_STANDBY_DELAY = { diff --git a/services/tests/mockingservicestests/Android.mk b/services/tests/mockingservicestests/Android.mk index e6cbb5badb9e7..b21b3e42adc35 100644 --- a/services/tests/mockingservicestests/Android.mk +++ b/services/tests/mockingservicestests/Android.mk @@ -20,14 +20,11 @@ LOCAL_MODULE_TAGS := tests LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_STATIC_JAVA_LIBRARIES := \ - frameworks-base-testutils \ services.core \ services.net \ androidx.test.runner \ mockito-target-extended-minus-junit4 \ platform-test-annotations \ - ShortcutManagerTestUtils \ - truth-prebuilt \ LOCAL_JAVA_LIBRARIES := android.test.mock android.test.base android.test.runner diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java index 877c8fad30865..f85ffc84e7887 100644 --- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java @@ -30,10 +30,20 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.timeout; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; +import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_LONG_TIME; +import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_SHORT_TIME; +import static com.android.server.AlarmManagerService.Constants + .KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION; +import static com.android.server.AlarmManagerService.Constants.KEY_LISTENER_TIMEOUT; +import static com.android.server.AlarmManagerService.Constants.KEY_MAX_INTERVAL; +import static com.android.server.AlarmManagerService.Constants.KEY_MIN_FUTURITY; +import static com.android.server.AlarmManagerService.Constants.KEY_MIN_INTERVAL; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; @@ -45,6 +55,7 @@ import android.app.IActivityManager; import android.app.IUidObserver; import android.app.PendingIntent; import android.app.usage.UsageStatsManagerInternal; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.os.Handler; @@ -52,7 +63,9 @@ import android.os.Looper; import android.os.PowerManager; import android.os.SystemClock; import android.os.UserHandle; +import android.provider.Settings; import android.util.Log; +import android.util.SparseArray; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -68,6 +81,9 @@ import org.mockito.Answers; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoSession; +import org.mockito.quality.Strictness; + +import java.util.ArrayList; @SmallTest @RunWith(AndroidJUnit4.class) @@ -80,6 +96,8 @@ public class AlarmManagerServiceTest { private AlarmManagerService mService; @Mock + private ContentResolver mMockResolver; + @Mock private IActivityManager mIActivityManager; @Mock private UsageStatsManagerInternal mUsageStatsManagerInternal; @@ -186,9 +204,11 @@ public class AlarmManagerServiceTest { public final void setUp() throws Exception { mMockingSession = mockitoSession() .initMocks(this) - .mockStatic(ActivityManager.class, Answers.CALLS_REAL_METHODS) + .spyStatic(ActivityManager.class) .mockStatic(LocalServices.class) - .mockStatic(Looper.class, Answers.CALLS_REAL_METHODS) + .spyStatic(Looper.class) + .spyStatic(Settings.Global.class) + .strictness(Strictness.WARN) .startMocking(); doReturn(mIActivityManager).when(ActivityManager::getService); doReturn(mAppStateTracker).when(() -> LocalServices.getService(AppStateTracker.class)); @@ -201,15 +221,19 @@ public class AlarmManagerServiceTest { .thenReturn(STANDBY_BUCKET_ACTIVE); doReturn(Looper.getMainLooper()).when(Looper::myLooper); - final Context context = InstrumentationRegistry.getTargetContext(); - mInjector = spy(new Injector(context)); + final Context context = spy(InstrumentationRegistry.getTargetContext()); + when(context.getContentResolver()).thenReturn(mMockResolver); + doNothing().when(mMockResolver).registerContentObserver(any(), anyBoolean(), any()); + doReturn("min_futurity=0").when(() -> + Settings.Global.getString(mMockResolver, Settings.Global.ALARM_MANAGER_CONSTANTS)); + mInjector = new Injector(context); mService = new AlarmManagerService(context, mInjector); spyOn(mService); doNothing().when(mService).publishBinderService(any(), any()); mService.onStart(); mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); - mService.mConstants.MIN_FUTURITY = 0; + assertEquals(0, mService.mConstants.MIN_FUTURITY); assertEquals(mService.mSystemUiUid, SYSTEM_UI_UID); assertEquals(mService.mClockReceiver, mClockReceiver); assertEquals(mService.mWakeLock, mWakeLock); @@ -235,7 +259,6 @@ public class AlarmManagerServiceTest { final long triggerTime = mNowElapsedTest + 5000; final PendingIntent alarmPi = getNewMockPendingIntent(); setTestAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime, alarmPi); - verify(mInjector).setAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime); assertEquals(triggerTime, mTestTimer.getElapsed()); } @@ -256,13 +279,46 @@ public class AlarmManagerServiceTest { verify(mWakeLock, timeout(DEFAULT_TIMEOUT)).release(); } + @Test + public void testUpdateConstants() { + final StringBuilder constantsBuilder = new StringBuilder(); + constantsBuilder.append(KEY_MIN_FUTURITY); + constantsBuilder.append("=5,"); + constantsBuilder.append(KEY_MIN_INTERVAL); + constantsBuilder.append("=10,"); + constantsBuilder.append(KEY_MAX_INTERVAL); + constantsBuilder.append("=15,"); + constantsBuilder.append(KEY_ALLOW_WHILE_IDLE_SHORT_TIME); + constantsBuilder.append("=20,"); + constantsBuilder.append(KEY_ALLOW_WHILE_IDLE_LONG_TIME); + constantsBuilder.append("=25,"); + constantsBuilder.append(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION); + constantsBuilder.append("=30,"); + constantsBuilder.append(KEY_LISTENER_TIMEOUT); + constantsBuilder.append("=35,"); + + doReturn(constantsBuilder.toString()).when(() -> Settings.Global.getString(mMockResolver, + Settings.Global.ALARM_MANAGER_CONSTANTS)); + mService.mConstants.onChange(false, null); + 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_SHORT_TIME); + assertEquals(25, mService.mConstants.ALLOW_WHILE_IDLE_LONG_TIME); + assertEquals(30, mService.mConstants.ALLOW_WHILE_IDLE_WHITELIST_DURATION); + assertEquals(35, mService.mConstants.LISTENER_TIMEOUT); + } + @Test public void testMinFuturity() { - mService.mConstants.MIN_FUTURITY = 10; + doReturn("min_futurity=10").when(() -> + Settings.Global.getString(mMockResolver, Settings.Global.ALARM_MANAGER_CONSTANTS)); + mService.mConstants.onChange(false, null); + assertEquals(10, mService.mConstants.MIN_FUTURITY); final long triggerTime = mNowElapsedTest + 1; final long expectedTriggerTime = mNowElapsedTest + mService.mConstants.MIN_FUTURITY; setTestAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime, getNewMockPendingIntent()); - verify(mInjector).setAlarm(ELAPSED_REALTIME_WAKEUP, expectedTriggerTime); + assertEquals(expectedTriggerTime, mTestTimer.getElapsed()); } @Test @@ -344,6 +400,31 @@ public class AlarmManagerServiceTest { () -> (mTestTimer.getElapsed() == expectedNextTrigger))); } + @Test + public void testAlarmRestrictedInBatterSaver() throws PendingIntent.CanceledException { + final ArgumentCaptor listenerArgumentCaptor = + ArgumentCaptor.forClass(AppStateTracker.Listener.class); + verify(mAppStateTracker).addListener(listenerArgumentCaptor.capture()); + + final PendingIntent alarmPi = getNewMockPendingIntent(); + when(mAppStateTracker.areAlarmsRestricted(TEST_CALLING_UID, TEST_CALLING_PACKAGE, + false)).thenReturn(true); + setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 2, alarmPi); + assertEquals(mNowElapsedTest + 2, mTestTimer.getElapsed()); + + final SparseArray> restrictedAlarms = + mService.mPendingBackgroundAlarms; + assertNull(restrictedAlarms.get(TEST_CALLING_UID)); + + mNowElapsedTest = mTestTimer.expire(); + pollingCheck(DEFAULT_TIMEOUT, () -> (restrictedAlarms.get(TEST_CALLING_UID) != null)); + + listenerArgumentCaptor.getValue().unblockAlarmsForUid(TEST_CALLING_UID); + verify(alarmPi).send(any(Context.class), eq(0), any(Intent.class), any(), + any(Handler.class), isNull(), any()); + assertNull(restrictedAlarms.get(TEST_CALLING_UID)); + } + @After public void tearDown() { if (mMockingSession != null) { diff --git a/services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java index 26e77eb166cac..8f39b4ab11d3e 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java @@ -32,9 +32,10 @@ import android.os.IBinder; import android.os.Looper; import android.os.UserHandle; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; import android.util.Pair; +import androidx.test.filters.SmallTest; + import org.mockito.ArgumentMatchers; import java.util.ArrayList; @@ -44,7 +45,7 @@ import java.util.Collections; @SmallTest public class PersistentConnectionTest extends AndroidTestCase { private static final String TAG = "PersistentConnectionTest"; - + private static class MyConnection extends PersistentConnection { public long uptimeMillis = 12345;