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