blob: c8e67820ce464593b67b590700397667ab745163 [file] [log] [blame]
Makoto Onuki2206af32017-11-21 16:25:35 -08001/*
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 */
16package com.android.server;
17
Amith Yamasani119be9a2018-02-18 22:23:00 -080018import static android.app.usage.UsageStatsManager.REASON_MAIN_DEFAULT;
19import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
20
Makoto Onukie4918212018-02-06 11:30:15 -080021import static com.android.server.AppStateTracker.TARGET_OP;
Makoto Onuki2206af32017-11-21 16:25:35 -080022
23import static org.junit.Assert.assertEquals;
24import static org.junit.Assert.assertFalse;
25import static org.junit.Assert.assertNotNull;
26import static org.junit.Assert.assertTrue;
27import static org.mockito.ArgumentMatchers.any;
Christopher Tate20afddd2018-02-28 15:19:19 -080028import static org.mockito.ArgumentMatchers.anyBoolean;
Makoto Onuki2206af32017-11-21 16:25:35 -080029import static org.mockito.ArgumentMatchers.anyInt;
30import static org.mockito.ArgumentMatchers.anyString;
31import static org.mockito.ArgumentMatchers.eq;
32import static org.mockito.ArgumentMatchers.isNull;
33import static org.mockito.Mockito.mock;
34import static org.mockito.Mockito.reset;
35import static org.mockito.Mockito.times;
36import static org.mockito.Mockito.verify;
37import static org.mockito.Mockito.when;
38
39import android.app.ActivityManager;
Makoto Onukie4918212018-02-06 11:30:15 -080040import android.app.ActivityManagerInternal;
Makoto Onuki2206af32017-11-21 16:25:35 -080041import android.app.AppOpsManager;
42import android.app.AppOpsManager.OpEntry;
43import android.app.AppOpsManager.PackageOps;
44import android.app.IActivityManager;
45import android.app.IUidObserver;
Makoto Onukieb898f12018-01-23 15:26:27 -080046import android.app.usage.UsageStatsManager;
47import android.app.usage.UsageStatsManagerInternal;
48import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
Makoto Onuki2206af32017-11-21 16:25:35 -080049import android.content.BroadcastReceiver;
50import android.content.Context;
51import android.content.Intent;
52import android.content.IntentFilter;
Nancy Zheng525aaa12018-01-12 11:45:37 -080053import android.os.BatteryManager;
Makoto Onuki2206af32017-11-21 16:25:35 -080054import android.os.Handler;
55import android.os.Looper;
56import android.os.PowerManager.ServiceType;
57import android.os.PowerManagerInternal;
58import android.os.PowerSaveState;
59import android.os.Process;
60import android.os.RemoteException;
61import android.os.UserHandle;
Nancy Zheng525aaa12018-01-12 11:45:37 -080062import android.provider.Settings.Global;
Nancy Zhenga18c1f12018-01-18 16:29:59 -080063import android.test.mock.MockContentResolver;
Makoto Onuki2206af32017-11-21 16:25:35 -080064import android.util.ArraySet;
65import android.util.Pair;
66
67import com.android.internal.app.IAppOpsCallback;
68import com.android.internal.app.IAppOpsService;
Makoto Onukie4918212018-02-06 11:30:15 -080069import com.android.server.AppStateTracker.Listener;
Makoto Onuki2206af32017-11-21 16:25:35 -080070
71import org.junit.Before;
72import org.junit.Test;
73import org.junit.runner.RunWith;
74import org.mockito.ArgumentCaptor;
75import org.mockito.Mock;
76import org.mockito.MockitoAnnotations;
Makoto Onuki5622f472018-02-26 15:26:54 -080077import org.mockito.stubbing.Answer;
Makoto Onuki2206af32017-11-21 16:25:35 -080078
79import java.util.ArrayList;
80import java.util.Arrays;
Makoto Onukieb898f12018-01-23 15:26:27 -080081import java.util.HashMap;
Makoto Onuki2206af32017-11-21 16:25:35 -080082import java.util.List;
83import java.util.Random;
84import java.util.concurrent.CountDownLatch;
85import java.util.concurrent.TimeUnit;
86import java.util.function.Consumer;
87
Makoto Onuki4ac1cf82018-09-05 13:45:40 -070088import androidx.test.filters.SmallTest;
89import androidx.test.runner.AndroidJUnit4;
90
Makoto Onukiadb50d82018-01-29 16:20:30 -080091/**
Makoto Onukie4918212018-02-06 11:30:15 -080092 * Tests for {@link AppStateTracker}
Makoto Onukiadb50d82018-01-29 16:20:30 -080093 *
94 * Run with:
Makoto Onuki4ac1cf82018-09-05 13:45:40 -070095 atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
Makoto Onukiadb50d82018-01-29 16:20:30 -080096 */
Makoto Onuki2206af32017-11-21 16:25:35 -080097@SmallTest
98@RunWith(AndroidJUnit4.class)
Makoto Onukie4918212018-02-06 11:30:15 -080099public class AppStateTrackerTest {
Makoto Onuki2206af32017-11-21 16:25:35 -0800100
Makoto Onukie4918212018-02-06 11:30:15 -0800101 private class AppStateTrackerTestable extends AppStateTracker {
102 AppStateTrackerTestable() {
Makoto Onuki2206af32017-11-21 16:25:35 -0800103 super(mMockContext, Looper.getMainLooper());
104 }
105
106 @Override
107 AppOpsManager injectAppOpsManager() {
108 return mMockAppOpsManager;
109 }
110
111 @Override
112 IAppOpsService injectIAppOpsService() {
113 return mMockIAppOpsService;
114 }
115
116 @Override
117 IActivityManager injectIActivityManager() {
118 return mMockIActivityManager;
119 }
120
121 @Override
Makoto Onukie4918212018-02-06 11:30:15 -0800122 ActivityManagerInternal injectActivityManagerInternal() {
123 return mMockIActivityManagerInternal;
124 }
125
126 @Override
Makoto Onuki2206af32017-11-21 16:25:35 -0800127 PowerManagerInternal injectPowerManagerInternal() {
128 return mMockPowerManagerInternal;
129 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800130
131 @Override
Makoto Onukieb898f12018-01-23 15:26:27 -0800132 UsageStatsManagerInternal injectUsageStatsManagerInternal() {
133 return mMockUsageStatsManagerInternal;
134 }
135
136 @Override
137 int injectGetGlobalSettingInt(String key, int def) {
138 Integer val = mGlobalSettings.get(key);
139
140 return (val == null) ? def : val;
141 }
142
143 @Override
Nancy Zheng525aaa12018-01-12 11:45:37 -0800144 boolean isSmallBatteryDevice() { return mIsSmallBatteryDevice; };
Makoto Onuki2206af32017-11-21 16:25:35 -0800145 }
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
Makoto Onukie4918212018-02-06 11:30:15 -0800167 private ActivityManagerInternal mMockIActivityManagerInternal;
168
169 @Mock
Makoto Onuki2206af32017-11-21 16:25:35 -0800170 private AppOpsManager mMockAppOpsManager;
171
172 @Mock
173 private IAppOpsService mMockIAppOpsService;
174
175 @Mock
176 private PowerManagerInternal mMockPowerManagerInternal;
177
Makoto Onukieb898f12018-01-23 15:26:27 -0800178 @Mock
179 private UsageStatsManagerInternal mMockUsageStatsManagerInternal;
180
181 private MockContentResolver mMockContentResolver;
182
Makoto Onuki2206af32017-11-21 16:25:35 -0800183 private IUidObserver mIUidObserver;
184 private IAppOpsCallback.Stub mAppOpsCallback;
185 private Consumer<PowerSaveState> mPowerSaveObserver;
186 private BroadcastReceiver mReceiver;
Makoto Onukieb898f12018-01-23 15:26:27 -0800187 private AppIdleStateChangeListener mAppIdleStateChangeListener;
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800188
Makoto Onuki2206af32017-11-21 16:25:35 -0800189 private boolean mPowerSaveMode;
Nancy Zheng525aaa12018-01-12 11:45:37 -0800190 private boolean mIsSmallBatteryDevice;
Makoto Onuki2206af32017-11-21 16:25:35 -0800191
192 private final ArraySet<Pair<Integer, String>> mRestrictedPackages = new ArraySet();
193
Makoto Onukieb898f12018-01-23 15:26:27 -0800194 private final HashMap<String, Integer> mGlobalSettings = new HashMap<>();
195
Makoto Onuki5622f472018-02-26 15:26:54 -0800196 private Answer<List<PackageOps>> mGetPackagesForOps =
197 inv -> new ArrayList<PackageOps>();
198
Makoto Onuki2206af32017-11-21 16:25:35 -0800199 @Before
200 public void setUp() {
201 mMainHandler = new Handler(Looper.getMainLooper());
202 }
203
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
212 private PowerSaveState getPowerSaveState() {
213 return new PowerSaveState.Builder().setBatterySaverEnabled(mPowerSaveMode).build();
214 }
215
Makoto Onukie4918212018-02-06 11:30:15 -0800216 private AppStateTrackerTestable newInstance() throws Exception {
Makoto Onuki2206af32017-11-21 16:25:35 -0800217 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
Makoto Onukie4918212018-02-06 11:30:15 -0800226 final AppStateTrackerTestable instance = new AppStateTrackerTestable();
Makoto Onuki2206af32017-11-21 16:25:35 -0800227
228 return instance;
229 }
230
Makoto Onukie4918212018-02-06 11:30:15 -0800231 private void callStart(AppStateTrackerTestable instance) throws RemoteException {
Makoto Onuki12391f22018-01-18 21:44:28 +0000232
Makoto Onuki2206af32017-11-21 16:25:35 -0800233 // 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)
Makoto Onuki5622f472018-02-26 15:26:54 -0800238 )).thenAnswer(mGetPackagesForOps);
Makoto Onuki2206af32017-11-21 16:25:35 -0800239
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800240 mMockContentResolver = new MockContentResolver();
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800241 when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800242
Makoto Onuki2206af32017-11-21 16:25:35 -0800243 // Call start.
Makoto Onukie4918212018-02-06 11:30:15 -0800244 instance.onSystemServicesReady();
Makoto Onuki2206af32017-11-21 16:25:35 -0800245
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);
Makoto Onukieb898f12018-01-23 15:26:27 -0800255 ArgumentCaptor<AppIdleStateChangeListener> appIdleStateChangeListenerCaptor =
256 ArgumentCaptor.forClass(AppIdleStateChangeListener.class);
Makoto Onuki2206af32017-11-21 16:25:35 -0800257
258 verify(mMockIActivityManager).registerUidObserver(
259 uidObserverArgumentCaptor.capture(),
260 eq(ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_IDLE
Makoto Onukiadb50d82018-01-29 16:20:30 -0800261 | ActivityManager.UID_OBSERVER_ACTIVE
262 | ActivityManager.UID_OBSERVER_PROCSTATE),
Makoto Onuki2206af32017-11-21 16:25:35 -0800263 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());
Makoto Onuki12391f22018-01-18 21:44:28 +0000272
Makoto Onuki2206af32017-11-21 16:25:35 -0800273 verify(mMockContext).registerReceiver(
274 receiverCaptor.capture(), any(IntentFilter.class));
Makoto Onukieb898f12018-01-23 15:26:27 -0800275 verify(mMockUsageStatsManagerInternal).addAppIdleStateChangeListener(
276 appIdleStateChangeListenerCaptor.capture());
Makoto Onuki2206af32017-11-21 16:25:35 -0800277
278 mIUidObserver = uidObserverArgumentCaptor.getValue();
279 mAppOpsCallback = appOpsCallbackCaptor.getValue();
280 mPowerSaveObserver = powerSaveObserverCaptor.getValue();
281 mReceiver = receiverCaptor.getValue();
Makoto Onukieb898f12018-01-23 15:26:27 -0800282 mAppIdleStateChangeListener = appIdleStateChangeListenerCaptor.getValue();
Makoto Onuki2206af32017-11-21 16:25:35 -0800283
284 assertNotNull(mIUidObserver);
285 assertNotNull(mAppOpsCallback);
286 assertNotNull(mPowerSaveObserver);
287 assertNotNull(mReceiver);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800288 assertNotNull(instance.mFlagsObserver);
Makoto Onuki2206af32017-11-21 16:25:35 -0800289 }
290
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
Makoto Onukie4918212018-02-06 11:30:15 -0800308 private void areRestricted(AppStateTrackerTestable instance, int uid, String packageName,
Makoto Onuki15407842018-01-19 14:23:11 -0800309 int restrictionTypes, boolean exemptFromBatterySaver) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800310 assertEquals(((restrictionTypes & JOBS_ONLY) != 0),
Makoto Onuki15407842018-01-19 14:23:11 -0800311 instance.areJobsRestricted(uid, packageName, exemptFromBatterySaver));
Makoto Onuki2206af32017-11-21 16:25:35 -0800312 assertEquals(((restrictionTypes & ALARMS_ONLY) != 0),
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800313 instance.areAlarmsRestricted(uid, packageName, exemptFromBatterySaver));
Makoto Onuki2206af32017-11-21 16:25:35 -0800314 }
315
Makoto Onukie4918212018-02-06 11:30:15 -0800316 private void areRestricted(AppStateTrackerTestable instance, int uid, String packageName,
Makoto Onuki15407842018-01-19 14:23:11 -0800317 int restrictionTypes) {
318 areRestricted(instance, uid, packageName, restrictionTypes,
319 /*exemptFromBatterySaver=*/ false);
320 }
321
Makoto Onukie4918212018-02-06 11:30:15 -0800322 private void areRestrictedWithExemption(AppStateTrackerTestable instance,
Makoto Onukieb898f12018-01-23 15:26:27 -0800323 int uid, String packageName, int restrictionTypes) {
324 areRestricted(instance, uid, packageName, restrictionTypes,
325 /*exemptFromBatterySaver=*/ true);
326 }
327
Makoto Onuki2206af32017-11-21 16:25:35 -0800328 @Test
329 public void testAll() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800330 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -0800331 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
Makoto Onukieb898f12018-01-23 15:26:27 -0800338 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
Makoto Onuki2206af32017-11-21 16:25:35 -0800342 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
Makoto Onukieb898f12018-01-23 15:26:27 -0800351 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
Makoto Onuki2206af32017-11-21 16:25:35 -0800355 // Toggle the foreground state.
356 mPowerSaveMode = true;
357 mPowerSaveObserver.accept(getPowerSaveState());
358
Makoto Onukiadb50d82018-01-29 16:20:30 -0800359 assertFalse(instance.isUidActive(UID_1));
360 assertFalse(instance.isUidActive(UID_2));
361 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
Makoto Onuki2206af32017-11-21 16:25:35 -0800362
363 mIUidObserver.onUidActive(UID_1);
Makoto Onuki4d298b52018-02-05 10:54:58 -0800364 waitUntilMainHandlerDrain();
Makoto Onuki2206af32017-11-21 16:25:35 -0800365 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);
Makoto Onukiadb50d82018-01-29 16:20:30 -0800368 assertTrue(instance.isUidActive(UID_1));
369 assertFalse(instance.isUidActive(UID_2));
Makoto Onuki2206af32017-11-21 16:25:35 -0800370
371 mIUidObserver.onUidGone(UID_1, /*disable=*/ false);
Makoto Onuki4d298b52018-02-05 10:54:58 -0800372 waitUntilMainHandlerDrain();
Makoto Onuki2206af32017-11-21 16:25:35 -0800373 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);
Makoto Onukiadb50d82018-01-29 16:20:30 -0800376 assertFalse(instance.isUidActive(UID_1));
377 assertFalse(instance.isUidActive(UID_2));
Makoto Onuki2206af32017-11-21 16:25:35 -0800378
379 mIUidObserver.onUidActive(UID_1);
Makoto Onuki4d298b52018-02-05 10:54:58 -0800380 waitUntilMainHandlerDrain();
Makoto Onuki2206af32017-11-21 16:25:35 -0800381 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);
Makoto Onuki4d298b52018-02-05 10:54:58 -0800386 waitUntilMainHandlerDrain();
Makoto Onuki2206af32017-11-21 16:25:35 -0800387 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);
Makoto Onukiadb50d82018-01-29 16:20:30 -0800390 assertFalse(instance.isUidActive(UID_1));
391 assertFalse(instance.isUidActive(UID_2));
Makoto Onuki2206af32017-11-21 16:25:35 -0800392
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
Suprabh Shukla5bf49812018-05-24 18:38:50 -0700449 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1}, new int[] {}, new int[] {UID_2});
Makoto Onuki2206af32017-11-21 16:25:35 -0800450
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
Makoto Onukieb898f12018-01-23 15:26:27 -0800485 @Test
Suprabh Shukla5bf49812018-05-24 18:38:50 -0700486 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
Makoto Onukiadb50d82018-01-29 16:20:30 -0800495 public void testUidStateForeground() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800496 final AppStateTrackerTestable instance = newInstance();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800497 callStart(instance);
498
499 mIUidObserver.onUidActive(UID_1);
500
Makoto Onuki4d298b52018-02-05 10:54:58 -0800501 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800502 assertTrue(instance.isUidActive(UID_1));
503 assertFalse(instance.isUidActive(UID_2));
504 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
505
Makoto Onukie4918212018-02-06 11:30:15 -0800506 assertTrue(instance.isUidActiveSynced(UID_1));
507 assertFalse(instance.isUidActiveSynced(UID_2));
508 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
509
Makoto Onukiadb50d82018-01-29 16:20:30 -0800510 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
Makoto Onuki4d298b52018-02-05 10:54:58 -0800518 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800519 assertTrue(instance.isUidActive(UID_1));
520 assertFalse(instance.isUidActive(UID_2));
521 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
522
Makoto Onukie4918212018-02-06 11:30:15 -0800523 assertTrue(instance.isUidActiveSynced(UID_1));
524 assertFalse(instance.isUidActiveSynced(UID_2));
525 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
526
Makoto Onukiadb50d82018-01-29 16:20:30 -0800527 assertFalse(instance.isUidInForeground(UID_1));
528 assertTrue(instance.isUidInForeground(UID_2));
529 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
530
531
532 mIUidObserver.onUidStateChanged(UID_1,
533 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
534
Makoto Onuki4d298b52018-02-05 10:54:58 -0800535 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800536 assertTrue(instance.isUidActive(UID_1));
537 assertFalse(instance.isUidActive(UID_2));
538 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
539
540 assertTrue(instance.isUidInForeground(UID_1));
541 assertTrue(instance.isUidInForeground(UID_2));
542 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
543
544 mIUidObserver.onUidGone(UID_1, true);
545
Makoto Onuki4d298b52018-02-05 10:54:58 -0800546 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800547 assertFalse(instance.isUidActive(UID_1));
548 assertFalse(instance.isUidActive(UID_2));
549 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
550
551 assertFalse(instance.isUidInForeground(UID_1));
552 assertTrue(instance.isUidInForeground(UID_2));
553 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
554
555 mIUidObserver.onUidIdle(UID_2, true);
556
Makoto Onuki4d298b52018-02-05 10:54:58 -0800557 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800558 assertFalse(instance.isUidActive(UID_1));
559 assertFalse(instance.isUidActive(UID_2));
560 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
561
562 assertFalse(instance.isUidInForeground(UID_1));
563 assertFalse(instance.isUidInForeground(UID_2));
564 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
565
566 mIUidObserver.onUidStateChanged(UID_1,
567 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0);
568
Makoto Onuki4d298b52018-02-05 10:54:58 -0800569 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800570 assertFalse(instance.isUidActive(UID_1));
571 assertFalse(instance.isUidActive(UID_2));
572 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
573
574 assertTrue(instance.isUidInForeground(UID_1));
575 assertFalse(instance.isUidInForeground(UID_2));
576 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
577
578 mIUidObserver.onUidStateChanged(UID_1,
579 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0);
580
Makoto Onuki4d298b52018-02-05 10:54:58 -0800581 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800582 assertFalse(instance.isUidActive(UID_1));
583 assertFalse(instance.isUidActive(UID_2));
584 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
585
Makoto Onukie4918212018-02-06 11:30:15 -0800586 assertFalse(instance.isUidActiveSynced(UID_1));
587 assertFalse(instance.isUidActiveSynced(UID_2));
588 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
589
Makoto Onukiadb50d82018-01-29 16:20:30 -0800590 assertFalse(instance.isUidInForeground(UID_1));
591 assertFalse(instance.isUidInForeground(UID_2));
592 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
Makoto Onukie4918212018-02-06 11:30:15 -0800593
594 // The result from AMI.isUidActive() only affects isUidActiveSynced().
595 when(mMockIActivityManagerInternal.isUidActive(anyInt())).thenReturn(true);
596
597 assertFalse(instance.isUidActive(UID_1));
598 assertFalse(instance.isUidActive(UID_2));
599 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
600
601 assertTrue(instance.isUidActiveSynced(UID_1));
602 assertTrue(instance.isUidActiveSynced(UID_2));
603 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
604
605 assertFalse(instance.isUidInForeground(UID_1));
606 assertFalse(instance.isUidInForeground(UID_2));
607 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
608
Makoto Onukiadb50d82018-01-29 16:20:30 -0800609 }
610
611 @Test
Makoto Onukieb898f12018-01-23 15:26:27 -0800612 public void testExempt() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800613 final AppStateTrackerTestable instance = newInstance();
Makoto Onukieb898f12018-01-23 15:26:27 -0800614 callStart(instance);
615
616 assertFalse(instance.isForceAllAppsStandbyEnabled());
617 areRestricted(instance, UID_1, PACKAGE_1, NONE);
618 areRestricted(instance, UID_2, PACKAGE_2, NONE);
619 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
620
621 mPowerSaveMode = true;
622 mPowerSaveObserver.accept(getPowerSaveState());
623
624 assertTrue(instance.isForceAllAppsStandbyEnabled());
625
626 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
627 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
628 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
629 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
630
631 // Exempt package 2 on user-10.
632 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800633 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
Makoto Onukieb898f12018-01-23 15:26:27 -0800634
635 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
636 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
637 areRestricted(instance, UID_10_2, PACKAGE_2, NONE);
638
639 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE);
640 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
641 areRestrictedWithExemption(instance, UID_10_2, PACKAGE_2, NONE);
642
643 // Exempt package 1 on user-0.
644 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800645 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
Makoto Onukieb898f12018-01-23 15:26:27 -0800646
647 areRestricted(instance, UID_1, PACKAGE_1, NONE);
648 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
649 areRestricted(instance, UID_10_2, PACKAGE_2, NONE);
650
651 // Unexempt package 2 on user-10.
652 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800653 UsageStatsManager.STANDBY_BUCKET_ACTIVE, REASON_MAIN_USAGE);
Makoto Onukieb898f12018-01-23 15:26:27 -0800654
655 areRestricted(instance, UID_1, PACKAGE_1, NONE);
656 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
657 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
658
659 // Check force-app-standby.
660 // EXEMPT doesn't exempt from force-app-standby.
661 mPowerSaveMode = false;
662 mPowerSaveObserver.accept(getPowerSaveState());
663
664 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800665 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
Makoto Onukieb898f12018-01-23 15:26:27 -0800666 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 0, false,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800667 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
Makoto Onukieb898f12018-01-23 15:26:27 -0800668
669 setAppOps(UID_1, PACKAGE_1, true);
670
671 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
672 areRestricted(instance, UID_2, PACKAGE_2, NONE);
673
674 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
675 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
676 }
677
Andreas Gampecea9e6d2018-02-22 18:06:44 -0800678 @Test
Makoto Onuki2206af32017-11-21 16:25:35 -0800679 public void loadPersistedAppOps() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800680 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -0800681
682 final List<PackageOps> ops = new ArrayList<>();
683
684 //--------------------------------------------------
685 List<OpEntry> entries = new ArrayList<>();
Makoto Onuki4ac1cf82018-09-05 13:45:40 -0700686 entries.add(new OpEntry(
Makoto Onuki2206af32017-11-21 16:25:35 -0800687 AppOpsManager.OP_ACCESS_NOTIFICATIONS,
688 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
Makoto Onuki4ac1cf82018-09-05 13:45:40 -0700689 entries.add(new OpEntry(
Makoto Onukie4918212018-02-06 11:30:15 -0800690 AppStateTracker.TARGET_OP,
Makoto Onuki2206af32017-11-21 16:25:35 -0800691 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
692
693 ops.add(new PackageOps(PACKAGE_1, UID_1, entries));
694
695 //--------------------------------------------------
696 entries = new ArrayList<>();
Makoto Onuki4ac1cf82018-09-05 13:45:40 -0700697 entries.add(new OpEntry(
Makoto Onukie4918212018-02-06 11:30:15 -0800698 AppStateTracker.TARGET_OP,
Makoto Onuki2206af32017-11-21 16:25:35 -0800699 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
700
701 ops.add(new PackageOps(PACKAGE_2, UID_2, entries));
702
703 //--------------------------------------------------
704 entries = new ArrayList<>();
Makoto Onuki4ac1cf82018-09-05 13:45:40 -0700705 entries.add(new OpEntry(
Makoto Onukie4918212018-02-06 11:30:15 -0800706 AppStateTracker.TARGET_OP,
Makoto Onuki2206af32017-11-21 16:25:35 -0800707 AppOpsManager.MODE_ALLOWED, 0, 0, 0, 0, null));
708
709 ops.add(new PackageOps(PACKAGE_1, UID_10_1, entries));
710
711 //--------------------------------------------------
712 entries = new ArrayList<>();
Makoto Onuki4ac1cf82018-09-05 13:45:40 -0700713 entries.add(new OpEntry(
Makoto Onukie4918212018-02-06 11:30:15 -0800714 AppStateTracker.TARGET_OP,
Makoto Onuki2206af32017-11-21 16:25:35 -0800715 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
Makoto Onuki4ac1cf82018-09-05 13:45:40 -0700716 entries.add(new OpEntry(
Makoto Onuki2206af32017-11-21 16:25:35 -0800717 AppOpsManager.OP_ACCESS_NOTIFICATIONS,
718 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
719
720 ops.add(new PackageOps(PACKAGE_3, UID_10_3, entries));
721
Makoto Onuki5622f472018-02-26 15:26:54 -0800722 mGetPackagesForOps = inv -> {
723 final int[] arg = (int[]) inv.getArgument(0);
724 assertEquals(1, arg.length);
725 assertEquals(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, arg[0]);
726 return ops;
727 };
728
Makoto Onuki2206af32017-11-21 16:25:35 -0800729 callStart(instance);
730
731 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
732 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
733 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_3, PACKAGE_3));
734
735 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1));
736 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
737 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_3, PACKAGE_3));
738 }
739
740 private void assertNoCallbacks(Listener l) throws Exception {
741 waitUntilMainHandlerDrain();
742 verify(l, times(0)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800743 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
744 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800745
746 verify(l, times(0)).unblockAllUnrestrictedAlarms();
747 verify(l, times(0)).unblockAlarmsForUid(anyInt());
748 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
749 reset(l);
750 }
751
752 @Test
753 public void testPowerSaveListener() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800754 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -0800755 callStart(instance);
756
Makoto Onuki4ac1cf82018-09-05 13:45:40 -0700757 Listener l = mock(Listener.class);
Makoto Onuki2206af32017-11-21 16:25:35 -0800758 instance.addListener(l);
759
760 // Power save on.
761 mPowerSaveMode = true;
762 mPowerSaveObserver.accept(getPowerSaveState());
763
764 waitUntilMainHandlerDrain();
765 verify(l, times(1)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800766 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
767 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800768
769 verify(l, times(0)).unblockAllUnrestrictedAlarms();
770 verify(l, times(0)).unblockAlarmsForUid(anyInt());
771 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
772 reset(l);
773
774 // Power save off.
775 mPowerSaveMode = false;
776 mPowerSaveObserver.accept(getPowerSaveState());
777
778 waitUntilMainHandlerDrain();
779 verify(l, times(1)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800780 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
781 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800782
783 verify(l, times(1)).unblockAllUnrestrictedAlarms();
784 verify(l, times(0)).unblockAlarmsForUid(anyInt());
785 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
786 reset(l);
787
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800788 // Updating to the same state should not fire listener
789 mPowerSaveMode = false;
Makoto Onuki2206af32017-11-21 16:25:35 -0800790 mPowerSaveObserver.accept(getPowerSaveState());
791
792 assertNoCallbacks(l);
793 }
794
795 @Test
796 public void testAllListeners() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800797 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -0800798 callStart(instance);
799
Makoto Onuki4ac1cf82018-09-05 13:45:40 -0700800 Listener l = mock(Listener.class);
Makoto Onuki2206af32017-11-21 16:25:35 -0800801 instance.addListener(l);
802
803 // -------------------------------------------------------------------------
804 // Test with apppops.
805
806 setAppOps(UID_10_2, PACKAGE_2, true);
807
808 waitUntilMainHandlerDrain();
809 verify(l, times(0)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800810 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
811 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800812
813 verify(l, times(0)).unblockAllUnrestrictedAlarms();
814 verify(l, times(0)).unblockAlarmsForUid(anyInt());
815 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
816 reset(l);
817
818 setAppOps(UID_10_2, PACKAGE_2, false);
819
820 waitUntilMainHandlerDrain();
821 verify(l, times(0)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800822 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
823 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800824
825 verify(l, times(0)).unblockAllUnrestrictedAlarms();
826 verify(l, times(0)).unblockAlarmsForUid(anyInt());
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800827 verify(l, times(1)).unblockAlarmsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
Makoto Onuki2206af32017-11-21 16:25:35 -0800828 reset(l);
829
830 setAppOps(UID_10_2, PACKAGE_2, false);
831
832 verify(l, times(0)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800833 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
834 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800835
836 verify(l, times(0)).unblockAllUnrestrictedAlarms();
837 verify(l, times(0)).unblockAlarmsForUid(anyInt());
838 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
839
840 // Unrestrict while battery saver is on. Shouldn't fire.
841 mPowerSaveMode = true;
842 mPowerSaveObserver.accept(getPowerSaveState());
843
844 // Note toggling appops while BS is on will suppress unblockAlarmsForUidPackage().
845 setAppOps(UID_10_2, PACKAGE_2, true);
846
847 waitUntilMainHandlerDrain();
848 verify(l, times(1)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800849 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
850 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800851
852 verify(l, times(0)).unblockAllUnrestrictedAlarms();
853 verify(l, times(0)).unblockAlarmsForUid(anyInt());
854 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
855 reset(l);
856
857 // Battery saver off.
858 mPowerSaveMode = false;
859 mPowerSaveObserver.accept(getPowerSaveState());
860
861 waitUntilMainHandlerDrain();
862 verify(l, times(1)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800863 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
864 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800865
866 verify(l, times(1)).unblockAllUnrestrictedAlarms();
867 verify(l, times(0)).unblockAlarmsForUid(anyInt());
868 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
869 reset(l);
870
871 // -------------------------------------------------------------------------
872 // Tests with system/user/temp whitelist.
873
Suprabh Shukla5bf49812018-05-24 18:38:50 -0700874 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {});
Makoto Onuki2206af32017-11-21 16:25:35 -0800875
876 waitUntilMainHandlerDrain();
877 verify(l, times(1)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800878 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
879 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800880
881 verify(l, times(0)).unblockAllUnrestrictedAlarms();
882 verify(l, times(0)).unblockAlarmsForUid(anyInt());
883 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
884 reset(l);
885
Suprabh Shukla5bf49812018-05-24 18:38:50 -0700886 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
Makoto Onuki2206af32017-11-21 16:25:35 -0800887
888 waitUntilMainHandlerDrain();
889 verify(l, times(1)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800890 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
891 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800892
893 verify(l, times(1)).unblockAllUnrestrictedAlarms();
894 verify(l, times(0)).unblockAlarmsForUid(anyInt());
895 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
896 reset(l);
897
898 // Update temp whitelist.
Suprabh Shukla5bf49812018-05-24 18:38:50 -0700899 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {},
900 new int[] {UID_1, UID_3});
Makoto Onuki2206af32017-11-21 16:25:35 -0800901
902 waitUntilMainHandlerDrain();
903 verify(l, times(1)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800904 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
905 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800906
907 verify(l, times(0)).unblockAllUnrestrictedAlarms();
908 verify(l, times(0)).unblockAlarmsForUid(anyInt());
909 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
910 reset(l);
911
Suprabh Shukla5bf49812018-05-24 18:38:50 -0700912 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3});
Makoto Onuki2206af32017-11-21 16:25:35 -0800913
914 waitUntilMainHandlerDrain();
915 verify(l, times(1)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800916 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
917 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800918
919 verify(l, times(0)).unblockAllUnrestrictedAlarms();
920 verify(l, times(0)).unblockAlarmsForUid(anyInt());
921 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
922 reset(l);
923
924 // Do the same thing with battery saver on. (Currently same callbacks are called.)
925 mPowerSaveMode = true;
926 mPowerSaveObserver.accept(getPowerSaveState());
927
Makoto Onukieb898f12018-01-23 15:26:27 -0800928 waitUntilMainHandlerDrain();
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800929 verify(l, times(1)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800930 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
931 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800932
933 verify(l, times(0)).unblockAllUnrestrictedAlarms();
934 verify(l, times(0)).unblockAlarmsForUid(anyInt());
935 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
936 reset(l);
937
Suprabh Shukla5bf49812018-05-24 18:38:50 -0700938 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {});
Makoto Onuki2206af32017-11-21 16:25:35 -0800939
940 waitUntilMainHandlerDrain();
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800941 // Called once for updating all whitelist and once for updating temp whitelist
942 verify(l, times(2)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800943 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
944 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800945
946 verify(l, times(0)).unblockAllUnrestrictedAlarms();
947 verify(l, times(0)).unblockAlarmsForUid(anyInt());
948 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
949 reset(l);
950
Suprabh Shukla5bf49812018-05-24 18:38:50 -0700951 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
Makoto Onuki2206af32017-11-21 16:25:35 -0800952
953 waitUntilMainHandlerDrain();
954 verify(l, times(1)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800955 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
956 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800957
958 verify(l, times(1)).unblockAllUnrestrictedAlarms();
959 verify(l, times(0)).unblockAlarmsForUid(anyInt());
960 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
961 reset(l);
962
963 // Update temp whitelist.
Suprabh Shukla5bf49812018-05-24 18:38:50 -0700964 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {},
965 new int[] {UID_1, UID_3});
Makoto Onuki2206af32017-11-21 16:25:35 -0800966
967 waitUntilMainHandlerDrain();
968 verify(l, times(1)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800969 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
970 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800971
972 verify(l, times(0)).unblockAllUnrestrictedAlarms();
973 verify(l, times(0)).unblockAlarmsForUid(anyInt());
974 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
975 reset(l);
976
Suprabh Shukla5bf49812018-05-24 18:38:50 -0700977 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3});
Makoto Onuki2206af32017-11-21 16:25:35 -0800978
979 waitUntilMainHandlerDrain();
980 verify(l, times(1)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -0800981 verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
982 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -0800983
984 verify(l, times(0)).unblockAllUnrestrictedAlarms();
985 verify(l, times(0)).unblockAlarmsForUid(anyInt());
986 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
987 reset(l);
988
989
990 // -------------------------------------------------------------------------
991 // Tests with proc state changes.
992
993 // With battery save.
994 mPowerSaveMode = true;
995 mPowerSaveObserver.accept(getPowerSaveState());
996
997 mIUidObserver.onUidActive(UID_10_1);
998
999 waitUntilMainHandlerDrain();
1000 verify(l, times(0)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -08001001 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1002 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -08001003
1004 verify(l, times(0)).unblockAllUnrestrictedAlarms();
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001005 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001006 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1007 reset(l);
1008
1009 mIUidObserver.onUidGone(UID_10_1, true);
1010
1011 waitUntilMainHandlerDrain();
1012 verify(l, times(0)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -08001013 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1014 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -08001015
1016 verify(l, times(0)).unblockAllUnrestrictedAlarms();
1017 verify(l, times(0)).unblockAlarmsForUid(anyInt());
1018 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1019 reset(l);
1020
1021 mIUidObserver.onUidActive(UID_10_1);
1022
1023 waitUntilMainHandlerDrain();
1024 verify(l, times(0)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -08001025 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1026 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -08001027
1028 verify(l, times(0)).unblockAllUnrestrictedAlarms();
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001029 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001030 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1031 reset(l);
1032
1033 mIUidObserver.onUidIdle(UID_10_1, true);
1034
1035 waitUntilMainHandlerDrain();
1036 verify(l, times(0)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -08001037 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1038 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -08001039
1040 verify(l, times(0)).unblockAllUnrestrictedAlarms();
1041 verify(l, times(0)).unblockAlarmsForUid(anyInt());
1042 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1043 reset(l);
1044
1045 // Without battery save.
1046 mPowerSaveMode = false;
1047 mPowerSaveObserver.accept(getPowerSaveState());
1048
Makoto Onukieb898f12018-01-23 15:26:27 -08001049 waitUntilMainHandlerDrain();
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001050 verify(l, times(1)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -08001051 verify(l, times(0)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1052 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001053
1054 verify(l, times(1)).unblockAllUnrestrictedAlarms();
1055 verify(l, times(0)).unblockAlarmsForUid(anyInt());
1056 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1057 reset(l);
1058
Makoto Onuki2206af32017-11-21 16:25:35 -08001059 mIUidObserver.onUidActive(UID_10_1);
1060
1061 waitUntilMainHandlerDrain();
1062 verify(l, times(0)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -08001063 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1064 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -08001065
1066 verify(l, times(0)).unblockAllUnrestrictedAlarms();
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001067 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001068 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1069 reset(l);
1070
1071 mIUidObserver.onUidGone(UID_10_1, true);
1072
1073 waitUntilMainHandlerDrain();
1074 verify(l, times(0)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -08001075 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1076 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -08001077
1078 verify(l, times(0)).unblockAllUnrestrictedAlarms();
1079 verify(l, times(0)).unblockAlarmsForUid(anyInt());
1080 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1081 reset(l);
1082
1083 mIUidObserver.onUidActive(UID_10_1);
1084
1085 waitUntilMainHandlerDrain();
1086 verify(l, times(0)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -08001087 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1088 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -08001089
1090 verify(l, times(0)).unblockAllUnrestrictedAlarms();
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001091 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001092 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1093 reset(l);
1094
1095 mIUidObserver.onUidIdle(UID_10_1, true);
1096
1097 waitUntilMainHandlerDrain();
1098 verify(l, times(0)).updateAllJobs();
Christopher Tate20afddd2018-02-28 15:19:19 -08001099 verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
1100 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
Makoto Onuki2206af32017-11-21 16:25:35 -08001101
1102 verify(l, times(0)).unblockAllUnrestrictedAlarms();
1103 verify(l, times(0)).unblockAlarmsForUid(anyInt());
1104 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1105 reset(l);
1106 }
1107
1108 @Test
1109 public void testUserRemoved() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -08001110 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -08001111 callStart(instance);
1112
1113 mIUidObserver.onUidActive(UID_1);
1114 mIUidObserver.onUidActive(UID_10_1);
1115
Makoto Onuki4d298b52018-02-05 10:54:58 -08001116 waitUntilMainHandlerDrain();
1117
Makoto Onuki2206af32017-11-21 16:25:35 -08001118 setAppOps(UID_2, PACKAGE_2, true);
1119 setAppOps(UID_10_2, PACKAGE_2, true);
1120
Makoto Onukiadb50d82018-01-29 16:20:30 -08001121 assertTrue(instance.isUidActive(UID_1));
1122 assertTrue(instance.isUidActive(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001123
1124 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
1125 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
1126
1127 final Intent intent = new Intent(Intent.ACTION_USER_REMOVED);
1128 intent.putExtra(Intent.EXTRA_USER_HANDLE, 10);
1129 mReceiver.onReceive(mMockContext, intent);
1130
1131 waitUntilMainHandlerDrain();
1132
Makoto Onukiadb50d82018-01-29 16:20:30 -08001133 assertTrue(instance.isUidActive(UID_1));
1134 assertFalse(instance.isUidActive(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001135
1136 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
1137 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
1138 }
1139
Nancy Zheng525aaa12018-01-12 11:45:37 -08001140 @Test
1141 public void testSmallBatteryAndPluggedIn() throws Exception {
1142 // This is a small battery device
1143 mIsSmallBatteryDevice = true;
1144
Makoto Onukie4918212018-02-06 11:30:15 -08001145 final AppStateTrackerTestable instance = newInstance();
Nancy Zheng525aaa12018-01-12 11:45:37 -08001146 callStart(instance);
1147 assertFalse(instance.isForceAllAppsStandbyEnabled());
1148
1149 // Setting/experiment for all app standby for small battery is enabled
Makoto Onukieb898f12018-01-23 15:26:27 -08001150 mGlobalSettings.put(Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 1);
Nancy Zheng525aaa12018-01-12 11:45:37 -08001151 instance.mFlagsObserver.onChange(true,
1152 Global.getUriFor(Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED));
1153 assertTrue(instance.isForceAllAppsStandbyEnabled());
1154
1155 // When battery is plugged in, force app standby is disabled
1156 Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
1157 intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB);
1158 mReceiver.onReceive(mMockContext, intent);
1159 assertFalse(instance.isForceAllAppsStandbyEnabled());
1160
1161 // When battery stops plugged in, force app standby is enabled
1162 mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED));
1163 assertTrue(instance.isForceAllAppsStandbyEnabled());
1164 }
1165
1166 @Test
1167 public void testNotSmallBatteryAndPluggedIn() throws Exception {
1168 // Not a small battery device, so plugged in status should not affect forced app standby
1169 mIsSmallBatteryDevice = false;
1170
Makoto Onukie4918212018-02-06 11:30:15 -08001171 final AppStateTrackerTestable instance = newInstance();
Nancy Zheng525aaa12018-01-12 11:45:37 -08001172 callStart(instance);
1173 assertFalse(instance.isForceAllAppsStandbyEnabled());
1174
1175 mPowerSaveMode = true;
1176 mPowerSaveObserver.accept(getPowerSaveState());
1177 assertTrue(instance.isForceAllAppsStandbyEnabled());
1178
1179 // When battery is plugged in, force app standby is unaffected
1180 Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
1181 intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB);
1182 mReceiver.onReceive(mMockContext, intent);
1183 assertTrue(instance.isForceAllAppsStandbyEnabled());
1184
1185 // When battery stops plugged in, force app standby is unaffected
1186 mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED));
1187 assertTrue(instance.isForceAllAppsStandbyEnabled());
1188 }
1189
Makoto Onuki2206af32017-11-21 16:25:35 -08001190 static int[] array(int... appIds) {
1191 Arrays.sort(appIds);
1192 return appIds;
1193 }
1194
1195 private final Random mRandom = new Random();
1196
1197 int[] makeRandomArray() {
1198 final ArrayList<Integer> list = new ArrayList<>();
1199 for (int i = 0; i < 5; i++) {
1200 if (mRandom.nextDouble() < 0.5) {
1201 list.add(i);
1202 }
1203 }
1204 return Arrays.stream(list.toArray(new Integer[list.size()]))
1205 .mapToInt(Integer::intValue).toArray();
1206 }
1207
1208 static boolean isAnyAppIdUnwhitelistedSlow(int[] prevArray, int[] newArray) {
1209 Arrays.sort(newArray); // Just in case...
1210 for (int p : prevArray) {
1211 if (Arrays.binarySearch(newArray, p) < 0) {
1212 return true;
1213 }
1214 }
1215 return false;
1216 }
1217
1218 private void checkAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray, boolean expected) {
1219 assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
Makoto Onukie4918212018-02-06 11:30:15 -08001220 expected, AppStateTracker.isAnyAppIdUnwhitelisted(prevArray, newArray));
Makoto Onuki2206af32017-11-21 16:25:35 -08001221
1222 // Also test isAnyAppIdUnwhitelistedSlow.
1223 assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
1224 expected, isAnyAppIdUnwhitelistedSlow(prevArray, newArray));
1225 }
1226
1227 @Test
1228 public void isAnyAppIdUnwhitelisted() {
1229 checkAnyAppIdUnwhitelisted(array(), array(), false);
1230
1231 checkAnyAppIdUnwhitelisted(array(1), array(), true);
1232 checkAnyAppIdUnwhitelisted(array(1), array(1), false);
1233 checkAnyAppIdUnwhitelisted(array(1), array(0, 1), false);
1234 checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false);
1235 checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false);
1236
1237 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(), true);
1238 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2), true);
1239 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2, 10), false);
1240 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(2, 10), true);
1241 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 1, 2, 4, 3, 10), false);
1242 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 0, 1, 2, 10), false);
1243
1244 // Random test
1245 int trueCount = 0;
1246 final int count = 10000;
1247 for (int i = 0; i < count; i++) {
1248 final int[] array1 = makeRandomArray();
1249 final int[] array2 = makeRandomArray();
1250
1251 final boolean expected = isAnyAppIdUnwhitelistedSlow(array1, array2);
Makoto Onukie4918212018-02-06 11:30:15 -08001252 final boolean actual = AppStateTracker.isAnyAppIdUnwhitelisted(array1, array2);
Makoto Onuki2206af32017-11-21 16:25:35 -08001253
1254 assertEquals("Input: " + Arrays.toString(array1) + " " + Arrays.toString(array2),
1255 expected, actual);
1256 if (expected) {
1257 trueCount++;
1258 }
1259 }
1260
1261 // Make sure makeRandomArray() didn't generate all same arrays by accident.
1262 assertTrue(trueCount > 0);
1263 assertTrue(trueCount < count);
1264 }
1265}