blob: 796d36453870c5fd191228516c85c2c6b1196a4d [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;
28import static org.mockito.ArgumentMatchers.anyInt;
29import static org.mockito.ArgumentMatchers.anyString;
30import static org.mockito.ArgumentMatchers.eq;
31import static org.mockito.ArgumentMatchers.isNull;
32import static org.mockito.Mockito.mock;
33import static org.mockito.Mockito.reset;
34import static org.mockito.Mockito.times;
35import static org.mockito.Mockito.verify;
36import static org.mockito.Mockito.when;
37
38import android.app.ActivityManager;
Makoto Onukie4918212018-02-06 11:30:15 -080039import android.app.ActivityManagerInternal;
Makoto Onuki2206af32017-11-21 16:25:35 -080040import android.app.AppOpsManager;
41import android.app.AppOpsManager.OpEntry;
42import android.app.AppOpsManager.PackageOps;
43import android.app.IActivityManager;
44import android.app.IUidObserver;
Makoto Onukieb898f12018-01-23 15:26:27 -080045import android.app.usage.UsageStatsManager;
46import android.app.usage.UsageStatsManagerInternal;
47import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
Makoto Onuki2206af32017-11-21 16:25:35 -080048import android.content.BroadcastReceiver;
49import android.content.Context;
50import android.content.Intent;
51import android.content.IntentFilter;
Nancy Zheng525aaa12018-01-12 11:45:37 -080052import android.os.BatteryManager;
Makoto Onuki2206af32017-11-21 16:25:35 -080053import android.os.Handler;
54import android.os.Looper;
55import android.os.PowerManager.ServiceType;
56import android.os.PowerManagerInternal;
57import android.os.PowerSaveState;
58import android.os.Process;
59import android.os.RemoteException;
60import android.os.UserHandle;
Nancy Zheng525aaa12018-01-12 11:45:37 -080061import android.provider.Settings.Global;
Makoto Onuki2206af32017-11-21 16:25:35 -080062import android.support.test.filters.SmallTest;
63import android.support.test.runner.AndroidJUnit4;
Nancy Zhenga18c1f12018-01-18 16:29:59 -080064import android.test.mock.MockContentResolver;
Makoto Onuki2206af32017-11-21 16:25:35 -080065import android.util.ArraySet;
66import android.util.Pair;
67
68import com.android.internal.app.IAppOpsCallback;
69import com.android.internal.app.IAppOpsService;
Makoto Onukie4918212018-02-06 11:30:15 -080070import com.android.server.AppStateTracker.Listener;
Makoto Onuki2206af32017-11-21 16:25:35 -080071
72import org.junit.Before;
73import org.junit.Test;
74import org.junit.runner.RunWith;
75import org.mockito.ArgumentCaptor;
76import org.mockito.Mock;
77import org.mockito.MockitoAnnotations;
78
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 Onukiadb50d82018-01-29 16:20:30 -080088/**
Makoto Onukie4918212018-02-06 11:30:15 -080089 * Tests for {@link AppStateTracker}
Makoto Onukiadb50d82018-01-29 16:20:30 -080090 *
91 * Run with:
Makoto Onukie4918212018-02-06 11:30:15 -080092 atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java
Makoto Onukiadb50d82018-01-29 16:20:30 -080093 */
Makoto Onuki2206af32017-11-21 16:25:35 -080094@SmallTest
95@RunWith(AndroidJUnit4.class)
Makoto Onukie4918212018-02-06 11:30:15 -080096public class AppStateTrackerTest {
Makoto Onuki2206af32017-11-21 16:25:35 -080097
Makoto Onukie4918212018-02-06 11:30:15 -080098 private class AppStateTrackerTestable extends AppStateTracker {
99 AppStateTrackerTestable() {
Makoto Onuki2206af32017-11-21 16:25:35 -0800100 super(mMockContext, Looper.getMainLooper());
101 }
102
103 @Override
104 AppOpsManager injectAppOpsManager() {
105 return mMockAppOpsManager;
106 }
107
108 @Override
109 IAppOpsService injectIAppOpsService() {
110 return mMockIAppOpsService;
111 }
112
113 @Override
114 IActivityManager injectIActivityManager() {
115 return mMockIActivityManager;
116 }
117
118 @Override
Makoto Onukie4918212018-02-06 11:30:15 -0800119 ActivityManagerInternal injectActivityManagerInternal() {
120 return mMockIActivityManagerInternal;
121 }
122
123 @Override
Makoto Onuki2206af32017-11-21 16:25:35 -0800124 PowerManagerInternal injectPowerManagerInternal() {
125 return mMockPowerManagerInternal;
126 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800127
128 @Override
Makoto Onukieb898f12018-01-23 15:26:27 -0800129 UsageStatsManagerInternal injectUsageStatsManagerInternal() {
130 return mMockUsageStatsManagerInternal;
131 }
132
133 @Override
134 int injectGetGlobalSettingInt(String key, int def) {
135 Integer val = mGlobalSettings.get(key);
136
137 return (val == null) ? def : val;
138 }
139
140 @Override
Nancy Zheng525aaa12018-01-12 11:45:37 -0800141 boolean isSmallBatteryDevice() { return mIsSmallBatteryDevice; };
Makoto Onuki2206af32017-11-21 16:25:35 -0800142 }
143
144 private static final int UID_1 = Process.FIRST_APPLICATION_UID + 1;
145 private static final int UID_2 = Process.FIRST_APPLICATION_UID + 2;
146 private static final int UID_3 = Process.FIRST_APPLICATION_UID + 3;
147 private static final int UID_10_1 = UserHandle.getUid(10, UID_1);
148 private static final int UID_10_2 = UserHandle.getUid(10, UID_2);
149 private static final int UID_10_3 = UserHandle.getUid(10, UID_3);
150 private static final String PACKAGE_1 = "package1";
151 private static final String PACKAGE_2 = "package2";
152 private static final String PACKAGE_3 = "package3";
153 private static final String PACKAGE_SYSTEM = "android";
154
155 private Handler mMainHandler;
156
157 @Mock
158 private Context mMockContext;
159
160 @Mock
161 private IActivityManager mMockIActivityManager;
162
163 @Mock
Makoto Onukie4918212018-02-06 11:30:15 -0800164 private ActivityManagerInternal mMockIActivityManagerInternal;
165
166 @Mock
Makoto Onuki2206af32017-11-21 16:25:35 -0800167 private AppOpsManager mMockAppOpsManager;
168
169 @Mock
170 private IAppOpsService mMockIAppOpsService;
171
172 @Mock
173 private PowerManagerInternal mMockPowerManagerInternal;
174
Makoto Onukieb898f12018-01-23 15:26:27 -0800175 @Mock
176 private UsageStatsManagerInternal mMockUsageStatsManagerInternal;
177
178 private MockContentResolver mMockContentResolver;
179
Makoto Onuki2206af32017-11-21 16:25:35 -0800180 private IUidObserver mIUidObserver;
181 private IAppOpsCallback.Stub mAppOpsCallback;
182 private Consumer<PowerSaveState> mPowerSaveObserver;
183 private BroadcastReceiver mReceiver;
Makoto Onukieb898f12018-01-23 15:26:27 -0800184 private AppIdleStateChangeListener mAppIdleStateChangeListener;
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800185
Makoto Onuki2206af32017-11-21 16:25:35 -0800186 private boolean mPowerSaveMode;
Nancy Zheng525aaa12018-01-12 11:45:37 -0800187 private boolean mIsSmallBatteryDevice;
Makoto Onuki2206af32017-11-21 16:25:35 -0800188
189 private final ArraySet<Pair<Integer, String>> mRestrictedPackages = new ArraySet();
190
Makoto Onukieb898f12018-01-23 15:26:27 -0800191 private final HashMap<String, Integer> mGlobalSettings = new HashMap<>();
192
Makoto Onuki2206af32017-11-21 16:25:35 -0800193 @Before
194 public void setUp() {
195 mMainHandler = new Handler(Looper.getMainLooper());
196 }
197
198 private void waitUntilMainHandlerDrain() throws Exception {
199 final CountDownLatch l = new CountDownLatch(1);
200 mMainHandler.post(() -> {
201 l.countDown();
202 });
203 assertTrue(l.await(5, TimeUnit.SECONDS));
204 }
205
206 private PowerSaveState getPowerSaveState() {
207 return new PowerSaveState.Builder().setBatterySaverEnabled(mPowerSaveMode).build();
208 }
209
Makoto Onukie4918212018-02-06 11:30:15 -0800210 private AppStateTrackerTestable newInstance() throws Exception {
Makoto Onuki2206af32017-11-21 16:25:35 -0800211 MockitoAnnotations.initMocks(this);
212
213 when(mMockIAppOpsService.checkOperation(eq(TARGET_OP), anyInt(), anyString()))
214 .thenAnswer(inv -> {
215 return mRestrictedPackages.indexOf(
216 Pair.create(inv.getArgument(1), inv.getArgument(2))) >= 0 ?
217 AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED;
218 });
219
Makoto Onukie4918212018-02-06 11:30:15 -0800220 final AppStateTrackerTestable instance = new AppStateTrackerTestable();
Makoto Onuki2206af32017-11-21 16:25:35 -0800221
222 return instance;
223 }
224
Makoto Onukie4918212018-02-06 11:30:15 -0800225 private void callStart(AppStateTrackerTestable instance) throws RemoteException {
Makoto Onuki12391f22018-01-18 21:44:28 +0000226
Makoto Onuki2206af32017-11-21 16:25:35 -0800227 // Set up functions that start() calls.
228 when(mMockPowerManagerInternal.getLowPowerState(eq(ServiceType.FORCE_ALL_APPS_STANDBY)))
229 .thenAnswer(inv -> getPowerSaveState());
230 when(mMockAppOpsManager.getPackagesForOps(
231 any(int[].class)
Makoto Onuki12391f22018-01-18 21:44:28 +0000232 )).thenAnswer(inv -> new ArrayList<AppOpsManager.PackageOps>());
Makoto Onuki2206af32017-11-21 16:25:35 -0800233
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800234 mMockContentResolver = new MockContentResolver();
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800235 when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800236
Makoto Onuki2206af32017-11-21 16:25:35 -0800237 // Call start.
Makoto Onukie4918212018-02-06 11:30:15 -0800238 instance.onSystemServicesReady();
Makoto Onuki2206af32017-11-21 16:25:35 -0800239
240 // Capture the listeners.
241 ArgumentCaptor<IUidObserver> uidObserverArgumentCaptor =
242 ArgumentCaptor.forClass(IUidObserver.class);
243 ArgumentCaptor<IAppOpsCallback.Stub> appOpsCallbackCaptor =
244 ArgumentCaptor.forClass(IAppOpsCallback.Stub.class);
245 ArgumentCaptor<Consumer<PowerSaveState>> powerSaveObserverCaptor =
246 ArgumentCaptor.forClass(Consumer.class);
247 ArgumentCaptor<BroadcastReceiver> receiverCaptor =
248 ArgumentCaptor.forClass(BroadcastReceiver.class);
Makoto Onukieb898f12018-01-23 15:26:27 -0800249 ArgumentCaptor<AppIdleStateChangeListener> appIdleStateChangeListenerCaptor =
250 ArgumentCaptor.forClass(AppIdleStateChangeListener.class);
Makoto Onuki2206af32017-11-21 16:25:35 -0800251
252 verify(mMockIActivityManager).registerUidObserver(
253 uidObserverArgumentCaptor.capture(),
254 eq(ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_IDLE
Makoto Onukiadb50d82018-01-29 16:20:30 -0800255 | ActivityManager.UID_OBSERVER_ACTIVE
256 | ActivityManager.UID_OBSERVER_PROCSTATE),
Makoto Onuki2206af32017-11-21 16:25:35 -0800257 eq(ActivityManager.PROCESS_STATE_UNKNOWN),
258 isNull());
259 verify(mMockIAppOpsService).startWatchingMode(
260 eq(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND),
261 isNull(),
262 appOpsCallbackCaptor.capture());
263 verify(mMockPowerManagerInternal).registerLowPowerModeObserver(
264 eq(ServiceType.FORCE_ALL_APPS_STANDBY),
265 powerSaveObserverCaptor.capture());
Makoto Onuki12391f22018-01-18 21:44:28 +0000266
Makoto Onuki2206af32017-11-21 16:25:35 -0800267 verify(mMockContext).registerReceiver(
268 receiverCaptor.capture(), any(IntentFilter.class));
Makoto Onukieb898f12018-01-23 15:26:27 -0800269 verify(mMockUsageStatsManagerInternal).addAppIdleStateChangeListener(
270 appIdleStateChangeListenerCaptor.capture());
Makoto Onuki2206af32017-11-21 16:25:35 -0800271
272 mIUidObserver = uidObserverArgumentCaptor.getValue();
273 mAppOpsCallback = appOpsCallbackCaptor.getValue();
274 mPowerSaveObserver = powerSaveObserverCaptor.getValue();
275 mReceiver = receiverCaptor.getValue();
Makoto Onukieb898f12018-01-23 15:26:27 -0800276 mAppIdleStateChangeListener = appIdleStateChangeListenerCaptor.getValue();
Makoto Onuki2206af32017-11-21 16:25:35 -0800277
278 assertNotNull(mIUidObserver);
279 assertNotNull(mAppOpsCallback);
280 assertNotNull(mPowerSaveObserver);
281 assertNotNull(mReceiver);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800282 assertNotNull(instance.mFlagsObserver);
Makoto Onuki2206af32017-11-21 16:25:35 -0800283 }
284
285 private void setAppOps(int uid, String packageName, boolean restrict) throws RemoteException {
286 final Pair p = Pair.create(uid, packageName);
287 if (restrict) {
288 mRestrictedPackages.add(p);
289 } else {
290 mRestrictedPackages.remove(p);
291 }
292 if (mAppOpsCallback != null) {
293 mAppOpsCallback.opChanged(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName);
294 }
295 }
296
297 private static final int NONE = 0;
298 private static final int ALARMS_ONLY = 1 << 0;
299 private static final int JOBS_ONLY = 1 << 1;
300 private static final int JOBS_AND_ALARMS = ALARMS_ONLY | JOBS_ONLY;
301
Makoto Onukie4918212018-02-06 11:30:15 -0800302 private void areRestricted(AppStateTrackerTestable instance, int uid, String packageName,
Makoto Onuki15407842018-01-19 14:23:11 -0800303 int restrictionTypes, boolean exemptFromBatterySaver) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800304 assertEquals(((restrictionTypes & JOBS_ONLY) != 0),
Makoto Onuki15407842018-01-19 14:23:11 -0800305 instance.areJobsRestricted(uid, packageName, exemptFromBatterySaver));
Makoto Onuki2206af32017-11-21 16:25:35 -0800306 assertEquals(((restrictionTypes & ALARMS_ONLY) != 0),
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800307 instance.areAlarmsRestricted(uid, packageName, exemptFromBatterySaver));
Makoto Onuki2206af32017-11-21 16:25:35 -0800308 }
309
Makoto Onukie4918212018-02-06 11:30:15 -0800310 private void areRestricted(AppStateTrackerTestable instance, int uid, String packageName,
Makoto Onuki15407842018-01-19 14:23:11 -0800311 int restrictionTypes) {
312 areRestricted(instance, uid, packageName, restrictionTypes,
313 /*exemptFromBatterySaver=*/ false);
314 }
315
Makoto Onukie4918212018-02-06 11:30:15 -0800316 private void areRestrictedWithExemption(AppStateTrackerTestable instance,
Makoto Onukieb898f12018-01-23 15:26:27 -0800317 int uid, String packageName, int restrictionTypes) {
318 areRestricted(instance, uid, packageName, restrictionTypes,
319 /*exemptFromBatterySaver=*/ true);
320 }
321
Makoto Onuki2206af32017-11-21 16:25:35 -0800322 @Test
323 public void testAll() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800324 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -0800325 callStart(instance);
326
327 assertFalse(instance.isForceAllAppsStandbyEnabled());
328 areRestricted(instance, UID_1, PACKAGE_1, NONE);
329 areRestricted(instance, UID_2, PACKAGE_2, NONE);
330 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
331
Makoto Onukieb898f12018-01-23 15:26:27 -0800332 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE);
333 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
334 areRestrictedWithExemption(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
335
Makoto Onuki2206af32017-11-21 16:25:35 -0800336 mPowerSaveMode = true;
337 mPowerSaveObserver.accept(getPowerSaveState());
338
339 assertTrue(instance.isForceAllAppsStandbyEnabled());
340
341 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
342 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
343 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
344
Makoto Onukieb898f12018-01-23 15:26:27 -0800345 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE);
346 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
347 areRestrictedWithExemption(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
348
Makoto Onuki2206af32017-11-21 16:25:35 -0800349 // Toggle the foreground state.
350 mPowerSaveMode = true;
351 mPowerSaveObserver.accept(getPowerSaveState());
352
Makoto Onukiadb50d82018-01-29 16:20:30 -0800353 assertFalse(instance.isUidActive(UID_1));
354 assertFalse(instance.isUidActive(UID_2));
355 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
Makoto Onuki2206af32017-11-21 16:25:35 -0800356
357 mIUidObserver.onUidActive(UID_1);
Makoto Onuki4d298b52018-02-05 10:54:58 -0800358 waitUntilMainHandlerDrain();
Makoto Onuki2206af32017-11-21 16:25:35 -0800359 areRestricted(instance, UID_1, PACKAGE_1, NONE);
360 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
361 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
Makoto Onukiadb50d82018-01-29 16:20:30 -0800362 assertTrue(instance.isUidActive(UID_1));
363 assertFalse(instance.isUidActive(UID_2));
Makoto Onuki2206af32017-11-21 16:25:35 -0800364
365 mIUidObserver.onUidGone(UID_1, /*disable=*/ false);
Makoto Onuki4d298b52018-02-05 10:54:58 -0800366 waitUntilMainHandlerDrain();
Makoto Onuki2206af32017-11-21 16:25:35 -0800367 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
368 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
369 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
Makoto Onukiadb50d82018-01-29 16:20:30 -0800370 assertFalse(instance.isUidActive(UID_1));
371 assertFalse(instance.isUidActive(UID_2));
Makoto Onuki2206af32017-11-21 16:25:35 -0800372
373 mIUidObserver.onUidActive(UID_1);
Makoto Onuki4d298b52018-02-05 10:54:58 -0800374 waitUntilMainHandlerDrain();
Makoto Onuki2206af32017-11-21 16:25:35 -0800375 areRestricted(instance, UID_1, PACKAGE_1, NONE);
376 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
377 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
378
379 mIUidObserver.onUidIdle(UID_1, /*disable=*/ false);
Makoto Onuki4d298b52018-02-05 10:54:58 -0800380 waitUntilMainHandlerDrain();
Makoto Onuki2206af32017-11-21 16:25:35 -0800381 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
382 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
383 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
Makoto Onukiadb50d82018-01-29 16:20:30 -0800384 assertFalse(instance.isUidActive(UID_1));
385 assertFalse(instance.isUidActive(UID_2));
Makoto Onuki2206af32017-11-21 16:25:35 -0800386
387 // Toggle the app ops.
388 mPowerSaveMode = false;
389 mPowerSaveObserver.accept(getPowerSaveState());
390
391 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
392 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1));
393 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
394 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
395
396 areRestricted(instance, UID_1, PACKAGE_1, NONE);
397 areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
398 areRestricted(instance, UID_2, PACKAGE_2, NONE);
399 areRestricted(instance, UID_10_2, PACKAGE_2, NONE);
400 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
401
402 setAppOps(UID_1, PACKAGE_1, true);
403 setAppOps(UID_10_2, PACKAGE_2, true);
404 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
405 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1));
406 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
407 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
408
409 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
410 areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
411 areRestricted(instance, UID_2, PACKAGE_2, NONE);
412 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
413 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
414
415 // Toggle power saver, should still be the same.
416 mPowerSaveMode = true;
417 mPowerSaveObserver.accept(getPowerSaveState());
418
419 mPowerSaveMode = false;
420 mPowerSaveObserver.accept(getPowerSaveState());
421
422 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
423 areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
424 areRestricted(instance, UID_2, PACKAGE_2, NONE);
425 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
426 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
427
428 // Clear the app ops and update the whitelist.
429 setAppOps(UID_1, PACKAGE_1, false);
430 setAppOps(UID_10_2, PACKAGE_2, false);
431
432 mPowerSaveMode = true;
433 mPowerSaveObserver.accept(getPowerSaveState());
434
435 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
436 areRestricted(instance, UID_10_1, PACKAGE_1, JOBS_AND_ALARMS);
437 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
438 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
439 areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS);
440 areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
441 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
442
443 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1}, new int[] {UID_2});
444
445 areRestricted(instance, UID_1, PACKAGE_1, NONE);
446 areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
447 areRestricted(instance, UID_2, PACKAGE_2, ALARMS_ONLY);
448 areRestricted(instance, UID_10_2, PACKAGE_2, ALARMS_ONLY);
449 areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS);
450 areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
451 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
452
453 // Again, make sure toggling the global state doesn't change it.
454 mPowerSaveMode = false;
455 mPowerSaveObserver.accept(getPowerSaveState());
456
457 mPowerSaveMode = true;
458 mPowerSaveObserver.accept(getPowerSaveState());
459
460 areRestricted(instance, UID_1, PACKAGE_1, NONE);
461 areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
462 areRestricted(instance, UID_2, PACKAGE_2, ALARMS_ONLY);
463 areRestricted(instance, UID_10_2, PACKAGE_2, ALARMS_ONLY);
464 areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS);
465 areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
466 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
467
468 assertTrue(instance.isUidPowerSaveWhitelisted(UID_1));
469 assertTrue(instance.isUidPowerSaveWhitelisted(UID_10_1));
470 assertFalse(instance.isUidPowerSaveWhitelisted(UID_2));
471 assertFalse(instance.isUidPowerSaveWhitelisted(UID_10_2));
472
473 assertFalse(instance.isUidTempPowerSaveWhitelisted(UID_1));
474 assertFalse(instance.isUidTempPowerSaveWhitelisted(UID_10_1));
475 assertTrue(instance.isUidTempPowerSaveWhitelisted(UID_2));
476 assertTrue(instance.isUidTempPowerSaveWhitelisted(UID_10_2));
477 }
478
Makoto Onukieb898f12018-01-23 15:26:27 -0800479 @Test
Makoto Onukiadb50d82018-01-29 16:20:30 -0800480 public void testUidStateForeground() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800481 final AppStateTrackerTestable instance = newInstance();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800482 callStart(instance);
483
484 mIUidObserver.onUidActive(UID_1);
485
Makoto Onuki4d298b52018-02-05 10:54:58 -0800486 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800487 assertTrue(instance.isUidActive(UID_1));
488 assertFalse(instance.isUidActive(UID_2));
489 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
490
Makoto Onukie4918212018-02-06 11:30:15 -0800491 assertTrue(instance.isUidActiveSynced(UID_1));
492 assertFalse(instance.isUidActiveSynced(UID_2));
493 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
494
Makoto Onukiadb50d82018-01-29 16:20:30 -0800495 assertFalse(instance.isUidInForeground(UID_1));
496 assertFalse(instance.isUidInForeground(UID_2));
497 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
498
499
500 mIUidObserver.onUidStateChanged(UID_2,
501 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE, 0);
502
Makoto Onuki4d298b52018-02-05 10:54:58 -0800503 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800504 assertTrue(instance.isUidActive(UID_1));
505 assertFalse(instance.isUidActive(UID_2));
506 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
507
Makoto Onukie4918212018-02-06 11:30:15 -0800508 assertTrue(instance.isUidActiveSynced(UID_1));
509 assertFalse(instance.isUidActiveSynced(UID_2));
510 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
511
Makoto Onukiadb50d82018-01-29 16:20:30 -0800512 assertFalse(instance.isUidInForeground(UID_1));
513 assertTrue(instance.isUidInForeground(UID_2));
514 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
515
516
517 mIUidObserver.onUidStateChanged(UID_1,
518 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
519
Makoto Onuki4d298b52018-02-05 10:54:58 -0800520 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800521 assertTrue(instance.isUidActive(UID_1));
522 assertFalse(instance.isUidActive(UID_2));
523 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
524
525 assertTrue(instance.isUidInForeground(UID_1));
526 assertTrue(instance.isUidInForeground(UID_2));
527 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
528
529 mIUidObserver.onUidGone(UID_1, true);
530
Makoto Onuki4d298b52018-02-05 10:54:58 -0800531 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800532 assertFalse(instance.isUidActive(UID_1));
533 assertFalse(instance.isUidActive(UID_2));
534 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
535
536 assertFalse(instance.isUidInForeground(UID_1));
537 assertTrue(instance.isUidInForeground(UID_2));
538 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
539
540 mIUidObserver.onUidIdle(UID_2, true);
541
Makoto Onuki4d298b52018-02-05 10:54:58 -0800542 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800543 assertFalse(instance.isUidActive(UID_1));
544 assertFalse(instance.isUidActive(UID_2));
545 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
546
547 assertFalse(instance.isUidInForeground(UID_1));
548 assertFalse(instance.isUidInForeground(UID_2));
549 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
550
551 mIUidObserver.onUidStateChanged(UID_1,
552 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0);
553
Makoto Onuki4d298b52018-02-05 10:54:58 -0800554 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800555 assertFalse(instance.isUidActive(UID_1));
556 assertFalse(instance.isUidActive(UID_2));
557 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
558
559 assertTrue(instance.isUidInForeground(UID_1));
560 assertFalse(instance.isUidInForeground(UID_2));
561 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
562
563 mIUidObserver.onUidStateChanged(UID_1,
564 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0);
565
Makoto Onuki4d298b52018-02-05 10:54:58 -0800566 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800567 assertFalse(instance.isUidActive(UID_1));
568 assertFalse(instance.isUidActive(UID_2));
569 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
570
Makoto Onukie4918212018-02-06 11:30:15 -0800571 assertFalse(instance.isUidActiveSynced(UID_1));
572 assertFalse(instance.isUidActiveSynced(UID_2));
573 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
574
Makoto Onukiadb50d82018-01-29 16:20:30 -0800575 assertFalse(instance.isUidInForeground(UID_1));
576 assertFalse(instance.isUidInForeground(UID_2));
577 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
Makoto Onukie4918212018-02-06 11:30:15 -0800578
579 // The result from AMI.isUidActive() only affects isUidActiveSynced().
580 when(mMockIActivityManagerInternal.isUidActive(anyInt())).thenReturn(true);
581
582 assertFalse(instance.isUidActive(UID_1));
583 assertFalse(instance.isUidActive(UID_2));
584 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
585
586 assertTrue(instance.isUidActiveSynced(UID_1));
587 assertTrue(instance.isUidActiveSynced(UID_2));
588 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
589
590 assertFalse(instance.isUidInForeground(UID_1));
591 assertFalse(instance.isUidInForeground(UID_2));
592 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
593
Makoto Onukiadb50d82018-01-29 16:20:30 -0800594 }
595
596 @Test
Makoto Onukieb898f12018-01-23 15:26:27 -0800597 public void testExempt() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800598 final AppStateTrackerTestable instance = newInstance();
Makoto Onukieb898f12018-01-23 15:26:27 -0800599 callStart(instance);
600
601 assertFalse(instance.isForceAllAppsStandbyEnabled());
602 areRestricted(instance, UID_1, PACKAGE_1, NONE);
603 areRestricted(instance, UID_2, PACKAGE_2, NONE);
604 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
605
606 mPowerSaveMode = true;
607 mPowerSaveObserver.accept(getPowerSaveState());
608
609 assertTrue(instance.isForceAllAppsStandbyEnabled());
610
611 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
612 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
613 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
614 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
615
616 // Exempt package 2 on user-10.
617 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800618 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
Makoto Onukieb898f12018-01-23 15:26:27 -0800619
620 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
621 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
622 areRestricted(instance, UID_10_2, PACKAGE_2, NONE);
623
624 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE);
625 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
626 areRestrictedWithExemption(instance, UID_10_2, PACKAGE_2, NONE);
627
628 // Exempt package 1 on user-0.
629 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800630 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
Makoto Onukieb898f12018-01-23 15:26:27 -0800631
632 areRestricted(instance, UID_1, PACKAGE_1, NONE);
633 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
634 areRestricted(instance, UID_10_2, PACKAGE_2, NONE);
635
636 // Unexempt package 2 on user-10.
637 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800638 UsageStatsManager.STANDBY_BUCKET_ACTIVE, REASON_MAIN_USAGE);
Makoto Onukieb898f12018-01-23 15:26:27 -0800639
640 areRestricted(instance, UID_1, PACKAGE_1, NONE);
641 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
642 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
643
644 // Check force-app-standby.
645 // EXEMPT doesn't exempt from force-app-standby.
646 mPowerSaveMode = false;
647 mPowerSaveObserver.accept(getPowerSaveState());
648
649 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800650 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
Makoto Onukieb898f12018-01-23 15:26:27 -0800651 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 0, false,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800652 UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
Makoto Onukieb898f12018-01-23 15:26:27 -0800653
654 setAppOps(UID_1, PACKAGE_1, true);
655
656 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
657 areRestricted(instance, UID_2, PACKAGE_2, NONE);
658
659 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
660 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
661 }
662
Makoto Onuki2206af32017-11-21 16:25:35 -0800663 public void loadPersistedAppOps() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800664 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -0800665
666 final List<PackageOps> ops = new ArrayList<>();
667
668 //--------------------------------------------------
669 List<OpEntry> entries = new ArrayList<>();
670 entries.add(new AppOpsManager.OpEntry(
671 AppOpsManager.OP_ACCESS_NOTIFICATIONS,
672 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
673 entries.add(new AppOpsManager.OpEntry(
Makoto Onukie4918212018-02-06 11:30:15 -0800674 AppStateTracker.TARGET_OP,
Makoto Onuki2206af32017-11-21 16:25:35 -0800675 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
676
677 ops.add(new PackageOps(PACKAGE_1, UID_1, entries));
678
679 //--------------------------------------------------
680 entries = new ArrayList<>();
681 entries.add(new AppOpsManager.OpEntry(
Makoto Onukie4918212018-02-06 11:30:15 -0800682 AppStateTracker.TARGET_OP,
Makoto Onuki2206af32017-11-21 16:25:35 -0800683 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
684
685 ops.add(new PackageOps(PACKAGE_2, UID_2, entries));
686
687 //--------------------------------------------------
688 entries = new ArrayList<>();
689 entries.add(new AppOpsManager.OpEntry(
Makoto Onukie4918212018-02-06 11:30:15 -0800690 AppStateTracker.TARGET_OP,
Makoto Onuki2206af32017-11-21 16:25:35 -0800691 AppOpsManager.MODE_ALLOWED, 0, 0, 0, 0, null));
692
693 ops.add(new PackageOps(PACKAGE_1, UID_10_1, entries));
694
695 //--------------------------------------------------
696 entries = new ArrayList<>();
697 entries.add(new AppOpsManager.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 entries.add(new AppOpsManager.OpEntry(
701 AppOpsManager.OP_ACCESS_NOTIFICATIONS,
702 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
703
704 ops.add(new PackageOps(PACKAGE_3, UID_10_3, entries));
705
706 callStart(instance);
707
708 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
709 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
710 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_3, PACKAGE_3));
711
712 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1));
713 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
714 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_3, PACKAGE_3));
715 }
716
717 private void assertNoCallbacks(Listener l) throws Exception {
718 waitUntilMainHandlerDrain();
719 verify(l, times(0)).updateAllJobs();
720 verify(l, times(0)).updateJobsForUid(anyInt());
721 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
722
723 verify(l, times(0)).unblockAllUnrestrictedAlarms();
724 verify(l, times(0)).unblockAlarmsForUid(anyInt());
725 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
726 reset(l);
727 }
728
729 @Test
730 public void testPowerSaveListener() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800731 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -0800732 callStart(instance);
733
Makoto Onukie4918212018-02-06 11:30:15 -0800734 AppStateTracker.Listener l = mock(AppStateTracker.Listener.class);
Makoto Onuki2206af32017-11-21 16:25:35 -0800735 instance.addListener(l);
736
737 // Power save on.
738 mPowerSaveMode = true;
739 mPowerSaveObserver.accept(getPowerSaveState());
740
741 waitUntilMainHandlerDrain();
742 verify(l, times(1)).updateAllJobs();
743 verify(l, times(0)).updateJobsForUid(anyInt());
744 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
745
746 verify(l, times(0)).unblockAllUnrestrictedAlarms();
747 verify(l, times(0)).unblockAlarmsForUid(anyInt());
748 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
749 reset(l);
750
751 // Power save off.
752 mPowerSaveMode = false;
753 mPowerSaveObserver.accept(getPowerSaveState());
754
755 waitUntilMainHandlerDrain();
756 verify(l, times(1)).updateAllJobs();
757 verify(l, times(0)).updateJobsForUid(anyInt());
758 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
759
760 verify(l, times(1)).unblockAllUnrestrictedAlarms();
761 verify(l, times(0)).unblockAlarmsForUid(anyInt());
762 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
763 reset(l);
764
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800765 // Updating to the same state should not fire listener
766 mPowerSaveMode = false;
Makoto Onuki2206af32017-11-21 16:25:35 -0800767 mPowerSaveObserver.accept(getPowerSaveState());
768
769 assertNoCallbacks(l);
770 }
771
772 @Test
773 public void testAllListeners() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800774 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -0800775 callStart(instance);
776
Makoto Onukie4918212018-02-06 11:30:15 -0800777 AppStateTracker.Listener l = mock(AppStateTracker.Listener.class);
Makoto Onuki2206af32017-11-21 16:25:35 -0800778 instance.addListener(l);
779
780 // -------------------------------------------------------------------------
781 // Test with apppops.
782
783 setAppOps(UID_10_2, PACKAGE_2, true);
784
785 waitUntilMainHandlerDrain();
786 verify(l, times(0)).updateAllJobs();
787 verify(l, times(0)).updateJobsForUid(anyInt());
788 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
789
790 verify(l, times(0)).unblockAllUnrestrictedAlarms();
791 verify(l, times(0)).unblockAlarmsForUid(anyInt());
792 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
793 reset(l);
794
795 setAppOps(UID_10_2, PACKAGE_2, false);
796
797 waitUntilMainHandlerDrain();
798 verify(l, times(0)).updateAllJobs();
799 verify(l, times(0)).updateJobsForUid(anyInt());
800 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
801
802 verify(l, times(0)).unblockAllUnrestrictedAlarms();
803 verify(l, times(0)).unblockAlarmsForUid(anyInt());
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800804 verify(l, times(1)).unblockAlarmsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
Makoto Onuki2206af32017-11-21 16:25:35 -0800805 reset(l);
806
807 setAppOps(UID_10_2, PACKAGE_2, false);
808
809 verify(l, times(0)).updateAllJobs();
810 verify(l, times(0)).updateJobsForUid(anyInt());
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800811 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
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
817 // Unrestrict while battery saver is on. Shouldn't fire.
818 mPowerSaveMode = true;
819 mPowerSaveObserver.accept(getPowerSaveState());
820
821 // Note toggling appops while BS is on will suppress unblockAlarmsForUidPackage().
822 setAppOps(UID_10_2, PACKAGE_2, true);
823
824 waitUntilMainHandlerDrain();
825 verify(l, times(1)).updateAllJobs();
826 verify(l, times(0)).updateJobsForUid(anyInt());
827 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
828
829 verify(l, times(0)).unblockAllUnrestrictedAlarms();
830 verify(l, times(0)).unblockAlarmsForUid(anyInt());
831 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
832 reset(l);
833
834 // Battery saver off.
835 mPowerSaveMode = false;
836 mPowerSaveObserver.accept(getPowerSaveState());
837
838 waitUntilMainHandlerDrain();
839 verify(l, times(1)).updateAllJobs();
840 verify(l, times(0)).updateJobsForUid(anyInt());
841 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
842
843 verify(l, times(1)).unblockAllUnrestrictedAlarms();
844 verify(l, times(0)).unblockAlarmsForUid(anyInt());
845 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
846 reset(l);
847
848 // -------------------------------------------------------------------------
849 // Tests with system/user/temp whitelist.
850
851 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {});
852
853 waitUntilMainHandlerDrain();
854 verify(l, times(1)).updateAllJobs();
855 verify(l, times(0)).updateJobsForUid(anyInt());
856 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
857
858 verify(l, times(0)).unblockAllUnrestrictedAlarms();
859 verify(l, times(0)).unblockAlarmsForUid(anyInt());
860 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
861 reset(l);
862
863 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {});
864
865 waitUntilMainHandlerDrain();
866 verify(l, times(1)).updateAllJobs();
867 verify(l, times(0)).updateJobsForUid(anyInt());
868 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
869
870 verify(l, times(1)).unblockAllUnrestrictedAlarms();
871 verify(l, times(0)).unblockAlarmsForUid(anyInt());
872 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
873 reset(l);
874
875 // Update temp whitelist.
876 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_1, UID_3});
877
878 waitUntilMainHandlerDrain();
879 verify(l, times(1)).updateAllJobs();
880 verify(l, times(0)).updateJobsForUid(anyInt());
881 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
882
883 verify(l, times(0)).unblockAllUnrestrictedAlarms();
884 verify(l, times(0)).unblockAlarmsForUid(anyInt());
885 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
886 reset(l);
887
888 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_3});
889
890 waitUntilMainHandlerDrain();
891 verify(l, times(1)).updateAllJobs();
892 verify(l, times(0)).updateJobsForUid(anyInt());
893 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
894
895 verify(l, times(0)).unblockAllUnrestrictedAlarms();
896 verify(l, times(0)).unblockAlarmsForUid(anyInt());
897 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
898 reset(l);
899
900 // Do the same thing with battery saver on. (Currently same callbacks are called.)
901 mPowerSaveMode = true;
902 mPowerSaveObserver.accept(getPowerSaveState());
903
Makoto Onukieb898f12018-01-23 15:26:27 -0800904 waitUntilMainHandlerDrain();
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800905 verify(l, times(1)).updateAllJobs();
906 verify(l, times(0)).updateJobsForUid(anyInt());
907 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
908
909 verify(l, times(0)).unblockAllUnrestrictedAlarms();
910 verify(l, times(0)).unblockAlarmsForUid(anyInt());
911 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
912 reset(l);
913
Makoto Onuki2206af32017-11-21 16:25:35 -0800914 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {});
915
916 waitUntilMainHandlerDrain();
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800917 // Called once for updating all whitelist and once for updating temp whitelist
918 verify(l, times(2)).updateAllJobs();
Makoto Onuki2206af32017-11-21 16:25:35 -0800919 verify(l, times(0)).updateJobsForUid(anyInt());
920 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
921
922 verify(l, times(0)).unblockAllUnrestrictedAlarms();
923 verify(l, times(0)).unblockAlarmsForUid(anyInt());
924 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
925 reset(l);
926
927 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {});
928
929 waitUntilMainHandlerDrain();
930 verify(l, times(1)).updateAllJobs();
931 verify(l, times(0)).updateJobsForUid(anyInt());
932 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
933
934 verify(l, times(1)).unblockAllUnrestrictedAlarms();
935 verify(l, times(0)).unblockAlarmsForUid(anyInt());
936 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
937 reset(l);
938
939 // Update temp whitelist.
940 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_1, UID_3});
941
942 waitUntilMainHandlerDrain();
943 verify(l, times(1)).updateAllJobs();
944 verify(l, times(0)).updateJobsForUid(anyInt());
945 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
946
947 verify(l, times(0)).unblockAllUnrestrictedAlarms();
948 verify(l, times(0)).unblockAlarmsForUid(anyInt());
949 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
950 reset(l);
951
952 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_3});
953
954 waitUntilMainHandlerDrain();
955 verify(l, times(1)).updateAllJobs();
956 verify(l, times(0)).updateJobsForUid(anyInt());
957 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
958
959 verify(l, times(0)).unblockAllUnrestrictedAlarms();
960 verify(l, times(0)).unblockAlarmsForUid(anyInt());
961 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
962 reset(l);
963
964
965 // -------------------------------------------------------------------------
966 // Tests with proc state changes.
967
968 // With battery save.
969 mPowerSaveMode = true;
970 mPowerSaveObserver.accept(getPowerSaveState());
971
972 mIUidObserver.onUidActive(UID_10_1);
973
974 waitUntilMainHandlerDrain();
975 verify(l, times(0)).updateAllJobs();
976 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
977 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
978
979 verify(l, times(0)).unblockAllUnrestrictedAlarms();
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800980 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -0800981 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
982 reset(l);
983
984 mIUidObserver.onUidGone(UID_10_1, true);
985
986 waitUntilMainHandlerDrain();
987 verify(l, times(0)).updateAllJobs();
988 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
989 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
990
991 verify(l, times(0)).unblockAllUnrestrictedAlarms();
992 verify(l, times(0)).unblockAlarmsForUid(anyInt());
993 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
994 reset(l);
995
996 mIUidObserver.onUidActive(UID_10_1);
997
998 waitUntilMainHandlerDrain();
999 verify(l, times(0)).updateAllJobs();
1000 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
1001 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
1002
1003 verify(l, times(0)).unblockAllUnrestrictedAlarms();
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001004 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001005 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1006 reset(l);
1007
1008 mIUidObserver.onUidIdle(UID_10_1, true);
1009
1010 waitUntilMainHandlerDrain();
1011 verify(l, times(0)).updateAllJobs();
1012 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
1013 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
1014
1015 verify(l, times(0)).unblockAllUnrestrictedAlarms();
1016 verify(l, times(0)).unblockAlarmsForUid(anyInt());
1017 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1018 reset(l);
1019
1020 // Without battery save.
1021 mPowerSaveMode = false;
1022 mPowerSaveObserver.accept(getPowerSaveState());
1023
Makoto Onukieb898f12018-01-23 15:26:27 -08001024 waitUntilMainHandlerDrain();
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001025 verify(l, times(1)).updateAllJobs();
1026 verify(l, times(0)).updateJobsForUid(eq(UID_10_1));
1027 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
1028
1029 verify(l, times(1)).unblockAllUnrestrictedAlarms();
1030 verify(l, times(0)).unblockAlarmsForUid(anyInt());
1031 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1032 reset(l);
1033
Makoto Onuki2206af32017-11-21 16:25:35 -08001034 mIUidObserver.onUidActive(UID_10_1);
1035
1036 waitUntilMainHandlerDrain();
1037 verify(l, times(0)).updateAllJobs();
1038 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
1039 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
1040
1041 verify(l, times(0)).unblockAllUnrestrictedAlarms();
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001042 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001043 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1044 reset(l);
1045
1046 mIUidObserver.onUidGone(UID_10_1, true);
1047
1048 waitUntilMainHandlerDrain();
1049 verify(l, times(0)).updateAllJobs();
1050 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
1051 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
1052
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 mIUidObserver.onUidActive(UID_10_1);
1059
1060 waitUntilMainHandlerDrain();
1061 verify(l, times(0)).updateAllJobs();
1062 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
1063 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
1064
1065 verify(l, times(0)).unblockAllUnrestrictedAlarms();
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001066 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001067 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1068 reset(l);
1069
1070 mIUidObserver.onUidIdle(UID_10_1, true);
1071
1072 waitUntilMainHandlerDrain();
1073 verify(l, times(0)).updateAllJobs();
1074 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
1075 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
1076
1077 verify(l, times(0)).unblockAllUnrestrictedAlarms();
1078 verify(l, times(0)).unblockAlarmsForUid(anyInt());
1079 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1080 reset(l);
1081 }
1082
1083 @Test
1084 public void testUserRemoved() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -08001085 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -08001086 callStart(instance);
1087
1088 mIUidObserver.onUidActive(UID_1);
1089 mIUidObserver.onUidActive(UID_10_1);
1090
Makoto Onuki4d298b52018-02-05 10:54:58 -08001091 waitUntilMainHandlerDrain();
1092
Makoto Onuki2206af32017-11-21 16:25:35 -08001093 setAppOps(UID_2, PACKAGE_2, true);
1094 setAppOps(UID_10_2, PACKAGE_2, true);
1095
Makoto Onukiadb50d82018-01-29 16:20:30 -08001096 assertTrue(instance.isUidActive(UID_1));
1097 assertTrue(instance.isUidActive(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001098
1099 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
1100 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
1101
1102 final Intent intent = new Intent(Intent.ACTION_USER_REMOVED);
1103 intent.putExtra(Intent.EXTRA_USER_HANDLE, 10);
1104 mReceiver.onReceive(mMockContext, intent);
1105
1106 waitUntilMainHandlerDrain();
1107
Makoto Onukiadb50d82018-01-29 16:20:30 -08001108 assertTrue(instance.isUidActive(UID_1));
1109 assertFalse(instance.isUidActive(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001110
1111 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
1112 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
1113 }
1114
Nancy Zheng525aaa12018-01-12 11:45:37 -08001115 @Test
1116 public void testSmallBatteryAndPluggedIn() throws Exception {
1117 // This is a small battery device
1118 mIsSmallBatteryDevice = true;
1119
Makoto Onukie4918212018-02-06 11:30:15 -08001120 final AppStateTrackerTestable instance = newInstance();
Nancy Zheng525aaa12018-01-12 11:45:37 -08001121 callStart(instance);
1122 assertFalse(instance.isForceAllAppsStandbyEnabled());
1123
1124 // Setting/experiment for all app standby for small battery is enabled
Makoto Onukieb898f12018-01-23 15:26:27 -08001125 mGlobalSettings.put(Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 1);
Nancy Zheng525aaa12018-01-12 11:45:37 -08001126 instance.mFlagsObserver.onChange(true,
1127 Global.getUriFor(Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED));
1128 assertTrue(instance.isForceAllAppsStandbyEnabled());
1129
1130 // When battery is plugged in, force app standby is disabled
1131 Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
1132 intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB);
1133 mReceiver.onReceive(mMockContext, intent);
1134 assertFalse(instance.isForceAllAppsStandbyEnabled());
1135
1136 // When battery stops plugged in, force app standby is enabled
1137 mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED));
1138 assertTrue(instance.isForceAllAppsStandbyEnabled());
1139 }
1140
1141 @Test
1142 public void testNotSmallBatteryAndPluggedIn() throws Exception {
1143 // Not a small battery device, so plugged in status should not affect forced app standby
1144 mIsSmallBatteryDevice = false;
1145
Makoto Onukie4918212018-02-06 11:30:15 -08001146 final AppStateTrackerTestable instance = newInstance();
Nancy Zheng525aaa12018-01-12 11:45:37 -08001147 callStart(instance);
1148 assertFalse(instance.isForceAllAppsStandbyEnabled());
1149
1150 mPowerSaveMode = true;
1151 mPowerSaveObserver.accept(getPowerSaveState());
1152 assertTrue(instance.isForceAllAppsStandbyEnabled());
1153
1154 // When battery is plugged in, force app standby is unaffected
1155 Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
1156 intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB);
1157 mReceiver.onReceive(mMockContext, intent);
1158 assertTrue(instance.isForceAllAppsStandbyEnabled());
1159
1160 // When battery stops plugged in, force app standby is unaffected
1161 mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED));
1162 assertTrue(instance.isForceAllAppsStandbyEnabled());
1163 }
1164
Makoto Onuki2206af32017-11-21 16:25:35 -08001165 static int[] array(int... appIds) {
1166 Arrays.sort(appIds);
1167 return appIds;
1168 }
1169
1170 private final Random mRandom = new Random();
1171
1172 int[] makeRandomArray() {
1173 final ArrayList<Integer> list = new ArrayList<>();
1174 for (int i = 0; i < 5; i++) {
1175 if (mRandom.nextDouble() < 0.5) {
1176 list.add(i);
1177 }
1178 }
1179 return Arrays.stream(list.toArray(new Integer[list.size()]))
1180 .mapToInt(Integer::intValue).toArray();
1181 }
1182
1183 static boolean isAnyAppIdUnwhitelistedSlow(int[] prevArray, int[] newArray) {
1184 Arrays.sort(newArray); // Just in case...
1185 for (int p : prevArray) {
1186 if (Arrays.binarySearch(newArray, p) < 0) {
1187 return true;
1188 }
1189 }
1190 return false;
1191 }
1192
1193 private void checkAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray, boolean expected) {
1194 assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
Makoto Onukie4918212018-02-06 11:30:15 -08001195 expected, AppStateTracker.isAnyAppIdUnwhitelisted(prevArray, newArray));
Makoto Onuki2206af32017-11-21 16:25:35 -08001196
1197 // Also test isAnyAppIdUnwhitelistedSlow.
1198 assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
1199 expected, isAnyAppIdUnwhitelistedSlow(prevArray, newArray));
1200 }
1201
1202 @Test
1203 public void isAnyAppIdUnwhitelisted() {
1204 checkAnyAppIdUnwhitelisted(array(), array(), false);
1205
1206 checkAnyAppIdUnwhitelisted(array(1), array(), true);
1207 checkAnyAppIdUnwhitelisted(array(1), array(1), false);
1208 checkAnyAppIdUnwhitelisted(array(1), array(0, 1), false);
1209 checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false);
1210 checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false);
1211
1212 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(), true);
1213 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2), true);
1214 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2, 10), false);
1215 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(2, 10), true);
1216 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 1, 2, 4, 3, 10), false);
1217 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 0, 1, 2, 10), false);
1218
1219 // Random test
1220 int trueCount = 0;
1221 final int count = 10000;
1222 for (int i = 0; i < count; i++) {
1223 final int[] array1 = makeRandomArray();
1224 final int[] array2 = makeRandomArray();
1225
1226 final boolean expected = isAnyAppIdUnwhitelistedSlow(array1, array2);
Makoto Onukie4918212018-02-06 11:30:15 -08001227 final boolean actual = AppStateTracker.isAnyAppIdUnwhitelisted(array1, array2);
Makoto Onuki2206af32017-11-21 16:25:35 -08001228
1229 assertEquals("Input: " + Arrays.toString(array1) + " " + Arrays.toString(array2),
1230 expected, actual);
1231 if (expected) {
1232 trueCount++;
1233 }
1234 }
1235
1236 // Make sure makeRandomArray() didn't generate all same arrays by accident.
1237 assertTrue(trueCount > 0);
1238 assertTrue(trueCount < count);
1239 }
1240}