1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.server; 17 18 import static android.app.usage.UsageStatsManager.REASON_MAIN_DEFAULT; 19 import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE; 20 21 import static com.android.server.AppStateTracker.TARGET_OP; 22 23 import static org.junit.Assert.assertEquals; 24 import static org.junit.Assert.assertFalse; 25 import static org.junit.Assert.assertNotNull; 26 import static org.junit.Assert.assertTrue; 27 import static org.mockito.ArgumentMatchers.any; 28 import static org.mockito.ArgumentMatchers.anyBoolean; 29 import static org.mockito.ArgumentMatchers.anyInt; 30 import static org.mockito.ArgumentMatchers.anyString; 31 import static org.mockito.ArgumentMatchers.eq; 32 import static org.mockito.ArgumentMatchers.isNull; 33 import static org.mockito.Mockito.mock; 34 import static org.mockito.Mockito.reset; 35 import static org.mockito.Mockito.times; 36 import static org.mockito.Mockito.verify; 37 import static org.mockito.Mockito.when; 38 39 import android.app.ActivityManager; 40 import android.app.ActivityManagerInternal; 41 import android.app.AppOpsManager; 42 import android.app.AppOpsManager.OpEntry; 43 import android.app.AppOpsManager.PackageOps; 44 import android.app.IActivityManager; 45 import android.app.IUidObserver; 46 import android.app.usage.UsageStatsManager; 47 import android.app.usage.UsageStatsManagerInternal; 48 import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener; 49 import android.content.BroadcastReceiver; 50 import android.content.Context; 51 import android.content.Intent; 52 import android.content.IntentFilter; 53 import android.os.BatteryManager; 54 import android.os.Handler; 55 import android.os.Looper; 56 import android.os.PowerManager.ServiceType; 57 import android.os.PowerManagerInternal; 58 import android.os.PowerSaveState; 59 import android.os.Process; 60 import android.os.RemoteException; 61 import android.os.UserHandle; 62 import android.provider.Settings.Global; 63 import android.test.mock.MockContentResolver; 64 import android.util.ArraySet; 65 import android.util.Pair; 66 67 import com.android.internal.app.IAppOpsCallback; 68 import com.android.internal.app.IAppOpsService; 69 import com.android.server.AppStateTracker.Listener; 70 71 import org.junit.Before; 72 import org.junit.Test; 73 import org.junit.runner.RunWith; 74 import org.mockito.ArgumentCaptor; 75 import org.mockito.Mock; 76 import org.mockito.MockitoAnnotations; 77 import org.mockito.stubbing.Answer; 78 79 import java.util.ArrayList; 80 import java.util.Arrays; 81 import java.util.HashMap; 82 import java.util.List; 83 import java.util.Random; 84 import java.util.concurrent.CountDownLatch; 85 import java.util.concurrent.TimeUnit; 86 import java.util.function.Consumer; 87 88 import androidx.test.filters.SmallTest; 89 import androidx.test.runner.AndroidJUnit4; 90 91 /** 92 * Tests for {@link AppStateTracker} 93 * 94 * Run with: 95 atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java 96 */ 97 @SmallTest 98 @RunWith(AndroidJUnit4.class) 99 public class AppStateTrackerTest { 100 101 private class AppStateTrackerTestable extends AppStateTracker { AppStateTrackerTestable()102 AppStateTrackerTestable() { 103 super(mMockContext, Looper.getMainLooper()); 104 } 105 106 @Override injectAppOpsManager()107 AppOpsManager injectAppOpsManager() { 108 return mMockAppOpsManager; 109 } 110 111 @Override injectIAppOpsService()112 IAppOpsService injectIAppOpsService() { 113 return mMockIAppOpsService; 114 } 115 116 @Override injectIActivityManager()117 IActivityManager injectIActivityManager() { 118 return mMockIActivityManager; 119 } 120 121 @Override injectActivityManagerInternal()122 ActivityManagerInternal injectActivityManagerInternal() { 123 return mMockIActivityManagerInternal; 124 } 125 126 @Override injectPowerManagerInternal()127 PowerManagerInternal injectPowerManagerInternal() { 128 return mMockPowerManagerInternal; 129 } 130 131 @Override injectUsageStatsManagerInternal()132 UsageStatsManagerInternal injectUsageStatsManagerInternal() { 133 return mMockUsageStatsManagerInternal; 134 } 135 136 @Override injectGetGlobalSettingInt(String key, int def)137 int injectGetGlobalSettingInt(String key, int def) { 138 Integer val = mGlobalSettings.get(key); 139 140 return (val == null) ? def : val; 141 } 142 143 @Override isSmallBatteryDevice()144 boolean isSmallBatteryDevice() { return mIsSmallBatteryDevice; }; 145 } 146 147 private static final int UID_1 = Process.FIRST_APPLICATION_UID + 1; 148 private static final int UID_2 = Process.FIRST_APPLICATION_UID + 2; 149 private static final int UID_3 = Process.FIRST_APPLICATION_UID + 3; 150 private static final int UID_10_1 = UserHandle.getUid(10, UID_1); 151 private static final int UID_10_2 = UserHandle.getUid(10, UID_2); 152 private static final int UID_10_3 = UserHandle.getUid(10, UID_3); 153 private static final String PACKAGE_1 = "package1"; 154 private static final String PACKAGE_2 = "package2"; 155 private static final String PACKAGE_3 = "package3"; 156 private static final String PACKAGE_SYSTEM = "android"; 157 158 private Handler mMainHandler; 159 160 @Mock 161 private Context mMockContext; 162 163 @Mock 164 private IActivityManager mMockIActivityManager; 165 166 @Mock 167 private ActivityManagerInternal mMockIActivityManagerInternal; 168 169 @Mock 170 private AppOpsManager mMockAppOpsManager; 171 172 @Mock 173 private IAppOpsService mMockIAppOpsService; 174 175 @Mock 176 private PowerManagerInternal mMockPowerManagerInternal; 177 178 @Mock 179 private UsageStatsManagerInternal mMockUsageStatsManagerInternal; 180 181 private MockContentResolver mMockContentResolver; 182 183 private IUidObserver mIUidObserver; 184 private IAppOpsCallback.Stub mAppOpsCallback; 185 private Consumer<PowerSaveState> mPowerSaveObserver; 186 private BroadcastReceiver mReceiver; 187 private AppIdleStateChangeListener mAppIdleStateChangeListener; 188 189 private boolean mPowerSaveMode; 190 private boolean mIsSmallBatteryDevice; 191 192 private final ArraySet<Pair<Integer, String>> mRestrictedPackages = new ArraySet(); 193 194 private final HashMap<String, Integer> mGlobalSettings = new HashMap<>(); 195 196 private Answer<List<PackageOps>> mGetPackagesForOps = 197 inv -> new ArrayList<PackageOps>(); 198 199 @Before setUp()200 public void setUp() { 201 mMainHandler = new Handler(Looper.getMainLooper()); 202 } 203 waitUntilMainHandlerDrain()204 private void waitUntilMainHandlerDrain() throws Exception { 205 final CountDownLatch l = new CountDownLatch(1); 206 mMainHandler.post(() -> { 207 l.countDown(); 208 }); 209 assertTrue(l.await(5, TimeUnit.SECONDS)); 210 } 211 getPowerSaveState()212 private PowerSaveState getPowerSaveState() { 213 return new PowerSaveState.Builder().setBatterySaverEnabled(mPowerSaveMode).build(); 214 } 215 newInstance()216 private AppStateTrackerTestable newInstance() throws Exception { 217 MockitoAnnotations.initMocks(this); 218 219 when(mMockIAppOpsService.checkOperation(eq(TARGET_OP), anyInt(), anyString())) 220 .thenAnswer(inv -> { 221 return mRestrictedPackages.indexOf( 222 Pair.create(inv.getArgument(1), inv.getArgument(2))) >= 0 ? 223 AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED; 224 }); 225 226 final AppStateTrackerTestable instance = new AppStateTrackerTestable(); 227 228 return instance; 229 } 230 callStart(AppStateTrackerTestable instance)231 private void callStart(AppStateTrackerTestable instance) throws RemoteException { 232 233 // Set up functions that start() calls. 234 when(mMockPowerManagerInternal.getLowPowerState(eq(ServiceType.FORCE_ALL_APPS_STANDBY))) 235 .thenAnswer(inv -> getPowerSaveState()); 236 when(mMockAppOpsManager.getPackagesForOps( 237 any(int[].class) 238 )).thenAnswer(mGetPackagesForOps); 239 240 mMockContentResolver = new MockContentResolver(); 241 when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver); 242 243 // Call start. 244 instance.onSystemServicesReady(); 245 246 // Capture the listeners. 247 ArgumentCaptor<IUidObserver> uidObserverArgumentCaptor = 248 ArgumentCaptor.forClass(IUidObserver.class); 249 ArgumentCaptor<IAppOpsCallback.Stub> appOpsCallbackCaptor = 250 ArgumentCaptor.forClass(IAppOpsCallback.Stub.class); 251 ArgumentCaptor<Consumer<PowerSaveState>> powerSaveObserverCaptor = 252 ArgumentCaptor.forClass(Consumer.class); 253 ArgumentCaptor<BroadcastReceiver> receiverCaptor = 254 ArgumentCaptor.forClass(BroadcastReceiver.class); 255 ArgumentCaptor<AppIdleStateChangeListener> appIdleStateChangeListenerCaptor = 256 ArgumentCaptor.forClass(AppIdleStateChangeListener.class); 257 258 verify(mMockIActivityManager).registerUidObserver( 259 uidObserverArgumentCaptor.capture(), 260 eq(ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_IDLE 261 | ActivityManager.UID_OBSERVER_ACTIVE 262 | ActivityManager.UID_OBSERVER_PROCSTATE), 263 eq(ActivityManager.PROCESS_STATE_UNKNOWN), 264 isNull()); 265 verify(mMockIAppOpsService).startWatchingMode( 266 eq(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND), 267 isNull(), 268 appOpsCallbackCaptor.capture()); 269 verify(mMockPowerManagerInternal).registerLowPowerModeObserver( 270 eq(ServiceType.FORCE_ALL_APPS_STANDBY), 271 powerSaveObserverCaptor.capture()); 272 273 verify(mMockContext).registerReceiver( 274 receiverCaptor.capture(), any(IntentFilter.class)); 275 verify(mMockUsageStatsManagerInternal).addAppIdleStateChangeListener( 276 appIdleStateChangeListenerCaptor.capture()); 277 278 mIUidObserver = uidObserverArgumentCaptor.getValue(); 279 mAppOpsCallback = appOpsCallbackCaptor.getValue(); 280 mPowerSaveObserver = powerSaveObserverCaptor.getValue(); 281 mReceiver = receiverCaptor.getValue(); 282 mAppIdleStateChangeListener = appIdleStateChangeListenerCaptor.getValue(); 283 284 assertNotNull(mIUidObserver); 285 assertNotNull(mAppOpsCallback); 286 assertNotNull(mPowerSaveObserver); 287 assertNotNull(mReceiver); 288 assertNotNull(instance.mFlagsObserver); 289 } 290 setAppOps(int uid, String packageName, boolean restrict)291 private void setAppOps(int uid, String packageName, boolean restrict) throws RemoteException { 292 final Pair p = Pair.create(uid, packageName); 293 if (restrict) { 294 mRestrictedPackages.add(p); 295 } else { 296 mRestrictedPackages.remove(p); 297 } 298 if (mAppOpsCallback != null) { 299 mAppOpsCallback.opChanged(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName); 300 } 301 } 302 303 private static final int NONE = 0; 304 private static final int ALARMS_ONLY = 1 << 0; 305 private static final int JOBS_ONLY = 1 << 1; 306 private static final int JOBS_AND_ALARMS = ALARMS_ONLY | JOBS_ONLY; 307 areRestricted(AppStateTrackerTestable instance, int uid, String packageName, int restrictionTypes, boolean exemptFromBatterySaver)308 private void areRestricted(AppStateTrackerTestable instance, int uid, String packageName, 309 int restrictionTypes, boolean exemptFromBatterySaver) { 310 assertEquals(((restrictionTypes & JOBS_ONLY) != 0), 311 instance.areJobsRestricted(uid, packageName, exemptFromBatterySaver)); 312 assertEquals(((restrictionTypes & ALARMS_ONLY) != 0), 313 instance.areAlarmsRestricted(uid, packageName, exemptFromBatterySaver)); 314 } 315 areRestricted(AppStateTrackerTestable instance, int uid, String packageName, int restrictionTypes)316 private void areRestricted(AppStateTrackerTestable instance, int uid, String packageName, 317 int restrictionTypes) { 318 areRestricted(instance, uid, packageName, restrictionTypes, 319 /*exemptFromBatterySaver=*/ false); 320 } 321 areRestrictedWithExemption(AppStateTrackerTestable instance, int uid, String packageName, int restrictionTypes)322 private void areRestrictedWithExemption(AppStateTrackerTestable instance, 323 int uid, String packageName, int restrictionTypes) { 324 areRestricted(instance, uid, packageName, restrictionTypes, 325 /*exemptFromBatterySaver=*/ true); 326 } 327 328 @Test testAll()329 public void testAll() throws Exception { 330 final AppStateTrackerTestable instance = newInstance(); 331 callStart(instance); 332 333 assertFalse(instance.isForceAllAppsStandbyEnabled()); 334 areRestricted(instance, UID_1, PACKAGE_1, NONE); 335 areRestricted(instance, UID_2, PACKAGE_2, NONE); 336 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 337 338 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE); 339 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE); 340 areRestrictedWithExemption(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 341 342 mPowerSaveMode = true; 343 mPowerSaveObserver.accept(getPowerSaveState()); 344 345 assertTrue(instance.isForceAllAppsStandbyEnabled()); 346 347 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 348 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 349 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 350 351 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE); 352 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE); 353 areRestrictedWithExemption(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 354 355 // Toggle the foreground state. 356 mPowerSaveMode = true; 357 mPowerSaveObserver.accept(getPowerSaveState()); 358 359 assertFalse(instance.isUidActive(UID_1)); 360 assertFalse(instance.isUidActive(UID_2)); 361 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 362 363 mIUidObserver.onUidActive(UID_1); 364 waitUntilMainHandlerDrain(); 365 areRestricted(instance, UID_1, PACKAGE_1, NONE); 366 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 367 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 368 assertTrue(instance.isUidActive(UID_1)); 369 assertFalse(instance.isUidActive(UID_2)); 370 371 mIUidObserver.onUidGone(UID_1, /*disable=*/ false); 372 waitUntilMainHandlerDrain(); 373 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 374 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 375 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 376 assertFalse(instance.isUidActive(UID_1)); 377 assertFalse(instance.isUidActive(UID_2)); 378 379 mIUidObserver.onUidActive(UID_1); 380 waitUntilMainHandlerDrain(); 381 areRestricted(instance, UID_1, PACKAGE_1, NONE); 382 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 383 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 384 385 mIUidObserver.onUidIdle(UID_1, /*disable=*/ false); 386 waitUntilMainHandlerDrain(); 387 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 388 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 389 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 390 assertFalse(instance.isUidActive(UID_1)); 391 assertFalse(instance.isUidActive(UID_2)); 392 393 // Toggle the app ops. 394 mPowerSaveMode = false; 395 mPowerSaveObserver.accept(getPowerSaveState()); 396 397 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1)); 398 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1)); 399 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2)); 400 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2)); 401 402 areRestricted(instance, UID_1, PACKAGE_1, NONE); 403 areRestricted(instance, UID_10_1, PACKAGE_1, NONE); 404 areRestricted(instance, UID_2, PACKAGE_2, NONE); 405 areRestricted(instance, UID_10_2, PACKAGE_2, NONE); 406 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 407 408 setAppOps(UID_1, PACKAGE_1, true); 409 setAppOps(UID_10_2, PACKAGE_2, true); 410 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1)); 411 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1)); 412 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2)); 413 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2)); 414 415 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 416 areRestricted(instance, UID_10_1, PACKAGE_1, NONE); 417 areRestricted(instance, UID_2, PACKAGE_2, NONE); 418 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS); 419 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 420 421 // Toggle power saver, should still be the same. 422 mPowerSaveMode = true; 423 mPowerSaveObserver.accept(getPowerSaveState()); 424 425 mPowerSaveMode = false; 426 mPowerSaveObserver.accept(getPowerSaveState()); 427 428 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 429 areRestricted(instance, UID_10_1, PACKAGE_1, NONE); 430 areRestricted(instance, UID_2, PACKAGE_2, NONE); 431 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS); 432 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 433 434 // Clear the app ops and update the whitelist. 435 setAppOps(UID_1, PACKAGE_1, false); 436 setAppOps(UID_10_2, PACKAGE_2, false); 437 438 mPowerSaveMode = true; 439 mPowerSaveObserver.accept(getPowerSaveState()); 440 441 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 442 areRestricted(instance, UID_10_1, PACKAGE_1, JOBS_AND_ALARMS); 443 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 444 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS); 445 areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS); 446 areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS); 447 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 448 449 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1}, new int[] {}, new int[] {UID_2}); 450 451 areRestricted(instance, UID_1, PACKAGE_1, NONE); 452 areRestricted(instance, UID_10_1, PACKAGE_1, NONE); 453 areRestricted(instance, UID_2, PACKAGE_2, ALARMS_ONLY); 454 areRestricted(instance, UID_10_2, PACKAGE_2, ALARMS_ONLY); 455 areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS); 456 areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS); 457 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 458 459 // Again, make sure toggling the global state doesn't change it. 460 mPowerSaveMode = false; 461 mPowerSaveObserver.accept(getPowerSaveState()); 462 463 mPowerSaveMode = true; 464 mPowerSaveObserver.accept(getPowerSaveState()); 465 466 areRestricted(instance, UID_1, PACKAGE_1, NONE); 467 areRestricted(instance, UID_10_1, PACKAGE_1, NONE); 468 areRestricted(instance, UID_2, PACKAGE_2, ALARMS_ONLY); 469 areRestricted(instance, UID_10_2, PACKAGE_2, ALARMS_ONLY); 470 areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS); 471 areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS); 472 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 473 474 assertTrue(instance.isUidPowerSaveWhitelisted(UID_1)); 475 assertTrue(instance.isUidPowerSaveWhitelisted(UID_10_1)); 476 assertFalse(instance.isUidPowerSaveWhitelisted(UID_2)); 477 assertFalse(instance.isUidPowerSaveWhitelisted(UID_10_2)); 478 479 assertFalse(instance.isUidTempPowerSaveWhitelisted(UID_1)); 480 assertFalse(instance.isUidTempPowerSaveWhitelisted(UID_10_1)); 481 assertTrue(instance.isUidTempPowerSaveWhitelisted(UID_2)); 482 assertTrue(instance.isUidTempPowerSaveWhitelisted(UID_10_2)); 483 } 484 485 @Test testPowerSaveUserWhitelist()486 public void testPowerSaveUserWhitelist() throws Exception { 487 final AppStateTrackerTestable instance = newInstance(); 488 instance.setPowerSaveWhitelistAppIds(new int[] {}, new int[] {UID_1, UID_2}, new int[] {}); 489 assertTrue(instance.isUidPowerSaveUserWhitelisted(UID_1)); 490 assertTrue(instance.isUidPowerSaveUserWhitelisted(UID_2)); 491 assertFalse(instance.isUidPowerSaveUserWhitelisted(UID_3)); 492 } 493 494 @Test testUidStateForeground()495 public void testUidStateForeground() throws Exception { 496 final AppStateTrackerTestable instance = newInstance(); 497 callStart(instance); 498 499 mIUidObserver.onUidActive(UID_1); 500 501 waitUntilMainHandlerDrain(); 502 assertTrue(instance.isUidActive(UID_1)); 503 assertFalse(instance.isUidActive(UID_2)); 504 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 505 506 assertTrue(instance.isUidActiveSynced(UID_1)); 507 assertFalse(instance.isUidActiveSynced(UID_2)); 508 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID)); 509 510 assertFalse(instance.isUidInForeground(UID_1)); 511 assertFalse(instance.isUidInForeground(UID_2)); 512 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 513 514 515 mIUidObserver.onUidStateChanged(UID_2, 516 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE, 0); 517 518 waitUntilMainHandlerDrain(); 519 assertTrue(instance.isUidActive(UID_1)); 520 assertFalse(instance.isUidActive(UID_2)); 521 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 522 523 assertTrue(instance.isUidActiveSynced(UID_1)); 524 assertFalse(instance.isUidActiveSynced(UID_2)); 525 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID)); 526 527 assertFalse(instance.isUidInForeground(UID_1)); 528 assertTrue(instance.isUidInForeground(UID_2)); 529 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 530 531 532 mIUidObserver.onUidStateChanged(UID_1, 533 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0); 534 535 waitUntilMainHandlerDrain(); 536 assertTrue(instance.isUidActive(UID_1)); 537 assertFalse(instance.isUidActive(UID_2)); 538 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 539 540 assertTrue(instance.isUidInForeground(UID_1)); 541 assertTrue(instance.isUidInForeground(UID_2)); 542 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 543 544 mIUidObserver.onUidGone(UID_1, true); 545 546 waitUntilMainHandlerDrain(); 547 assertFalse(instance.isUidActive(UID_1)); 548 assertFalse(instance.isUidActive(UID_2)); 549 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 550 551 assertFalse(instance.isUidInForeground(UID_1)); 552 assertTrue(instance.isUidInForeground(UID_2)); 553 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 554 555 mIUidObserver.onUidIdle(UID_2, true); 556 557 waitUntilMainHandlerDrain(); 558 assertFalse(instance.isUidActive(UID_1)); 559 assertFalse(instance.isUidActive(UID_2)); 560 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 561 562 assertFalse(instance.isUidInForeground(UID_1)); 563 assertFalse(instance.isUidInForeground(UID_2)); 564 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 565 566 mIUidObserver.onUidStateChanged(UID_1, 567 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0); 568 569 waitUntilMainHandlerDrain(); 570 assertFalse(instance.isUidActive(UID_1)); 571 assertFalse(instance.isUidActive(UID_2)); 572 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 573 574 assertTrue(instance.isUidInForeground(UID_1)); 575 assertFalse(instance.isUidInForeground(UID_2)); 576 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 577 578 mIUidObserver.onUidStateChanged(UID_1, 579 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0); 580 581 waitUntilMainHandlerDrain(); 582 assertFalse(instance.isUidActive(UID_1)); 583 assertFalse(instance.isUidActive(UID_2)); 584 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 585 586 assertFalse(instance.isUidActiveSynced(UID_1)); 587 assertFalse(instance.isUidActiveSynced(UID_2)); 588 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID)); 589 590 assertFalse(instance.isUidInForeground(UID_1)); 591 assertFalse(instance.isUidInForeground(UID_2)); 592 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 593 594 // The result from AMI.isUidActive() only affects isUidActiveSynced(). 595 when(mMockIActivityManagerInternal.isUidActive(anyInt())).thenReturn(true); 596 597 assertFalse(instance.isUidActive(UID_1)); 598 assertFalse(instance.isUidActive(UID_2)); 599 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 600 601 assertTrue(instance.isUidActiveSynced(UID_1)); 602 assertTrue(instance.isUidActiveSynced(UID_2)); 603 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID)); 604 605 assertFalse(instance.isUidInForeground(UID_1)); 606 assertFalse(instance.isUidInForeground(UID_2)); 607 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 608 609 } 610 611 @Test testExempt()612 public void testExempt() throws Exception { 613 final AppStateTrackerTestable instance = newInstance(); 614 callStart(instance); 615 616 assertFalse(instance.isForceAllAppsStandbyEnabled()); 617 areRestricted(instance, UID_1, PACKAGE_1, NONE); 618 areRestricted(instance, UID_2, PACKAGE_2, NONE); 619 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 620 621 mPowerSaveMode = true; 622 mPowerSaveObserver.accept(getPowerSaveState()); 623 624 assertTrue(instance.isForceAllAppsStandbyEnabled()); 625 626 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 627 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 628 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS); 629 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 630 631 // Exempt package 2 on user-10. 632 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false, 633 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT); 634 635 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 636 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 637 areRestricted(instance, UID_10_2, PACKAGE_2, NONE); 638 639 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE); 640 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE); 641 areRestrictedWithExemption(instance, UID_10_2, PACKAGE_2, NONE); 642 643 // Exempt package 1 on user-0. 644 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false, 645 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT); 646 647 areRestricted(instance, UID_1, PACKAGE_1, NONE); 648 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 649 areRestricted(instance, UID_10_2, PACKAGE_2, NONE); 650 651 // Unexempt package 2 on user-10. 652 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false, 653 UsageStatsManager.STANDBY_BUCKET_ACTIVE, REASON_MAIN_USAGE); 654 655 areRestricted(instance, UID_1, PACKAGE_1, NONE); 656 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 657 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS); 658 659 // Check force-app-standby. 660 // EXEMPT doesn't exempt from force-app-standby. 661 mPowerSaveMode = false; 662 mPowerSaveObserver.accept(getPowerSaveState()); 663 664 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false, 665 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT); 666 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 0, false, 667 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT); 668 669 setAppOps(UID_1, PACKAGE_1, true); 670 671 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 672 areRestricted(instance, UID_2, PACKAGE_2, NONE); 673 674 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 675 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE); 676 } 677 678 @Test loadPersistedAppOps()679 public void loadPersistedAppOps() throws Exception { 680 final AppStateTrackerTestable instance = newInstance(); 681 682 final List<PackageOps> ops = new ArrayList<>(); 683 684 //-------------------------------------------------- 685 List<OpEntry> entries = new ArrayList<>(); 686 entries.add(new OpEntry( 687 AppOpsManager.OP_ACCESS_NOTIFICATIONS, 688 AppOpsManager.MODE_IGNORED)); 689 entries.add(new OpEntry( 690 AppStateTracker.TARGET_OP, 691 AppOpsManager.MODE_IGNORED)); 692 693 ops.add(new PackageOps(PACKAGE_1, UID_1, entries)); 694 695 //-------------------------------------------------- 696 entries = new ArrayList<>(); 697 entries.add(new OpEntry( 698 AppStateTracker.TARGET_OP, 699 AppOpsManager.MODE_IGNORED)); 700 701 ops.add(new PackageOps(PACKAGE_2, UID_2, entries)); 702 703 //-------------------------------------------------- 704 entries = new ArrayList<>(); 705 entries.add(new OpEntry( 706 AppStateTracker.TARGET_OP, 707 AppOpsManager.MODE_ALLOWED)); 708 709 ops.add(new PackageOps(PACKAGE_1, UID_10_1, entries)); 710 711 //-------------------------------------------------- 712 entries = new ArrayList<>(); 713 entries.add(new OpEntry( 714 AppStateTracker.TARGET_OP, 715 AppOpsManager.MODE_IGNORED)); 716 entries.add(new OpEntry( 717 AppOpsManager.OP_ACCESS_NOTIFICATIONS, 718 AppOpsManager.MODE_IGNORED)); 719 720 ops.add(new PackageOps(PACKAGE_3, UID_10_3, entries)); 721 722 mGetPackagesForOps = inv -> { 723 final int[] arg = (int[]) inv.getArgument(0); 724 assertEquals(1, arg.length); 725 assertEquals(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, arg[0]); 726 return ops; 727 }; 728 729 callStart(instance); 730 731 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1)); 732 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2)); 733 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_3, PACKAGE_3)); 734 735 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1)); 736 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2)); 737 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_3, PACKAGE_3)); 738 } 739 assertNoCallbacks(Listener l)740 private void assertNoCallbacks(Listener l) throws Exception { 741 waitUntilMainHandlerDrain(); 742 verify(l, times(0)).updateAllJobs(); 743 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 744 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 745 746 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 747 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 748 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 749 reset(l); 750 } 751 752 @Test testPowerSaveListener()753 public void testPowerSaveListener() throws Exception { 754 final AppStateTrackerTestable instance = newInstance(); 755 callStart(instance); 756 757 Listener l = mock(Listener.class); 758 instance.addListener(l); 759 760 // Power save on. 761 mPowerSaveMode = true; 762 mPowerSaveObserver.accept(getPowerSaveState()); 763 764 waitUntilMainHandlerDrain(); 765 verify(l, times(1)).updateAllJobs(); 766 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 767 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 768 769 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 770 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 771 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 772 reset(l); 773 774 // Power save off. 775 mPowerSaveMode = false; 776 mPowerSaveObserver.accept(getPowerSaveState()); 777 778 waitUntilMainHandlerDrain(); 779 verify(l, times(1)).updateAllJobs(); 780 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 781 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 782 783 verify(l, times(1)).unblockAllUnrestrictedAlarms(); 784 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 785 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 786 reset(l); 787 788 // Updating to the same state should not fire listener 789 mPowerSaveMode = false; 790 mPowerSaveObserver.accept(getPowerSaveState()); 791 792 assertNoCallbacks(l); 793 } 794 795 @Test testAllListeners()796 public void testAllListeners() throws Exception { 797 final AppStateTrackerTestable instance = newInstance(); 798 callStart(instance); 799 800 Listener l = mock(Listener.class); 801 instance.addListener(l); 802 803 // ------------------------------------------------------------------------- 804 // Test with apppops. 805 806 setAppOps(UID_10_2, PACKAGE_2, true); 807 808 waitUntilMainHandlerDrain(); 809 verify(l, times(0)).updateAllJobs(); 810 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 811 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean()); 812 813 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 814 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 815 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 816 reset(l); 817 818 setAppOps(UID_10_2, PACKAGE_2, false); 819 820 waitUntilMainHandlerDrain(); 821 verify(l, times(0)).updateAllJobs(); 822 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 823 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean()); 824 825 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 826 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 827 verify(l, times(1)).unblockAlarmsForUidPackage(eq(UID_10_2), eq(PACKAGE_2)); 828 reset(l); 829 830 setAppOps(UID_10_2, PACKAGE_2, false); 831 832 verify(l, times(0)).updateAllJobs(); 833 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 834 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 835 836 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 837 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 838 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 839 840 // Unrestrict while battery saver is on. Shouldn't fire. 841 mPowerSaveMode = true; 842 mPowerSaveObserver.accept(getPowerSaveState()); 843 844 // Note toggling appops while BS is on will suppress unblockAlarmsForUidPackage(). 845 setAppOps(UID_10_2, PACKAGE_2, true); 846 847 waitUntilMainHandlerDrain(); 848 verify(l, times(1)).updateAllJobs(); 849 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 850 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean()); 851 852 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 853 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 854 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 855 reset(l); 856 857 // Battery saver off. 858 mPowerSaveMode = false; 859 mPowerSaveObserver.accept(getPowerSaveState()); 860 861 waitUntilMainHandlerDrain(); 862 verify(l, times(1)).updateAllJobs(); 863 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 864 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 865 866 verify(l, times(1)).unblockAllUnrestrictedAlarms(); 867 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 868 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 869 reset(l); 870 871 // ------------------------------------------------------------------------- 872 // Tests with system/user/temp whitelist. 873 874 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {}); 875 876 waitUntilMainHandlerDrain(); 877 verify(l, times(1)).updateAllJobs(); 878 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 879 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 880 881 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 882 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 883 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 884 reset(l); 885 886 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {}); 887 888 waitUntilMainHandlerDrain(); 889 verify(l, times(1)).updateAllJobs(); 890 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 891 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 892 893 verify(l, times(1)).unblockAllUnrestrictedAlarms(); 894 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 895 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 896 reset(l); 897 898 // Update temp whitelist. 899 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, 900 new int[] {UID_1, UID_3}); 901 902 waitUntilMainHandlerDrain(); 903 verify(l, times(1)).updateAllJobs(); 904 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 905 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 906 907 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 908 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 909 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 910 reset(l); 911 912 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3}); 913 914 waitUntilMainHandlerDrain(); 915 verify(l, times(1)).updateAllJobs(); 916 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 917 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 918 919 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 920 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 921 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 922 reset(l); 923 924 // Do the same thing with battery saver on. (Currently same callbacks are called.) 925 mPowerSaveMode = true; 926 mPowerSaveObserver.accept(getPowerSaveState()); 927 928 waitUntilMainHandlerDrain(); 929 verify(l, times(1)).updateAllJobs(); 930 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 931 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 932 933 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 934 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 935 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 936 reset(l); 937 938 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {}); 939 940 waitUntilMainHandlerDrain(); 941 // Called once for updating all whitelist and once for updating temp whitelist 942 verify(l, times(2)).updateAllJobs(); 943 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 944 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 945 946 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 947 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 948 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 949 reset(l); 950 951 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {}); 952 953 waitUntilMainHandlerDrain(); 954 verify(l, times(1)).updateAllJobs(); 955 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 956 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 957 958 verify(l, times(1)).unblockAllUnrestrictedAlarms(); 959 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 960 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 961 reset(l); 962 963 // Update temp whitelist. 964 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, 965 new int[] {UID_1, UID_3}); 966 967 waitUntilMainHandlerDrain(); 968 verify(l, times(1)).updateAllJobs(); 969 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 970 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 971 972 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 973 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 974 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 975 reset(l); 976 977 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3}); 978 979 waitUntilMainHandlerDrain(); 980 verify(l, times(1)).updateAllJobs(); 981 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 982 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 983 984 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 985 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 986 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 987 reset(l); 988 989 990 // ------------------------------------------------------------------------- 991 // Tests with proc state changes. 992 993 // With battery save. 994 mPowerSaveMode = true; 995 mPowerSaveObserver.accept(getPowerSaveState()); 996 997 mIUidObserver.onUidActive(UID_10_1); 998 999 waitUntilMainHandlerDrain(); 1000 verify(l, times(0)).updateAllJobs(); 1001 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1002 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1003 1004 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1005 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1)); 1006 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1007 reset(l); 1008 1009 mIUidObserver.onUidGone(UID_10_1, true); 1010 1011 waitUntilMainHandlerDrain(); 1012 verify(l, times(0)).updateAllJobs(); 1013 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1014 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1015 1016 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1017 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 1018 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1019 reset(l); 1020 1021 mIUidObserver.onUidActive(UID_10_1); 1022 1023 waitUntilMainHandlerDrain(); 1024 verify(l, times(0)).updateAllJobs(); 1025 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1026 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1027 1028 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1029 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1)); 1030 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1031 reset(l); 1032 1033 mIUidObserver.onUidIdle(UID_10_1, true); 1034 1035 waitUntilMainHandlerDrain(); 1036 verify(l, times(0)).updateAllJobs(); 1037 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1038 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1039 1040 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1041 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 1042 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1043 reset(l); 1044 1045 // Without battery save. 1046 mPowerSaveMode = false; 1047 mPowerSaveObserver.accept(getPowerSaveState()); 1048 1049 waitUntilMainHandlerDrain(); 1050 verify(l, times(1)).updateAllJobs(); 1051 verify(l, times(0)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1052 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1053 1054 verify(l, times(1)).unblockAllUnrestrictedAlarms(); 1055 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 1056 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1057 reset(l); 1058 1059 mIUidObserver.onUidActive(UID_10_1); 1060 1061 waitUntilMainHandlerDrain(); 1062 verify(l, times(0)).updateAllJobs(); 1063 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1064 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1065 1066 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1067 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1)); 1068 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1069 reset(l); 1070 1071 mIUidObserver.onUidGone(UID_10_1, true); 1072 1073 waitUntilMainHandlerDrain(); 1074 verify(l, times(0)).updateAllJobs(); 1075 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1076 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1077 1078 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1079 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 1080 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1081 reset(l); 1082 1083 mIUidObserver.onUidActive(UID_10_1); 1084 1085 waitUntilMainHandlerDrain(); 1086 verify(l, times(0)).updateAllJobs(); 1087 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1088 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1089 1090 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1091 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1)); 1092 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1093 reset(l); 1094 1095 mIUidObserver.onUidIdle(UID_10_1, true); 1096 1097 waitUntilMainHandlerDrain(); 1098 verify(l, times(0)).updateAllJobs(); 1099 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1100 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1101 1102 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1103 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 1104 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1105 reset(l); 1106 } 1107 1108 @Test testUserRemoved()1109 public void testUserRemoved() throws Exception { 1110 final AppStateTrackerTestable instance = newInstance(); 1111 callStart(instance); 1112 1113 mIUidObserver.onUidActive(UID_1); 1114 mIUidObserver.onUidActive(UID_10_1); 1115 1116 waitUntilMainHandlerDrain(); 1117 1118 setAppOps(UID_2, PACKAGE_2, true); 1119 setAppOps(UID_10_2, PACKAGE_2, true); 1120 1121 assertTrue(instance.isUidActive(UID_1)); 1122 assertTrue(instance.isUidActive(UID_10_1)); 1123 1124 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2)); 1125 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2)); 1126 1127 final Intent intent = new Intent(Intent.ACTION_USER_REMOVED); 1128 intent.putExtra(Intent.EXTRA_USER_HANDLE, 10); 1129 mReceiver.onReceive(mMockContext, intent); 1130 1131 waitUntilMainHandlerDrain(); 1132 1133 assertTrue(instance.isUidActive(UID_1)); 1134 assertFalse(instance.isUidActive(UID_10_1)); 1135 1136 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2)); 1137 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2)); 1138 } 1139 1140 @Test testSmallBatteryAndPluggedIn()1141 public void testSmallBatteryAndPluggedIn() throws Exception { 1142 // This is a small battery device 1143 mIsSmallBatteryDevice = true; 1144 1145 final AppStateTrackerTestable instance = newInstance(); 1146 callStart(instance); 1147 assertFalse(instance.isForceAllAppsStandbyEnabled()); 1148 1149 // Setting/experiment for all app standby for small battery is enabled 1150 mGlobalSettings.put(Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 1); 1151 instance.mFlagsObserver.onChange(true, 1152 Global.getUriFor(Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED)); 1153 assertTrue(instance.isForceAllAppsStandbyEnabled()); 1154 1155 // When battery is plugged in, force app standby is disabled 1156 Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); 1157 intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB); 1158 mReceiver.onReceive(mMockContext, intent); 1159 assertFalse(instance.isForceAllAppsStandbyEnabled()); 1160 1161 // When battery stops plugged in, force app standby is enabled 1162 mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED)); 1163 assertTrue(instance.isForceAllAppsStandbyEnabled()); 1164 } 1165 1166 @Test testNotSmallBatteryAndPluggedIn()1167 public void testNotSmallBatteryAndPluggedIn() throws Exception { 1168 // Not a small battery device, so plugged in status should not affect forced app standby 1169 mIsSmallBatteryDevice = false; 1170 1171 final AppStateTrackerTestable instance = newInstance(); 1172 callStart(instance); 1173 assertFalse(instance.isForceAllAppsStandbyEnabled()); 1174 1175 mPowerSaveMode = true; 1176 mPowerSaveObserver.accept(getPowerSaveState()); 1177 assertTrue(instance.isForceAllAppsStandbyEnabled()); 1178 1179 // When battery is plugged in, force app standby is unaffected 1180 Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); 1181 intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB); 1182 mReceiver.onReceive(mMockContext, intent); 1183 assertTrue(instance.isForceAllAppsStandbyEnabled()); 1184 1185 // When battery stops plugged in, force app standby is unaffected 1186 mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED)); 1187 assertTrue(instance.isForceAllAppsStandbyEnabled()); 1188 } 1189 array(int... appIds)1190 static int[] array(int... appIds) { 1191 Arrays.sort(appIds); 1192 return appIds; 1193 } 1194 1195 private final Random mRandom = new Random(); 1196 makeRandomArray()1197 int[] makeRandomArray() { 1198 final ArrayList<Integer> list = new ArrayList<>(); 1199 for (int i = 0; i < 5; i++) { 1200 if (mRandom.nextDouble() < 0.5) { 1201 list.add(i); 1202 } 1203 } 1204 return Arrays.stream(list.toArray(new Integer[list.size()])) 1205 .mapToInt(Integer::intValue).toArray(); 1206 } 1207 isAnyAppIdUnwhitelistedSlow(int[] prevArray, int[] newArray)1208 static boolean isAnyAppIdUnwhitelistedSlow(int[] prevArray, int[] newArray) { 1209 Arrays.sort(newArray); // Just in case... 1210 for (int p : prevArray) { 1211 if (Arrays.binarySearch(newArray, p) < 0) { 1212 return true; 1213 } 1214 } 1215 return false; 1216 } 1217 checkAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray, boolean expected)1218 private void checkAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray, boolean expected) { 1219 assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray), 1220 expected, AppStateTracker.isAnyAppIdUnwhitelisted(prevArray, newArray)); 1221 1222 // Also test isAnyAppIdUnwhitelistedSlow. 1223 assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray), 1224 expected, isAnyAppIdUnwhitelistedSlow(prevArray, newArray)); 1225 } 1226 1227 @Test isAnyAppIdUnwhitelisted()1228 public void isAnyAppIdUnwhitelisted() { 1229 checkAnyAppIdUnwhitelisted(array(), array(), false); 1230 1231 checkAnyAppIdUnwhitelisted(array(1), array(), true); 1232 checkAnyAppIdUnwhitelisted(array(1), array(1), false); 1233 checkAnyAppIdUnwhitelisted(array(1), array(0, 1), false); 1234 checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false); 1235 checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false); 1236 1237 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(), true); 1238 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2), true); 1239 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2, 10), false); 1240 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(2, 10), true); 1241 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 1, 2, 4, 3, 10), false); 1242 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 0, 1, 2, 10), false); 1243 1244 // Random test 1245 int trueCount = 0; 1246 final int count = 10000; 1247 for (int i = 0; i < count; i++) { 1248 final int[] array1 = makeRandomArray(); 1249 final int[] array2 = makeRandomArray(); 1250 1251 final boolean expected = isAnyAppIdUnwhitelistedSlow(array1, array2); 1252 final boolean actual = AppStateTracker.isAnyAppIdUnwhitelisted(array1, array2); 1253 1254 assertEquals("Input: " + Arrays.toString(array1) + " " + Arrays.toString(array2), 1255 expected, actual); 1256 if (expected) { 1257 trueCount++; 1258 } 1259 } 1260 1261 // Make sure makeRandomArray() didn't generate all same arrays by accident. 1262 assertTrue(trueCount > 0); 1263 assertTrue(trueCount < count); 1264 } 1265 } 1266