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.AppStateTrackerImpl.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.net.Uri;
52 import android.os.BatteryManager;
53 import android.os.Handler;
54 import android.os.Looper;
55 import android.os.PowerManager.ServiceType;
56 import android.os.PowerManagerInternal;
57 import android.os.PowerSaveState;
58 import android.os.Process;
59 import android.os.RemoteException;
60 import android.os.UserHandle;
61 import android.platform.test.annotations.Presubmit;
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 androidx.test.filters.SmallTest;
68 import androidx.test.runner.AndroidJUnit4;
69 
70 import com.android.internal.app.IAppOpsCallback;
71 import com.android.internal.app.IAppOpsService;
72 import com.android.server.AppStateTrackerImpl.Listener;
73 import com.android.server.usage.AppStandbyInternal;
74 import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
75 
76 import org.junit.Before;
77 import org.junit.Test;
78 import org.junit.runner.RunWith;
79 import org.mockito.ArgumentCaptor;
80 import org.mockito.Mock;
81 import org.mockito.MockitoAnnotations;
82 import org.mockito.stubbing.Answer;
83 
84 import java.util.ArrayList;
85 import java.util.Arrays;
86 import java.util.Collections;
87 import java.util.HashMap;
88 import java.util.List;
89 import java.util.Random;
90 import java.util.concurrent.CountDownLatch;
91 import java.util.concurrent.TimeUnit;
92 import java.util.function.Consumer;
93 
94 /**
95  * Tests for {@link AppStateTrackerImpl}
96  *
97  * Run with: atest com.android.server.AppStateTrackerTest
98  */
99 @Presubmit
100 @SmallTest
101 @RunWith(AndroidJUnit4.class)
102 public class AppStateTrackerTest {
103 
104     private class AppStateTrackerTestable extends AppStateTrackerImpl {
AppStateTrackerTestable()105         AppStateTrackerTestable() {
106             super(mMockContext, Looper.getMainLooper());
107         }
108 
109         @Override
injectAppOpsManager()110         AppOpsManager injectAppOpsManager() {
111             return mMockAppOpsManager;
112         }
113 
114         @Override
injectIAppOpsService()115         IAppOpsService injectIAppOpsService() {
116             return mMockIAppOpsService;
117         }
118 
119         @Override
injectIActivityManager()120         IActivityManager injectIActivityManager() {
121             return mMockIActivityManager;
122         }
123 
124         @Override
injectActivityManagerInternal()125         ActivityManagerInternal injectActivityManagerInternal() {
126             return mMockIActivityManagerInternal;
127         }
128 
129         @Override
injectPowerManagerInternal()130         PowerManagerInternal injectPowerManagerInternal() {
131             return mMockPowerManagerInternal;
132         }
133 
134         @Override
injectAppStandbyInternal()135         AppStandbyInternal injectAppStandbyInternal() {
136             when(mMockAppStandbyInternal.isAppIdleEnabled()).thenReturn(true);
137             return mMockAppStandbyInternal;
138         }
139 
140         @Override
injectGetGlobalSettingInt(String key, int def)141         int injectGetGlobalSettingInt(String key, int def) {
142             Integer val = mGlobalSettings.get(key);
143 
144             return (val == null) ? def : val;
145         }
146 
147         @Override
isSmallBatteryDevice()148         boolean isSmallBatteryDevice() {
149             return mIsSmallBatteryDevice;
150         }
151     }
152 
153     private static final int UID_1 = Process.FIRST_APPLICATION_UID + 1;
154     private static final int UID_2 = Process.FIRST_APPLICATION_UID + 2;
155     private static final int UID_3 = Process.FIRST_APPLICATION_UID + 3;
156     private static final int UID_10_1 = UserHandle.getUid(10, UID_1);
157     private static final int UID_10_2 = UserHandle.getUid(10, UID_2);
158     private static final int UID_10_3 = UserHandle.getUid(10, UID_3);
159     private static final String PACKAGE_1 = "package1";
160     private static final String PACKAGE_2 = "package2";
161     private static final String PACKAGE_3 = "package3";
162     private static final String PACKAGE_SYSTEM = "android";
163 
164     private Handler mMainHandler;
165 
166     @Mock
167     private Context mMockContext;
168 
169     @Mock
170     private IActivityManager mMockIActivityManager;
171 
172     @Mock
173     private ActivityManagerInternal mMockIActivityManagerInternal;
174 
175     @Mock
176     private AppOpsManager mMockAppOpsManager;
177 
178     @Mock
179     private IAppOpsService mMockIAppOpsService;
180 
181     @Mock
182     private PowerManagerInternal mMockPowerManagerInternal;
183 
184     @Mock
185     private AppStandbyInternal mMockAppStandbyInternal;
186 
187     private MockContentResolver mMockContentResolver;
188 
189     private IUidObserver mIUidObserver;
190     private IAppOpsCallback.Stub mAppOpsCallback;
191     private Consumer<PowerSaveState> mPowerSaveObserver;
192     private BroadcastReceiver mReceiver;
193     private AppIdleStateChangeListener mAppIdleStateChangeListener;
194 
195     private boolean mPowerSaveMode;
196     private boolean mIsSmallBatteryDevice;
197 
198     private final ArraySet<Pair<Integer, String>> mRestrictedPackages = new ArraySet();
199 
200     private final HashMap<String, Integer> mGlobalSettings = new HashMap<>();
201 
202     private Answer<List<PackageOps>> mGetPackagesForOps =
203             inv -> new ArrayList<PackageOps>();
204 
205     @Before
setUp()206     public void setUp() {
207         mMainHandler = new Handler(Looper.getMainLooper());
208     }
209 
210     /**
211      * Enqueues a message and waits for it to complete. This ensures that any messages posted until
212      * now have been executed.
213      *
214      * Note that these messages may have enqueued more messages, which may or may not have executed
215      * when this method returns.
216      */
waitUntilMainHandlerDrain()217     private void waitUntilMainHandlerDrain() throws Exception {
218         final CountDownLatch l = new CountDownLatch(1);
219         mMainHandler.post(() -> {
220             l.countDown();
221         });
222         assertTrue(l.await(5, TimeUnit.SECONDS));
223     }
224 
getPowerSaveState()225     private PowerSaveState getPowerSaveState() {
226         return new PowerSaveState.Builder().setBatterySaverEnabled(mPowerSaveMode).build();
227     }
228 
newInstance()229     private AppStateTrackerTestable newInstance() throws Exception {
230         MockitoAnnotations.initMocks(this);
231 
232         when(mMockIAppOpsService.checkOperation(eq(TARGET_OP), anyInt(), anyString()))
233                 .thenAnswer(inv -> {
234                     return mRestrictedPackages.indexOf(
235                             Pair.create(inv.getArgument(1), inv.getArgument(2))) >= 0 ?
236                             AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED;
237                 });
238 
239         final AppStateTrackerTestable instance = new AppStateTrackerTestable();
240 
241         return instance;
242     }
243 
callStart(AppStateTrackerTestable instance)244     private void callStart(AppStateTrackerTestable instance) throws RemoteException {
245 
246         // Set up functions that start() calls.
247         when(mMockPowerManagerInternal.getLowPowerState(eq(ServiceType.FORCE_ALL_APPS_STANDBY)))
248                 .thenAnswer(inv -> getPowerSaveState());
249         when(mMockAppOpsManager.getPackagesForOps(
250                 any(int[].class)
251         )).thenAnswer(mGetPackagesForOps);
252 
253         mMockContentResolver = new MockContentResolver();
254         when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
255 
256         // Call start.
257         instance.onSystemServicesReady();
258 
259         // Capture the listeners.
260         ArgumentCaptor<IUidObserver> uidObserverArgumentCaptor =
261                 ArgumentCaptor.forClass(IUidObserver.class);
262         ArgumentCaptor<IAppOpsCallback.Stub> appOpsCallbackCaptor =
263                 ArgumentCaptor.forClass(IAppOpsCallback.Stub.class);
264         ArgumentCaptor<Consumer<PowerSaveState>> powerSaveObserverCaptor =
265                 ArgumentCaptor.forClass(Consumer.class);
266         ArgumentCaptor<BroadcastReceiver> receiverCaptor =
267                 ArgumentCaptor.forClass(BroadcastReceiver.class);
268         ArgumentCaptor<AppIdleStateChangeListener> appIdleStateChangeListenerCaptor =
269                 ArgumentCaptor.forClass(AppIdleStateChangeListener.class);
270 
271         verify(mMockIActivityManager).registerUidObserver(
272                 uidObserverArgumentCaptor.capture(),
273                 eq(ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_IDLE
274                         | ActivityManager.UID_OBSERVER_ACTIVE),
275                 eq(ActivityManager.PROCESS_STATE_UNKNOWN),
276                 isNull());
277         verify(mMockIAppOpsService).startWatchingMode(
278                 eq(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND),
279                 isNull(),
280                 appOpsCallbackCaptor.capture());
281         verify(mMockPowerManagerInternal).registerLowPowerModeObserver(
282                 eq(ServiceType.FORCE_ALL_APPS_STANDBY),
283                 powerSaveObserverCaptor.capture());
284 
285         verify(mMockContext, times(2)).registerReceiver(
286                 receiverCaptor.capture(), any(IntentFilter.class));
287         verify(mMockAppStandbyInternal).addListener(
288                 appIdleStateChangeListenerCaptor.capture());
289 
290         mIUidObserver = uidObserverArgumentCaptor.getValue();
291         mAppOpsCallback = appOpsCallbackCaptor.getValue();
292         mPowerSaveObserver = powerSaveObserverCaptor.getValue();
293         mReceiver = receiverCaptor.getValue();
294         mAppIdleStateChangeListener = appIdleStateChangeListenerCaptor.getValue();
295 
296         assertNotNull(mIUidObserver);
297         assertNotNull(mAppOpsCallback);
298         assertNotNull(mPowerSaveObserver);
299         assertNotNull(mReceiver);
300         assertNotNull(instance.mFlagsObserver);
301     }
302 
setAppOps(int uid, String packageName, boolean restrict)303     private void setAppOps(int uid, String packageName, boolean restrict) throws RemoteException {
304         final Pair p = Pair.create(uid, packageName);
305         if (restrict) {
306             mRestrictedPackages.add(p);
307         } else {
308             mRestrictedPackages.remove(p);
309         }
310         if (mAppOpsCallback != null) {
311             mAppOpsCallback.opChanged(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName);
312         }
313     }
314 
areJobsRestricted(AppStateTrackerTestable instance, int[] uids, String[] packages, boolean[] restricted, boolean exemption)315     private void areJobsRestricted(AppStateTrackerTestable instance, int[] uids, String[] packages,
316             boolean[] restricted, boolean exemption) {
317         assertTrue(uids.length == packages.length && uids.length == restricted.length);
318         for (int i = 0; i < uids.length; i++) {
319             assertEquals(restricted[i],
320                     instance.areJobsRestricted(uids[i], packages[i], exemption));
321         }
322     }
323 
areAlarmsRestrictedByFAS(AppStateTrackerTestable instance, int[] uids, String[] packages, boolean[] restricted)324     private void areAlarmsRestrictedByFAS(AppStateTrackerTestable instance, int[] uids,
325             String[] packages, boolean[] restricted) {
326         assertTrue(uids.length == packages.length && uids.length == restricted.length);
327         for (int i = 0; i < uids.length; i++) {
328             assertEquals(restricted[i], instance.areAlarmsRestricted(uids[i], packages[i]));
329         }
330     }
331 
areAlarmsRestrictedByBatterySaver(AppStateTrackerTestable instance, int[] uids, String[] packages, boolean[] restricted)332     private void areAlarmsRestrictedByBatterySaver(AppStateTrackerTestable instance, int[] uids,
333             String[] packages, boolean[] restricted) {
334         assertTrue(uids.length == packages.length && uids.length == restricted.length);
335         for (int i = 0; i < uids.length; i++) {
336             assertEquals(restricted[i],
337                     instance.areAlarmsRestrictedByBatterySaver(uids[i], packages[i]));
338         }
339     }
340 
341     @Test
testAll()342     public void testAll() throws Exception {
343         final AppStateTrackerTestable instance = newInstance();
344         callStart(instance);
345 
346         assertFalse(instance.isForceAllAppsStandbyEnabled());
347         areJobsRestricted(instance,
348                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
349                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
350                 new boolean[] {false, false, false, false},
351                 false);
352         areJobsRestricted(instance,
353                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
354                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
355                 new boolean[] {false, false, false, false},
356                 true);
357         areAlarmsRestrictedByBatterySaver(instance,
358                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
359                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
360                 new boolean[] {false, false, false, false});
361 
362         mPowerSaveMode = true;
363         mPowerSaveObserver.accept(getPowerSaveState());
364 
365         assertTrue(instance.isForceAllAppsStandbyEnabled());
366 
367         areJobsRestricted(instance,
368                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
369                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
370                 new boolean[] {true, true, true, false},
371                 false);
372         areJobsRestricted(instance,
373                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
374                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
375                 new boolean[] {false, false, false, false},
376                 true);
377         areAlarmsRestrictedByBatterySaver(instance,
378                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
379                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
380                 new boolean[] {true, true, true, false});
381 
382         // Toggle the foreground state.
383 
384         assertFalse(instance.isUidActive(UID_1));
385         assertFalse(instance.isUidActive(UID_2));
386         assertTrue(instance.isUidActive(Process.SYSTEM_UID));
387 
388         mIUidObserver.onUidActive(UID_1);
389         waitUntilMainHandlerDrain();
390         waitUntilMainHandlerDrain();
391 
392         areJobsRestricted(instance,
393                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
394                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
395                 new boolean[] {false, true, true, false},
396                 false);
397         areAlarmsRestrictedByBatterySaver(instance,
398                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
399                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
400                 new boolean[] {false, true, true, false});
401 
402         assertTrue(instance.isUidActive(UID_1));
403         assertFalse(instance.isUidActive(UID_2));
404 
405         mIUidObserver.onUidGone(UID_1, /*disable=*/ false);
406         waitUntilMainHandlerDrain();
407         waitUntilMainHandlerDrain();
408 
409         areJobsRestricted(instance,
410                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
411                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
412                 new boolean[] {true, true, true, false},
413                 false);
414         areAlarmsRestrictedByBatterySaver(instance,
415                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
416                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
417                 new boolean[] {true, true, true, false});
418 
419         assertFalse(instance.isUidActive(UID_1));
420         assertFalse(instance.isUidActive(UID_2));
421 
422         mIUidObserver.onUidActive(UID_1);
423         waitUntilMainHandlerDrain();
424         waitUntilMainHandlerDrain();
425 
426         areJobsRestricted(instance,
427                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
428                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
429                 new boolean[] {false, true, true, false},
430                 false);
431         areAlarmsRestrictedByBatterySaver(instance,
432                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
433                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
434                 new boolean[] {false, true, true, false});
435 
436         mIUidObserver.onUidIdle(UID_1, /*disable=*/ false);
437         waitUntilMainHandlerDrain();
438         waitUntilMainHandlerDrain();
439 
440         areJobsRestricted(instance,
441                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
442                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
443                 new boolean[] {true, true, true, false},
444                 false);
445         areAlarmsRestrictedByBatterySaver(instance,
446                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
447                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
448                 new boolean[] {true, true, true, false});
449 
450         assertFalse(instance.isUidActive(UID_1));
451         assertFalse(instance.isUidActive(UID_2));
452 
453         // Toggle the app ops.
454         mPowerSaveMode = false;
455         mPowerSaveObserver.accept(getPowerSaveState());
456 
457         assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
458         assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1));
459         assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
460         assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
461 
462         areJobsRestricted(instance,
463                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
464                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
465                 new boolean[] {false, false, false, false, false},
466                 false);
467         areAlarmsRestrictedByBatterySaver(instance,
468                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
469                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
470                 new boolean[] {false, false, false, false, false});
471         areAlarmsRestrictedByFAS(instance,
472                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
473                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
474                 new boolean[] {false, false, false, false, false});
475 
476         setAppOps(UID_1, PACKAGE_1, true);
477         setAppOps(UID_10_2, PACKAGE_2, true);
478         assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
479         assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1));
480         assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
481         assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
482 
483         areJobsRestricted(instance,
484                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
485                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
486                 new boolean[] {true, false, false, true, false},
487                 false);
488         areJobsRestricted(instance,
489                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
490                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
491                 new boolean[] {true, false, false, true, false},
492                 true);
493 
494         areAlarmsRestrictedByBatterySaver(instance,
495                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
496                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
497                 new boolean[] {false, false, false, false, false});
498         areAlarmsRestrictedByFAS(instance,
499                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
500                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
501                 new boolean[] {true, false, false, true, false});
502 
503         // Toggle power saver, should still be the same.
504         mPowerSaveMode = true;
505         mPowerSaveObserver.accept(getPowerSaveState());
506 
507         areJobsRestricted(instance,
508                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
509                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
510                 new boolean[] {true, true, true, true, false},
511                 false);
512         areJobsRestricted(instance,
513                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
514                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
515                 new boolean[] {true, false, false, true, false},
516                 true);
517 
518         areAlarmsRestrictedByBatterySaver(instance,
519                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
520                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
521                 new boolean[] {true, true, true, true, false});
522         areAlarmsRestrictedByFAS(instance,
523                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
524                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
525                 new boolean[] {true, false, false, true, false});
526 
527         mPowerSaveMode = false;
528         mPowerSaveObserver.accept(getPowerSaveState());
529 
530         areJobsRestricted(instance,
531                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
532                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
533                 new boolean[] {true, false, false, true, false},
534                 false);
535         areJobsRestricted(instance,
536                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
537                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
538                 new boolean[] {true, false, false, true, false},
539                 true);
540 
541         areAlarmsRestrictedByBatterySaver(instance,
542                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
543                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
544                 new boolean[] {false, false, false, false, false});
545         areAlarmsRestrictedByFAS(instance,
546                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
547                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
548                 new boolean[] {true, false, false, true, false});
549 
550         // Clear the app ops and update the exemption list.
551         setAppOps(UID_1, PACKAGE_1, false);
552         setAppOps(UID_10_2, PACKAGE_2, false);
553 
554         mPowerSaveMode = true;
555         mPowerSaveObserver.accept(getPowerSaveState());
556 
557         areJobsRestricted(instance,
558                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
559                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
560                 new boolean[] {true, true, true, true, false},
561                 false);
562         areJobsRestricted(instance,
563                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
564                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
565                 new boolean[] {false, false, false, false, false},
566                 true);
567 
568         areAlarmsRestrictedByBatterySaver(instance,
569                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
570                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
571                 new boolean[] {true, true, true, true, false});
572         areAlarmsRestrictedByFAS(instance,
573                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, Process.SYSTEM_UID},
574                 new String[] {PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
575                 new boolean[] {false, false, false, false, false});
576 
577         instance.setPowerSaveExemptionListAppIds(new int[] {UID_1}, new int[] {},
578                 new int[] {UID_2});
579 
580         areJobsRestricted(instance,
581                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, UID_3, UID_10_3, Process.SYSTEM_UID},
582                 new String[]{PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_3, PACKAGE_3,
583                         PACKAGE_SYSTEM},
584                 new boolean[] {false, false, false, false, true, true, false},
585                 false);
586 
587         areAlarmsRestrictedByBatterySaver(instance,
588                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, UID_3, UID_10_3, Process.SYSTEM_UID},
589                 new String[]{PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_3, PACKAGE_3,
590                         PACKAGE_SYSTEM},
591                 new boolean[] {false, false, true, true, true, true, false});
592 
593         // Again, make sure toggling the global state doesn't change it.
594         mPowerSaveMode = false;
595         mPowerSaveObserver.accept(getPowerSaveState());
596 
597         mPowerSaveMode = true;
598         mPowerSaveObserver.accept(getPowerSaveState());
599 
600         areJobsRestricted(instance,
601                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, UID_3, UID_10_3, Process.SYSTEM_UID},
602                 new String[]{PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_3, PACKAGE_3,
603                         PACKAGE_SYSTEM},
604                 new boolean[] {false, false, false, false, true, true, false},
605                 false);
606 
607         areAlarmsRestrictedByBatterySaver(instance,
608                 new int[] {UID_1, UID_10_1, UID_2, UID_10_2, UID_3, UID_10_3, Process.SYSTEM_UID},
609                 new String[]{PACKAGE_1, PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_3, PACKAGE_3,
610                         PACKAGE_SYSTEM},
611                 new boolean[] {false, false, true, true, true, true, false});
612 
613         assertTrue(instance.isUidPowerSaveExempt(UID_1));
614         assertTrue(instance.isUidPowerSaveExempt(UID_10_1));
615         assertFalse(instance.isUidPowerSaveExempt(UID_2));
616         assertFalse(instance.isUidPowerSaveExempt(UID_10_2));
617 
618         assertFalse(instance.isUidTempPowerSaveExempt(UID_1));
619         assertFalse(instance.isUidTempPowerSaveExempt(UID_10_1));
620         assertTrue(instance.isUidTempPowerSaveExempt(UID_2));
621         assertTrue(instance.isUidTempPowerSaveExempt(UID_10_2));
622     }
623 
624     @Test
testPowerSaveUserExemptionList()625     public void testPowerSaveUserExemptionList() throws Exception {
626         final AppStateTrackerTestable instance = newInstance();
627         instance.setPowerSaveExemptionListAppIds(new int[] {}, new int[] {UID_1, UID_2},
628                 new int[] {});
629         assertTrue(instance.isUidPowerSaveUserExempt(UID_1));
630         assertTrue(instance.isUidPowerSaveUserExempt(UID_2));
631         assertFalse(instance.isUidPowerSaveUserExempt(UID_3));
632     }
633 
634     @Test
testUidStateForeground()635     public void testUidStateForeground() throws Exception {
636         final AppStateTrackerTestable instance = newInstance();
637         callStart(instance);
638 
639         mIUidObserver.onUidActive(UID_1);
640 
641         waitUntilMainHandlerDrain();
642         waitUntilMainHandlerDrain();
643 
644         assertTrue(instance.isUidActive(UID_1));
645         assertFalse(instance.isUidActive(UID_2));
646         assertTrue(instance.isUidActive(Process.SYSTEM_UID));
647 
648         assertTrue(instance.isUidActiveSynced(UID_1));
649         assertFalse(instance.isUidActiveSynced(UID_2));
650         assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
651 
652         mIUidObserver.onUidStateChanged(UID_2,
653                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE, 0,
654                 ActivityManager.PROCESS_CAPABILITY_NONE);
655 
656         waitUntilMainHandlerDrain();
657         waitUntilMainHandlerDrain();
658 
659         assertTrue(instance.isUidActive(UID_1));
660         assertFalse(instance.isUidActive(UID_2));
661         assertTrue(instance.isUidActive(Process.SYSTEM_UID));
662 
663         assertTrue(instance.isUidActiveSynced(UID_1));
664         assertFalse(instance.isUidActiveSynced(UID_2));
665         assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
666 
667         mIUidObserver.onUidStateChanged(UID_1,
668                 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0,
669                 ActivityManager.PROCESS_CAPABILITY_NONE);
670 
671         waitUntilMainHandlerDrain();
672         waitUntilMainHandlerDrain();
673 
674         assertTrue(instance.isUidActive(UID_1));
675         assertFalse(instance.isUidActive(UID_2));
676         assertTrue(instance.isUidActive(Process.SYSTEM_UID));
677 
678         mIUidObserver.onUidGone(UID_1, true);
679 
680         waitUntilMainHandlerDrain();
681         waitUntilMainHandlerDrain();
682 
683         assertFalse(instance.isUidActive(UID_1));
684         assertFalse(instance.isUidActive(UID_2));
685         assertTrue(instance.isUidActive(Process.SYSTEM_UID));
686 
687         mIUidObserver.onUidIdle(UID_2, true);
688 
689         waitUntilMainHandlerDrain();
690         waitUntilMainHandlerDrain();
691 
692         assertFalse(instance.isUidActive(UID_1));
693         assertFalse(instance.isUidActive(UID_2));
694         assertTrue(instance.isUidActive(Process.SYSTEM_UID));
695 
696         mIUidObserver.onUidStateChanged(UID_1,
697                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0,
698                 ActivityManager.PROCESS_CAPABILITY_NONE);
699 
700         waitUntilMainHandlerDrain();
701         waitUntilMainHandlerDrain();
702 
703         assertFalse(instance.isUidActive(UID_1));
704         assertFalse(instance.isUidActive(UID_2));
705         assertTrue(instance.isUidActive(Process.SYSTEM_UID));
706 
707         mIUidObserver.onUidStateChanged(UID_1,
708                 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0,
709                 ActivityManager.PROCESS_CAPABILITY_NONE);
710 
711         waitUntilMainHandlerDrain();
712         waitUntilMainHandlerDrain();
713 
714         assertFalse(instance.isUidActive(UID_1));
715         assertFalse(instance.isUidActive(UID_2));
716         assertTrue(instance.isUidActive(Process.SYSTEM_UID));
717 
718         assertFalse(instance.isUidActiveSynced(UID_1));
719         assertFalse(instance.isUidActiveSynced(UID_2));
720         assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
721 
722         // The result from AMI.isUidActive() only affects isUidActiveSynced().
723         when(mMockIActivityManagerInternal.isUidActive(anyInt())).thenReturn(true);
724 
725         assertFalse(instance.isUidActive(UID_1));
726         assertFalse(instance.isUidActive(UID_2));
727         assertTrue(instance.isUidActive(Process.SYSTEM_UID));
728 
729         assertTrue(instance.isUidActiveSynced(UID_1));
730         assertTrue(instance.isUidActiveSynced(UID_2));
731         assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
732     }
733 
734     @Test
testExemptedBucket()735     public void testExemptedBucket() throws Exception {
736         final AppStateTrackerTestable instance = newInstance();
737         callStart(instance);
738 
739         assertFalse(instance.isForceAllAppsStandbyEnabled());
740 
741         areJobsRestricted(instance,
742                 new int[] {UID_1, UID_2, Process.SYSTEM_UID},
743                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_SYSTEM},
744                 new boolean[] {false, false, false},
745                 false);
746         areAlarmsRestrictedByBatterySaver(instance,
747                 new int[] {UID_1, UID_2, Process.SYSTEM_UID},
748                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_SYSTEM},
749                 new boolean[] {false, false, false});
750 
751         mPowerSaveMode = true;
752         mPowerSaveObserver.accept(getPowerSaveState());
753 
754         assertTrue(instance.isForceAllAppsStandbyEnabled());
755 
756         areJobsRestricted(instance,
757                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
758                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
759                 new boolean[] {true, true, true, false},
760                 false);
761         areJobsRestricted(instance,
762                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
763                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
764                 new boolean[] {false, false, false, false},
765                 true);
766         areAlarmsRestrictedByBatterySaver(instance,
767                 new int[] {UID_1, UID_2, UID_10_2, Process.SYSTEM_UID},
768                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2, PACKAGE_SYSTEM},
769                 new boolean[] {true, true, true, false});
770 
771         // Exempt package 2 on user-10.
772         mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false,
773                 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
774 
775         areJobsRestricted(instance,
776                 new int[] {UID_1, UID_2, UID_10_2},
777                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
778                 new boolean[] {true, true, false},
779                 false);
780         areJobsRestricted(instance,
781                 new int[] {UID_1, UID_2, UID_10_2},
782                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
783                 new boolean[] {false, false, false},
784                 true);
785         areAlarmsRestrictedByBatterySaver(instance,
786                 new int[] {UID_1, UID_2, UID_10_2},
787                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
788                 new boolean[] {true, true, false});
789 
790         // Exempt package 1 on user-0.
791         mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false,
792                 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
793 
794         areJobsRestricted(instance,
795                 new int[] {UID_1, UID_2, UID_10_2},
796                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
797                 new boolean[] {false, true, false},
798                 false);
799         areJobsRestricted(instance,
800                 new int[] {UID_1, UID_2, UID_10_2},
801                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
802                 new boolean[] {false, false, false},
803                 true);
804         areAlarmsRestrictedByBatterySaver(instance,
805                 new int[] {UID_1, UID_2, UID_10_2},
806                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
807                 new boolean[] {false, true, false});
808 
809         // Unexempt package 2 on user-10.
810         mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false,
811                 UsageStatsManager.STANDBY_BUCKET_ACTIVE, REASON_MAIN_USAGE);
812 
813         areJobsRestricted(instance,
814                 new int[] {UID_1, UID_2, UID_10_2},
815                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
816                 new boolean[] {false, true, true},
817                 false);
818         areJobsRestricted(instance,
819                 new int[] {UID_1, UID_2, UID_10_2},
820                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
821                 new boolean[] {false, false, false},
822                 true);
823         areAlarmsRestrictedByBatterySaver(instance,
824                 new int[] {UID_1, UID_2, UID_10_2},
825                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
826                 new boolean[] {false, true, true});
827 
828         // Check force-app-standby.
829         // EXEMPT doesn't exempt from force-app-standby.
830         mPowerSaveMode = false;
831         mPowerSaveObserver.accept(getPowerSaveState());
832 
833         mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false,
834                 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
835         mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 0, false,
836                 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
837 
838         // All 3 packages (u0:p1, u0:p2, u10:p2) are now in the exempted bucket.
839         setAppOps(UID_1, PACKAGE_1, true);
840 
841         areJobsRestricted(instance,
842                 new int[] {UID_1, UID_2, UID_10_2},
843                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
844                 new boolean[] {true, false, false},
845                 false);
846         areJobsRestricted(instance,
847                 new int[] {UID_1, UID_2, UID_10_2},
848                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
849                 new boolean[] {true, false, false},
850                 true);
851 
852         areAlarmsRestrictedByBatterySaver(instance,
853                 new int[] {UID_1, UID_2, UID_10_2},
854                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
855                 new boolean[] {false, false, false});
856         areAlarmsRestrictedByFAS(instance,
857                 new int[] {UID_1, UID_2, UID_10_2},
858                 new String[] {PACKAGE_1, PACKAGE_2, PACKAGE_2},
859                 new boolean[] {true, false, false});
860     }
861 
862     @Test
loadPersistedAppOps()863     public void loadPersistedAppOps() throws Exception {
864         final AppStateTrackerTestable instance = newInstance();
865 
866         final List<PackageOps> ops = new ArrayList<>();
867 
868         //--------------------------------------------------
869         List<OpEntry> entries = new ArrayList<>();
870         entries.add(new OpEntry(
871                 AppOpsManager.OP_ACCESS_NOTIFICATIONS,
872                 AppOpsManager.MODE_IGNORED,
873                 Collections.emptyMap()));
874         entries.add(new OpEntry(
875                 AppStateTrackerImpl.TARGET_OP,
876                 AppOpsManager.MODE_IGNORED,
877                 Collections.emptyMap()));
878 
879         ops.add(new PackageOps(PACKAGE_1, UID_1, entries));
880 
881         //--------------------------------------------------
882         entries = new ArrayList<>();
883         entries.add(new OpEntry(
884                 AppStateTrackerImpl.TARGET_OP,
885                 AppOpsManager.MODE_IGNORED,
886                 Collections.emptyMap()));
887 
888         ops.add(new PackageOps(PACKAGE_2, UID_2, entries));
889 
890         //--------------------------------------------------
891         entries = new ArrayList<>();
892         entries.add(new OpEntry(
893                 AppStateTrackerImpl.TARGET_OP,
894                 AppOpsManager.MODE_ALLOWED,
895                 Collections.emptyMap()));
896 
897         ops.add(new PackageOps(PACKAGE_1, UID_10_1, entries));
898 
899         //--------------------------------------------------
900         entries = new ArrayList<>();
901         entries.add(new OpEntry(
902                 AppStateTrackerImpl.TARGET_OP,
903                 AppOpsManager.MODE_IGNORED,
904                 Collections.emptyMap()));
905         entries.add(new OpEntry(
906                 AppOpsManager.OP_ACCESS_NOTIFICATIONS,
907                 AppOpsManager.MODE_IGNORED,
908                 Collections.emptyMap()));
909 
910         ops.add(new PackageOps(PACKAGE_3, UID_10_3, entries));
911 
912         mGetPackagesForOps = inv -> {
913             final int[] arg = (int[]) inv.getArgument(0);
914             assertEquals(1, arg.length);
915             assertEquals(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, arg[0]);
916             return ops;
917         };
918 
919         callStart(instance);
920 
921         assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
922         assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
923         assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_3, PACKAGE_3));
924 
925         assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1));
926         assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
927         assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_3, PACKAGE_3));
928     }
929 
assertNoCallbacks(Listener l)930     private void assertNoCallbacks(Listener l) throws Exception {
931         waitUntilMainHandlerDrain();
932         verify(l, times(0)).updateAllJobs();
933         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
934         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
935 
936         verify(l, times(0)).unblockAllUnrestrictedAlarms();
937         verify(l, times(0)).unblockAlarmsForUid(anyInt());
938         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
939         reset(l);
940     }
941 
942     @Test
testPowerSaveListener()943     public void testPowerSaveListener() throws Exception {
944         final AppStateTrackerTestable instance = newInstance();
945         callStart(instance);
946 
947         Listener l = mock(Listener.class);
948         instance.addListener(l);
949 
950         // Power save on.
951         mPowerSaveMode = true;
952         mPowerSaveObserver.accept(getPowerSaveState());
953 
954         waitUntilMainHandlerDrain();
955         verify(l, times(1)).updateAllJobs();
956         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
957         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
958 
959         verify(l, times(1)).updateAllAlarms();
960         verify(l, times(0)).updateAlarmsForUid(anyInt());
961         verify(l, times(0)).unblockAllUnrestrictedAlarms();
962         verify(l, times(0)).unblockAlarmsForUid(anyInt());
963         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
964         reset(l);
965 
966         // Power save off.
967         mPowerSaveMode = false;
968         mPowerSaveObserver.accept(getPowerSaveState());
969 
970         waitUntilMainHandlerDrain();
971         verify(l, times(1)).updateAllJobs();
972         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
973         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
974 
975         verify(l, times(1)).updateAllAlarms();
976         verify(l, times(0)).updateAlarmsForUid(anyInt());
977         verify(l, times(0)).unblockAllUnrestrictedAlarms();
978         verify(l, times(0)).unblockAlarmsForUid(anyInt());
979         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
980         reset(l);
981 
982         // Updating to the same state should not fire listener
983         mPowerSaveMode = false;
984         mPowerSaveObserver.accept(getPowerSaveState());
985 
986         assertNoCallbacks(l);
987     }
988 
989     @Test
testAllListeners()990     public void testAllListeners() throws Exception {
991         final AppStateTrackerTestable instance = newInstance();
992         callStart(instance);
993 
994         Listener l = mock(Listener.class);
995         instance.addListener(l);
996 
997         // -------------------------------------------------------------------------
998         // Test with apppops.
999 
1000         setAppOps(UID_10_2, PACKAGE_2, true);
1001 
1002         waitUntilMainHandlerDrain();
1003         verify(l, times(0)).updateAllJobs();
1004         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1005         verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean());
1006 
1007         verify(l, times(0)).updateAllAlarms();
1008         verify(l, times(0)).updateAlarmsForUid(anyInt());
1009         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1010         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1011         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1012         reset(l);
1013 
1014         setAppOps(UID_10_2, PACKAGE_2, false);
1015 
1016         waitUntilMainHandlerDrain();
1017         verify(l, times(0)).updateAllJobs();
1018         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1019         verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean());
1020 
1021         verify(l, times(0)).updateAllAlarms();
1022         verify(l, times(0)).updateAlarmsForUid(anyInt());
1023         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1024         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1025         verify(l, times(1)).unblockAlarmsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
1026         reset(l);
1027 
1028         setAppOps(UID_10_2, PACKAGE_2, false);
1029 
1030         verify(l, times(0)).updateAllJobs();
1031         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1032         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1033 
1034         verify(l, times(0)).updateAllAlarms();
1035         verify(l, times(0)).updateAlarmsForUid(anyInt());
1036         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1037         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1038         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1039 
1040         // Test overlap with battery saver
1041         mPowerSaveMode = true;
1042         mPowerSaveObserver.accept(getPowerSaveState());
1043 
1044         setAppOps(UID_10_2, PACKAGE_2, true);
1045 
1046         waitUntilMainHandlerDrain();
1047         verify(l, times(1)).updateAllJobs();
1048         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1049         verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean());
1050 
1051         verify(l, times(1)).updateAllAlarms();
1052         verify(l, times(0)).updateAlarmsForUid(anyInt());
1053         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1054         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1055         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1056         reset(l);
1057 
1058         // Battery saver off.
1059         mPowerSaveMode = false;
1060         mPowerSaveObserver.accept(getPowerSaveState());
1061 
1062         waitUntilMainHandlerDrain();
1063         verify(l, times(1)).updateAllJobs();
1064         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1065         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1066 
1067         verify(l, times(1)).updateAllAlarms();
1068         verify(l, times(0)).updateAlarmsForUid(anyInt());
1069         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1070         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1071         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1072         reset(l);
1073 
1074         // -------------------------------------------------------------------------
1075         // Tests with system/user/temp exemption list.
1076 
1077         instance.setPowerSaveExemptionListAppIds(new int[] {UID_1, UID_2}, new int[] {},
1078                 new int[] {});
1079 
1080         waitUntilMainHandlerDrain();
1081         verify(l, times(1)).updateAllJobs();
1082         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1083         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1084 
1085         verify(l, times(1)).updateAllAlarms();
1086         verify(l, times(0)).updateAlarmsForUid(anyInt());
1087         verify(l, times(1)).unblockAllUnrestrictedAlarms();
1088         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1089         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1090         reset(l);
1091 
1092         instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
1093 
1094         waitUntilMainHandlerDrain();
1095         verify(l, times(1)).updateAllJobs();
1096         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1097         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1098 
1099         verify(l, times(1)).updateAllAlarms();
1100         verify(l, times(0)).updateAlarmsForUid(anyInt());
1101         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1102         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1103         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1104         reset(l);
1105 
1106         // Update temp exemption list.
1107         instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {},
1108                 new int[] {UID_1, UID_3});
1109 
1110         waitUntilMainHandlerDrain();
1111         verify(l, times(1)).updateAllJobs();
1112         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1113         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1114 
1115         verify(l, times(0)).updateAllAlarms();
1116         verify(l, times(0)).updateAlarmsForUid(anyInt());
1117         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1118         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1119         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1120         reset(l);
1121 
1122         instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {},
1123                 new int[] {UID_3});
1124 
1125         waitUntilMainHandlerDrain();
1126         verify(l, times(1)).updateAllJobs();
1127         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1128         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1129 
1130         verify(l, times(0)).updateAllAlarms();
1131         verify(l, times(0)).updateAlarmsForUid(anyInt());
1132         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1133         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1134         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1135         reset(l);
1136 
1137         // Do the same thing with battery saver on.
1138         mPowerSaveMode = true;
1139         mPowerSaveObserver.accept(getPowerSaveState());
1140 
1141         waitUntilMainHandlerDrain();
1142         verify(l, times(1)).updateAllJobs();
1143         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1144         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1145 
1146         verify(l, times(1)).updateAllAlarms();
1147         verify(l, times(0)).updateAlarmsForUid(anyInt());
1148         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1149         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1150         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1151         reset(l);
1152 
1153         instance.setPowerSaveExemptionListAppIds(new int[] {UID_1, UID_2}, new int[] {},
1154                 new int[] {});
1155 
1156         waitUntilMainHandlerDrain();
1157         // Called once for updating all exemption list and once for updating temp exemption list
1158         verify(l, times(2)).updateAllJobs();
1159         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1160         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1161 
1162         verify(l, times(1)).updateAllAlarms();
1163         verify(l, times(0)).updateAlarmsForUid(anyInt());
1164         verify(l, times(1)).unblockAllUnrestrictedAlarms();
1165         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1166         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1167         reset(l);
1168 
1169         instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
1170 
1171         waitUntilMainHandlerDrain();
1172         verify(l, times(1)).updateAllJobs();
1173         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1174         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1175 
1176         verify(l, times(1)).updateAllAlarms();
1177         verify(l, times(0)).updateAlarmsForUid(anyInt());
1178         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1179         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1180         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1181         reset(l);
1182 
1183         // Update temp exemption list.
1184         instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {},
1185                 new int[] {UID_1, UID_3});
1186 
1187         waitUntilMainHandlerDrain();
1188         verify(l, times(1)).updateAllJobs();
1189         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1190         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1191 
1192         verify(l, times(0)).updateAllAlarms();
1193         verify(l, times(0)).updateAlarmsForUid(anyInt());
1194         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1195         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1196         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1197         reset(l);
1198 
1199         instance.setPowerSaveExemptionListAppIds(new int[] {UID_2}, new int[] {},
1200                 new int[] {UID_3});
1201 
1202         waitUntilMainHandlerDrain();
1203         verify(l, times(1)).updateAllJobs();
1204         verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
1205         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1206 
1207         verify(l, times(0)).updateAllAlarms();
1208         verify(l, times(0)).updateAlarmsForUid(anyInt());
1209         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1210         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1211         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1212         reset(l);
1213 
1214 
1215         // -------------------------------------------------------------------------
1216         // Tests with proc state changes.
1217 
1218         // With battery saver.
1219         // Battery saver is already on.
1220 
1221         mIUidObserver.onUidActive(UID_10_1);
1222 
1223         waitUntilMainHandlerDrain();
1224         waitUntilMainHandlerDrain();
1225         verify(l, times(0)).updateAllJobs();
1226         verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1227         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1228 
1229         verify(l, times(0)).updateAllAlarms();
1230         verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
1231         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1232         verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
1233         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1234         reset(l);
1235 
1236         mIUidObserver.onUidGone(UID_10_1, true);
1237 
1238         waitUntilMainHandlerDrain();
1239         waitUntilMainHandlerDrain();
1240         verify(l, times(0)).updateAllJobs();
1241         verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1242         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1243 
1244         verify(l, times(0)).updateAllAlarms();
1245         verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
1246         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1247         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1248         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1249         reset(l);
1250 
1251         mIUidObserver.onUidActive(UID_10_1);
1252 
1253         waitUntilMainHandlerDrain();
1254         waitUntilMainHandlerDrain();
1255         verify(l, times(0)).updateAllJobs();
1256         verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1257         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1258 
1259         verify(l, times(0)).updateAllAlarms();
1260         verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
1261         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1262         verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
1263         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1264         reset(l);
1265 
1266         mIUidObserver.onUidIdle(UID_10_1, true);
1267 
1268         waitUntilMainHandlerDrain();
1269         waitUntilMainHandlerDrain();
1270         verify(l, times(0)).updateAllJobs();
1271         verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1272         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1273 
1274         verify(l, times(0)).updateAllAlarms();
1275         verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
1276         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1277         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1278         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1279         reset(l);
1280 
1281         // Without battery saver.
1282         mPowerSaveMode = false;
1283         mPowerSaveObserver.accept(getPowerSaveState());
1284 
1285         waitUntilMainHandlerDrain();
1286         verify(l, times(1)).updateAllJobs();
1287         verify(l, times(0)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1288         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1289 
1290         verify(l, times(1)).updateAllAlarms();
1291         verify(l, times(0)).updateAlarmsForUid(eq(UID_10_1));
1292         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1293         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1294         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1295         reset(l);
1296 
1297         mIUidObserver.onUidActive(UID_10_1);
1298 
1299         waitUntilMainHandlerDrain();
1300         waitUntilMainHandlerDrain();
1301         verify(l, times(0)).updateAllJobs();
1302         verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1303         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1304 
1305         verify(l, times(0)).updateAllAlarms();
1306         verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
1307         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1308         verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
1309         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1310         reset(l);
1311 
1312         mIUidObserver.onUidGone(UID_10_1, true);
1313 
1314         waitUntilMainHandlerDrain();
1315         waitUntilMainHandlerDrain();
1316         verify(l, times(0)).updateAllJobs();
1317         verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1318         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1319 
1320         verify(l, times(0)).updateAllAlarms();
1321         verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
1322         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1323         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1324         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1325         reset(l);
1326 
1327         mIUidObserver.onUidActive(UID_10_1);
1328 
1329         waitUntilMainHandlerDrain();
1330         waitUntilMainHandlerDrain();
1331         verify(l, times(0)).updateAllJobs();
1332         verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1333         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1334 
1335         verify(l, times(0)).updateAllAlarms();
1336         verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
1337         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1338         verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
1339         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1340         reset(l);
1341 
1342         mIUidObserver.onUidIdle(UID_10_1, true);
1343 
1344         waitUntilMainHandlerDrain();
1345         waitUntilMainHandlerDrain();
1346         verify(l, times(0)).updateAllJobs();
1347         verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1348         verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
1349 
1350         verify(l, times(0)).updateAllAlarms();
1351         verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1));
1352         verify(l, times(0)).unblockAllUnrestrictedAlarms();
1353         verify(l, times(0)).unblockAlarmsForUid(anyInt());
1354         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1355         reset(l);
1356     }
1357 
1358     @Test
testUserRemoved()1359     public void testUserRemoved() throws Exception {
1360         final AppStateTrackerTestable instance = newInstance();
1361         callStart(instance);
1362 
1363         mIUidObserver.onUidActive(UID_1);
1364         mIUidObserver.onUidActive(UID_10_1);
1365 
1366         waitUntilMainHandlerDrain();
1367         waitUntilMainHandlerDrain();
1368 
1369         setAppOps(UID_2, PACKAGE_2, true);
1370         setAppOps(UID_10_2, PACKAGE_2, true);
1371 
1372         assertTrue(instance.isUidActive(UID_1));
1373         assertTrue(instance.isUidActive(UID_10_1));
1374 
1375         assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
1376         assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
1377 
1378         final Intent intent = new Intent(Intent.ACTION_USER_REMOVED);
1379         intent.putExtra(Intent.EXTRA_USER_HANDLE, 10);
1380         mReceiver.onReceive(mMockContext, intent);
1381 
1382         waitUntilMainHandlerDrain();
1383 
1384         assertTrue(instance.isUidActive(UID_1));
1385         assertFalse(instance.isUidActive(UID_10_1));
1386 
1387         assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
1388         assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
1389     }
1390 
1391     @Test
testSmallBatteryAndPluggedIn()1392     public void testSmallBatteryAndPluggedIn() throws Exception {
1393         // This is a small battery device
1394         mIsSmallBatteryDevice = true;
1395 
1396         final AppStateTrackerTestable instance = newInstance();
1397         callStart(instance);
1398         assertFalse(instance.isForceAllAppsStandbyEnabled());
1399 
1400         // Setting/experiment for all app standby for small battery is enabled
1401         mGlobalSettings.put(Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 1);
1402         instance.mFlagsObserver.onChange(true,
1403                 Global.getUriFor(Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED));
1404         assertTrue(instance.isForceAllAppsStandbyEnabled());
1405 
1406         // When battery is plugged in, force app standby is disabled
1407         Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
1408         intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB);
1409         mReceiver.onReceive(mMockContext, intent);
1410         assertFalse(instance.isForceAllAppsStandbyEnabled());
1411 
1412         // When battery stops plugged in, force app standby is enabled
1413         mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED));
1414         assertTrue(instance.isForceAllAppsStandbyEnabled());
1415     }
1416 
1417     @Test
testNotSmallBatteryAndPluggedIn()1418     public void testNotSmallBatteryAndPluggedIn() throws Exception {
1419         // Not a small battery device, so plugged in status should not affect forced app standby
1420         mIsSmallBatteryDevice = false;
1421 
1422         final AppStateTrackerTestable instance = newInstance();
1423         callStart(instance);
1424         assertFalse(instance.isForceAllAppsStandbyEnabled());
1425 
1426         mPowerSaveMode = true;
1427         mPowerSaveObserver.accept(getPowerSaveState());
1428         assertTrue(instance.isForceAllAppsStandbyEnabled());
1429 
1430         // When battery is plugged in, force app standby is unaffected
1431         Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
1432         intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB);
1433         mReceiver.onReceive(mMockContext, intent);
1434         assertTrue(instance.isForceAllAppsStandbyEnabled());
1435 
1436         // When battery stops plugged in, force app standby is unaffected
1437         mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED));
1438         assertTrue(instance.isForceAllAppsStandbyEnabled());
1439     }
1440 
1441     @Test
testStateClearedOnPackageRemoved()1442     public void testStateClearedOnPackageRemoved() throws Exception {
1443         final AppStateTrackerTestable instance = newInstance();
1444         callStart(instance);
1445 
1446         instance.mActiveUids.put(UID_1, true);
1447         instance.mRunAnyRestrictedPackages.add(Pair.create(UID_1, PACKAGE_1));
1448         instance.mExemptedBucketPackages.add(UserHandle.getUserId(UID_2), PACKAGE_2);
1449 
1450         // Replace PACKAGE_1, nothing should change
1451         Intent packageRemoved = new Intent(Intent.ACTION_PACKAGE_REMOVED)
1452                 .putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(UID_1))
1453                 .putExtra(Intent.EXTRA_UID, UID_1)
1454                 .putExtra(Intent.EXTRA_REPLACING, true)
1455                 .setData(Uri.fromParts(IntentFilter.SCHEME_PACKAGE, PACKAGE_1, null));
1456         mReceiver.onReceive(mMockContext, packageRemoved);
1457 
1458         assertEquals(1, instance.mActiveUids.size());
1459         assertEquals(1, instance.mRunAnyRestrictedPackages.size());
1460         assertEquals(1, instance.mExemptedBucketPackages.size());
1461 
1462         // Replace PACKAGE_2, nothing should change
1463         packageRemoved = new Intent(Intent.ACTION_PACKAGE_REMOVED)
1464                 .putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(UID_2))
1465                 .putExtra(Intent.EXTRA_UID, UID_2)
1466                 .putExtra(Intent.EXTRA_REPLACING, true)
1467                 .setData(Uri.fromParts(IntentFilter.SCHEME_PACKAGE, PACKAGE_2, null));
1468         mReceiver.onReceive(mMockContext, packageRemoved);
1469 
1470         assertEquals(1, instance.mActiveUids.size());
1471         assertEquals(1, instance.mRunAnyRestrictedPackages.size());
1472         assertEquals(1, instance.mExemptedBucketPackages.size());
1473 
1474         // Remove PACKAGE_1
1475         packageRemoved = new Intent(Intent.ACTION_PACKAGE_REMOVED)
1476                 .putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(UID_1))
1477                 .putExtra(Intent.EXTRA_UID, UID_1)
1478                 .setData(Uri.fromParts(IntentFilter.SCHEME_PACKAGE, PACKAGE_1, null));
1479         mReceiver.onReceive(mMockContext, packageRemoved);
1480 
1481         assertEquals(0, instance.mActiveUids.size());
1482         assertEquals(0, instance.mRunAnyRestrictedPackages.size());
1483         assertEquals(1, instance.mExemptedBucketPackages.size());
1484 
1485         // Remove PACKAGE_2
1486         packageRemoved = new Intent(Intent.ACTION_PACKAGE_REMOVED)
1487                 .putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(UID_2))
1488                 .putExtra(Intent.EXTRA_UID, UID_2)
1489                 .setData(Uri.fromParts(IntentFilter.SCHEME_PACKAGE, PACKAGE_2, null));
1490         mReceiver.onReceive(mMockContext, packageRemoved);
1491 
1492         assertEquals(0, instance.mActiveUids.size());
1493         assertEquals(0, instance.mRunAnyRestrictedPackages.size());
1494         assertEquals(0, instance.mExemptedBucketPackages.size());
1495     }
1496 
array(int... appIds)1497     static int[] array(int... appIds) {
1498         Arrays.sort(appIds);
1499         return appIds;
1500     }
1501 
1502     private final Random mRandom = new Random();
1503 
makeRandomArray()1504     int[] makeRandomArray() {
1505         final ArrayList<Integer> list = new ArrayList<>();
1506         for (int i = 0; i < 5; i++) {
1507             if (mRandom.nextDouble() < 0.5) {
1508                 list.add(i);
1509             }
1510         }
1511         return Arrays.stream(list.toArray(new Integer[list.size()]))
1512                 .mapToInt(Integer::intValue).toArray();
1513     }
1514 
isAnyAppIdUnexemptSlow(int[] prevArray, int[] newArray)1515     static boolean isAnyAppIdUnexemptSlow(int[] prevArray, int[] newArray) {
1516         Arrays.sort(newArray); // Just in case...
1517         for (int p : prevArray) {
1518             if (Arrays.binarySearch(newArray, p) < 0) {
1519                 return true;
1520             }
1521         }
1522         return false;
1523     }
1524 
checkAnyAppIdUnexempt(int[] prevArray, int[] newArray, boolean expected)1525     private void checkAnyAppIdUnexempt(int[] prevArray, int[] newArray, boolean expected) {
1526         assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
1527                 expected, AppStateTrackerImpl.isAnyAppIdUnexempt(prevArray, newArray));
1528 
1529         // Also test isAnyAppIdUnexempt.
1530         assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
1531                 expected, isAnyAppIdUnexemptSlow(prevArray, newArray));
1532     }
1533 
1534     @Test
isAnyAppIdUnexempt()1535     public void isAnyAppIdUnexempt() {
1536         checkAnyAppIdUnexempt(array(), array(), false);
1537 
1538         checkAnyAppIdUnexempt(array(1), array(), true);
1539         checkAnyAppIdUnexempt(array(1), array(1), false);
1540         checkAnyAppIdUnexempt(array(1), array(0, 1), false);
1541         checkAnyAppIdUnexempt(array(1), array(0, 1, 2), false);
1542         checkAnyAppIdUnexempt(array(1), array(0, 1, 2), false);
1543 
1544         checkAnyAppIdUnexempt(array(1, 2, 10), array(), true);
1545         checkAnyAppIdUnexempt(array(1, 2, 10), array(1, 2), true);
1546         checkAnyAppIdUnexempt(array(1, 2, 10), array(1, 2, 10), false);
1547         checkAnyAppIdUnexempt(array(1, 2, 10), array(2, 10), true);
1548         checkAnyAppIdUnexempt(array(1, 2, 10), array(0, 1, 2, 4, 3, 10), false);
1549         checkAnyAppIdUnexempt(array(1, 2, 10), array(0, 0, 1, 2, 10), false);
1550 
1551         // Random test
1552         int trueCount = 0;
1553         final int count = 10000;
1554         for (int i = 0; i < count; i++) {
1555             final int[] array1 = makeRandomArray();
1556             final int[] array2 = makeRandomArray();
1557 
1558             final boolean expected = isAnyAppIdUnexemptSlow(array1, array2);
1559             final boolean actual = AppStateTrackerImpl.isAnyAppIdUnexempt(array1, array2);
1560 
1561             assertEquals("Input: " + Arrays.toString(array1) + " " + Arrays.toString(array2),
1562                     expected, actual);
1563             if (expected) {
1564                 trueCount++;
1565             }
1566         }
1567 
1568         // Make sure makeRandomArray() didn't generate all same arrays by accident.
1569         assertTrue(trueCount > 0);
1570         assertTrue(trueCount < count);
1571     }
1572 }
1573