blob: 43fe674c5d78fc8d10148019d7e48a2bb32ac397 [file] [log] [blame]
Julia Reynoldsb852e562017-06-06 16:14:18 -04001/*
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.notification;
17
18import static com.android.server.notification.ManagedServices.APPROVAL_BY_COMPONENT;
19import static com.android.server.notification.ManagedServices.APPROVAL_BY_PACKAGE;
20
21import static junit.framework.Assert.assertEquals;
22import static junit.framework.Assert.assertFalse;
Julia Reynoldsca8e5352018-09-18 13:39:26 -040023import static junit.framework.Assert.assertNotNull;
Julia Reynoldsb852e562017-06-06 16:14:18 -040024import static junit.framework.Assert.assertTrue;
25
26import static org.mockito.Matchers.any;
27import static org.mockito.Matchers.anyInt;
28import static org.mockito.Matchers.eq;
Julia Reynolds70aaea72018-07-13 13:38:34 -040029import static org.mockito.Mockito.mock;
Julia Reynoldsb852e562017-06-06 16:14:18 -040030import static org.mockito.Mockito.never;
31import static org.mockito.Mockito.times;
32import static org.mockito.Mockito.verify;
33import static org.mockito.Mockito.when;
34
35import android.content.ComponentName;
36import android.content.Context;
37import android.content.Intent;
Julia Reynoldsca8e5352018-09-18 13:39:26 -040038import android.content.ServiceConnection;
Julia Reynoldsb852e562017-06-06 16:14:18 -040039import android.content.pm.IPackageManager;
40import android.content.pm.PackageManager;
41import android.content.pm.ResolveInfo;
42import android.content.pm.ServiceInfo;
43import android.content.pm.UserInfo;
Julia Reynoldsfa206a42017-08-14 13:22:23 -040044import android.os.Build;
Julia Reynoldsb852e562017-06-06 16:14:18 -040045import android.os.IBinder;
46import android.os.IInterface;
47import android.os.UserHandle;
48import android.os.UserManager;
49import android.provider.Settings;
50import android.text.TextUtils;
51import android.util.ArrayMap;
Julia Reynoldsca8e5352018-09-18 13:39:26 -040052import android.util.ArraySet;
53import android.util.IntArray;
54import android.util.SparseArray;
Julia Reynoldsb852e562017-06-06 16:14:18 -040055import android.util.Xml;
56
57import com.android.internal.util.FastXmlSerializer;
Jason Monk74f5e362017-12-06 08:56:33 -050058import com.android.server.UiServiceTestCase;
Julia Reynoldsb852e562017-06-06 16:14:18 -040059
60import com.google.android.collect.Lists;
61
62import org.junit.Before;
63import org.junit.Test;
64import org.mockito.Mock;
65import org.mockito.MockitoAnnotations;
66import org.mockito.invocation.InvocationOnMock;
67import org.mockito.stubbing.Answer;
68import org.xmlpull.v1.XmlPullParser;
69import org.xmlpull.v1.XmlSerializer;
70
71import java.io.BufferedInputStream;
72import java.io.BufferedOutputStream;
73import java.io.ByteArrayInputStream;
74import java.io.ByteArrayOutputStream;
75import java.util.ArrayList;
Julia Reynoldsca8e5352018-09-18 13:39:26 -040076import java.util.Collection;
Annie Meng8b646fd2019-02-01 18:46:42 +000077import java.util.Collections;
Julia Reynoldsb852e562017-06-06 16:14:18 -040078import java.util.List;
Julia Reynoldsca8e5352018-09-18 13:39:26 -040079import java.util.Set;
Julia Reynoldsb852e562017-06-06 16:14:18 -040080
Jason Monk74f5e362017-12-06 08:56:33 -050081public class ManagedServicesTest extends UiServiceTestCase {
Julia Reynoldsb852e562017-06-06 16:14:18 -040082
83 @Mock
84 private IPackageManager mIpm;
85 @Mock
86 private PackageManager mPm;
87 @Mock
88 private UserManager mUm;
89 @Mock
90 private ManagedServices.UserProfiles mUserProfiles;
91 Object mLock = new Object();
92
93 UserInfo mZero = new UserInfo(0, "zero", 0);
94 UserInfo mTen = new UserInfo(10, "ten", 0);
95
96 private static final String SETTING = "setting";
97 private static final String SECONDARY_SETTING = "secondary_setting";
98
99 private ArrayMap<Integer, String> mExpectedPrimaryPackages;
100 private ArrayMap<Integer, String> mExpectedPrimaryComponentNames;
101 private ArrayMap<Integer, String> mExpectedSecondaryPackages;
102 private ArrayMap<Integer, String> mExpectedSecondaryComponentNames;
103
Julia Reynolds5aa13a42017-08-24 09:10:23 -0400104 // type : user : list of approved
Julia Reynoldsb852e562017-06-06 16:14:18 -0400105 private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedPrimary = new ArrayMap<>();
106 private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedSecondary = new ArrayMap<>();
107
108 @Before
109 public void setUp() throws Exception {
110 MockitoAnnotations.initMocks(this);
111
112 getContext().setMockPackageManager(mPm);
113 getContext().addMockSystemService(Context.USER_SERVICE, mUm);
114
115 List<UserInfo> users = new ArrayList<>();
116 users.add(mZero);
117 users.add(mTen);
118 users.add(new UserInfo(11, "11", 0));
119 users.add(new UserInfo(12, "12", 0));
120 for (UserInfo user : users) {
121 when(mUm.getUserInfo(eq(user.id))).thenReturn(user);
122 }
123 when(mUm.getUsers()).thenReturn(users);
Julia Reynoldsca8e5352018-09-18 13:39:26 -0400124 IntArray profileIds = new IntArray();
125 profileIds.add(0);
126 profileIds.add(11);
127 profileIds.add(10);
128 profileIds.add(12);
129 when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
Julia Reynoldsb852e562017-06-06 16:14:18 -0400130
131 mExpectedPrimaryPackages = new ArrayMap<>();
132 mExpectedPrimaryPackages.put(0, "this.is.a.package.name:another.package");
133 mExpectedPrimaryPackages.put(10, "this.is.another.package");
134 mExpectedPrimaryPackages.put(11, "");
135 mExpectedPrimaryPackages.put(12, "bananas!");
136 mExpectedPrimaryComponentNames = new ArrayMap<>();
137 mExpectedPrimaryComponentNames.put(0, "this.is.a.package.name/Ba:another.package/B1");
138 mExpectedPrimaryComponentNames.put(10, "this.is.another.package/M1");
139 mExpectedPrimaryComponentNames.put(11, "");
140 mExpectedPrimaryComponentNames.put(12, "bananas!/Bananas!");
141 mExpectedPrimary.put(APPROVAL_BY_PACKAGE, mExpectedPrimaryPackages);
142 mExpectedPrimary.put(APPROVAL_BY_COMPONENT, mExpectedPrimaryComponentNames);
143
144 mExpectedSecondaryComponentNames = new ArrayMap<>();
145 mExpectedSecondaryComponentNames.put(0, "secondary/component.Name");
146 mExpectedSecondaryComponentNames.put(10,
147 "this.is.another.package/with.Component:component/2:package/component2");
148 mExpectedSecondaryPackages = new ArrayMap<>();
149 mExpectedSecondaryPackages.put(0, "secondary");
150 mExpectedSecondaryPackages.put(10,
151 "this.is.another.package:component:package");
152 mExpectedSecondary.put(APPROVAL_BY_PACKAGE, mExpectedSecondaryPackages);
153 mExpectedSecondary.put(APPROVAL_BY_COMPONENT, mExpectedSecondaryComponentNames);
154 }
155
156 @Test
157 public void testBackupAndRestore_migration() throws Exception {
158 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
159 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
160 mIpm, approvalLevel);
161
162 for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) {
163 service.onSettingRestored(
164 service.getConfig().secureSettingName,
165 mExpectedPrimary.get(approvalLevel).get(userId),
Julia Reynoldsfa206a42017-08-14 13:22:23 -0400166 Build.VERSION_CODES.O, userId);
Julia Reynoldsb852e562017-06-06 16:14:18 -0400167 }
168 verifyExpectedApprovedEntries(service, true);
169
170 for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) {
171 service.onSettingRestored(service.getConfig().secondarySettingName,
Julia Reynoldsfa206a42017-08-14 13:22:23 -0400172 mExpectedSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.O,
173 userId);
Julia Reynoldsb852e562017-06-06 16:14:18 -0400174 }
175 verifyExpectedApprovedEntries(service);
176 }
177 }
178
179 @Test
Julia Reynoldsfa206a42017-08-14 13:22:23 -0400180 public void testBackupAndRestore_migration_preO() throws Exception {
Julia Reynoldsca8e5352018-09-18 13:39:26 -0400181 ArrayMap<Integer, String> backupPrimaryPackages = new ArrayMap<>();
Julia Reynoldsfa206a42017-08-14 13:22:23 -0400182 backupPrimaryPackages.put(0, "backup.0:backup:0a");
183 backupPrimaryPackages.put(10, "10.backup");
184 backupPrimaryPackages.put(11, "eleven");
185 backupPrimaryPackages.put(12, "");
Julia Reynoldsca8e5352018-09-18 13:39:26 -0400186 ArrayMap<Integer, String> backupPrimaryComponentNames = new ArrayMap<>();
Julia Reynoldsfa206a42017-08-14 13:22:23 -0400187 backupPrimaryComponentNames.put(0, "backup.first/whatever:a/b");
188 backupPrimaryComponentNames.put(10, "again/M1");
189 backupPrimaryComponentNames.put(11, "orange/youglad:itisnot/banana");
190 backupPrimaryComponentNames.put(12, "");
191 ArrayMap<Integer, ArrayMap<Integer, String>> backupPrimary = new ArrayMap<>();
192 backupPrimary.put(APPROVAL_BY_PACKAGE, backupPrimaryPackages);
193 backupPrimary.put(APPROVAL_BY_COMPONENT, backupPrimaryComponentNames);
194
Julia Reynoldsca8e5352018-09-18 13:39:26 -0400195 ArrayMap<Integer, String> backupSecondaryComponentNames = new ArrayMap<>();
Julia Reynoldsfa206a42017-08-14 13:22:23 -0400196 backupSecondaryComponentNames.put(0, "secondary.1/component.Name");
197 backupSecondaryComponentNames.put(10,
198 "this.is.another.package.backup/with.Component:component.backup/2");
Julia Reynoldsca8e5352018-09-18 13:39:26 -0400199 ArrayMap<Integer, String> backupSecondaryPackages = new ArrayMap<>();
Julia Reynoldsfa206a42017-08-14 13:22:23 -0400200 backupSecondaryPackages.put(0, "");
201 backupSecondaryPackages.put(10,
202 "this.is.another.package.backup:package.backup");
203 ArrayMap<Integer, ArrayMap<Integer, String>> backupSecondary = new ArrayMap<>();
204 backupSecondary.put(APPROVAL_BY_PACKAGE, backupSecondaryPackages);
205 backupSecondary.put(APPROVAL_BY_COMPONENT, backupSecondaryComponentNames);
206
207 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
208 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
209 mIpm, approvalLevel);
210
211 // not an expected flow but a way to get data into the settings
212 for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) {
213 service.onSettingRestored(
214 service.getConfig().secureSettingName,
215 mExpectedPrimary.get(approvalLevel).get(userId),
216 Build.VERSION_CODES.O, userId);
217 }
218
219 for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) {
220 service.onSettingRestored(service.getConfig().secondarySettingName,
221 mExpectedSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.O,
222 userId);
223 }
224
225 // actual test
226 for (int userId : backupPrimary.get(approvalLevel).keySet()) {
227 service.onSettingRestored(
228 service.getConfig().secureSettingName,
229 backupPrimary.get(approvalLevel).get(userId),
230 Build.VERSION_CODES.N_MR1, userId);
231 }
232 verifyExpectedApprovedEntries(service, true);
233
234 for (int userId : backupSecondary.get(approvalLevel).keySet()) {
235 service.onSettingRestored(service.getConfig().secondarySettingName,
236 backupSecondary.get(approvalLevel).get(userId),
237 Build.VERSION_CODES.N_MR1, userId);
238 }
239 verifyExpectedApprovedEntries(service);
240 verifyExpectedApprovedEntries(service, backupPrimary.get(approvalLevel));
241 verifyExpectedApprovedEntries(service, backupSecondary.get(approvalLevel));
242 }
243 }
244
245 @Test
Julia Reynoldsb852e562017-06-06 16:14:18 -0400246 public void testReadXml_migrationFromSettings() throws Exception {
247 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
248 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
249 mIpm, approvalLevel);
250
251 // approved services aren't in xml
252 XmlPullParser parser = Xml.newPullParser();
253 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(new byte[]{})),
254 null);
255 writeExpectedValuesToSettings(approvalLevel);
256
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400257 service.migrateToXml();
Julia Reynoldsb852e562017-06-06 16:14:18 -0400258
259 verifyExpectedApprovedEntries(service);
260 }
261 }
262
263 @Test
264 public void testReadXml() throws Exception {
265 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
266 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
267 mIpm, approvalLevel);
268
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400269 loadXml(service);
Julia Reynoldsb852e562017-06-06 16:14:18 -0400270
271 verifyExpectedApprovedEntries(service);
Julia Reynolds45523002017-09-12 09:43:57 -0400272
273 int[] invalidUsers = new int[] {98, 99};
274 for (int invalidUser : invalidUsers) {
275 assertFalse("service type " + service.mApprovalLevel + ":"
276 + invalidUser + " is allowed for user " + invalidUser,
277 service.isPackageOrComponentAllowed(
278 String.valueOf(invalidUser), invalidUser));
279 }
Julia Reynoldsb852e562017-06-06 16:14:18 -0400280 }
281 }
282
283 @Test
Artem Iglikovbec96172018-04-24 12:46:44 +0100284 public void testReadXml_appendsListOfApprovedComponents() throws Exception {
285 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
286 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
287 mIpm, approvalLevel);
288
289 String preApprovedPackage = "some.random.package";
290 String preApprovedComponent = "some.random.package/C1";
291
292 List<String> packages = new ArrayList<>();
293 packages.add(preApprovedPackage);
294 addExpectedServices(service, packages, 0);
295
296 service.setPackageOrComponentEnabled(preApprovedComponent, 0, true, true);
297
298 loadXml(service);
299
300 verifyExpectedApprovedEntries(service);
301
302 String verifyValue = (approvalLevel == APPROVAL_BY_COMPONENT)
303 ? preApprovedComponent
304 : preApprovedPackage;
305 assertTrue(service.isPackageOrComponentAllowed(verifyValue, 0));
306 }
307 }
308
Annie Meng8b646fd2019-02-01 18:46:42 +0000309 /** Test that restore ignores the user id attribute and applies the data to the target user. */
310 @Test
311 public void testReadXml_onlyRestoresForTargetUser() throws Exception {
312 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
313 ManagedServices service =
314 new TestManagedServices(
315 getContext(), mLock, mUserProfiles, mIpm, approvalLevel);
316 String testPackage = "user.test.package";
317 String testComponent = "user.test.component/C1";
318 String resolvedValue =
319 (approvalLevel == APPROVAL_BY_COMPONENT) ? testComponent : testPackage;
320 XmlPullParser parser =
321 getParserWithEntries(service, getXmlEntry(resolvedValue, 0, true));
322
323 service.readXml(parser, null, true, 10);
324
325 assertFalse(service.isPackageOrComponentAllowed(resolvedValue, 0));
326 assertTrue(service.isPackageOrComponentAllowed(resolvedValue, 10));
327 }
328 }
329
330 /** Test that backup only writes packages/components that belong to the target user. */
331 @Test
332 public void testWriteXml_onlyBackupsForTargetUser() throws Exception {
333 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
334 ManagedServices service =
335 new TestManagedServices(
336 getContext(), mLock, mUserProfiles, mIpm, approvalLevel);
337 // Set up components.
338 String testPackage0 = "user0.test.package";
339 String testComponent0 = "user0.test.component/C1";
340 String testPackage10 = "user10.test.package";
341 String testComponent10 = "user10.test.component/C1";
342 String resolvedValue0 =
343 (approvalLevel == APPROVAL_BY_COMPONENT) ? testComponent0 : testPackage0;
344 String resolvedValue10 =
345 (approvalLevel == APPROVAL_BY_COMPONENT) ? testComponent10 : testPackage10;
346 addExpectedServices(
347 service, Collections.singletonList(service.getPackageName(resolvedValue0)), 0);
348 addExpectedServices(
349 service,
350 Collections.singletonList(service.getPackageName(resolvedValue10)),
351 10);
352 XmlPullParser parser =
353 getParserWithEntries(
354 service,
355 getXmlEntry(resolvedValue0, 0, true),
356 getXmlEntry(resolvedValue10, 10, true));
357 service.readXml(parser, null, false, UserHandle.USER_ALL);
358
359 // Write backup.
360 XmlSerializer serializer = new FastXmlSerializer();
361 ByteArrayOutputStream baos = new ByteArrayOutputStream();
362 serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
363 serializer.startDocument(null, true);
364 service.writeXml(serializer, true, 10);
365 serializer.endDocument();
366 serializer.flush();
367
368 // Reset values.
369 service.setPackageOrComponentEnabled(resolvedValue0, 0, true, false);
370 service.setPackageOrComponentEnabled(resolvedValue10, 10, true, false);
371
372 // Parse backup via restore.
373 XmlPullParser restoreParser = Xml.newPullParser();
374 restoreParser.setInput(
375 new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), null);
376 restoreParser.nextTag();
377 service.readXml(restoreParser, null, true, 10);
378
379 assertFalse(service.isPackageOrComponentAllowed(resolvedValue0, 0));
380 assertFalse(service.isPackageOrComponentAllowed(resolvedValue0, 10));
381 assertTrue(service.isPackageOrComponentAllowed(resolvedValue10, 10));
382 }
383 }
384
Artem Iglikovbec96172018-04-24 12:46:44 +0100385 @Test
Julia Reynoldsb852e562017-06-06 16:14:18 -0400386 public void testWriteXml_trimsMissingServices() throws Exception {
387 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
388 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
389 mIpm, approvalLevel);
390 loadXml(service);
391
392 // remove missing
393 mExpectedPrimaryPackages.put(0, "another.package");
394 mExpectedPrimaryPackages.remove(12);
395 mExpectedPrimaryComponentNames.put(0, "another.package/B1");
396 mExpectedPrimaryComponentNames.remove(12);
397 mExpectedSecondaryPackages.put(10, "this.is.another.package:component");
398 mExpectedSecondaryComponentNames.put(
399 10, "this.is.another.package/with.Component:component/2");
400
401 for (UserInfo userInfo : mUm.getUsers()) {
402 List<String> entriesExpectedToHaveServices = new ArrayList<>();
403 if (mExpectedPrimary.get(approvalLevel).containsKey(userInfo.id)) {
404 for (String packageOrComponent :
405 mExpectedPrimary.get(approvalLevel).get(userInfo.id).split(":")) {
406 if (!TextUtils.isEmpty(packageOrComponent)) {
407 entriesExpectedToHaveServices.add(
408 service.getPackageName(packageOrComponent));
409 }
410 }
411 }
412 if (mExpectedSecondary.get(approvalLevel).containsKey(userInfo.id)) {
413 for (String packageOrComponent :
414 mExpectedSecondary.get(approvalLevel).get(userInfo.id).split(":")) {
415 if (!TextUtils.isEmpty(packageOrComponent)) {
416 entriesExpectedToHaveServices.add(
417 service.getPackageName(packageOrComponent));
418 }
419 }
420 }
421 addExpectedServices(service, entriesExpectedToHaveServices, userInfo.id);
422 }
423
424 XmlSerializer serializer = new FastXmlSerializer();
425 ByteArrayOutputStream baos = new ByteArrayOutputStream();
426 serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
427 serializer.startDocument(null, true);
Annie Meng8b646fd2019-02-01 18:46:42 +0000428 for (UserInfo userInfo : mUm.getUsers()) {
429 service.writeXml(serializer, true, userInfo.id);
430 }
Julia Reynoldsb852e562017-06-06 16:14:18 -0400431 serializer.endDocument();
432 serializer.flush();
433
434 XmlPullParser parser = Xml.newPullParser();
435 parser.setInput(new BufferedInputStream(
436 new ByteArrayInputStream(baos.toByteArray())), null);
437 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +0000438 for (UserInfo userInfo : mUm.getUsers()) {
439 service.readXml(parser, null, true, userInfo.id);
440 }
Julia Reynoldsb852e562017-06-06 16:14:18 -0400441
442 verifyExpectedApprovedEntries(service);
443 assertFalse(service.isPackageOrComponentAllowed("this.is.a.package.name", 0));
444 assertFalse(service.isPackageOrComponentAllowed("bananas!", 12));
445 assertFalse(service.isPackageOrComponentAllowed("package/component2", 10));
446 }
447 }
448
449 @Test
450 public void testWriteXml_writesSetting() throws Exception {
451 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
452 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
453 mIpm, approvalLevel);
454 loadXml(service);
455
456 XmlSerializer serializer = new FastXmlSerializer();
457 ByteArrayOutputStream baos = new ByteArrayOutputStream();
458 serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
459 serializer.startDocument(null, true);
Annie Meng8b646fd2019-02-01 18:46:42 +0000460 service.writeXml(serializer, false, UserHandle.USER_ALL);
Julia Reynoldsb852e562017-06-06 16:14:18 -0400461 serializer.endDocument();
462 serializer.flush();
463
Julia Reynoldsca8e5352018-09-18 13:39:26 -0400464 for (int userId : mUserProfiles.getCurrentProfileIds().toArray()) {
Julia Reynoldsb852e562017-06-06 16:14:18 -0400465 List<String> expected =
466 stringToList(mExpectedPrimary.get(approvalLevel).get(userId));
467 List<String> actual = stringToList(Settings.Secure.getStringForUser(
468 getContext().getContentResolver(),
469 service.getConfig().secureSettingName, userId));
470 assertContentsInAnyOrder(actual, expected);
471 }
472 }
473 }
474
475 @Test
476 public void rebindServices_onlyBindsExactMatchesIfComponent() throws Exception {
477 // If the primary and secondary lists contain component names, only those components within
478 // the package should be matched
479 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
480 mIpm,
481 ManagedServices.APPROVAL_BY_COMPONENT);
482
483 List<String> packages = new ArrayList<>();
484 packages.add("package");
485 packages.add("anotherPackage");
486 addExpectedServices(service, packages, 0);
487
488 // only 2 components are approved per package
489 mExpectedPrimaryComponentNames.clear();
490 mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2");
491 mExpectedSecondaryComponentNames.clear();
492 mExpectedSecondaryComponentNames.put(0, "anotherPackage/C1:anotherPackage/C2");
493
494 loadXml(service);
495
496 // verify the 2 components per package are enabled (bound)
497 verifyExpectedBoundEntries(service, true);
498 verifyExpectedBoundEntries(service, false);
499
500 // verify the last component per package is not enabled/we don't try to bind to it
501 for (String pkg : packages) {
502 ComponentName unapprovedAdditionalComponent =
503 ComponentName.unflattenFromString(pkg + "/C3");
504 assertFalse(
505 service.isComponentEnabledForCurrentProfiles(
506 unapprovedAdditionalComponent));
507 verify(mIpm, never()).getServiceInfo(
508 eq(unapprovedAdditionalComponent), anyInt(), anyInt());
509 }
510 }
511
512 @Test
513 public void rebindServices_bindsEverythingInAPackage() throws Exception {
514 // If the primary and secondary lists contain packages, all components within those packages
515 // should be bound
516 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
517 APPROVAL_BY_PACKAGE);
518
519 List<String> packages = new ArrayList<>();
520 packages.add("package");
521 packages.add("packagea");
522 addExpectedServices(service, packages, 0);
523
524 // 2 approved packages
525 mExpectedPrimaryPackages.clear();
526 mExpectedPrimaryPackages.put(0, "package");
527 mExpectedSecondaryPackages.clear();
528 mExpectedSecondaryPackages.put(0, "packagea");
529
530 loadXml(service);
531
532 // verify the 3 components per package are enabled (bound)
533 verifyExpectedBoundEntries(service, true);
534 verifyExpectedBoundEntries(service, false);
535 }
536
537 @Test
538 public void testPackageUninstall_packageNoLongerInApprovedList() throws Exception {
539 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
540 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
541 mIpm, approvalLevel);
Julia Reynoldsb852e562017-06-06 16:14:18 -0400542 writeExpectedValuesToSettings(approvalLevel);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400543 service.migrateToXml();
Julia Reynoldsb852e562017-06-06 16:14:18 -0400544
545 mExpectedPrimaryPackages.put(0, "another.package");
546 mExpectedPrimaryComponentNames.put(0, "another.package/B1");
547 service.onPackagesChanged(true, new String[]{"this.is.a.package.name"}, new int[]{103});
548
549 verifyExpectedApprovedEntries(service);
550 }
551 }
552
553 @Test
554 public void testPackageUninstall_componentNoLongerInApprovedList() throws Exception {
555 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
556 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
557 mIpm, approvalLevel);
Julia Reynoldsb852e562017-06-06 16:14:18 -0400558 writeExpectedValuesToSettings(approvalLevel);
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400559 service.migrateToXml();
Julia Reynoldsb852e562017-06-06 16:14:18 -0400560
561 mExpectedSecondaryComponentNames.put(10, "component/2");
562 mExpectedSecondaryPackages.put(10, "component");
563 service.onPackagesChanged(true, new String[]{"this.is.another.package"}, new int[]{
564 UserHandle.PER_USER_RANGE + 1});
565
566 verifyExpectedApprovedEntries(service);
567 }
568 }
569
570 @Test
Julia Reynolds14590742018-07-30 09:25:35 -0400571 public void testIsPackageAllowed() {
572 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
573 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
574 mIpm, approvalLevel);
575 writeExpectedValuesToSettings(approvalLevel);
576 service.migrateToXml();
577
578 verifyExpectedApprovedPackages(service);
579 }
580 }
581
582 @Test
583 public void testUpgradeAppBindsNewServices() throws Exception {
584 // If the primary and secondary lists contain component names, only those components within
585 // the package should be matched
586 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
587 mIpm,
588 ManagedServices.APPROVAL_BY_PACKAGE);
589
590 List<String> packages = new ArrayList<>();
591 packages.add("package");
592 addExpectedServices(service, packages, 0);
593
594 // only 2 components are approved per package
595 mExpectedPrimaryComponentNames.clear();
596 mExpectedPrimaryPackages.clear();
597 mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2");
598 mExpectedSecondaryComponentNames.clear();
599 mExpectedSecondaryPackages.clear();
600
601 loadXml(service);
602
603 // new component expected
604 mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2:package/C3");
605
606 service.onPackagesChanged(false, new String[]{"package"}, new int[]{0});
607
608 // verify the 3 components per package are enabled (bound)
609 verifyExpectedBoundEntries(service, true);
610
611 // verify the last component per package is not enabled/we don't try to bind to it
612 for (String pkg : packages) {
613 ComponentName unapprovedAdditionalComponent =
614 ComponentName.unflattenFromString(pkg + "/C3");
615 assertFalse(
616 service.isComponentEnabledForCurrentProfiles(
617 unapprovedAdditionalComponent));
618 verify(mIpm, never()).getServiceInfo(
619 eq(unapprovedAdditionalComponent), anyInt(), anyInt());
620 }
621 }
622
623 @Test
Julia Reynoldsb852e562017-06-06 16:14:18 -0400624 public void testSetPackageOrComponentEnabled() throws Exception {
625 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
626 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
627 mIpm, approvalLevel);
628 ArrayMap<Integer, ArrayList<String>> expectedEnabled = new ArrayMap<>();
629 expectedEnabled.put(0,
630 Lists.newArrayList(new String[]{"package/Comp", "package/C2", "again/M4"}));
631 expectedEnabled.put(10,
632 Lists.newArrayList(new String[]{"user10package/B", "user10/Component",
633 "user10package1/K", "user10.3/Component", "user10package2/L",
634 "user10.4/Component"}));
635
636 for (int userId : expectedEnabled.keySet()) {
637 ArrayList<String> expectedForUser = expectedEnabled.get(userId);
638 for (int i = 0; i < expectedForUser.size(); i++) {
639 boolean primary = i % 2 == 0;
640 service.setPackageOrComponentEnabled(expectedForUser.get(i), userId, primary,
641 true);
642 }
643 }
644
645 // verify everything added is approved
646 for (int userId : expectedEnabled.keySet()) {
647 ArrayList<String> expectedForUser = expectedEnabled.get(userId);
648 for (int i = 0; i < expectedForUser.size(); i++) {
649 String verifyValue = (approvalLevel == APPROVAL_BY_COMPONENT)
650 ? expectedForUser.get(i)
651 : service.getPackageName(expectedForUser.get(i));
652 assertTrue("Not allowed: user: " + userId + " entry: " + verifyValue
653 + " for approval level " + approvalLevel,
654 service.isPackageOrComponentAllowed(verifyValue, userId));
655 }
656 }
657
658 ArrayMap<Integer, ArrayList<String>> expectedNoAccess = new ArrayMap<>();
659 for (int userId : expectedEnabled.keySet()) {
660 ArrayList<String> expectedForUser = expectedEnabled.get(userId);
661 for (int i = expectedForUser.size() - 1; i >= 0; i--) {
662 ArrayList<String> removed = new ArrayList<>();
663 if (i % 3 == 0) {
664 String revokeAccessFor = expectedForUser.remove(i);
665 removed.add(revokeAccessFor);
666 service.setPackageOrComponentEnabled(
667 revokeAccessFor, userId, i % 2 == 0, false);
668 }
669 expectedNoAccess.put(userId, removed);
670 }
671 }
672
673 // verify everything still there is approved
674 for (int userId : expectedEnabled.keySet()) {
675 ArrayList<String> expectedForUser = expectedEnabled.get(userId);
676 for (int i = 0; i < expectedForUser.size(); i++) {
677 String verifyValue = (approvalLevel == APPROVAL_BY_COMPONENT)
678 ? expectedForUser.get(i)
679 : service.getPackageName(expectedForUser.get(i));
680 assertTrue("Not allowed: user: " + userId + " entry: " + verifyValue,
681 service.isPackageOrComponentAllowed(verifyValue, userId));
682 }
683 }
684 // verify everything removed isn't
685 for (int userId : expectedNoAccess.keySet()) {
686 ArrayList<String> notExpectedForUser = expectedNoAccess.get(userId);
687 for (int i = 0; i < notExpectedForUser.size(); i++) {
688 assertFalse(
689 "Is allowed: user: " + userId + " entry: " + notExpectedForUser.get(i),
690 service.isPackageOrComponentAllowed(notExpectedForUser.get(i), userId));
691 }
692 }
693 }
694 }
695
696 @Test
Julia Reynolds4c456dd2019-01-07 12:22:00 -0500697 public void testGetAllowedPackages_byUser() throws Exception {
Julia Reynoldsb852e562017-06-06 16:14:18 -0400698 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
699 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
700 mIpm, approvalLevel);
701 loadXml(service);
702
703 List<String> allowedPackagesForUser0 = new ArrayList<>();
704 allowedPackagesForUser0.add("this.is.a.package.name");
705 allowedPackagesForUser0.add("another.package");
706 allowedPackagesForUser0.add("secondary");
707
708 List<String> actual = service.getAllowedPackages(0);
709 assertEquals(3, actual.size());
710 for (String pkg : allowedPackagesForUser0) {
711 assertTrue(actual.contains(pkg));
712 }
713
714 List<String> allowedPackagesForUser10 = new ArrayList<>();
715 allowedPackagesForUser10.add("this.is.another.package");
716 allowedPackagesForUser10.add("package");
717 allowedPackagesForUser10.add("this.is.another.package");
718 allowedPackagesForUser10.add("component");
719
720 actual = service.getAllowedPackages(10);
721 assertEquals(4, actual.size());
722 for (String pkg : allowedPackagesForUser10) {
723 assertTrue(actual.contains(pkg));
724 }
725 }
726 }
727
728 @Test
Julia Reynoldsca8e5352018-09-18 13:39:26 -0400729 public void testGetAllowedComponentsByUser() throws Exception {
Julia Reynoldsb852e562017-06-06 16:14:18 -0400730 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
731 APPROVAL_BY_COMPONENT);
732 loadXml(service);
733
734 List<ComponentName> expected = new ArrayList<>();
735 expected.add(ComponentName.unflattenFromString("this.is.another.package/M1"));
736 expected.add(ComponentName.unflattenFromString("this.is.another.package/with.Component"));
737 expected.add(ComponentName.unflattenFromString("component/2"));
738 expected.add(ComponentName.unflattenFromString("package/component2"));
739
740 List<ComponentName> actual = service.getAllowedComponents(10);
741
742 assertContentsInAnyOrder(expected, actual);
743
744 assertEquals(expected.size(), actual.size());
745
746 for (ComponentName cn : expected) {
747 assertTrue("Actual missing " + cn, actual.contains(cn));
748 }
749
750 for (ComponentName cn : actual) {
751 assertTrue("Actual contains extra " + cn, expected.contains(cn));
752 }
753 }
754
755 @Test
756 public void testGetAllowedComponents_approvalByPackage() throws Exception {
757 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
758 APPROVAL_BY_PACKAGE);
759 loadXml(service);
760
761 assertEquals(0, service.getAllowedComponents(10).size());
762 }
763
Julia Reynolds5aa13a42017-08-24 09:10:23 -0400764 @Test
Julia Reynolds4c456dd2019-01-07 12:22:00 -0500765 public void testGetAllowedPackages() throws Exception {
766 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
767 mIpm, APPROVAL_BY_COMPONENT);
768 loadXml(service);
769 service.mApprovalLevel = APPROVAL_BY_PACKAGE;
770 loadXml(service);
771
772 List<String> allowedPackages = new ArrayList<>();
773 allowedPackages.add("this.is.a.package.name");
774 allowedPackages.add("another.package");
775 allowedPackages.add("secondary");
776 allowedPackages.add("this.is.another.package");
777 allowedPackages.add("package");
778 allowedPackages.add("component");
779 allowedPackages.add("bananas!");
780
781 Set<String> actual = service.getAllowedPackages();
782 assertEquals(allowedPackages.size(), actual.size());
783 for (String pkg : allowedPackages) {
784 assertTrue(actual.contains(pkg));
785 }
786 }
787
788 @Test
Julia Reynolds5aa13a42017-08-24 09:10:23 -0400789 public void testOnUserRemoved() throws Exception {
790 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
791 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
792 mIpm, approvalLevel);
793 loadXml(service);
794
795 ArrayMap<Integer, String> verifyMap = mExpectedPrimary.get(service.mApprovalLevel);
796 String user0 = verifyMap.remove(0);
797 verifyMap = mExpectedSecondary.get(service.mApprovalLevel);
798 user0 = user0 + ":" + verifyMap.remove(0);
799
800 service.onUserRemoved(0);
801
802 for (String verifyValue : user0.split(":")) {
803 if (!TextUtils.isEmpty(verifyValue)) {
804 assertFalse("service type " + service.mApprovalLevel + ":" + verifyValue
805 + " is still allowed",
806 service.isPackageOrComponentAllowed(verifyValue, 0));
807 }
808 }
809
810 verifyExpectedApprovedEntries(service);
811 }
812 }
813
Julia Reynolds70aaea72018-07-13 13:38:34 -0400814 @Test
815 public void testIsSameUser() {
816 IInterface service = mock(IInterface.class);
817 when(service.asBinder()).thenReturn(mock(IBinder.class));
818 ManagedServices services = new TestManagedServices(getContext(), mLock, mUserProfiles,
819 mIpm, APPROVAL_BY_PACKAGE);
820 services.registerService(service, null, 10);
821 ManagedServices.ManagedServiceInfo info = services.checkServiceTokenLocked(service);
822 info.isSystem = true;
823
824 assertFalse(services.isSameUser(service, 0));
825 assertTrue(services.isSameUser(service, 10));
826 }
827
Julia Reynoldsca8e5352018-09-18 13:39:26 -0400828 @Test
829 public void testGetAllowedComponents() throws Exception {
830 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
831 APPROVAL_BY_COMPONENT);
832 loadXml(service);
833
834 SparseArray<ArraySet<ComponentName>> expected = new SparseArray<>();
835
836 ArraySet<ComponentName> expected10 = new ArraySet<>();
837 expected10.add(ComponentName.unflattenFromString("this.is.another.package/M1"));
838 expected10.add(ComponentName.unflattenFromString("this.is.another.package/with.Component"));
839 expected10.add(ComponentName.unflattenFromString("component/2"));
840 expected10.add(ComponentName.unflattenFromString("package/component2"));
841 expected.put(10, expected10);
842 ArraySet<ComponentName> expected0 = new ArraySet<>();
843 expected0.add(ComponentName.unflattenFromString("secondary/component.Name"));
844 expected0.add(ComponentName.unflattenFromString("this.is.a.package.name/Ba"));
845 expected0.add(ComponentName.unflattenFromString("another.package/B1"));
846 expected.put(0, expected0);
847 ArraySet<ComponentName> expected12 = new ArraySet<>();
848 expected12.add(ComponentName.unflattenFromString("bananas!/Bananas!"));
849 expected.put(12, expected12);
850 expected.put(11, new ArraySet<>());
851
852 SparseArray<ArraySet<ComponentName>> actual =
853 service.getAllowedComponents(mUserProfiles.getCurrentProfileIds());
854
855 assertContentsInAnyOrder(expected, actual);
856 }
857
858 @Test
859 public void testPopulateComponentsToUnbind_forceRebind() {
860 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
861 APPROVAL_BY_COMPONENT);
862
863 IInterface iInterface = mock(IInterface.class);
864 when(iInterface.asBinder()).thenReturn(mock(IBinder.class));
865
866 ManagedServices.ManagedServiceInfo service0 = service.new ManagedServiceInfo(
867 iInterface, ComponentName.unflattenFromString("a/a"), 0, false,
868 mock(ServiceConnection.class), 26);
869 ManagedServices.ManagedServiceInfo service10 = service.new ManagedServiceInfo(
870 iInterface, ComponentName.unflattenFromString("b/b"), 10, false,
871 mock(ServiceConnection.class), 26);
872 Set<ManagedServices.ManagedServiceInfo> removableBoundServices = new ArraySet<>();
873 removableBoundServices.add(service0);
874 removableBoundServices.add(service10);
875
876 SparseArray<Set<ComponentName>> allowedComponentsToBind = new SparseArray<>();
877 Set<ComponentName> allowed0 = new ArraySet<>();
878 allowed0.add(ComponentName.unflattenFromString("a/a"));
879 allowedComponentsToBind.put(0, allowed0);
880 Set<ComponentName> allowed10 = new ArraySet<>();
881 allowed10.add(ComponentName.unflattenFromString("b/b"));
882 allowedComponentsToBind.put(10, allowed10);
883
884 SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
885
886 service.populateComponentsToUnbind(true, removableBoundServices, allowedComponentsToBind,
887 componentsToUnbind);
888
889 assertEquals(2, componentsToUnbind.size());
890 assertTrue(componentsToUnbind.get(0).contains(ComponentName.unflattenFromString("a/a")));
891 assertTrue(componentsToUnbind.get(10).contains(ComponentName.unflattenFromString("b/b")));
892 }
893
894 @Test
895 public void testPopulateComponentsToUnbind() {
896 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
897 APPROVAL_BY_COMPONENT);
898
899 IInterface iInterface = mock(IInterface.class);
900 when(iInterface.asBinder()).thenReturn(mock(IBinder.class));
901
902 ManagedServices.ManagedServiceInfo service0 = service.new ManagedServiceInfo(
903 iInterface, ComponentName.unflattenFromString("a/a"), 0, false,
904 mock(ServiceConnection.class), 26);
905 ManagedServices.ManagedServiceInfo service0a = service.new ManagedServiceInfo(
906 iInterface, ComponentName.unflattenFromString("c/c"), 0, false,
907 mock(ServiceConnection.class), 26);
908 ManagedServices.ManagedServiceInfo service10 = service.new ManagedServiceInfo(
909 iInterface, ComponentName.unflattenFromString("b/b"), 10, false,
910 mock(ServiceConnection.class), 26);
911 Set<ManagedServices.ManagedServiceInfo> removableBoundServices = new ArraySet<>();
912 removableBoundServices.add(service0);
913 removableBoundServices.add(service0a);
914 removableBoundServices.add(service10);
915
916 SparseArray<Set<ComponentName>> allowedComponentsToBind = new SparseArray<>();
917 Set<ComponentName> allowed0 = new ArraySet<>();
918 allowed0.add(ComponentName.unflattenFromString("a/a"));
919 allowedComponentsToBind.put(0, allowed0);
920 Set<ComponentName> allowed10 = new ArraySet<>();
921 allowed10.add(ComponentName.unflattenFromString("b/b"));
922 allowedComponentsToBind.put(10, allowed10);
923
924 SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
925
926 service.populateComponentsToUnbind(false, removableBoundServices, allowedComponentsToBind,
927 componentsToUnbind);
928
929 assertEquals(1, componentsToUnbind.size());
930 assertEquals(1, componentsToUnbind.get(0).size());
931 assertTrue(componentsToUnbind.get(0).contains(ComponentName.unflattenFromString("c/c")));
932 }
933
934 @Test
935 public void populateComponentsToBind() {
936 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
937 APPROVAL_BY_COMPONENT);
938
939 SparseArray<ArraySet<ComponentName>> approvedComponentsByUser = new SparseArray<>();
940 ArraySet<ComponentName> allowed0 = new ArraySet<>();
941 allowed0.add(ComponentName.unflattenFromString("a/a"));
942 approvedComponentsByUser.put(0, allowed0);
943 ArraySet<ComponentName> allowed10 = new ArraySet<>();
944 allowed10.add(ComponentName.unflattenFromString("b/b"));
945 allowed10.add(ComponentName.unflattenFromString("c/c"));
946 approvedComponentsByUser.put(10, allowed10);
947 ArraySet<ComponentName> allowed15 = new ArraySet<>();
948 allowed15.add(ComponentName.unflattenFromString("d/d"));
949 approvedComponentsByUser.put(15, allowed15);
950
951 IntArray users = new IntArray();
952 users.add(10);
953 users.add(0);
954
955 SparseArray<Set<ComponentName>> componentsToBind = new SparseArray<>();
956
957 service.populateComponentsToBind(componentsToBind, users, approvedComponentsByUser);
958
959 assertEquals(2, componentsToBind.size());
960 assertEquals(1, componentsToBind.get(0).size());
961 assertTrue(componentsToBind.get(0).contains(ComponentName.unflattenFromString("a/a")));
962 assertEquals(2, componentsToBind.get(10).size());
963 assertTrue(componentsToBind.get(10).contains(ComponentName.unflattenFromString("b/b")));
964 assertTrue(componentsToBind.get(10).contains(ComponentName.unflattenFromString("c/c")));
965 }
966
Beverly42d01902019-01-03 12:47:57 -0500967 @Test
968 public void testOnPackagesChanged_nullValuesPassed_noNullPointers() {
969 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
970 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
971 mIpm, approvalLevel);
972 // null uid list
973 service.onPackagesChanged(true, new String[]{"this.is.a.package.name"}, null);
974
975 // null package list
976 service.onPackagesChanged(true, null, new int[]{103});
977 }
978 }
979
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400980 private void loadXml(ManagedServices service) throws Exception {
Julia Reynoldsb852e562017-06-06 16:14:18 -0400981 final StringBuffer xml = new StringBuffer();
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400982 xml.append("<" + service.getConfig().xmlTag + ">\n");
Julia Reynoldsb852e562017-06-06 16:14:18 -0400983 for (int userId : mExpectedPrimary.get(service.mApprovalLevel).keySet()) {
984 xml.append(getXmlEntry(
985 mExpectedPrimary.get(service.mApprovalLevel).get(userId), userId, true));
986 }
987 for (int userId : mExpectedSecondary.get(service.mApprovalLevel).keySet()) {
988 xml.append(getXmlEntry(
989 mExpectedSecondary.get(service.mApprovalLevel).get(userId), userId, false));
990 }
Julia Reynolds45523002017-09-12 09:43:57 -0400991 xml.append("<" + ManagedServices.TAG_MANAGED_SERVICES + " "
992 + ManagedServices.ATT_USER_ID + "=\"99\" "
993 + ManagedServices.ATT_IS_PRIMARY + "=\"true\" "
994 + ManagedServices.ATT_APPROVED_LIST + "=\"99\" />\n");
995 xml.append("<" + ManagedServices.TAG_MANAGED_SERVICES + " "
996 + ManagedServices.ATT_USER_ID + "=\"98\" "
997 + ManagedServices.ATT_IS_PRIMARY + "=\"false\" "
998 + ManagedServices.ATT_APPROVED_LIST + "=\"98\" />\n");
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -0400999 xml.append("</" + service.getConfig().xmlTag + ">");
Julia Reynoldsb852e562017-06-06 16:14:18 -04001000
1001 XmlPullParser parser = Xml.newPullParser();
1002 parser.setInput(new BufferedInputStream(
1003 new ByteArrayInputStream(xml.toString().getBytes())), null);
1004 parser.nextTag();
Annie Meng8b646fd2019-02-01 18:46:42 +00001005 service.readXml(parser, null, false, UserHandle.USER_ALL);
1006 }
1007
1008 private XmlPullParser getParserWithEntries(ManagedServices service, String... xmlEntries)
1009 throws Exception {
1010 final StringBuffer xml = new StringBuffer();
1011 xml.append("<" + service.getConfig().xmlTag + ">\n");
1012 for (String xmlEntry : xmlEntries) {
1013 xml.append(xmlEntry);
1014 }
1015 xml.append("</" + service.getConfig().xmlTag + ">");
1016
1017 XmlPullParser parser = Xml.newPullParser();
1018 parser.setInput(new BufferedInputStream(
1019 new ByteArrayInputStream(xml.toString().getBytes())), null);
1020 parser.nextTag();
1021 return parser;
Julia Reynoldsb852e562017-06-06 16:14:18 -04001022 }
1023
1024 private void addExpectedServices(final ManagedServices service, final List<String> packages,
1025 int userId) {
1026 when(mPm.queryIntentServicesAsUser(any(), anyInt(), eq(userId))).
1027 thenAnswer(new Answer<List<ResolveInfo>>() {
1028 @Override
1029 public List<ResolveInfo> answer(InvocationOnMock invocationOnMock)
1030 throws Throwable {
1031 Object[] args = invocationOnMock.getArguments();
1032 Intent invocationIntent = (Intent) args[0];
1033 if (invocationIntent != null) {
1034 if (invocationIntent.getAction().equals(
1035 service.getConfig().serviceInterface)
1036 && packages.contains(invocationIntent.getPackage())) {
1037 List<ResolveInfo> dummyServices = new ArrayList<>();
1038 for (int i = 1; i <= 3; i ++) {
1039 ResolveInfo resolveInfo = new ResolveInfo();
1040 ServiceInfo serviceInfo = new ServiceInfo();
1041 serviceInfo.packageName = invocationIntent.getPackage();
1042 serviceInfo.name = "C"+i;
1043 serviceInfo.permission = service.getConfig().bindPermission;
1044 resolveInfo.serviceInfo = serviceInfo;
1045 dummyServices.add(resolveInfo);
1046 }
1047 return dummyServices;
1048 }
1049 }
1050 return new ArrayList<>();
1051 }
1052 });
1053 }
1054
1055 private List<String> stringToList(String list) {
1056 if (list == null) {
1057 list = "";
1058 }
1059 return new ArrayList<>(Lists.newArrayList(list.split(
1060 ManagedServices.ENABLED_SERVICES_SEPARATOR)));
1061 }
1062
Julia Reynoldsca8e5352018-09-18 13:39:26 -04001063 private void assertContentsInAnyOrder(Collection<?> expected, Collection<?> actual) {
1064 assertNotNull(actual);
Julia Reynoldsb852e562017-06-06 16:14:18 -04001065 assertEquals(expected.size(), actual.size());
1066
1067 for (Object o : expected) {
1068 assertTrue("Actual missing " + o, actual.contains(o));
1069 }
1070
1071 for (Object o : actual) {
1072 assertTrue("Actual contains extra " + o, expected.contains(o));
1073 }
1074 }
1075
Julia Reynoldsca8e5352018-09-18 13:39:26 -04001076 private void assertContentsInAnyOrder(SparseArray<ArraySet<ComponentName>> expected,
1077 SparseArray<ArraySet<ComponentName>> actual) throws Exception {
1078 assertEquals(expected.size(), actual.size());
1079
1080 for (int i = 0; i < expected.size(); i++) {
1081 int key = expected.keyAt(i);
1082 assertTrue(actual.indexOfKey(key) >= 0);
1083 try {
1084 assertContentsInAnyOrder(expected.valueAt(i), actual.get(key));
1085 } catch (Throwable t) {
1086 throw new Exception("Error validating " + key, t);
1087 }
1088 }
1089 }
1090
Julia Reynoldsb852e562017-06-06 16:14:18 -04001091 private void verifyExpectedBoundEntries(ManagedServices service, boolean primary)
1092 throws Exception {
1093 ArrayMap<Integer, String> verifyMap = primary ? mExpectedPrimary.get(service.mApprovalLevel)
1094 : mExpectedSecondary.get(service.mApprovalLevel);
1095 for (int userId : verifyMap.keySet()) {
1096 for (String packageOrComponent : verifyMap.get(userId).split(":")) {
1097 if (!TextUtils.isEmpty(packageOrComponent)) {
1098 if (service.mApprovalLevel == APPROVAL_BY_PACKAGE) {
Julia Reynolds5aa13a42017-08-24 09:10:23 -04001099 assertTrue(packageOrComponent,
1100 service.isComponentEnabledForPackage(packageOrComponent));
Julia Reynolds14590742018-07-30 09:25:35 -04001101 for (int i = 1; i <= 3; i++) {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001102 ComponentName componentName = ComponentName.unflattenFromString(
1103 packageOrComponent +"/C" + i);
1104 assertTrue(service.isComponentEnabledForCurrentProfiles(
1105 componentName));
1106 verify(mIpm, times(1)).getServiceInfo(
1107 eq(componentName), anyInt(), anyInt());
1108 }
1109 } else {
1110 ComponentName componentName =
1111 ComponentName.unflattenFromString(packageOrComponent);
1112 assertTrue(service.isComponentEnabledForCurrentProfiles(componentName));
1113 verify(mIpm, times(1)).getServiceInfo(
1114 eq(componentName), anyInt(), anyInt());
1115 }
1116 }
1117 }
1118 }
1119 }
1120
1121 private void verifyExpectedApprovedEntries(ManagedServices service) {
1122 verifyExpectedApprovedEntries(service, true);
1123 verifyExpectedApprovedEntries(service, false);
1124 }
1125
1126 private void verifyExpectedApprovedEntries(ManagedServices service, boolean primary) {
1127 ArrayMap<Integer, String> verifyMap = primary
1128 ? mExpectedPrimary.get(service.mApprovalLevel)
1129 : mExpectedSecondary.get(service.mApprovalLevel);
Julia Reynoldsfa206a42017-08-14 13:22:23 -04001130 verifyExpectedApprovedEntries(service, verifyMap);
1131 }
1132
1133 private void verifyExpectedApprovedEntries(ManagedServices service,
1134 ArrayMap<Integer, String> verifyMap) {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001135 for (int userId : verifyMap.keySet()) {
1136 for (String verifyValue : verifyMap.get(userId).split(":")) {
1137 if (!TextUtils.isEmpty(verifyValue)) {
1138 assertTrue("service type " + service.mApprovalLevel + ":"
Julia Reynoldsfa206a42017-08-14 13:22:23 -04001139 + verifyValue + " is not allowed for user " + userId,
Julia Reynoldsb852e562017-06-06 16:14:18 -04001140 service.isPackageOrComponentAllowed(verifyValue, userId));
1141 }
1142 }
1143 }
1144 }
1145
Julia Reynolds14590742018-07-30 09:25:35 -04001146
1147 private void verifyExpectedApprovedPackages(ManagedServices service) {
1148 verifyExpectedApprovedPackages(service, true);
1149 verifyExpectedApprovedPackages(service, false);
1150 }
1151
1152 private void verifyExpectedApprovedPackages(ManagedServices service, boolean primary) {
1153 ArrayMap<Integer, String> verifyMap = primary
1154 ? mExpectedPrimary.get(service.mApprovalLevel)
1155 : mExpectedSecondary.get(service.mApprovalLevel);
1156 verifyExpectedApprovedPackages(service, verifyMap);
1157 }
1158
1159 private void verifyExpectedApprovedPackages(ManagedServices service,
1160 ArrayMap<Integer, String> verifyMap) {
1161 for (int userId : verifyMap.keySet()) {
1162 for (String verifyValue : verifyMap.get(userId).split(":")) {
1163 if (!TextUtils.isEmpty(verifyValue)) {
1164 ComponentName component = ComponentName.unflattenFromString(verifyValue);
1165 if (component != null ) {
1166 assertTrue("service type " + service.mApprovalLevel + ":"
1167 + verifyValue + " is not allowed for user " + userId,
1168 service.isPackageAllowed(component.getPackageName(), userId));
1169 } else {
1170 assertTrue("service type " + service.mApprovalLevel + ":"
1171 + verifyValue + " is not allowed for user " + userId,
1172 service.isPackageAllowed(verifyValue, userId));
1173 }
1174 }
1175 }
1176 }
1177 }
1178
Julia Reynoldsb852e562017-06-06 16:14:18 -04001179 private void writeExpectedValuesToSettings(int approvalLevel) {
1180 for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) {
1181 Settings.Secure.putStringForUser(getContext().getContentResolver(), SETTING,
1182 mExpectedPrimary.get(approvalLevel).get(userId), userId);
1183 }
1184 for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) {
1185 Settings.Secure.putStringForUser(getContext().getContentResolver(), SECONDARY_SETTING,
1186 mExpectedSecondary.get(approvalLevel).get(userId), userId);
1187 }
1188 }
1189
1190 private String getXmlEntry(String approved, int userId, boolean isPrimary) {
1191 return "<" + ManagedServices.TAG_MANAGED_SERVICES + " "
1192 + ManagedServices.ATT_USER_ID + "=\"" + userId +"\" "
1193 + ManagedServices.ATT_IS_PRIMARY + "=\"" + isPrimary +"\" "
1194 + ManagedServices.ATT_APPROVED_LIST + "=\"" + approved +"\" "
1195 + "/>\n";
1196 }
1197
1198 class TestManagedServices extends ManagedServices {
1199
1200 public TestManagedServices(Context context, Object mutex, UserProfiles userProfiles,
1201 IPackageManager pm, int approvedServiceType) {
1202 super(context, mutex, userProfiles, pm);
1203 mApprovalLevel = approvedServiceType;
1204 }
1205
1206 @Override
1207 protected Config getConfig() {
1208 final Config c = new Config();
Julia Reynoldsd1bf5f02017-07-11 10:39:58 -04001209 c.xmlTag = "test";
Julia Reynoldsb852e562017-06-06 16:14:18 -04001210 c.secureSettingName = SETTING;
1211 c.secondarySettingName = SECONDARY_SETTING;
1212 c.bindPermission = "permission";
1213 c.serviceInterface = "serviceInterface";
1214 return c;
1215 }
1216
1217 @Override
1218 protected IInterface asInterface(IBinder binder) {
1219 return null;
1220 }
1221
1222 @Override
1223 protected boolean checkType(IInterface service) {
Julia Reynoldsca8e5352018-09-18 13:39:26 -04001224 return true;
Julia Reynoldsb852e562017-06-06 16:14:18 -04001225 }
1226
1227 @Override
1228 protected void onServiceAdded(ManagedServiceInfo info) {
1229
1230 }
Julia Reynoldsd0ceefa2019-03-03 16:10:52 -05001231
1232 @Override
1233 protected String getRequiredPermission() {
1234 return null;
1235 }
Julia Reynoldsb852e562017-06-06 16:14:18 -04001236 }
1237}