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