blob: 90db2a328c6fadcdcd1d4ea5753cdfe53ced629e [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
Makoto Onukie4918212018-02-06 11:30:15 -080018import static com.android.server.AppStateTracker.TARGET_OP;
Makoto Onuki2206af32017-11-21 16:25:35 -080019
20import static org.junit.Assert.assertEquals;
21import static org.junit.Assert.assertFalse;
22import static org.junit.Assert.assertNotNull;
23import static org.junit.Assert.assertTrue;
24import static org.mockito.ArgumentMatchers.any;
25import static org.mockito.ArgumentMatchers.anyInt;
26import static org.mockito.ArgumentMatchers.anyString;
27import static org.mockito.ArgumentMatchers.eq;
28import static org.mockito.ArgumentMatchers.isNull;
29import static org.mockito.Mockito.mock;
30import static org.mockito.Mockito.reset;
31import static org.mockito.Mockito.times;
32import static org.mockito.Mockito.verify;
33import static org.mockito.Mockito.when;
34
35import android.app.ActivityManager;
Makoto Onukie4918212018-02-06 11:30:15 -080036import android.app.ActivityManagerInternal;
Makoto Onuki2206af32017-11-21 16:25:35 -080037import android.app.AppOpsManager;
38import android.app.AppOpsManager.OpEntry;
39import android.app.AppOpsManager.PackageOps;
40import android.app.IActivityManager;
41import android.app.IUidObserver;
Makoto Onukieb898f12018-01-23 15:26:27 -080042import android.app.usage.UsageStatsManager;
43import android.app.usage.UsageStatsManagerInternal;
44import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
Makoto Onuki2206af32017-11-21 16:25:35 -080045import android.content.BroadcastReceiver;
46import android.content.Context;
47import android.content.Intent;
48import android.content.IntentFilter;
Nancy Zheng525aaa12018-01-12 11:45:37 -080049import android.os.BatteryManager;
Makoto Onuki2206af32017-11-21 16:25:35 -080050import android.os.Handler;
51import android.os.Looper;
52import android.os.PowerManager.ServiceType;
53import android.os.PowerManagerInternal;
54import android.os.PowerSaveState;
55import android.os.Process;
56import android.os.RemoteException;
57import android.os.UserHandle;
Nancy Zheng525aaa12018-01-12 11:45:37 -080058import android.provider.Settings.Global;
Makoto Onuki2206af32017-11-21 16:25:35 -080059import android.support.test.filters.SmallTest;
60import android.support.test.runner.AndroidJUnit4;
Nancy Zhenga18c1f12018-01-18 16:29:59 -080061import android.test.mock.MockContentResolver;
Makoto Onuki2206af32017-11-21 16:25:35 -080062import android.util.ArraySet;
63import android.util.Pair;
64
65import com.android.internal.app.IAppOpsCallback;
66import com.android.internal.app.IAppOpsService;
Makoto Onukie4918212018-02-06 11:30:15 -080067import com.android.server.AppStateTracker.Listener;
Makoto Onuki2206af32017-11-21 16:25:35 -080068
69import org.junit.Before;
70import org.junit.Test;
71import org.junit.runner.RunWith;
72import org.mockito.ArgumentCaptor;
73import org.mockito.Mock;
74import org.mockito.MockitoAnnotations;
75
76import java.util.ArrayList;
77import java.util.Arrays;
Makoto Onukieb898f12018-01-23 15:26:27 -080078import java.util.HashMap;
Makoto Onuki2206af32017-11-21 16:25:35 -080079import java.util.List;
80import java.util.Random;
81import java.util.concurrent.CountDownLatch;
82import java.util.concurrent.TimeUnit;
83import java.util.function.Consumer;
84
Makoto Onukiadb50d82018-01-29 16:20:30 -080085/**
Makoto Onukie4918212018-02-06 11:30:15 -080086 * Tests for {@link AppStateTracker}
Makoto Onukiadb50d82018-01-29 16:20:30 -080087 *
88 * Run with:
Makoto Onukie4918212018-02-06 11:30:15 -080089 atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java
Makoto Onukiadb50d82018-01-29 16:20:30 -080090 */
Makoto Onuki2206af32017-11-21 16:25:35 -080091@SmallTest
92@RunWith(AndroidJUnit4.class)
Makoto Onukie4918212018-02-06 11:30:15 -080093public class AppStateTrackerTest {
Makoto Onuki2206af32017-11-21 16:25:35 -080094
Makoto Onukie4918212018-02-06 11:30:15 -080095 private class AppStateTrackerTestable extends AppStateTracker {
96 AppStateTrackerTestable() {
Makoto Onuki2206af32017-11-21 16:25:35 -080097 super(mMockContext, Looper.getMainLooper());
98 }
99
100 @Override
101 AppOpsManager injectAppOpsManager() {
102 return mMockAppOpsManager;
103 }
104
105 @Override
106 IAppOpsService injectIAppOpsService() {
107 return mMockIAppOpsService;
108 }
109
110 @Override
111 IActivityManager injectIActivityManager() {
112 return mMockIActivityManager;
113 }
114
115 @Override
Makoto Onukie4918212018-02-06 11:30:15 -0800116 ActivityManagerInternal injectActivityManagerInternal() {
117 return mMockIActivityManagerInternal;
118 }
119
120 @Override
Makoto Onuki2206af32017-11-21 16:25:35 -0800121 PowerManagerInternal injectPowerManagerInternal() {
122 return mMockPowerManagerInternal;
123 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800124
125 @Override
Makoto Onukieb898f12018-01-23 15:26:27 -0800126 UsageStatsManagerInternal injectUsageStatsManagerInternal() {
127 return mMockUsageStatsManagerInternal;
128 }
129
130 @Override
131 int injectGetGlobalSettingInt(String key, int def) {
132 Integer val = mGlobalSettings.get(key);
133
134 return (val == null) ? def : val;
135 }
136
137 @Override
Nancy Zheng525aaa12018-01-12 11:45:37 -0800138 boolean isSmallBatteryDevice() { return mIsSmallBatteryDevice; };
Makoto Onuki2206af32017-11-21 16:25:35 -0800139 }
140
141 private static final int UID_1 = Process.FIRST_APPLICATION_UID + 1;
142 private static final int UID_2 = Process.FIRST_APPLICATION_UID + 2;
143 private static final int UID_3 = Process.FIRST_APPLICATION_UID + 3;
144 private static final int UID_10_1 = UserHandle.getUid(10, UID_1);
145 private static final int UID_10_2 = UserHandle.getUid(10, UID_2);
146 private static final int UID_10_3 = UserHandle.getUid(10, UID_3);
147 private static final String PACKAGE_1 = "package1";
148 private static final String PACKAGE_2 = "package2";
149 private static final String PACKAGE_3 = "package3";
150 private static final String PACKAGE_SYSTEM = "android";
151
152 private Handler mMainHandler;
153
154 @Mock
155 private Context mMockContext;
156
157 @Mock
158 private IActivityManager mMockIActivityManager;
159
160 @Mock
Makoto Onukie4918212018-02-06 11:30:15 -0800161 private ActivityManagerInternal mMockIActivityManagerInternal;
162
163 @Mock
Makoto Onuki2206af32017-11-21 16:25:35 -0800164 private AppOpsManager mMockAppOpsManager;
165
166 @Mock
167 private IAppOpsService mMockIAppOpsService;
168
169 @Mock
170 private PowerManagerInternal mMockPowerManagerInternal;
171
Makoto Onukieb898f12018-01-23 15:26:27 -0800172 @Mock
173 private UsageStatsManagerInternal mMockUsageStatsManagerInternal;
174
175 private MockContentResolver mMockContentResolver;
176
Makoto Onuki2206af32017-11-21 16:25:35 -0800177 private IUidObserver mIUidObserver;
178 private IAppOpsCallback.Stub mAppOpsCallback;
179 private Consumer<PowerSaveState> mPowerSaveObserver;
180 private BroadcastReceiver mReceiver;
Makoto Onukieb898f12018-01-23 15:26:27 -0800181 private AppIdleStateChangeListener mAppIdleStateChangeListener;
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800182
Makoto Onuki2206af32017-11-21 16:25:35 -0800183 private boolean mPowerSaveMode;
Nancy Zheng525aaa12018-01-12 11:45:37 -0800184 private boolean mIsSmallBatteryDevice;
Makoto Onuki2206af32017-11-21 16:25:35 -0800185
186 private final ArraySet<Pair<Integer, String>> mRestrictedPackages = new ArraySet();
187
Makoto Onukieb898f12018-01-23 15:26:27 -0800188 private final HashMap<String, Integer> mGlobalSettings = new HashMap<>();
189
Makoto Onuki2206af32017-11-21 16:25:35 -0800190 @Before
191 public void setUp() {
192 mMainHandler = new Handler(Looper.getMainLooper());
193 }
194
195 private void waitUntilMainHandlerDrain() throws Exception {
196 final CountDownLatch l = new CountDownLatch(1);
197 mMainHandler.post(() -> {
198 l.countDown();
199 });
200 assertTrue(l.await(5, TimeUnit.SECONDS));
201 }
202
203 private PowerSaveState getPowerSaveState() {
204 return new PowerSaveState.Builder().setBatterySaverEnabled(mPowerSaveMode).build();
205 }
206
Makoto Onukie4918212018-02-06 11:30:15 -0800207 private AppStateTrackerTestable newInstance() throws Exception {
Makoto Onuki2206af32017-11-21 16:25:35 -0800208 MockitoAnnotations.initMocks(this);
209
210 when(mMockIAppOpsService.checkOperation(eq(TARGET_OP), anyInt(), anyString()))
211 .thenAnswer(inv -> {
212 return mRestrictedPackages.indexOf(
213 Pair.create(inv.getArgument(1), inv.getArgument(2))) >= 0 ?
214 AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED;
215 });
216
Makoto Onukie4918212018-02-06 11:30:15 -0800217 final AppStateTrackerTestable instance = new AppStateTrackerTestable();
Makoto Onuki2206af32017-11-21 16:25:35 -0800218
219 return instance;
220 }
221
Makoto Onukie4918212018-02-06 11:30:15 -0800222 private void callStart(AppStateTrackerTestable instance) throws RemoteException {
Makoto Onuki12391f22018-01-18 21:44:28 +0000223
Makoto Onuki2206af32017-11-21 16:25:35 -0800224 // Set up functions that start() calls.
225 when(mMockPowerManagerInternal.getLowPowerState(eq(ServiceType.FORCE_ALL_APPS_STANDBY)))
226 .thenAnswer(inv -> getPowerSaveState());
227 when(mMockAppOpsManager.getPackagesForOps(
228 any(int[].class)
Makoto Onuki12391f22018-01-18 21:44:28 +0000229 )).thenAnswer(inv -> new ArrayList<AppOpsManager.PackageOps>());
Makoto Onuki2206af32017-11-21 16:25:35 -0800230
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800231 mMockContentResolver = new MockContentResolver();
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800232 when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800233
Makoto Onuki2206af32017-11-21 16:25:35 -0800234 // Call start.
Makoto Onukie4918212018-02-06 11:30:15 -0800235 instance.onSystemServicesReady();
Makoto Onuki2206af32017-11-21 16:25:35 -0800236
237 // Capture the listeners.
238 ArgumentCaptor<IUidObserver> uidObserverArgumentCaptor =
239 ArgumentCaptor.forClass(IUidObserver.class);
240 ArgumentCaptor<IAppOpsCallback.Stub> appOpsCallbackCaptor =
241 ArgumentCaptor.forClass(IAppOpsCallback.Stub.class);
242 ArgumentCaptor<Consumer<PowerSaveState>> powerSaveObserverCaptor =
243 ArgumentCaptor.forClass(Consumer.class);
244 ArgumentCaptor<BroadcastReceiver> receiverCaptor =
245 ArgumentCaptor.forClass(BroadcastReceiver.class);
Makoto Onukieb898f12018-01-23 15:26:27 -0800246 ArgumentCaptor<AppIdleStateChangeListener> appIdleStateChangeListenerCaptor =
247 ArgumentCaptor.forClass(AppIdleStateChangeListener.class);
Makoto Onuki2206af32017-11-21 16:25:35 -0800248
249 verify(mMockIActivityManager).registerUidObserver(
250 uidObserverArgumentCaptor.capture(),
251 eq(ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_IDLE
Makoto Onukiadb50d82018-01-29 16:20:30 -0800252 | ActivityManager.UID_OBSERVER_ACTIVE
253 | ActivityManager.UID_OBSERVER_PROCSTATE),
Makoto Onuki2206af32017-11-21 16:25:35 -0800254 eq(ActivityManager.PROCESS_STATE_UNKNOWN),
255 isNull());
256 verify(mMockIAppOpsService).startWatchingMode(
257 eq(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND),
258 isNull(),
259 appOpsCallbackCaptor.capture());
260 verify(mMockPowerManagerInternal).registerLowPowerModeObserver(
261 eq(ServiceType.FORCE_ALL_APPS_STANDBY),
262 powerSaveObserverCaptor.capture());
Makoto Onuki12391f22018-01-18 21:44:28 +0000263
Makoto Onuki2206af32017-11-21 16:25:35 -0800264 verify(mMockContext).registerReceiver(
265 receiverCaptor.capture(), any(IntentFilter.class));
Makoto Onukieb898f12018-01-23 15:26:27 -0800266 verify(mMockUsageStatsManagerInternal).addAppIdleStateChangeListener(
267 appIdleStateChangeListenerCaptor.capture());
Makoto Onuki2206af32017-11-21 16:25:35 -0800268
269 mIUidObserver = uidObserverArgumentCaptor.getValue();
270 mAppOpsCallback = appOpsCallbackCaptor.getValue();
271 mPowerSaveObserver = powerSaveObserverCaptor.getValue();
272 mReceiver = receiverCaptor.getValue();
Makoto Onukieb898f12018-01-23 15:26:27 -0800273 mAppIdleStateChangeListener = appIdleStateChangeListenerCaptor.getValue();
Makoto Onuki2206af32017-11-21 16:25:35 -0800274
275 assertNotNull(mIUidObserver);
276 assertNotNull(mAppOpsCallback);
277 assertNotNull(mPowerSaveObserver);
278 assertNotNull(mReceiver);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800279 assertNotNull(instance.mFlagsObserver);
Makoto Onuki2206af32017-11-21 16:25:35 -0800280 }
281
282 private void setAppOps(int uid, String packageName, boolean restrict) throws RemoteException {
283 final Pair p = Pair.create(uid, packageName);
284 if (restrict) {
285 mRestrictedPackages.add(p);
286 } else {
287 mRestrictedPackages.remove(p);
288 }
289 if (mAppOpsCallback != null) {
290 mAppOpsCallback.opChanged(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName);
291 }
292 }
293
294 private static final int NONE = 0;
295 private static final int ALARMS_ONLY = 1 << 0;
296 private static final int JOBS_ONLY = 1 << 1;
297 private static final int JOBS_AND_ALARMS = ALARMS_ONLY | JOBS_ONLY;
298
Makoto Onukie4918212018-02-06 11:30:15 -0800299 private void areRestricted(AppStateTrackerTestable instance, int uid, String packageName,
Makoto Onuki15407842018-01-19 14:23:11 -0800300 int restrictionTypes, boolean exemptFromBatterySaver) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800301 assertEquals(((restrictionTypes & JOBS_ONLY) != 0),
Makoto Onuki15407842018-01-19 14:23:11 -0800302 instance.areJobsRestricted(uid, packageName, exemptFromBatterySaver));
Makoto Onuki2206af32017-11-21 16:25:35 -0800303 assertEquals(((restrictionTypes & ALARMS_ONLY) != 0),
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800304 instance.areAlarmsRestricted(uid, packageName, exemptFromBatterySaver));
Makoto Onuki2206af32017-11-21 16:25:35 -0800305 }
306
Makoto Onukie4918212018-02-06 11:30:15 -0800307 private void areRestricted(AppStateTrackerTestable instance, int uid, String packageName,
Makoto Onuki15407842018-01-19 14:23:11 -0800308 int restrictionTypes) {
309 areRestricted(instance, uid, packageName, restrictionTypes,
310 /*exemptFromBatterySaver=*/ false);
311 }
312
Makoto Onukie4918212018-02-06 11:30:15 -0800313 private void areRestrictedWithExemption(AppStateTrackerTestable instance,
Makoto Onukieb898f12018-01-23 15:26:27 -0800314 int uid, String packageName, int restrictionTypes) {
315 areRestricted(instance, uid, packageName, restrictionTypes,
316 /*exemptFromBatterySaver=*/ true);
317 }
318
Makoto Onuki2206af32017-11-21 16:25:35 -0800319 @Test
320 public void testAll() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800321 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -0800322 callStart(instance);
323
324 assertFalse(instance.isForceAllAppsStandbyEnabled());
325 areRestricted(instance, UID_1, PACKAGE_1, NONE);
326 areRestricted(instance, UID_2, PACKAGE_2, NONE);
327 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
328
Makoto Onukieb898f12018-01-23 15:26:27 -0800329 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE);
330 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
331 areRestrictedWithExemption(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
332
Makoto Onuki2206af32017-11-21 16:25:35 -0800333 mPowerSaveMode = true;
334 mPowerSaveObserver.accept(getPowerSaveState());
335
336 assertTrue(instance.isForceAllAppsStandbyEnabled());
337
338 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
339 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
340 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
341
Makoto Onukieb898f12018-01-23 15:26:27 -0800342 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE);
343 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
344 areRestrictedWithExemption(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
345
Makoto Onuki2206af32017-11-21 16:25:35 -0800346 // Toggle the foreground state.
347 mPowerSaveMode = true;
348 mPowerSaveObserver.accept(getPowerSaveState());
349
Makoto Onukiadb50d82018-01-29 16:20:30 -0800350 assertFalse(instance.isUidActive(UID_1));
351 assertFalse(instance.isUidActive(UID_2));
352 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
Makoto Onuki2206af32017-11-21 16:25:35 -0800353
354 mIUidObserver.onUidActive(UID_1);
Makoto Onuki4d298b52018-02-05 10:54:58 -0800355 waitUntilMainHandlerDrain();
Makoto Onuki2206af32017-11-21 16:25:35 -0800356 areRestricted(instance, UID_1, PACKAGE_1, NONE);
357 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
358 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
Makoto Onukiadb50d82018-01-29 16:20:30 -0800359 assertTrue(instance.isUidActive(UID_1));
360 assertFalse(instance.isUidActive(UID_2));
Makoto Onuki2206af32017-11-21 16:25:35 -0800361
362 mIUidObserver.onUidGone(UID_1, /*disable=*/ false);
Makoto Onuki4d298b52018-02-05 10:54:58 -0800363 waitUntilMainHandlerDrain();
Makoto Onuki2206af32017-11-21 16:25:35 -0800364 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
365 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
366 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
Makoto Onukiadb50d82018-01-29 16:20:30 -0800367 assertFalse(instance.isUidActive(UID_1));
368 assertFalse(instance.isUidActive(UID_2));
Makoto Onuki2206af32017-11-21 16:25:35 -0800369
370 mIUidObserver.onUidActive(UID_1);
Makoto Onuki4d298b52018-02-05 10:54:58 -0800371 waitUntilMainHandlerDrain();
Makoto Onuki2206af32017-11-21 16:25:35 -0800372 areRestricted(instance, UID_1, PACKAGE_1, NONE);
373 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
374 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
375
376 mIUidObserver.onUidIdle(UID_1, /*disable=*/ false);
Makoto Onuki4d298b52018-02-05 10:54:58 -0800377 waitUntilMainHandlerDrain();
Makoto Onuki2206af32017-11-21 16:25:35 -0800378 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
379 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
380 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
Makoto Onukiadb50d82018-01-29 16:20:30 -0800381 assertFalse(instance.isUidActive(UID_1));
382 assertFalse(instance.isUidActive(UID_2));
Makoto Onuki2206af32017-11-21 16:25:35 -0800383
384 // Toggle the app ops.
385 mPowerSaveMode = false;
386 mPowerSaveObserver.accept(getPowerSaveState());
387
388 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
389 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1));
390 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
391 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
392
393 areRestricted(instance, UID_1, PACKAGE_1, NONE);
394 areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
395 areRestricted(instance, UID_2, PACKAGE_2, NONE);
396 areRestricted(instance, UID_10_2, PACKAGE_2, NONE);
397 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
398
399 setAppOps(UID_1, PACKAGE_1, true);
400 setAppOps(UID_10_2, PACKAGE_2, true);
401 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
402 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1));
403 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
404 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
405
406 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
407 areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
408 areRestricted(instance, UID_2, PACKAGE_2, NONE);
409 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
410 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
411
412 // Toggle power saver, should still be the same.
413 mPowerSaveMode = true;
414 mPowerSaveObserver.accept(getPowerSaveState());
415
416 mPowerSaveMode = false;
417 mPowerSaveObserver.accept(getPowerSaveState());
418
419 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
420 areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
421 areRestricted(instance, UID_2, PACKAGE_2, NONE);
422 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
423 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
424
425 // Clear the app ops and update the whitelist.
426 setAppOps(UID_1, PACKAGE_1, false);
427 setAppOps(UID_10_2, PACKAGE_2, false);
428
429 mPowerSaveMode = true;
430 mPowerSaveObserver.accept(getPowerSaveState());
431
432 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
433 areRestricted(instance, UID_10_1, PACKAGE_1, JOBS_AND_ALARMS);
434 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
435 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
436 areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS);
437 areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
438 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
439
440 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1}, new int[] {UID_2});
441
442 areRestricted(instance, UID_1, PACKAGE_1, NONE);
443 areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
444 areRestricted(instance, UID_2, PACKAGE_2, ALARMS_ONLY);
445 areRestricted(instance, UID_10_2, PACKAGE_2, ALARMS_ONLY);
446 areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS);
447 areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
448 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
449
450 // Again, make sure toggling the global state doesn't change it.
451 mPowerSaveMode = false;
452 mPowerSaveObserver.accept(getPowerSaveState());
453
454 mPowerSaveMode = true;
455 mPowerSaveObserver.accept(getPowerSaveState());
456
457 areRestricted(instance, UID_1, PACKAGE_1, NONE);
458 areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
459 areRestricted(instance, UID_2, PACKAGE_2, ALARMS_ONLY);
460 areRestricted(instance, UID_10_2, PACKAGE_2, ALARMS_ONLY);
461 areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS);
462 areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
463 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
464
465 assertTrue(instance.isUidPowerSaveWhitelisted(UID_1));
466 assertTrue(instance.isUidPowerSaveWhitelisted(UID_10_1));
467 assertFalse(instance.isUidPowerSaveWhitelisted(UID_2));
468 assertFalse(instance.isUidPowerSaveWhitelisted(UID_10_2));
469
470 assertFalse(instance.isUidTempPowerSaveWhitelisted(UID_1));
471 assertFalse(instance.isUidTempPowerSaveWhitelisted(UID_10_1));
472 assertTrue(instance.isUidTempPowerSaveWhitelisted(UID_2));
473 assertTrue(instance.isUidTempPowerSaveWhitelisted(UID_10_2));
474 }
475
Makoto Onukieb898f12018-01-23 15:26:27 -0800476 @Test
Makoto Onukiadb50d82018-01-29 16:20:30 -0800477 public void testUidStateForeground() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800478 final AppStateTrackerTestable instance = newInstance();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800479 callStart(instance);
480
481 mIUidObserver.onUidActive(UID_1);
482
Makoto Onuki4d298b52018-02-05 10:54:58 -0800483 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800484 assertTrue(instance.isUidActive(UID_1));
485 assertFalse(instance.isUidActive(UID_2));
486 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
487
Makoto Onukie4918212018-02-06 11:30:15 -0800488 assertTrue(instance.isUidActiveSynced(UID_1));
489 assertFalse(instance.isUidActiveSynced(UID_2));
490 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
491
Makoto Onukiadb50d82018-01-29 16:20:30 -0800492 assertFalse(instance.isUidInForeground(UID_1));
493 assertFalse(instance.isUidInForeground(UID_2));
494 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
495
496
497 mIUidObserver.onUidStateChanged(UID_2,
498 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE, 0);
499
Makoto Onuki4d298b52018-02-05 10:54:58 -0800500 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800501 assertTrue(instance.isUidActive(UID_1));
502 assertFalse(instance.isUidActive(UID_2));
503 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
504
Makoto Onukie4918212018-02-06 11:30:15 -0800505 assertTrue(instance.isUidActiveSynced(UID_1));
506 assertFalse(instance.isUidActiveSynced(UID_2));
507 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
508
Makoto Onukiadb50d82018-01-29 16:20:30 -0800509 assertFalse(instance.isUidInForeground(UID_1));
510 assertTrue(instance.isUidInForeground(UID_2));
511 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
512
513
514 mIUidObserver.onUidStateChanged(UID_1,
515 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
516
Makoto Onuki4d298b52018-02-05 10:54:58 -0800517 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800518 assertTrue(instance.isUidActive(UID_1));
519 assertFalse(instance.isUidActive(UID_2));
520 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
521
522 assertTrue(instance.isUidInForeground(UID_1));
523 assertTrue(instance.isUidInForeground(UID_2));
524 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
525
526 mIUidObserver.onUidGone(UID_1, true);
527
Makoto Onuki4d298b52018-02-05 10:54:58 -0800528 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800529 assertFalse(instance.isUidActive(UID_1));
530 assertFalse(instance.isUidActive(UID_2));
531 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
532
533 assertFalse(instance.isUidInForeground(UID_1));
534 assertTrue(instance.isUidInForeground(UID_2));
535 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
536
537 mIUidObserver.onUidIdle(UID_2, true);
538
Makoto Onuki4d298b52018-02-05 10:54:58 -0800539 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800540 assertFalse(instance.isUidActive(UID_1));
541 assertFalse(instance.isUidActive(UID_2));
542 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
543
544 assertFalse(instance.isUidInForeground(UID_1));
545 assertFalse(instance.isUidInForeground(UID_2));
546 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
547
548 mIUidObserver.onUidStateChanged(UID_1,
549 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0);
550
Makoto Onuki4d298b52018-02-05 10:54:58 -0800551 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800552 assertFalse(instance.isUidActive(UID_1));
553 assertFalse(instance.isUidActive(UID_2));
554 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
555
556 assertTrue(instance.isUidInForeground(UID_1));
557 assertFalse(instance.isUidInForeground(UID_2));
558 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
559
560 mIUidObserver.onUidStateChanged(UID_1,
561 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0);
562
Makoto Onuki4d298b52018-02-05 10:54:58 -0800563 waitUntilMainHandlerDrain();
Makoto Onukiadb50d82018-01-29 16:20:30 -0800564 assertFalse(instance.isUidActive(UID_1));
565 assertFalse(instance.isUidActive(UID_2));
566 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
567
Makoto Onukie4918212018-02-06 11:30:15 -0800568 assertFalse(instance.isUidActiveSynced(UID_1));
569 assertFalse(instance.isUidActiveSynced(UID_2));
570 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
571
Makoto Onukiadb50d82018-01-29 16:20:30 -0800572 assertFalse(instance.isUidInForeground(UID_1));
573 assertFalse(instance.isUidInForeground(UID_2));
574 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
Makoto Onukie4918212018-02-06 11:30:15 -0800575
576 // The result from AMI.isUidActive() only affects isUidActiveSynced().
577 when(mMockIActivityManagerInternal.isUidActive(anyInt())).thenReturn(true);
578
579 assertFalse(instance.isUidActive(UID_1));
580 assertFalse(instance.isUidActive(UID_2));
581 assertTrue(instance.isUidActive(Process.SYSTEM_UID));
582
583 assertTrue(instance.isUidActiveSynced(UID_1));
584 assertTrue(instance.isUidActiveSynced(UID_2));
585 assertTrue(instance.isUidActiveSynced(Process.SYSTEM_UID));
586
587 assertFalse(instance.isUidInForeground(UID_1));
588 assertFalse(instance.isUidInForeground(UID_2));
589 assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
590
Makoto Onukiadb50d82018-01-29 16:20:30 -0800591 }
592
593 @Test
Makoto Onukieb898f12018-01-23 15:26:27 -0800594 public void testExempt() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800595 final AppStateTrackerTestable instance = newInstance();
Makoto Onukieb898f12018-01-23 15:26:27 -0800596 callStart(instance);
597
598 assertFalse(instance.isForceAllAppsStandbyEnabled());
599 areRestricted(instance, UID_1, PACKAGE_1, NONE);
600 areRestricted(instance, UID_2, PACKAGE_2, NONE);
601 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
602
603 mPowerSaveMode = true;
604 mPowerSaveObserver.accept(getPowerSaveState());
605
606 assertTrue(instance.isForceAllAppsStandbyEnabled());
607
608 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
609 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
610 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
611 areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
612
613 // Exempt package 2 on user-10.
614 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false,
615 UsageStatsManager.STANDBY_BUCKET_EXEMPTED);
616
617 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
618 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
619 areRestricted(instance, UID_10_2, PACKAGE_2, NONE);
620
621 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, NONE);
622 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
623 areRestrictedWithExemption(instance, UID_10_2, PACKAGE_2, NONE);
624
625 // Exempt package 1 on user-0.
626 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false,
627 UsageStatsManager.STANDBY_BUCKET_EXEMPTED);
628
629 areRestricted(instance, UID_1, PACKAGE_1, NONE);
630 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
631 areRestricted(instance, UID_10_2, PACKAGE_2, NONE);
632
633 // Unexempt package 2 on user-10.
634 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false,
635 UsageStatsManager.STANDBY_BUCKET_ACTIVE);
636
637 areRestricted(instance, UID_1, PACKAGE_1, NONE);
638 areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
639 areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
640
641 // Check force-app-standby.
642 // EXEMPT doesn't exempt from force-app-standby.
643 mPowerSaveMode = false;
644 mPowerSaveObserver.accept(getPowerSaveState());
645
646 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false,
647 UsageStatsManager.STANDBY_BUCKET_EXEMPTED);
648 mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 0, false,
649 UsageStatsManager.STANDBY_BUCKET_EXEMPTED);
650
651 setAppOps(UID_1, PACKAGE_1, true);
652
653 areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
654 areRestricted(instance, UID_2, PACKAGE_2, NONE);
655
656 areRestrictedWithExemption(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
657 areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
658 }
659
Makoto Onuki2206af32017-11-21 16:25:35 -0800660 public void loadPersistedAppOps() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800661 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -0800662
663 final List<PackageOps> ops = new ArrayList<>();
664
665 //--------------------------------------------------
666 List<OpEntry> entries = new ArrayList<>();
667 entries.add(new AppOpsManager.OpEntry(
668 AppOpsManager.OP_ACCESS_NOTIFICATIONS,
669 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
670 entries.add(new AppOpsManager.OpEntry(
Makoto Onukie4918212018-02-06 11:30:15 -0800671 AppStateTracker.TARGET_OP,
Makoto Onuki2206af32017-11-21 16:25:35 -0800672 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
673
674 ops.add(new PackageOps(PACKAGE_1, UID_1, entries));
675
676 //--------------------------------------------------
677 entries = new ArrayList<>();
678 entries.add(new AppOpsManager.OpEntry(
Makoto Onukie4918212018-02-06 11:30:15 -0800679 AppStateTracker.TARGET_OP,
Makoto Onuki2206af32017-11-21 16:25:35 -0800680 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
681
682 ops.add(new PackageOps(PACKAGE_2, UID_2, entries));
683
684 //--------------------------------------------------
685 entries = new ArrayList<>();
686 entries.add(new AppOpsManager.OpEntry(
Makoto Onukie4918212018-02-06 11:30:15 -0800687 AppStateTracker.TARGET_OP,
Makoto Onuki2206af32017-11-21 16:25:35 -0800688 AppOpsManager.MODE_ALLOWED, 0, 0, 0, 0, null));
689
690 ops.add(new PackageOps(PACKAGE_1, UID_10_1, entries));
691
692 //--------------------------------------------------
693 entries = new ArrayList<>();
694 entries.add(new AppOpsManager.OpEntry(
Makoto Onukie4918212018-02-06 11:30:15 -0800695 AppStateTracker.TARGET_OP,
Makoto Onuki2206af32017-11-21 16:25:35 -0800696 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
697 entries.add(new AppOpsManager.OpEntry(
698 AppOpsManager.OP_ACCESS_NOTIFICATIONS,
699 AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
700
701 ops.add(new PackageOps(PACKAGE_3, UID_10_3, entries));
702
703 callStart(instance);
704
705 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
706 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
707 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_3, PACKAGE_3));
708
709 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1));
710 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
711 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_3, PACKAGE_3));
712 }
713
714 private void assertNoCallbacks(Listener l) throws Exception {
715 waitUntilMainHandlerDrain();
716 verify(l, times(0)).updateAllJobs();
717 verify(l, times(0)).updateJobsForUid(anyInt());
718 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
719
720 verify(l, times(0)).unblockAllUnrestrictedAlarms();
721 verify(l, times(0)).unblockAlarmsForUid(anyInt());
722 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
723 reset(l);
724 }
725
726 @Test
727 public void testPowerSaveListener() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800728 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -0800729 callStart(instance);
730
Makoto Onukie4918212018-02-06 11:30:15 -0800731 AppStateTracker.Listener l = mock(AppStateTracker.Listener.class);
Makoto Onuki2206af32017-11-21 16:25:35 -0800732 instance.addListener(l);
733
734 // Power save on.
735 mPowerSaveMode = true;
736 mPowerSaveObserver.accept(getPowerSaveState());
737
738 waitUntilMainHandlerDrain();
739 verify(l, times(1)).updateAllJobs();
740 verify(l, times(0)).updateJobsForUid(anyInt());
741 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
742
743 verify(l, times(0)).unblockAllUnrestrictedAlarms();
744 verify(l, times(0)).unblockAlarmsForUid(anyInt());
745 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
746 reset(l);
747
748 // Power save off.
749 mPowerSaveMode = false;
750 mPowerSaveObserver.accept(getPowerSaveState());
751
752 waitUntilMainHandlerDrain();
753 verify(l, times(1)).updateAllJobs();
754 verify(l, times(0)).updateJobsForUid(anyInt());
755 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
756
757 verify(l, times(1)).unblockAllUnrestrictedAlarms();
758 verify(l, times(0)).unblockAlarmsForUid(anyInt());
759 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
760 reset(l);
761
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800762 // Updating to the same state should not fire listener
763 mPowerSaveMode = false;
Makoto Onuki2206af32017-11-21 16:25:35 -0800764 mPowerSaveObserver.accept(getPowerSaveState());
765
766 assertNoCallbacks(l);
767 }
768
769 @Test
770 public void testAllListeners() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -0800771 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -0800772 callStart(instance);
773
Makoto Onukie4918212018-02-06 11:30:15 -0800774 AppStateTracker.Listener l = mock(AppStateTracker.Listener.class);
Makoto Onuki2206af32017-11-21 16:25:35 -0800775 instance.addListener(l);
776
777 // -------------------------------------------------------------------------
778 // Test with apppops.
779
780 setAppOps(UID_10_2, PACKAGE_2, true);
781
782 waitUntilMainHandlerDrain();
783 verify(l, times(0)).updateAllJobs();
784 verify(l, times(0)).updateJobsForUid(anyInt());
785 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
786
787 verify(l, times(0)).unblockAllUnrestrictedAlarms();
788 verify(l, times(0)).unblockAlarmsForUid(anyInt());
789 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
790 reset(l);
791
792 setAppOps(UID_10_2, PACKAGE_2, false);
793
794 waitUntilMainHandlerDrain();
795 verify(l, times(0)).updateAllJobs();
796 verify(l, times(0)).updateJobsForUid(anyInt());
797 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
798
799 verify(l, times(0)).unblockAllUnrestrictedAlarms();
800 verify(l, times(0)).unblockAlarmsForUid(anyInt());
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800801 verify(l, times(1)).unblockAlarmsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
Makoto Onuki2206af32017-11-21 16:25:35 -0800802 reset(l);
803
804 setAppOps(UID_10_2, PACKAGE_2, false);
805
806 verify(l, times(0)).updateAllJobs();
807 verify(l, times(0)).updateJobsForUid(anyInt());
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800808 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
Makoto Onuki2206af32017-11-21 16:25:35 -0800809
810 verify(l, times(0)).unblockAllUnrestrictedAlarms();
811 verify(l, times(0)).unblockAlarmsForUid(anyInt());
812 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
813
814 // Unrestrict while battery saver is on. Shouldn't fire.
815 mPowerSaveMode = true;
816 mPowerSaveObserver.accept(getPowerSaveState());
817
818 // Note toggling appops while BS is on will suppress unblockAlarmsForUidPackage().
819 setAppOps(UID_10_2, PACKAGE_2, true);
820
821 waitUntilMainHandlerDrain();
822 verify(l, times(1)).updateAllJobs();
823 verify(l, times(0)).updateJobsForUid(anyInt());
824 verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
825
826 verify(l, times(0)).unblockAllUnrestrictedAlarms();
827 verify(l, times(0)).unblockAlarmsForUid(anyInt());
828 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
829 reset(l);
830
831 // Battery saver off.
832 mPowerSaveMode = false;
833 mPowerSaveObserver.accept(getPowerSaveState());
834
835 waitUntilMainHandlerDrain();
836 verify(l, times(1)).updateAllJobs();
837 verify(l, times(0)).updateJobsForUid(anyInt());
838 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
839
840 verify(l, times(1)).unblockAllUnrestrictedAlarms();
841 verify(l, times(0)).unblockAlarmsForUid(anyInt());
842 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
843 reset(l);
844
845 // -------------------------------------------------------------------------
846 // Tests with system/user/temp whitelist.
847
848 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {});
849
850 waitUntilMainHandlerDrain();
851 verify(l, times(1)).updateAllJobs();
852 verify(l, times(0)).updateJobsForUid(anyInt());
853 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
854
855 verify(l, times(0)).unblockAllUnrestrictedAlarms();
856 verify(l, times(0)).unblockAlarmsForUid(anyInt());
857 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
858 reset(l);
859
860 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {});
861
862 waitUntilMainHandlerDrain();
863 verify(l, times(1)).updateAllJobs();
864 verify(l, times(0)).updateJobsForUid(anyInt());
865 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
866
867 verify(l, times(1)).unblockAllUnrestrictedAlarms();
868 verify(l, times(0)).unblockAlarmsForUid(anyInt());
869 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
870 reset(l);
871
872 // Update temp whitelist.
873 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_1, UID_3});
874
875 waitUntilMainHandlerDrain();
876 verify(l, times(1)).updateAllJobs();
877 verify(l, times(0)).updateJobsForUid(anyInt());
878 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
879
880 verify(l, times(0)).unblockAllUnrestrictedAlarms();
881 verify(l, times(0)).unblockAlarmsForUid(anyInt());
882 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
883 reset(l);
884
885 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_3});
886
887 waitUntilMainHandlerDrain();
888 verify(l, times(1)).updateAllJobs();
889 verify(l, times(0)).updateJobsForUid(anyInt());
890 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
891
892 verify(l, times(0)).unblockAllUnrestrictedAlarms();
893 verify(l, times(0)).unblockAlarmsForUid(anyInt());
894 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
895 reset(l);
896
897 // Do the same thing with battery saver on. (Currently same callbacks are called.)
898 mPowerSaveMode = true;
899 mPowerSaveObserver.accept(getPowerSaveState());
900
Makoto Onukieb898f12018-01-23 15:26:27 -0800901 waitUntilMainHandlerDrain();
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800902 verify(l, times(1)).updateAllJobs();
903 verify(l, times(0)).updateJobsForUid(anyInt());
904 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
905
906 verify(l, times(0)).unblockAllUnrestrictedAlarms();
907 verify(l, times(0)).unblockAlarmsForUid(anyInt());
908 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
909 reset(l);
910
Makoto Onuki2206af32017-11-21 16:25:35 -0800911 instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {});
912
913 waitUntilMainHandlerDrain();
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800914 // Called once for updating all whitelist and once for updating temp whitelist
915 verify(l, times(2)).updateAllJobs();
Makoto Onuki2206af32017-11-21 16:25:35 -0800916 verify(l, times(0)).updateJobsForUid(anyInt());
917 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
918
919 verify(l, times(0)).unblockAllUnrestrictedAlarms();
920 verify(l, times(0)).unblockAlarmsForUid(anyInt());
921 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
922 reset(l);
923
924 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {});
925
926 waitUntilMainHandlerDrain();
927 verify(l, times(1)).updateAllJobs();
928 verify(l, times(0)).updateJobsForUid(anyInt());
929 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
930
931 verify(l, times(1)).unblockAllUnrestrictedAlarms();
932 verify(l, times(0)).unblockAlarmsForUid(anyInt());
933 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
934 reset(l);
935
936 // Update temp whitelist.
937 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_1, UID_3});
938
939 waitUntilMainHandlerDrain();
940 verify(l, times(1)).updateAllJobs();
941 verify(l, times(0)).updateJobsForUid(anyInt());
942 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
943
944 verify(l, times(0)).unblockAllUnrestrictedAlarms();
945 verify(l, times(0)).unblockAlarmsForUid(anyInt());
946 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
947 reset(l);
948
949 instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_3});
950
951 waitUntilMainHandlerDrain();
952 verify(l, times(1)).updateAllJobs();
953 verify(l, times(0)).updateJobsForUid(anyInt());
954 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
955
956 verify(l, times(0)).unblockAllUnrestrictedAlarms();
957 verify(l, times(0)).unblockAlarmsForUid(anyInt());
958 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
959 reset(l);
960
961
962 // -------------------------------------------------------------------------
963 // Tests with proc state changes.
964
965 // With battery save.
966 mPowerSaveMode = true;
967 mPowerSaveObserver.accept(getPowerSaveState());
968
969 mIUidObserver.onUidActive(UID_10_1);
970
971 waitUntilMainHandlerDrain();
972 verify(l, times(0)).updateAllJobs();
973 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
974 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
975
976 verify(l, times(0)).unblockAllUnrestrictedAlarms();
Nancy Zhenga18c1f12018-01-18 16:29:59 -0800977 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -0800978 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
979 reset(l);
980
981 mIUidObserver.onUidGone(UID_10_1, true);
982
983 waitUntilMainHandlerDrain();
984 verify(l, times(0)).updateAllJobs();
985 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
986 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
987
988 verify(l, times(0)).unblockAllUnrestrictedAlarms();
989 verify(l, times(0)).unblockAlarmsForUid(anyInt());
990 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
991 reset(l);
992
993 mIUidObserver.onUidActive(UID_10_1);
994
995 waitUntilMainHandlerDrain();
996 verify(l, times(0)).updateAllJobs();
997 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
998 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
999
1000 verify(l, times(0)).unblockAllUnrestrictedAlarms();
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001001 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001002 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1003 reset(l);
1004
1005 mIUidObserver.onUidIdle(UID_10_1, true);
1006
1007 waitUntilMainHandlerDrain();
1008 verify(l, times(0)).updateAllJobs();
1009 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
1010 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
1011
1012 verify(l, times(0)).unblockAllUnrestrictedAlarms();
1013 verify(l, times(0)).unblockAlarmsForUid(anyInt());
1014 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1015 reset(l);
1016
1017 // Without battery save.
1018 mPowerSaveMode = false;
1019 mPowerSaveObserver.accept(getPowerSaveState());
1020
Makoto Onukieb898f12018-01-23 15:26:27 -08001021 waitUntilMainHandlerDrain();
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001022 verify(l, times(1)).updateAllJobs();
1023 verify(l, times(0)).updateJobsForUid(eq(UID_10_1));
1024 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
1025
1026 verify(l, times(1)).unblockAllUnrestrictedAlarms();
1027 verify(l, times(0)).unblockAlarmsForUid(anyInt());
1028 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1029 reset(l);
1030
Makoto Onuki2206af32017-11-21 16:25:35 -08001031 mIUidObserver.onUidActive(UID_10_1);
1032
1033 waitUntilMainHandlerDrain();
1034 verify(l, times(0)).updateAllJobs();
1035 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
1036 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
1037
1038 verify(l, times(0)).unblockAllUnrestrictedAlarms();
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001039 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001040 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1041 reset(l);
1042
1043 mIUidObserver.onUidGone(UID_10_1, true);
1044
1045 waitUntilMainHandlerDrain();
1046 verify(l, times(0)).updateAllJobs();
1047 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
1048 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
1049
1050 verify(l, times(0)).unblockAllUnrestrictedAlarms();
1051 verify(l, times(0)).unblockAlarmsForUid(anyInt());
1052 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1053 reset(l);
1054
1055 mIUidObserver.onUidActive(UID_10_1);
1056
1057 waitUntilMainHandlerDrain();
1058 verify(l, times(0)).updateAllJobs();
1059 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
1060 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
1061
1062 verify(l, times(0)).unblockAllUnrestrictedAlarms();
Nancy Zhenga18c1f12018-01-18 16:29:59 -08001063 verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001064 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1065 reset(l);
1066
1067 mIUidObserver.onUidIdle(UID_10_1, true);
1068
1069 waitUntilMainHandlerDrain();
1070 verify(l, times(0)).updateAllJobs();
1071 verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
1072 verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
1073
1074 verify(l, times(0)).unblockAllUnrestrictedAlarms();
1075 verify(l, times(0)).unblockAlarmsForUid(anyInt());
1076 verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
1077 reset(l);
1078 }
1079
1080 @Test
1081 public void testUserRemoved() throws Exception {
Makoto Onukie4918212018-02-06 11:30:15 -08001082 final AppStateTrackerTestable instance = newInstance();
Makoto Onuki2206af32017-11-21 16:25:35 -08001083 callStart(instance);
1084
1085 mIUidObserver.onUidActive(UID_1);
1086 mIUidObserver.onUidActive(UID_10_1);
1087
Makoto Onuki4d298b52018-02-05 10:54:58 -08001088 waitUntilMainHandlerDrain();
1089
Makoto Onuki2206af32017-11-21 16:25:35 -08001090 setAppOps(UID_2, PACKAGE_2, true);
1091 setAppOps(UID_10_2, PACKAGE_2, true);
1092
Makoto Onukiadb50d82018-01-29 16:20:30 -08001093 assertTrue(instance.isUidActive(UID_1));
1094 assertTrue(instance.isUidActive(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001095
1096 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
1097 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
1098
1099 final Intent intent = new Intent(Intent.ACTION_USER_REMOVED);
1100 intent.putExtra(Intent.EXTRA_USER_HANDLE, 10);
1101 mReceiver.onReceive(mMockContext, intent);
1102
1103 waitUntilMainHandlerDrain();
1104
Makoto Onukiadb50d82018-01-29 16:20:30 -08001105 assertTrue(instance.isUidActive(UID_1));
1106 assertFalse(instance.isUidActive(UID_10_1));
Makoto Onuki2206af32017-11-21 16:25:35 -08001107
1108 assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
1109 assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
1110 }
1111
Nancy Zheng525aaa12018-01-12 11:45:37 -08001112 @Test
1113 public void testSmallBatteryAndPluggedIn() throws Exception {
1114 // This is a small battery device
1115 mIsSmallBatteryDevice = true;
1116
Makoto Onukie4918212018-02-06 11:30:15 -08001117 final AppStateTrackerTestable instance = newInstance();
Nancy Zheng525aaa12018-01-12 11:45:37 -08001118 callStart(instance);
1119 assertFalse(instance.isForceAllAppsStandbyEnabled());
1120
1121 // Setting/experiment for all app standby for small battery is enabled
Makoto Onukieb898f12018-01-23 15:26:27 -08001122 mGlobalSettings.put(Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 1);
Nancy Zheng525aaa12018-01-12 11:45:37 -08001123 instance.mFlagsObserver.onChange(true,
1124 Global.getUriFor(Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED));
1125 assertTrue(instance.isForceAllAppsStandbyEnabled());
1126
1127 // When battery is plugged in, force app standby is disabled
1128 Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
1129 intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB);
1130 mReceiver.onReceive(mMockContext, intent);
1131 assertFalse(instance.isForceAllAppsStandbyEnabled());
1132
1133 // When battery stops plugged in, force app standby is enabled
1134 mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED));
1135 assertTrue(instance.isForceAllAppsStandbyEnabled());
1136 }
1137
1138 @Test
1139 public void testNotSmallBatteryAndPluggedIn() throws Exception {
1140 // Not a small battery device, so plugged in status should not affect forced app standby
1141 mIsSmallBatteryDevice = false;
1142
Makoto Onukie4918212018-02-06 11:30:15 -08001143 final AppStateTrackerTestable instance = newInstance();
Nancy Zheng525aaa12018-01-12 11:45:37 -08001144 callStart(instance);
1145 assertFalse(instance.isForceAllAppsStandbyEnabled());
1146
1147 mPowerSaveMode = true;
1148 mPowerSaveObserver.accept(getPowerSaveState());
1149 assertTrue(instance.isForceAllAppsStandbyEnabled());
1150
1151 // When battery is plugged in, force app standby is unaffected
1152 Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
1153 intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_USB);
1154 mReceiver.onReceive(mMockContext, intent);
1155 assertTrue(instance.isForceAllAppsStandbyEnabled());
1156
1157 // When battery stops plugged in, force app standby is unaffected
1158 mReceiver.onReceive(mMockContext, new Intent(Intent.ACTION_BATTERY_CHANGED));
1159 assertTrue(instance.isForceAllAppsStandbyEnabled());
1160 }
1161
Makoto Onuki2206af32017-11-21 16:25:35 -08001162 static int[] array(int... appIds) {
1163 Arrays.sort(appIds);
1164 return appIds;
1165 }
1166
1167 private final Random mRandom = new Random();
1168
1169 int[] makeRandomArray() {
1170 final ArrayList<Integer> list = new ArrayList<>();
1171 for (int i = 0; i < 5; i++) {
1172 if (mRandom.nextDouble() < 0.5) {
1173 list.add(i);
1174 }
1175 }
1176 return Arrays.stream(list.toArray(new Integer[list.size()]))
1177 .mapToInt(Integer::intValue).toArray();
1178 }
1179
1180 static boolean isAnyAppIdUnwhitelistedSlow(int[] prevArray, int[] newArray) {
1181 Arrays.sort(newArray); // Just in case...
1182 for (int p : prevArray) {
1183 if (Arrays.binarySearch(newArray, p) < 0) {
1184 return true;
1185 }
1186 }
1187 return false;
1188 }
1189
1190 private void checkAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray, boolean expected) {
1191 assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
Makoto Onukie4918212018-02-06 11:30:15 -08001192 expected, AppStateTracker.isAnyAppIdUnwhitelisted(prevArray, newArray));
Makoto Onuki2206af32017-11-21 16:25:35 -08001193
1194 // Also test isAnyAppIdUnwhitelistedSlow.
1195 assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
1196 expected, isAnyAppIdUnwhitelistedSlow(prevArray, newArray));
1197 }
1198
1199 @Test
1200 public void isAnyAppIdUnwhitelisted() {
1201 checkAnyAppIdUnwhitelisted(array(), array(), false);
1202
1203 checkAnyAppIdUnwhitelisted(array(1), array(), true);
1204 checkAnyAppIdUnwhitelisted(array(1), array(1), false);
1205 checkAnyAppIdUnwhitelisted(array(1), array(0, 1), false);
1206 checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false);
1207 checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false);
1208
1209 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(), true);
1210 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2), true);
1211 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2, 10), false);
1212 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(2, 10), true);
1213 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 1, 2, 4, 3, 10), false);
1214 checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 0, 1, 2, 10), false);
1215
1216 // Random test
1217 int trueCount = 0;
1218 final int count = 10000;
1219 for (int i = 0; i < count; i++) {
1220 final int[] array1 = makeRandomArray();
1221 final int[] array2 = makeRandomArray();
1222
1223 final boolean expected = isAnyAppIdUnwhitelistedSlow(array1, array2);
Makoto Onukie4918212018-02-06 11:30:15 -08001224 final boolean actual = AppStateTracker.isAnyAppIdUnwhitelisted(array1, array2);
Makoto Onuki2206af32017-11-21 16:25:35 -08001225
1226 assertEquals("Input: " + Arrays.toString(array1) + " " + Arrays.toString(array2),
1227 expected, actual);
1228 if (expected) {
1229 trueCount++;
1230 }
1231 }
1232
1233 // Make sure makeRandomArray() didn't generate all same arrays by accident.
1234 assertTrue(trueCount > 0);
1235 assertTrue(trueCount < count);
1236 }
1237}