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