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.content.BroadcastReceiver; 48 import android.content.Context; 49 import android.content.Intent; 50 import android.content.IntentFilter; 51 import android.os.BatteryManager; 52 import android.os.Handler; 53 import android.os.Looper; 54 import android.os.PowerManager.ServiceType; 55 import android.os.PowerManagerInternal; 56 import android.os.PowerSaveState; 57 import android.os.Process; 58 import android.os.RemoteException; 59 import android.os.UserHandle; 60 import android.provider.Settings.Global; 61 import android.test.mock.MockContentResolver; 62 import android.util.ArraySet; 63 import android.util.Pair; 64 65 import androidx.test.filters.SmallTest; 66 import androidx.test.runner.AndroidJUnit4; 67 68 import com.android.internal.app.IAppOpsCallback; 69 import com.android.internal.app.IAppOpsService; 70 import com.android.server.AppStateTracker.Listener; 71 import com.android.server.usage.AppStandbyInternal; 72 import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; 73 74 import org.junit.Before; 75 import org.junit.Test; 76 import org.junit.runner.RunWith; 77 import org.mockito.ArgumentCaptor; 78 import org.mockito.Mock; 79 import org.mockito.MockitoAnnotations; 80 import org.mockito.stubbing.Answer; 81 82 import java.util.ArrayList; 83 import java.util.Arrays; 84 import java.util.Collections; 85 import java.util.HashMap; 86 import java.util.List; 87 import java.util.Random; 88 import java.util.concurrent.CountDownLatch; 89 import java.util.concurrent.TimeUnit; 90 import java.util.function.Consumer; 91 92 /** 93 * Tests for {@link AppStateTracker} 94 * 95 * Run with: atest com.android.server.AppStateTrackerTest 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 injectAppStandbyInternal()132 AppStandbyInternal injectAppStandbyInternal() { 133 return mMockAppStandbyInternal; 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 AppStandbyInternal mMockAppStandbyInternal; 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(mMockAppStandbyInternal).addListener( 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 ActivityManager.PROCESS_CAPABILITY_NONE); 518 519 waitUntilMainHandlerDrain(); 520 assertTrue(instance.isUidActive(UID_1)); 521 assertFalse(instance.isUidActive(UID_2)); 522 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 523 524 assertTrue(instance.isUidActiveSynced(UID_1)); 525 assertFalse(instance.isUidActiveSynced(UID_2)); 526 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID)); 527 528 assertFalse(instance.isUidInForeground(UID_1)); 529 assertTrue(instance.isUidInForeground(UID_2)); 530 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 531 532 533 mIUidObserver.onUidStateChanged(UID_1, 534 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 535 ActivityManager.PROCESS_CAPABILITY_NONE); 536 537 waitUntilMainHandlerDrain(); 538 assertTrue(instance.isUidActive(UID_1)); 539 assertFalse(instance.isUidActive(UID_2)); 540 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 541 542 assertTrue(instance.isUidInForeground(UID_1)); 543 assertTrue(instance.isUidInForeground(UID_2)); 544 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 545 546 mIUidObserver.onUidGone(UID_1, true); 547 548 waitUntilMainHandlerDrain(); 549 assertFalse(instance.isUidActive(UID_1)); 550 assertFalse(instance.isUidActive(UID_2)); 551 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 552 553 assertFalse(instance.isUidInForeground(UID_1)); 554 assertTrue(instance.isUidInForeground(UID_2)); 555 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 556 557 mIUidObserver.onUidIdle(UID_2, true); 558 559 waitUntilMainHandlerDrain(); 560 assertFalse(instance.isUidActive(UID_1)); 561 assertFalse(instance.isUidActive(UID_2)); 562 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 563 564 assertFalse(instance.isUidInForeground(UID_1)); 565 assertFalse(instance.isUidInForeground(UID_2)); 566 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 567 568 mIUidObserver.onUidStateChanged(UID_1, 569 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0, 570 ActivityManager.PROCESS_CAPABILITY_NONE); 571 572 waitUntilMainHandlerDrain(); 573 assertFalse(instance.isUidActive(UID_1)); 574 assertFalse(instance.isUidActive(UID_2)); 575 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 576 577 assertTrue(instance.isUidInForeground(UID_1)); 578 assertFalse(instance.isUidInForeground(UID_2)); 579 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 580 581 mIUidObserver.onUidStateChanged(UID_1, 582 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 583 ActivityManager.PROCESS_CAPABILITY_NONE); 584 585 waitUntilMainHandlerDrain(); 586 assertFalse(instance.isUidActive(UID_1)); 587 assertFalse(instance.isUidActive(UID_2)); 588 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 589 590 assertFalse(instance.isUidActiveSynced(UID_1)); 591 assertFalse(instance.isUidActiveSynced(UID_2)); 592 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID)); 593 594 assertFalse(instance.isUidInForeground(UID_1)); 595 assertFalse(instance.isUidInForeground(UID_2)); 596 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 597 598 // The result from AMI.isUidActive() only affects isUidActiveSynced(). 599 when(mMockIActivityManagerInternal.isUidActive(anyInt())).thenReturn(true); 600 601 assertFalse(instance.isUidActive(UID_1)); 602 assertFalse(instance.isUidActive(UID_2)); 603 assertTrue(instance.isUidActive(Process.SYSTEM_UID)); 604 605 assertTrue(instance.isUidActiveSynced(UID_1)); 606 assertTrue(instance.isUidActiveSynced(UID_2)); 607 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID)); 608 609 assertFalse(instance.isUidInForeground(UID_1)); 610 assertFalse(instance.isUidInForeground(UID_2)); 611 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID)); 612 613 } 614 615 @Test testExempt()616 public void testExempt() throws Exception { 617 final AppStateTrackerTestable instance = newInstance(); 618 callStart(instance); 619 620 assertFalse(instance.isForceAllAppsStandbyEnabled()); 621 areRestricted(instance, UID_1, PACKAGE_1, NONE); 622 areRestricted(instance, UID_2, PACKAGE_2, NONE); 623 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 624 625 mPowerSaveMode = true; 626 mPowerSaveObserver.accept(getPowerSaveState()); 627 628 assertTrue(instance.isForceAllAppsStandbyEnabled()); 629 630 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 631 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 632 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS); 633 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); 634 635 // Exempt package 2 on user-10. 636 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false, 637 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT); 638 639 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 640 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 641 areRestricted(instance, UID_10_2, PACKAGE_2, NONE); 642 643 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE); 644 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE); 645 areRestrictedWithExemption(instance, UID_10_2, PACKAGE_2, NONE); 646 647 // Exempt package 1 on user-0. 648 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false, 649 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT); 650 651 areRestricted(instance, UID_1, PACKAGE_1, NONE); 652 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 653 areRestricted(instance, UID_10_2, PACKAGE_2, NONE); 654 655 // Unexempt package 2 on user-10. 656 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false, 657 UsageStatsManager.STANDBY_BUCKET_ACTIVE, REASON_MAIN_USAGE); 658 659 areRestricted(instance, UID_1, PACKAGE_1, NONE); 660 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS); 661 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS); 662 663 // Check force-app-standby. 664 // EXEMPT doesn't exempt from force-app-standby. 665 mPowerSaveMode = false; 666 mPowerSaveObserver.accept(getPowerSaveState()); 667 668 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false, 669 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT); 670 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 0, false, 671 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT); 672 673 setAppOps(UID_1, PACKAGE_1, true); 674 675 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 676 areRestricted(instance, UID_2, PACKAGE_2, NONE); 677 678 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS); 679 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE); 680 } 681 682 @Test loadPersistedAppOps()683 public void loadPersistedAppOps() throws Exception { 684 final AppStateTrackerTestable instance = newInstance(); 685 686 final List<PackageOps> ops = new ArrayList<>(); 687 688 //-------------------------------------------------- 689 List<OpEntry> entries = new ArrayList<>(); 690 entries.add(new OpEntry( 691 AppOpsManager.OP_ACCESS_NOTIFICATIONS, 692 AppOpsManager.MODE_IGNORED, 693 Collections.emptyMap())); 694 entries.add(new OpEntry( 695 AppStateTracker.TARGET_OP, 696 AppOpsManager.MODE_IGNORED, 697 Collections.emptyMap())); 698 699 ops.add(new PackageOps(PACKAGE_1, UID_1, entries)); 700 701 //-------------------------------------------------- 702 entries = new ArrayList<>(); 703 entries.add(new OpEntry( 704 AppStateTracker.TARGET_OP, 705 AppOpsManager.MODE_IGNORED, 706 Collections.emptyMap())); 707 708 ops.add(new PackageOps(PACKAGE_2, UID_2, entries)); 709 710 //-------------------------------------------------- 711 entries = new ArrayList<>(); 712 entries.add(new OpEntry( 713 AppStateTracker.TARGET_OP, 714 AppOpsManager.MODE_ALLOWED, 715 Collections.emptyMap())); 716 717 ops.add(new PackageOps(PACKAGE_1, UID_10_1, entries)); 718 719 //-------------------------------------------------- 720 entries = new ArrayList<>(); 721 entries.add(new OpEntry( 722 AppStateTracker.TARGET_OP, 723 AppOpsManager.MODE_IGNORED, 724 Collections.emptyMap())); 725 entries.add(new OpEntry( 726 AppOpsManager.OP_ACCESS_NOTIFICATIONS, 727 AppOpsManager.MODE_IGNORED, 728 Collections.emptyMap())); 729 730 ops.add(new PackageOps(PACKAGE_3, UID_10_3, entries)); 731 732 mGetPackagesForOps = inv -> { 733 final int[] arg = (int[]) inv.getArgument(0); 734 assertEquals(1, arg.length); 735 assertEquals(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, arg[0]); 736 return ops; 737 }; 738 739 callStart(instance); 740 741 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1)); 742 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2)); 743 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_3, PACKAGE_3)); 744 745 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1)); 746 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2)); 747 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_3, PACKAGE_3)); 748 } 749 assertNoCallbacks(Listener l)750 private void assertNoCallbacks(Listener l) throws Exception { 751 waitUntilMainHandlerDrain(); 752 verify(l, times(0)).updateAllJobs(); 753 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 754 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 755 756 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 757 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 758 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 759 reset(l); 760 } 761 762 @Test testPowerSaveListener()763 public void testPowerSaveListener() throws Exception { 764 final AppStateTrackerTestable instance = newInstance(); 765 callStart(instance); 766 767 Listener l = mock(Listener.class); 768 instance.addListener(l); 769 770 // Power save on. 771 mPowerSaveMode = true; 772 mPowerSaveObserver.accept(getPowerSaveState()); 773 774 waitUntilMainHandlerDrain(); 775 verify(l, times(1)).updateAllJobs(); 776 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 777 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 778 779 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 780 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 781 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 782 reset(l); 783 784 // Power save off. 785 mPowerSaveMode = false; 786 mPowerSaveObserver.accept(getPowerSaveState()); 787 788 waitUntilMainHandlerDrain(); 789 verify(l, times(1)).updateAllJobs(); 790 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 791 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 792 793 verify(l, times(1)).unblockAllUnrestrictedAlarms(); 794 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 795 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 796 reset(l); 797 798 // Updating to the same state should not fire listener 799 mPowerSaveMode = false; 800 mPowerSaveObserver.accept(getPowerSaveState()); 801 802 assertNoCallbacks(l); 803 } 804 805 @Test testAllListeners()806 public void testAllListeners() throws Exception { 807 final AppStateTrackerTestable instance = newInstance(); 808 callStart(instance); 809 810 Listener l = mock(Listener.class); 811 instance.addListener(l); 812 813 // ------------------------------------------------------------------------- 814 // Test with apppops. 815 816 setAppOps(UID_10_2, PACKAGE_2, true); 817 818 waitUntilMainHandlerDrain(); 819 verify(l, times(0)).updateAllJobs(); 820 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 821 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean()); 822 823 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 824 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 825 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 826 reset(l); 827 828 setAppOps(UID_10_2, PACKAGE_2, false); 829 830 waitUntilMainHandlerDrain(); 831 verify(l, times(0)).updateAllJobs(); 832 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 833 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean()); 834 835 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 836 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 837 verify(l, times(1)).unblockAlarmsForUidPackage(eq(UID_10_2), eq(PACKAGE_2)); 838 reset(l); 839 840 setAppOps(UID_10_2, PACKAGE_2, false); 841 842 verify(l, times(0)).updateAllJobs(); 843 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 844 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 845 846 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 847 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 848 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 849 850 // Unrestrict while battery saver is on. Shouldn't fire. 851 mPowerSaveMode = true; 852 mPowerSaveObserver.accept(getPowerSaveState()); 853 854 // Note toggling appops while BS is on will suppress unblockAlarmsForUidPackage(). 855 setAppOps(UID_10_2, PACKAGE_2, true); 856 857 waitUntilMainHandlerDrain(); 858 verify(l, times(1)).updateAllJobs(); 859 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 860 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean()); 861 862 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 863 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 864 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 865 reset(l); 866 867 // Battery saver off. 868 mPowerSaveMode = false; 869 mPowerSaveObserver.accept(getPowerSaveState()); 870 871 waitUntilMainHandlerDrain(); 872 verify(l, times(1)).updateAllJobs(); 873 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 874 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 875 876 verify(l, times(1)).unblockAllUnrestrictedAlarms(); 877 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 878 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 879 reset(l); 880 881 // ------------------------------------------------------------------------- 882 // Tests with system/user/temp whitelist. 883 884 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {}); 885 886 waitUntilMainHandlerDrain(); 887 verify(l, times(1)).updateAllJobs(); 888 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 889 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 890 891 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 892 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 893 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 894 reset(l); 895 896 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {}); 897 898 waitUntilMainHandlerDrain(); 899 verify(l, times(1)).updateAllJobs(); 900 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 901 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 902 903 verify(l, times(1)).unblockAllUnrestrictedAlarms(); 904 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 905 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 906 reset(l); 907 908 // Update temp whitelist. 909 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, 910 new int[] {UID_1, UID_3}); 911 912 waitUntilMainHandlerDrain(); 913 verify(l, times(1)).updateAllJobs(); 914 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 915 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 916 917 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 918 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 919 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 920 reset(l); 921 922 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3}); 923 924 waitUntilMainHandlerDrain(); 925 verify(l, times(1)).updateAllJobs(); 926 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 927 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 928 929 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 930 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 931 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 932 reset(l); 933 934 // Do the same thing with battery saver on. (Currently same callbacks are called.) 935 mPowerSaveMode = true; 936 mPowerSaveObserver.accept(getPowerSaveState()); 937 938 waitUntilMainHandlerDrain(); 939 verify(l, times(1)).updateAllJobs(); 940 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 941 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 942 943 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 944 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 945 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 946 reset(l); 947 948 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {}); 949 950 waitUntilMainHandlerDrain(); 951 // Called once for updating all whitelist and once for updating temp whitelist 952 verify(l, times(2)).updateAllJobs(); 953 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 954 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 955 956 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 957 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 958 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 959 reset(l); 960 961 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {}); 962 963 waitUntilMainHandlerDrain(); 964 verify(l, times(1)).updateAllJobs(); 965 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 966 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 967 968 verify(l, times(1)).unblockAllUnrestrictedAlarms(); 969 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 970 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 971 reset(l); 972 973 // Update temp whitelist. 974 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, 975 new int[] {UID_1, UID_3}); 976 977 waitUntilMainHandlerDrain(); 978 verify(l, times(1)).updateAllJobs(); 979 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 980 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 981 982 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 983 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 984 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 985 reset(l); 986 987 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3}); 988 989 waitUntilMainHandlerDrain(); 990 verify(l, times(1)).updateAllJobs(); 991 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); 992 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 993 994 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 995 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 996 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 997 reset(l); 998 999 1000 // ------------------------------------------------------------------------- 1001 // Tests with proc state changes. 1002 1003 // With battery save. 1004 mPowerSaveMode = true; 1005 mPowerSaveObserver.accept(getPowerSaveState()); 1006 1007 mIUidObserver.onUidActive(UID_10_1); 1008 1009 waitUntilMainHandlerDrain(); 1010 verify(l, times(0)).updateAllJobs(); 1011 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1012 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1013 1014 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1015 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1)); 1016 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1017 reset(l); 1018 1019 mIUidObserver.onUidGone(UID_10_1, true); 1020 1021 waitUntilMainHandlerDrain(); 1022 verify(l, times(0)).updateAllJobs(); 1023 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1024 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1025 1026 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1027 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 1028 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1029 reset(l); 1030 1031 mIUidObserver.onUidActive(UID_10_1); 1032 1033 waitUntilMainHandlerDrain(); 1034 verify(l, times(0)).updateAllJobs(); 1035 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1036 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1037 1038 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1039 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1)); 1040 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1041 reset(l); 1042 1043 mIUidObserver.onUidIdle(UID_10_1, true); 1044 1045 waitUntilMainHandlerDrain(); 1046 verify(l, times(0)).updateAllJobs(); 1047 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1048 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1049 1050 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1051 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 1052 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1053 reset(l); 1054 1055 // Without battery save. 1056 mPowerSaveMode = false; 1057 mPowerSaveObserver.accept(getPowerSaveState()); 1058 1059 waitUntilMainHandlerDrain(); 1060 verify(l, times(1)).updateAllJobs(); 1061 verify(l, times(0)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1062 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1063 1064 verify(l, times(1)).unblockAllUnrestrictedAlarms(); 1065 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 1066 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1067 reset(l); 1068 1069 mIUidObserver.onUidActive(UID_10_1); 1070 1071 waitUntilMainHandlerDrain(); 1072 verify(l, times(0)).updateAllJobs(); 1073 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1074 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1075 1076 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1077 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1)); 1078 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1079 reset(l); 1080 1081 mIUidObserver.onUidGone(UID_10_1, true); 1082 1083 waitUntilMainHandlerDrain(); 1084 verify(l, times(0)).updateAllJobs(); 1085 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1086 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1087 1088 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1089 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 1090 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1091 reset(l); 1092 1093 mIUidObserver.onUidActive(UID_10_1); 1094 1095 waitUntilMainHandlerDrain(); 1096 verify(l, times(0)).updateAllJobs(); 1097 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1098 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1099 1100 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1101 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1)); 1102 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1103 reset(l); 1104 1105 mIUidObserver.onUidIdle(UID_10_1, true); 1106 1107 waitUntilMainHandlerDrain(); 1108 verify(l, times(0)).updateAllJobs(); 1109 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); 1110 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); 1111 1112 verify(l, times(0)).unblockAllUnrestrictedAlarms(); 1113 verify(l, times(0)).unblockAlarmsForUid(anyInt()); 1114 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); 1115 reset(l); 1116 } 1117 1118 @Test testUserRemoved()1119 public void testUserRemoved() throws Exception { 1120 final AppStateTrackerTestable instance = newInstance(); 1121 callStart(instance); 1122 1123 mIUidObserver.onUidActive(UID_1); 1124 mIUidObserver.onUidActive(UID_10_1); 1125 1126 waitUntilMainHandlerDrain(); 1127 1128 setAppOps(UID_2, PACKAGE_2, true); 1129 setAppOps(UID_10_2, PACKAGE_2, true); 1130 1131 assertTrue(instance.isUidActive(UID_1)); 1132 assertTrue(instance.isUidActive(UID_10_1)); 1133 1134 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2)); 1135 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2)); 1136 1137 final Intent intent = new Intent(Intent.ACTION_USER_REMOVED); 1138 intent.putExtra(Intent.EXTRA_USER_HANDLE, 10); 1139 mReceiver.onReceive(mMockContext, intent); 1140 1141 waitUntilMainHandlerDrain(); 1142 1143 assertTrue(instance.isUidActive(UID_1)); 1144 assertFalse(instance.isUidActive(UID_10_1)); 1145 1146 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2)); 1147 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2)); 1148 } 1149 1150 @Test testSmallBatteryAndPluggedIn()1151 public void testSmallBatteryAndPluggedIn() throws Exception { 1152 // This is a small battery device 1153 mIsSmallBatteryDevice = true; 1154 1155 final AppStateTrackerTestable instance = newInstance(); 1156 callStart(instance); 1157 assertFalse(instance.isForceAllAppsStandbyEnabled()); 1158 1159 // Setting/experiment for all app standby for small battery is enabled 1160 mGlobalSettings.put(Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 1); 1161 instance.mFlagsObserver.onChange(true, 1162 Global.getUriFor(Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED)); 1163 assertTrue(instance.isForceAllAppsStandbyEnabled()); 1164 1165 // When battery is plugged in, force app standby is disabled 1166 Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); 1167 intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB); 1168 mReceiver.onReceive(mMockContext, intent); 1169 assertFalse(instance.isForceAllAppsStandbyEnabled()); 1170 1171 // When battery stops plugged in, force app standby is enabled 1172 mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED)); 1173 assertTrue(instance.isForceAllAppsStandbyEnabled()); 1174 } 1175 1176 @Test testNotSmallBatteryAndPluggedIn()1177 public void testNotSmallBatteryAndPluggedIn() throws Exception { 1178 // Not a small battery device, so plugged in status should not affect forced app standby 1179 mIsSmallBatteryDevice = false; 1180 1181 final AppStateTrackerTestable instance = newInstance(); 1182 callStart(instance); 1183 assertFalse(instance.isForceAllAppsStandbyEnabled()); 1184 1185 mPowerSaveMode = true; 1186 mPowerSaveObserver.accept(getPowerSaveState()); 1187 assertTrue(instance.isForceAllAppsStandbyEnabled()); 1188 1189 // When battery is plugged in, force app standby is unaffected 1190 Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); 1191 intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB); 1192 mReceiver.onReceive(mMockContext, intent); 1193 assertTrue(instance.isForceAllAppsStandbyEnabled()); 1194 1195 // When battery stops plugged in, force app standby is unaffected 1196 mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED)); 1197 assertTrue(instance.isForceAllAppsStandbyEnabled()); 1198 } 1199 array(int... appIds)1200 static int[] array(int... appIds) { 1201 Arrays.sort(appIds); 1202 return appIds; 1203 } 1204 1205 private final Random mRandom = new Random(); 1206 makeRandomArray()1207 int[] makeRandomArray() { 1208 final ArrayList<Integer> list = new ArrayList<>(); 1209 for (int i = 0; i < 5; i++) { 1210 if (mRandom.nextDouble() < 0.5) { 1211 list.add(i); 1212 } 1213 } 1214 return Arrays.stream(list.toArray(new Integer[list.size()])) 1215 .mapToInt(Integer::intValue).toArray(); 1216 } 1217 isAnyAppIdUnwhitelistedSlow(int[] prevArray, int[] newArray)1218 static boolean isAnyAppIdUnwhitelistedSlow(int[] prevArray, int[] newArray) { 1219 Arrays.sort(newArray); // Just in case... 1220 for (int p : prevArray) { 1221 if (Arrays.binarySearch(newArray, p) < 0) { 1222 return true; 1223 } 1224 } 1225 return false; 1226 } 1227 checkAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray, boolean expected)1228 private void checkAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray, boolean expected) { 1229 assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray), 1230 expected, AppStateTracker.isAnyAppIdUnwhitelisted(prevArray, newArray)); 1231 1232 // Also test isAnyAppIdUnwhitelistedSlow. 1233 assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray), 1234 expected, isAnyAppIdUnwhitelistedSlow(prevArray, newArray)); 1235 } 1236 1237 @Test isAnyAppIdUnwhitelisted()1238 public void isAnyAppIdUnwhitelisted() { 1239 checkAnyAppIdUnwhitelisted(array(), array(), false); 1240 1241 checkAnyAppIdUnwhitelisted(array(1), array(), true); 1242 checkAnyAppIdUnwhitelisted(array(1), array(1), false); 1243 checkAnyAppIdUnwhitelisted(array(1), array(0, 1), false); 1244 checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false); 1245 checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false); 1246 1247 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(), true); 1248 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2), true); 1249 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2, 10), false); 1250 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(2, 10), true); 1251 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 1, 2, 4, 3, 10), false); 1252 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 0, 1, 2, 10), false); 1253 1254 // Random test 1255 int trueCount = 0; 1256 final int count = 10000; 1257 for (int i = 0; i < count; i++) { 1258 final int[] array1 = makeRandomArray(); 1259 final int[] array2 = makeRandomArray(); 1260 1261 final boolean expected = isAnyAppIdUnwhitelistedSlow(array1, array2); 1262 final boolean actual = AppStateTracker.isAnyAppIdUnwhitelisted(array1, array2); 1263 1264 assertEquals("Input: " + Arrays.toString(array1) + " " + Arrays.toString(array2), 1265 expected, actual); 1266 if (expected) { 1267 trueCount++; 1268 } 1269 } 1270 1271 // Make sure makeRandomArray() didn't generate all same arrays by accident. 1272 assertTrue(trueCount > 0); 1273 assertTrue(trueCount < count); 1274 } 1275 } 1276