1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.server.notification;
17 
18 import static com.android.server.notification.ManagedServices.APPROVAL_BY_COMPONENT;
19 import static com.android.server.notification.ManagedServices.APPROVAL_BY_PACKAGE;
20 
21 import static junit.framework.Assert.assertEquals;
22 import static junit.framework.Assert.assertFalse;
23 import static junit.framework.Assert.assertNotNull;
24 import static junit.framework.Assert.assertTrue;
25 
26 import static org.mockito.ArgumentMatchers.anyString;
27 import static org.mockito.Matchers.any;
28 import static org.mockito.Matchers.anyInt;
29 import static org.mockito.Matchers.eq;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.never;
32 import static org.mockito.Mockito.times;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
35 
36 import android.content.ComponentName;
37 import android.content.Context;
38 import android.content.Intent;
39 import android.content.ServiceConnection;
40 import android.content.pm.ApplicationInfo;
41 import android.content.pm.IPackageManager;
42 import android.content.pm.PackageManager;
43 import android.content.pm.ResolveInfo;
44 import android.content.pm.ServiceInfo;
45 import android.content.pm.UserInfo;
46 import android.os.Build;
47 import android.os.IBinder;
48 import android.os.IInterface;
49 import android.os.UserHandle;
50 import android.os.UserManager;
51 import android.provider.Settings;
52 import android.text.TextUtils;
53 import android.util.ArrayMap;
54 import android.util.ArraySet;
55 import android.util.IntArray;
56 import android.util.SparseArray;
57 import android.util.TypedXmlPullParser;
58 import android.util.TypedXmlSerializer;
59 import android.util.Xml;
60 
61 import com.android.internal.util.XmlUtils;
62 import com.android.server.UiServiceTestCase;
63 
64 import com.google.android.collect.Lists;
65 
66 import org.junit.Before;
67 import org.junit.Test;
68 import org.mockito.ArgumentCaptor;
69 import org.mockito.Mock;
70 import org.mockito.MockitoAnnotations;
71 import org.mockito.invocation.InvocationOnMock;
72 import org.mockito.stubbing.Answer;
73 
74 import java.io.BufferedInputStream;
75 import java.io.BufferedOutputStream;
76 import java.io.ByteArrayInputStream;
77 import java.io.ByteArrayOutputStream;
78 import java.nio.charset.StandardCharsets;
79 import java.util.ArrayList;
80 import java.util.Arrays;
81 import java.util.Collection;
82 import java.util.Collections;
83 import java.util.List;
84 import java.util.Set;
85 
86 public class ManagedServicesTest extends UiServiceTestCase {
87 
88     @Mock
89     private IPackageManager mIpm;
90     @Mock
91     private PackageManager mPm;
92     @Mock
93     private UserManager mUm;
94     @Mock
95     private ManagedServices.UserProfiles mUserProfiles;
96     Object mLock = new Object();
97 
98     UserInfo mZero = new UserInfo(0, "zero", 0);
99     UserInfo mTen = new UserInfo(10, "ten", 0);
100     private String mDefaultsString;
101     private String mVersionString;
102     private final Set<ComponentName> mDefaults = new ArraySet();
103     private ManagedServices mService;
104     private String mUserSetString;
105 
106     private static final String SETTING = "setting";
107     private static final String SECONDARY_SETTING = "secondary_setting";
108 
109     private ArrayMap<Integer, String> mExpectedPrimaryPackages;
110     private ArrayMap<Integer, String> mExpectedPrimaryComponentNames;
111     private ArrayMap<Integer, String> mExpectedSecondaryPackages;
112     private ArrayMap<Integer, String> mExpectedSecondaryComponentNames;
113 
114     // type : user : list of approved
115     private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedPrimary;
116     private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedSecondary;
117 
118     @Before
setUp()119     public void setUp() throws Exception {
120         MockitoAnnotations.initMocks(this);
121 
122         getContext().setMockPackageManager(mPm);
123         getContext().addMockSystemService(Context.USER_SERVICE, mUm);
124 
125         List<UserInfo> users = new ArrayList<>();
126         users.add(mZero);
127         users.add(mTen);
128         users.add(new UserInfo(11, "11", 0));
129         users.add(new UserInfo(12, "12", 0));
130         users.add(new UserInfo(13, "13", 0));
131         for (UserInfo user : users) {
132             when(mUm.getUserInfo(eq(user.id))).thenReturn(user);
133         }
134         when(mUm.getUsers()).thenReturn(users);
135         IntArray profileIds = new IntArray();
136         profileIds.add(0);
137         profileIds.add(11);
138         profileIds.add(10);
139         profileIds.add(12);
140         profileIds.add(13);
141         when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
142 
143         mVersionString = "4";
144         mExpectedPrimary = new ArrayMap<>();
145         mExpectedSecondary = new ArrayMap<>();
146         mExpectedPrimaryPackages = new ArrayMap<>();
147         mExpectedPrimaryPackages.put(0, "this.is.a.package.name:another.package");
148         mExpectedPrimaryPackages.put(10, "this.is.another.package");
149         mExpectedPrimaryPackages.put(11, "");
150         mExpectedPrimaryPackages.put(12, "bananas!");
151         mExpectedPrimaryPackages.put(13, "non.user.set.package");
152         mExpectedPrimaryComponentNames = new ArrayMap<>();
153         mExpectedPrimaryComponentNames.put(0, "this.is.a.package.name/Ba:another.package/B1");
154         mExpectedPrimaryComponentNames.put(10, "this.is.another.package/M1");
155         mExpectedPrimaryComponentNames.put(11, "");
156         mExpectedPrimaryComponentNames.put(12, "bananas!/Bananas!");
157         mExpectedPrimaryComponentNames.put(13, "non.user.set.package/M1");
158         mExpectedPrimary.put(APPROVAL_BY_PACKAGE, mExpectedPrimaryPackages);
159         mExpectedPrimary.put(APPROVAL_BY_COMPONENT, mExpectedPrimaryComponentNames);
160 
161         mExpectedSecondaryComponentNames = new ArrayMap<>();
162         mExpectedSecondaryComponentNames.put(0, "secondary/component.Name");
163         mExpectedSecondaryComponentNames.put(10,
164                 "this.is.another.package/with.Component:component/2:package/component2");
165         mExpectedSecondaryPackages = new ArrayMap<>();
166         mExpectedSecondaryPackages.put(0, "secondary");
167         mExpectedSecondaryPackages.put(10,
168                 "this.is.another.package:component:package");
169         mExpectedSecondary.put(APPROVAL_BY_PACKAGE, mExpectedSecondaryPackages);
170         mExpectedSecondary.put(APPROVAL_BY_COMPONENT, mExpectedSecondaryComponentNames);
171         mService = new TestManagedServices(getContext(), mLock, mUserProfiles,
172                 mIpm, APPROVAL_BY_COMPONENT);
173     }
174 
175     @Test
testBackupAndRestore_migration()176     public void testBackupAndRestore_migration() throws Exception {
177         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
178             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
179                     mIpm, approvalLevel);
180 
181             for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) {
182                 service.onSettingRestored(
183                         service.getConfig().secureSettingName,
184                         mExpectedPrimary.get(approvalLevel).get(userId),
185                         Build.VERSION_CODES.O, userId);
186             }
187             verifyExpectedApprovedEntries(service, true);
188 
189             for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) {
190                 service.onSettingRestored(service.getConfig().secondarySettingName,
191                         mExpectedSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.O,
192                         userId);
193             }
194             verifyExpectedApprovedEntries(service);
195         }
196     }
197 
198     @Test
testBackupAndRestore_migration_preO()199     public void testBackupAndRestore_migration_preO() throws Exception {
200         ArrayMap<Integer, String> backupPrimaryPackages = new ArrayMap<>();
201         backupPrimaryPackages.put(0, "backup.0:backup:0a");
202         backupPrimaryPackages.put(10, "10.backup");
203         backupPrimaryPackages.put(11, "eleven");
204         backupPrimaryPackages.put(12, "");
205         ArrayMap<Integer, String> backupPrimaryComponentNames = new ArrayMap<>();
206         backupPrimaryComponentNames.put(0, "backup.first/whatever:a/b");
207         backupPrimaryComponentNames.put(10, "again/M1");
208         backupPrimaryComponentNames.put(11, "orange/youglad:itisnot/banana");
209         backupPrimaryComponentNames.put(12, "");
210         ArrayMap<Integer, ArrayMap<Integer, String>> backupPrimary = new ArrayMap<>();
211         backupPrimary.put(APPROVAL_BY_PACKAGE, backupPrimaryPackages);
212         backupPrimary.put(APPROVAL_BY_COMPONENT, backupPrimaryComponentNames);
213 
214         ArrayMap<Integer, String> backupSecondaryComponentNames = new ArrayMap<>();
215         backupSecondaryComponentNames.put(0, "secondary.1/component.Name");
216         backupSecondaryComponentNames.put(10,
217                 "this.is.another.package.backup/with.Component:component.backup/2");
218         ArrayMap<Integer, String> backupSecondaryPackages = new ArrayMap<>();
219         backupSecondaryPackages.put(0, "");
220         backupSecondaryPackages.put(10,
221                 "this.is.another.package.backup:package.backup");
222         ArrayMap<Integer, ArrayMap<Integer, String>> backupSecondary = new ArrayMap<>();
223         backupSecondary.put(APPROVAL_BY_PACKAGE, backupSecondaryPackages);
224         backupSecondary.put(APPROVAL_BY_COMPONENT, backupSecondaryComponentNames);
225 
226         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
227             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
228                     mIpm, approvalLevel);
229 
230             // not an expected flow but a way to get data into the settings
231             for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) {
232                 service.onSettingRestored(
233                         service.getConfig().secureSettingName,
234                         mExpectedPrimary.get(approvalLevel).get(userId),
235                         Build.VERSION_CODES.O, userId);
236             }
237 
238             for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) {
239                 service.onSettingRestored(service.getConfig().secondarySettingName,
240                         mExpectedSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.O,
241                         userId);
242             }
243 
244             // actual test
245             for (int userId : backupPrimary.get(approvalLevel).keySet()) {
246                 service.onSettingRestored(
247                         service.getConfig().secureSettingName,
248                         backupPrimary.get(approvalLevel).get(userId),
249                         Build.VERSION_CODES.N_MR1, userId);
250             }
251 
252             for (int userId : backupSecondary.get(approvalLevel).keySet()) {
253                 service.onSettingRestored(service.getConfig().secondarySettingName,
254                         backupSecondary.get(approvalLevel).get(userId),
255                         Build.VERSION_CODES.N_MR1, userId);
256             }
257             // both sets of approved entries should be allowed
258             verifyExpectedApprovedEntries(service);
259             verifyExpectedApprovedEntries(service, backupPrimary.get(approvalLevel));
260             verifyExpectedApprovedEntries(service, backupSecondary.get(approvalLevel));
261         }
262     }
263 
264     @Test
testReadXml_migrationFromSettings()265     public void testReadXml_migrationFromSettings() throws Exception {
266         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
267             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
268                     mIpm, approvalLevel);
269 
270             // approved services aren't in xml
271             TypedXmlPullParser parser = Xml.newFastPullParser();
272             parser.setInput(new BufferedInputStream(new ByteArrayInputStream(new byte[]{})),
273                     null);
274             writeExpectedValuesToSettings(approvalLevel);
275 
276             service.migrateToXml();
277 
278             verifyExpectedApprovedEntries(service);
279         }
280     }
281 
282     @Test
testReadXml_noLongerMigrateFromSettings()283     public void testReadXml_noLongerMigrateFromSettings() throws Exception {
284         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
285             ManagedServices service = new TestManagedServicesNoSettings(getContext(), mLock,
286                     mUserProfiles, mIpm, approvalLevel);
287 
288             // approved services aren't in xml
289             TypedXmlPullParser parser = Xml.newFastPullParser();
290             parser.setInput(new BufferedInputStream(new ByteArrayInputStream(new byte[]{})),
291                     null);
292             writeExpectedValuesToSettings(approvalLevel);
293 
294             service.migrateToXml();
295             // No crash? success
296 
297             ArrayMap<Integer, String> verifyMap = approvalLevel == APPROVAL_BY_COMPONENT
298                     ? mExpectedPrimary.get(service.mApprovalLevel)
299                     : mExpectedSecondary.get(service.mApprovalLevel);
300             for (int userId : verifyMap.keySet()) {
301                 for (String verifyValue : verifyMap.get(userId).split(":")) {
302                     if (!TextUtils.isEmpty(verifyValue)) {
303                         assertFalse("service type " + service.mApprovalLevel + ":"
304                                         + verifyValue + " is allowed for user " + userId,
305                                 service.isPackageOrComponentAllowed(verifyValue, userId));
306                     }
307                 }
308             }
309         }
310     }
311 
312     @Test
testReadXml()313     public void testReadXml() throws Exception {
314         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
315             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
316                     mIpm, approvalLevel);
317 
318             loadXml(service);
319 
320             verifyExpectedApprovedEntries(service);
321 
322             int[] invalidUsers = new int[] {98, 99};
323             for (int invalidUser : invalidUsers) {
324                 assertFalse("service type " + service.mApprovalLevel + ":"
325                                 + invalidUser + " is allowed for user " + invalidUser,
326                         service.isPackageOrComponentAllowed(
327                                 String.valueOf(invalidUser), invalidUser));
328             }
329         }
330     }
331 
332     @Test
testReadXml_appendsListOfApprovedComponents()333     public void testReadXml_appendsListOfApprovedComponents() throws Exception {
334         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
335             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
336                     mIpm, approvalLevel);
337 
338             String preApprovedPackage = "some.random.package";
339             String preApprovedComponent = "some.random.package/C1";
340 
341             List<String> packages = new ArrayList<>();
342             packages.add(preApprovedPackage);
343             addExpectedServices(service, packages, 0);
344 
345             service.setPackageOrComponentEnabled(preApprovedComponent, 0, true, true);
346 
347             loadXml(service);
348 
349             verifyExpectedApprovedEntries(service);
350 
351             String verifyValue  = (approvalLevel == APPROVAL_BY_COMPONENT)
352                     ? preApprovedComponent
353                     : preApprovedPackage;
354             assertTrue(service.isPackageOrComponentAllowed(verifyValue, 0));
355         }
356     }
357 
358     /** Test that restore ignores the user id attribute and applies the data to the target user. */
359     @Test
testReadXml_onlyRestoresForTargetUser()360     public void testReadXml_onlyRestoresForTargetUser() throws Exception {
361         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
362             ManagedServices service =
363                     new TestManagedServices(
364                             getContext(), mLock, mUserProfiles, mIpm, approvalLevel);
365             String testPackage = "user.test.package";
366             String testComponent = "user.test.component/C1";
367             String resolvedValue =
368                     (approvalLevel == APPROVAL_BY_COMPONENT) ? testComponent : testPackage;
369             TypedXmlPullParser parser =
370                     getParserWithEntries(service, getXmlEntry(resolvedValue, 0, true));
371 
372             service.readXml(parser, null, true, 10);
373 
374             assertFalse(service.isPackageOrComponentAllowed(resolvedValue, 0));
375             assertTrue(service.isPackageOrComponentAllowed(resolvedValue, 10));
376         }
377     }
378 
379     /** Test that restore correctly parses the user_set attribute. */
380     @Test
testReadXml_restoresUserSet()381     public void testReadXml_restoresUserSet() throws Exception {
382         mVersionString = "4";
383         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
384             ManagedServices service =
385                     new TestManagedServices(
386                             getContext(), mLock, mUserProfiles, mIpm, approvalLevel);
387             String testPackage = "user.test.package";
388             String testComponent = "user.test.component/C1";
389             String resolvedValue =
390                     (approvalLevel == APPROVAL_BY_COMPONENT) ? testComponent : testPackage;
391             String xmlEntry = getXmlEntry(resolvedValue, 0, true, false);
392             TypedXmlPullParser parser = getParserWithEntries(service, xmlEntry);
393 
394             service.readXml(parser, null, true, 0);
395 
396             assertFalse("Failed while parsing xml:\n" + xmlEntry,
397                     service.isPackageOrComponentUserSet(resolvedValue, 0));
398 
399             xmlEntry = getXmlEntry(resolvedValue, 0, true, true);
400             parser = getParserWithEntries(service, xmlEntry);
401 
402             service.readXml(parser, null, true, 0);
403 
404             assertTrue("Failed while parsing xml:\n" + xmlEntry,
405                     service.isPackageOrComponentUserSet(resolvedValue, 0));
406         }
407     }
408 
409     /** Test that restore ignores the user id attribute and applies the data to the target user. */
410     @Test
testWriteReadXml_writeReadDefaults()411     public void testWriteReadXml_writeReadDefaults() throws Exception {
412         // setup
413         ManagedServices service1 =
414                 new TestManagedServices(
415                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
416         ManagedServices service2 =
417                 new TestManagedServices(
418                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
419         TypedXmlSerializer serializer = Xml.newFastSerializer();
420         ByteArrayOutputStream baos = new ByteArrayOutputStream();
421         BufferedOutputStream outStream = new BufferedOutputStream(baos);
422         serializer.setOutput(outStream, "utf-8");
423 
424         //data setup
425         service1.addDefaultComponentOrPackage("package/class");
426         serializer.startDocument(null, true);
427         service1.writeXml(serializer, false, 0);
428         serializer.endDocument();
429         outStream.flush();
430 
431         final TypedXmlPullParser parser = Xml.newFastPullParser();
432         BufferedInputStream input = new BufferedInputStream(
433                 new ByteArrayInputStream(baos.toByteArray()));
434 
435         parser.setInput(input, StandardCharsets.UTF_8.name());
436         XmlUtils.beginDocument(parser, "test");
437         service2.readXml(parser, null, false, 0);
438         ArraySet<ComponentName> defaults = service2.getDefaultComponents();
439 
440         assertEquals(1, defaults.size());
441         assertEquals(new ComponentName("package", "class"), defaults.valueAt(0));
442     }
443 
444     @Test
resetPackage_enableDefaultsOnly()445     public void resetPackage_enableDefaultsOnly() {
446         // setup
447         ManagedServices service =
448                 new TestManagedServices(
449                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
450         service.addApprovedList(
451                 "package/not-default:another-package/not-default:package2/default",
452                 0, true);
453         service.addDefaultComponentOrPackage("package/default");
454         service.addDefaultComponentOrPackage("package2/default");
455 
456         ArrayMap<Boolean, ArrayList<ComponentName>> componentsToActivate =
457                 service.resetComponents("package", 0);
458 
459         assertEquals(1, componentsToActivate.get(true).size());
460         assertEquals(new ComponentName("package", "default"),
461                 componentsToActivate.get(true).get(0));
462     }
463 
464 
465     @Test
resetPackage_nonDefaultsRemoved()466     public void resetPackage_nonDefaultsRemoved() {
467         // setup
468         ManagedServices service =
469                 new TestManagedServices(
470                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
471         service.addApprovedList(
472                 "package/not-default:another-package/not-default:package2/default",
473                 0, true);
474         service.addDefaultComponentOrPackage("package/default");
475         service.addDefaultComponentOrPackage("package2/default");
476 
477         ArrayMap<Boolean, ArrayList<ComponentName>> componentsToActivate =
478                 service.resetComponents("package", 0);
479 
480         assertEquals(1, componentsToActivate.get(true).size());
481         assertEquals(new ComponentName("package", "not-default"),
482                 componentsToActivate.get(false).get(0));
483     }
484 
485     @Test
resetPackage_onlyDefaultsOnly()486     public void resetPackage_onlyDefaultsOnly() {
487         // setup
488         ManagedServices service =
489                 new TestManagedServices(
490                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
491         service.addApprovedList(
492                 "package/not-default:another-package/not-default:package2/default",
493                 0, true);
494         service.addDefaultComponentOrPackage("package/default");
495         service.addDefaultComponentOrPackage("package2/default");
496 
497         assertEquals(3, service.getAllowedComponents(0).size());
498 
499         service.resetComponents("package", 0);
500 
501         List<ComponentName> components =  service.getAllowedComponents(0);
502         assertEquals(3, components.size());
503         assertTrue(components.contains(new ComponentName("package", "default")));
504     }
505 
506     @Test
resetPackage_affectCurrentUserOnly()507     public void resetPackage_affectCurrentUserOnly() {
508         // setup
509         ManagedServices service =
510                 new TestManagedServices(
511                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
512         service.addApprovedList(
513                 "package/not-default:another-package/not-default:package2/default",
514                 0, true);
515         service.addApprovedList(
516                 "package/not-default:another-package/not-default:package2/default",
517                 1, true);
518         service.addDefaultComponentOrPackage("package/default");
519         service.addDefaultComponentOrPackage("package2/default");
520 
521         service.resetComponents("package", 0);
522 
523         List<ComponentName> components =  service.getAllowedComponents(1);
524         assertEquals(3, components.size());
525     }
526 
527     @Test
resetPackage_samePackageMultipleClasses()528     public void resetPackage_samePackageMultipleClasses() {
529         // setup
530         ManagedServices service =
531                 new TestManagedServices(
532                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
533         service.addApprovedList(
534                 "package/not-default:another-package/not-default:package2/default",
535                 0, true);
536         service.addApprovedList(
537                 "package/class:another-package/class:package2/class",
538                 0, true);
539         service.addDefaultComponentOrPackage("package/default");
540         service.addDefaultComponentOrPackage("package2/default");
541 
542         service.resetComponents("package", 0);
543 
544         List<ComponentName> components =  service.getAllowedComponents(0);
545         assertEquals(5, components.size());
546         assertTrue(components.contains(new ComponentName("package", "default")));
547     }
548 
549     @Test
resetPackage_clearsUserSet()550     public void resetPackage_clearsUserSet() {
551         // setup
552         ManagedServices service =
553                 new TestManagedServices(
554                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
555         String componentName = "package/user-allowed";
556         service.addApprovedList(componentName, 0, true);
557 
558         service.resetComponents("package", 0);
559 
560         assertFalse(service.isPackageOrComponentUserSet(componentName, 0));
561     }
562 
563     /** Test that backup only writes packages/components that belong to the target user. */
564     @Test
testWriteXml_onlyBackupsForTargetUser()565     public void testWriteXml_onlyBackupsForTargetUser() throws Exception {
566         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
567             ManagedServices service =
568                     new TestManagedServices(
569                             getContext(), mLock, mUserProfiles, mIpm, approvalLevel);
570             // Set up components.
571             String testPackage0 = "user0.test.package";
572             String testComponent0 = "user0.test.component/C1";
573             String testPackage10 = "user10.test.package";
574             String testComponent10 = "user10.test.component/C1";
575             String resolvedValue0 =
576                     (approvalLevel == APPROVAL_BY_COMPONENT) ? testComponent0 : testPackage0;
577             String resolvedValue10 =
578                     (approvalLevel == APPROVAL_BY_COMPONENT) ? testComponent10 : testPackage10;
579             addExpectedServices(
580                     service, Collections.singletonList(service.getPackageName(resolvedValue0)), 0);
581             addExpectedServices(
582                     service,
583                     Collections.singletonList(service.getPackageName(resolvedValue10)),
584                     10);
585             TypedXmlPullParser parser =
586                     getParserWithEntries(
587                             service,
588                             getXmlEntry(resolvedValue0, 0, true),
589                             getXmlEntry(resolvedValue10, 10, true));
590             service.readXml(parser, null, false, UserHandle.USER_ALL);
591 
592             // Write backup.
593             TypedXmlSerializer serializer = Xml.newFastSerializer();
594             ByteArrayOutputStream baos = new ByteArrayOutputStream();
595             serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
596             serializer.startDocument(null, true);
597             service.writeXml(serializer, true, 10);
598             serializer.endDocument();
599             serializer.flush();
600 
601             // Reset values.
602             service.setPackageOrComponentEnabled(resolvedValue0, 0, true, false);
603             service.setPackageOrComponentEnabled(resolvedValue10, 10, true, false);
604 
605             // Parse backup via restore.
606             TypedXmlPullParser restoreParser = Xml.newFastPullParser();
607             restoreParser.setInput(
608                     new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), null);
609             restoreParser.nextTag();
610             service.readXml(restoreParser, null, true, 10);
611 
612             assertFalse(service.isPackageOrComponentAllowed(resolvedValue0, 0));
613             assertFalse(service.isPackageOrComponentAllowed(resolvedValue0, 10));
614             assertTrue(service.isPackageOrComponentAllowed(resolvedValue10, 10));
615         }
616     }
617 
618     @Test
testWriteXml_trimsMissingServices()619     public void testWriteXml_trimsMissingServices() throws Exception {
620         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
621             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
622                     mIpm, approvalLevel);
623             loadXml(service);
624 
625             // remove missing
626             mExpectedPrimaryPackages.put(0, "another.package");
627             mExpectedPrimaryPackages.remove(12);
628             mExpectedPrimaryComponentNames.put(0, "another.package/B1");
629             mExpectedPrimaryComponentNames.remove(12);
630             mExpectedSecondaryPackages.put(10, "this.is.another.package:component");
631             mExpectedSecondaryComponentNames.put(
632                     10, "this.is.another.package/with.Component:component/2");
633 
634             for (UserInfo userInfo : mUm.getUsers()) {
635                 List<String> entriesExpectedToHaveServices = new ArrayList<>();
636                 if (mExpectedPrimary.get(approvalLevel).containsKey(userInfo.id)) {
637                     for (String packageOrComponent :
638                             mExpectedPrimary.get(approvalLevel).get(userInfo.id).split(":")) {
639                         if (!TextUtils.isEmpty(packageOrComponent)) {
640                             entriesExpectedToHaveServices.add(
641                                     service.getPackageName(packageOrComponent));
642                         }
643                     }
644                 }
645                 if (mExpectedSecondary.get(approvalLevel).containsKey(userInfo.id)) {
646                     for (String packageOrComponent :
647                             mExpectedSecondary.get(approvalLevel).get(userInfo.id).split(":")) {
648                         if (!TextUtils.isEmpty(packageOrComponent)) {
649                             entriesExpectedToHaveServices.add(
650                                     service.getPackageName(packageOrComponent));
651                         }
652                     }
653                 }
654                 addExpectedServices(service, entriesExpectedToHaveServices, userInfo.id);
655             }
656 
657             TypedXmlSerializer serializer = Xml.newFastSerializer();
658             ByteArrayOutputStream baos = new ByteArrayOutputStream();
659             serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
660             serializer.startDocument(null, true);
661             for (UserInfo userInfo : mUm.getUsers()) {
662                 service.writeXml(serializer, true, userInfo.id);
663             }
664             serializer.endDocument();
665             serializer.flush();
666 
667             TypedXmlPullParser parser = Xml.newFastPullParser();
668             parser.setInput(new BufferedInputStream(
669                     new ByteArrayInputStream(baos.toByteArray())), null);
670             parser.nextTag();
671             for (UserInfo userInfo : mUm.getUsers()) {
672                 service.readXml(parser, null, true, userInfo.id);
673             }
674 
675             verifyExpectedApprovedEntries(service);
676             assertFalse(service.isPackageOrComponentAllowed("this.is.a.package.name", 0));
677             assertFalse(service.isPackageOrComponentAllowed("bananas!", 12));
678             assertFalse(service.isPackageOrComponentAllowed("package/component2", 10));
679         }
680     }
681 
682     @Test
testWriteXml_writesSetting()683     public void testWriteXml_writesSetting() throws Exception {
684         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
685             ManagedServices service = new TestManagedServicesSettings(getContext(), mLock,
686                     mUserProfiles, mIpm, approvalLevel);
687             loadXml(service);
688 
689             TypedXmlSerializer serializer = Xml.newFastSerializer();
690             ByteArrayOutputStream baos = new ByteArrayOutputStream();
691             serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
692             serializer.startDocument(null, true);
693             service.writeXml(serializer, false, UserHandle.USER_ALL);
694             serializer.endDocument();
695             serializer.flush();
696 
697             for (int userId : mUserProfiles.getCurrentProfileIds().toArray()) {
698                 List<String> expected =
699                         stringToList(mExpectedPrimary.get(approvalLevel).get(userId));
700                 List<String> actual = stringToList(Settings.Secure.getStringForUser(
701                         getContext().getContentResolver(),
702                         service.getConfig().secureSettingName, userId));
703                 assertContentsInAnyOrder(actual, expected);
704             }
705         }
706     }
707 
708     @Test
testWriteXml_doesNotWriteSetting()709     public void testWriteXml_doesNotWriteSetting() throws Exception {
710         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
711             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
712                     mIpm, approvalLevel);
713 
714             for (int userId : mUserProfiles.getCurrentProfileIds().toArray()) {
715                 Settings.Secure.putStringForUser(
716                         getContext().getContentResolver(),
717                         service.getConfig().secureSettingName, null, userId);
718             }
719             loadXml(service);
720 
721             TypedXmlSerializer serializer = Xml.newFastSerializer();
722             ByteArrayOutputStream baos = new ByteArrayOutputStream();
723             serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
724             serializer.startDocument(null, true);
725             service.writeXml(serializer, false, UserHandle.USER_ALL);
726             serializer.endDocument();
727             serializer.flush();
728 
729             for (int userId : mUserProfiles.getCurrentProfileIds().toArray()) {
730                 String actual = Settings.Secure.getStringForUser(
731                         getContext().getContentResolver(),
732                         service.getConfig().secureSettingName, userId);
733                 assertTrue(TextUtils.isEmpty(actual));
734             }
735         }
736     }
737 
738     @Test
testWriteXml_writesUserSet()739     public void testWriteXml_writesUserSet() throws Exception {
740         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
741             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
742                     mIpm, approvalLevel);
743             loadXml(service);
744 
745             TypedXmlSerializer serializer = Xml.newFastSerializer();
746             ByteArrayOutputStream baos = new ByteArrayOutputStream();
747             serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
748             serializer.startDocument(null, true);
749             service.writeXml(serializer, false, UserHandle.USER_ALL);
750             serializer.endDocument();
751             serializer.flush();
752 
753             TypedXmlPullParser parser = Xml.newFastPullParser();
754             byte[] rawOutput = baos.toByteArray();
755             parser.setInput(new BufferedInputStream(
756                     new ByteArrayInputStream(rawOutput)), null);
757             parser.nextTag();
758             for (UserInfo userInfo : mUm.getUsers()) {
759                 service.readXml(parser, null, true, userInfo.id);
760             }
761 
762             String resolvedUserSetComponent = approvalLevel == APPROVAL_BY_PACKAGE
763                     ? mExpectedPrimaryPackages.get(10)
764                     : mExpectedPrimaryComponentNames.get(10);
765             String resolvedNonUserSetComponent = approvalLevel == APPROVAL_BY_PACKAGE
766                     ? mExpectedPrimaryPackages.get(13)
767                     : mExpectedPrimaryComponentNames.get(13);
768 
769             try {
770                 assertFalse(service.isPackageOrComponentUserSet(resolvedNonUserSetComponent, 13));
771                 assertTrue(service.isPackageOrComponentUserSet(resolvedUserSetComponent, 10));
772             } catch (AssertionError e) {
773                 throw new AssertionError(
774                         "Assertion failed while parsing xml:\n" + new String(rawOutput), e);
775             }
776         }
777     }
778 
779     @Test
rebindServices_onlyBindsExactMatchesIfComponent()780     public void rebindServices_onlyBindsExactMatchesIfComponent() throws Exception {
781         // If the primary and secondary lists contain component names, only those components within
782         // the package should be matched
783         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
784                 mIpm,
785                 ManagedServices.APPROVAL_BY_COMPONENT);
786 
787         List<String> packages = new ArrayList<>();
788         packages.add("package");
789         packages.add("anotherPackage");
790         addExpectedServices(service, packages, 0);
791 
792         // only 2 components are approved per package
793         mExpectedPrimaryComponentNames.clear();
794         mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2");
795         mExpectedSecondaryComponentNames.clear();
796         mExpectedSecondaryComponentNames.put(0, "anotherPackage/C1:anotherPackage/C2");
797 
798         loadXml(service);
799 
800         // verify the 2 components per package are enabled (bound)
801         verifyExpectedBoundEntries(service, true);
802         verifyExpectedBoundEntries(service, false);
803 
804         // verify the last component per package is not enabled/we don't try to bind to it
805         for (String pkg : packages) {
806             ComponentName unapprovedAdditionalComponent =
807                     ComponentName.unflattenFromString(pkg + "/C3");
808             assertFalse(
809                     service.isComponentEnabledForCurrentProfiles(
810                             unapprovedAdditionalComponent));
811             verify(mIpm, never()).getServiceInfo(
812                     eq(unapprovedAdditionalComponent), anyInt(), anyInt());
813         }
814     }
815 
816     @Test
rebindServices_bindsEverythingInAPackage()817     public void rebindServices_bindsEverythingInAPackage() throws Exception {
818         // If the primary and secondary lists contain packages, all components within those packages
819         // should be bound
820         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
821                 APPROVAL_BY_PACKAGE);
822 
823         List<String> packages = new ArrayList<>();
824         packages.add("package");
825         packages.add("packagea");
826         addExpectedServices(service, packages, 0);
827 
828         // 2 approved packages
829         mExpectedPrimaryPackages.clear();
830         mExpectedPrimaryPackages.put(0, "package");
831         mExpectedSecondaryPackages.clear();
832         mExpectedSecondaryPackages.put(0, "packagea");
833 
834         loadXml(service);
835 
836         // verify the 3 components per package are enabled (bound)
837         verifyExpectedBoundEntries(service, true);
838         verifyExpectedBoundEntries(service, false);
839     }
840 
841     @Test
unbindOtherUserServices()842     public void unbindOtherUserServices() throws PackageManager.NameNotFoundException {
843         Context context = mock(Context.class);
844         PackageManager pm = mock(PackageManager.class);
845         ApplicationInfo ai = new ApplicationInfo();
846         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
847 
848         when(context.getPackageName()).thenReturn(mContext.getPackageName());
849         when(context.getUserId()).thenReturn(mContext.getUserId());
850         when(context.getPackageManager()).thenReturn(pm);
851         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
852 
853         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
854                 APPROVAL_BY_COMPONENT);
855         ComponentName cn = ComponentName.unflattenFromString("a/a");
856 
857         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
858             Object[] args = invocation.getArguments();
859             ServiceConnection sc = (ServiceConnection) args[1];
860             sc.onServiceConnected(cn, mock(IBinder.class));
861             return true;
862         });
863 
864         service.registerService(cn, 0);
865         service.registerService(cn, 10);
866         service.registerService(cn, 11);
867         service.unbindOtherUserServices(11);
868 
869         assertFalse(service.isBound(cn, 0));
870         assertFalse(service.isBound(cn, 10));
871         assertTrue(service.isBound(cn, 11));
872     }
873 
874     @Test
testPackageUninstall_packageNoLongerInApprovedList()875     public void testPackageUninstall_packageNoLongerInApprovedList() throws Exception {
876         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
877             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
878                     mIpm, approvalLevel);
879             writeExpectedValuesToSettings(approvalLevel);
880             service.migrateToXml();
881 
882             mExpectedPrimaryPackages.put(0, "another.package");
883             mExpectedPrimaryComponentNames.put(0, "another.package/B1");
884             service.onPackagesChanged(true, new String[]{"this.is.a.package.name"}, new int[]{103});
885 
886             verifyExpectedApprovedEntries(service);
887         }
888     }
889 
890     @Test
testPackageUninstall_componentNoLongerInApprovedList()891     public void testPackageUninstall_componentNoLongerInApprovedList() throws Exception {
892         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
893             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
894                     mIpm, approvalLevel);
895             writeExpectedValuesToSettings(approvalLevel);
896             service.migrateToXml();
897 
898             mExpectedSecondaryComponentNames.put(10, "component/2");
899             mExpectedSecondaryPackages.put(10, "component");
900             service.onPackagesChanged(true, new String[]{"this.is.another.package"}, new int[]{
901                     UserHandle.PER_USER_RANGE + 1});
902 
903             verifyExpectedApprovedEntries(service);
904         }
905     }
906 
907     @Test
testIsPackageAllowed()908     public void testIsPackageAllowed() {
909         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
910             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
911                     mIpm, approvalLevel);
912             writeExpectedValuesToSettings(approvalLevel);
913             service.migrateToXml();
914 
915             verifyExpectedApprovedPackages(service);
916         }
917     }
918 
919     @Test
testUpgradeAppBindsNewServices()920     public void testUpgradeAppBindsNewServices() throws Exception {
921         // If the primary and secondary lists contain component names, only those components within
922         // the package should be matched
923         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
924                 mIpm,
925                 ManagedServices.APPROVAL_BY_PACKAGE);
926 
927         List<String> packages = new ArrayList<>();
928         packages.add("package");
929         addExpectedServices(service, packages, 0);
930 
931         // only 2 components are approved per package
932         mExpectedPrimaryComponentNames.clear();
933         mExpectedPrimaryPackages.clear();
934         mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2");
935         mExpectedSecondaryComponentNames.clear();
936         mExpectedSecondaryPackages.clear();
937 
938         loadXml(service);
939 
940         // new component expected
941         mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2:package/C3");
942 
943         service.onPackagesChanged(false, new String[]{"package"}, new int[]{0});
944 
945         // verify the 3 components per package are enabled (bound)
946         verifyExpectedBoundEntries(service, true);
947 
948         // verify the last component per package is not enabled/we don't try to bind to it
949         for (String pkg : packages) {
950             ComponentName unapprovedAdditionalComponent =
951                     ComponentName.unflattenFromString(pkg + "/C3");
952             assertFalse(
953                     service.isComponentEnabledForCurrentProfiles(
954                             unapprovedAdditionalComponent));
955             verify(mIpm, never()).getServiceInfo(
956                     eq(unapprovedAdditionalComponent), anyInt(), anyInt());
957         }
958     }
959 
960     @Test
testSetPackageOrComponentEnabled()961     public void testSetPackageOrComponentEnabled() throws Exception {
962         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
963             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
964                     mIpm, approvalLevel);
965             ArrayMap<Integer, ArrayList<String>> expectedEnabled = new ArrayMap<>();
966             expectedEnabled.put(0,
967                     Lists.newArrayList(new String[]{"package/Comp", "package/C2", "again/M4"}));
968             expectedEnabled.put(10,
969                     Lists.newArrayList(new String[]{"user10package/B", "user10/Component",
970                             "user10package1/K", "user10.3/Component", "user10package2/L",
971                             "user10.4/Component"}));
972 
973             for (int userId : expectedEnabled.keySet()) {
974                 ArrayList<String> expectedForUser = expectedEnabled.get(userId);
975                 for (int i = 0; i < expectedForUser.size(); i++) {
976                     boolean primary = i % 2 == 0;
977                     service.setPackageOrComponentEnabled(expectedForUser.get(i), userId, primary,
978                             true);
979                 }
980             }
981 
982             // verify everything added is approved
983             for (int userId : expectedEnabled.keySet()) {
984                 ArrayList<String> expectedForUser = expectedEnabled.get(userId);
985                 for (int i = 0; i < expectedForUser.size(); i++) {
986                     String verifyValue  = (approvalLevel == APPROVAL_BY_COMPONENT)
987                             ? expectedForUser.get(i)
988                             : service.getPackageName(expectedForUser.get(i));
989                     assertTrue("Not allowed: user: " + userId + " entry: " + verifyValue
990                             + " for approval level " + approvalLevel,
991                             service.isPackageOrComponentAllowed(verifyValue, userId));
992                 }
993             }
994 
995             ArrayMap<Integer, ArrayList<String>> expectedNoAccess = new ArrayMap<>();
996             for (int userId : expectedEnabled.keySet()) {
997                 ArrayList<String> expectedForUser = expectedEnabled.get(userId);
998                 for (int i = expectedForUser.size() - 1; i >= 0; i--) {
999                     ArrayList<String> removed = new ArrayList<>();
1000                     if (i % 3 == 0) {
1001                         String revokeAccessFor = expectedForUser.remove(i);
1002                         removed.add(revokeAccessFor);
1003                         service.setPackageOrComponentEnabled(
1004                                 revokeAccessFor, userId, i % 2 == 0, false);
1005                     }
1006                     expectedNoAccess.put(userId, removed);
1007                 }
1008             }
1009 
1010             // verify everything still there is approved
1011             for (int userId : expectedEnabled.keySet()) {
1012                 ArrayList<String> expectedForUser = expectedEnabled.get(userId);
1013                 for (int i = 0; i < expectedForUser.size(); i++) {
1014                     String verifyValue  = (approvalLevel == APPROVAL_BY_COMPONENT)
1015                             ? expectedForUser.get(i)
1016                             : service.getPackageName(expectedForUser.get(i));
1017                     assertTrue("Not allowed: user: " + userId + " entry: " + verifyValue,
1018                             service.isPackageOrComponentAllowed(verifyValue, userId));
1019                 }
1020             }
1021             // verify everything removed isn't
1022             for (int userId : expectedNoAccess.keySet()) {
1023                 ArrayList<String> notExpectedForUser = expectedNoAccess.get(userId);
1024                 for (int i = 0; i < notExpectedForUser.size(); i++) {
1025                     assertFalse(
1026                             "Is allowed: user: " + userId + " entry: " + notExpectedForUser.get(i),
1027                             service.isPackageOrComponentAllowed(notExpectedForUser.get(i), userId));
1028                 }
1029             }
1030         }
1031     }
1032 
1033     @Test
testGetAllowedPackages_byUser()1034     public void testGetAllowedPackages_byUser() throws Exception {
1035         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
1036             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
1037                     mIpm, approvalLevel);
1038             loadXml(service);
1039 
1040             List<String> allowedPackagesForUser0 = new ArrayList<>();
1041             allowedPackagesForUser0.add("this.is.a.package.name");
1042             allowedPackagesForUser0.add("another.package");
1043             allowedPackagesForUser0.add("secondary");
1044 
1045             List<String> actual = service.getAllowedPackages(0);
1046             assertEquals(3, actual.size());
1047             for (String pkg : allowedPackagesForUser0) {
1048                 assertTrue(actual.contains(pkg));
1049             }
1050 
1051             List<String> allowedPackagesForUser10 = new ArrayList<>();
1052             allowedPackagesForUser10.add("this.is.another.package");
1053             allowedPackagesForUser10.add("package");
1054             allowedPackagesForUser10.add("this.is.another.package");
1055             allowedPackagesForUser10.add("component");
1056 
1057             actual = service.getAllowedPackages(10);
1058             assertEquals(4, actual.size());
1059             for (String pkg : allowedPackagesForUser10) {
1060                 assertTrue(actual.contains(pkg));
1061             }
1062         }
1063     }
1064 
1065     @Test
testGetAllowedComponentsByUser()1066     public void testGetAllowedComponentsByUser() throws Exception {
1067         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
1068                 APPROVAL_BY_COMPONENT);
1069         loadXml(service);
1070 
1071         List<ComponentName> expected = new ArrayList<>();
1072         expected.add(ComponentName.unflattenFromString("this.is.another.package/M1"));
1073         expected.add(ComponentName.unflattenFromString("this.is.another.package/with.Component"));
1074         expected.add(ComponentName.unflattenFromString("component/2"));
1075         expected.add(ComponentName.unflattenFromString("package/component2"));
1076 
1077         List<ComponentName> actual = service.getAllowedComponents(10);
1078 
1079         assertContentsInAnyOrder(expected, actual);
1080 
1081         assertEquals(expected.size(), actual.size());
1082 
1083         for (ComponentName cn : expected) {
1084             assertTrue("Actual missing " + cn, actual.contains(cn));
1085         }
1086 
1087         for (ComponentName cn : actual) {
1088             assertTrue("Actual contains extra " + cn, expected.contains(cn));
1089         }
1090     }
1091 
1092     @Test
testGetAllowedComponents_approvalByPackage()1093     public void testGetAllowedComponents_approvalByPackage() throws Exception {
1094         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
1095                 APPROVAL_BY_PACKAGE);
1096         loadXml(service);
1097 
1098         assertEquals(0, service.getAllowedComponents(10).size());
1099     }
1100 
1101     @Test
testGetAllowedPackages()1102     public void testGetAllowedPackages() throws Exception {
1103         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
1104                 mIpm, APPROVAL_BY_COMPONENT);
1105         loadXml(service);
1106         service.mApprovalLevel = APPROVAL_BY_PACKAGE;
1107         loadXml(service);
1108 
1109         List<String> allowedPackages = new ArrayList<>();
1110         allowedPackages.add("this.is.a.package.name");
1111         allowedPackages.add("another.package");
1112         allowedPackages.add("secondary");
1113         allowedPackages.add("this.is.another.package");
1114         allowedPackages.add("package");
1115         allowedPackages.add("component");
1116         allowedPackages.add("bananas!");
1117         allowedPackages.add("non.user.set.package");
1118 
1119         Set<String> actual = service.getAllowedPackages();
1120         assertEquals(allowedPackages.size(), actual.size());
1121         for (String pkg : allowedPackages) {
1122             assertTrue(actual.contains(pkg));
1123         }
1124     }
1125 
1126     @Test
testOnUserRemoved()1127     public void testOnUserRemoved() throws Exception {
1128         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
1129             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
1130                     mIpm, approvalLevel);
1131             loadXml(service);
1132 
1133             ArrayMap<Integer, String> verifyMap = mExpectedPrimary.get(service.mApprovalLevel);
1134             String user0 = verifyMap.remove(0);
1135             verifyMap = mExpectedSecondary.get(service.mApprovalLevel);
1136             user0 = user0 + ":" + verifyMap.remove(0);
1137 
1138             service.onUserRemoved(0);
1139 
1140             for (String verifyValue : user0.split(":")) {
1141                 if (!TextUtils.isEmpty(verifyValue)) {
1142                     assertFalse("service type " + service.mApprovalLevel + ":" + verifyValue
1143                             + " is still allowed",
1144                             service.isPackageOrComponentAllowed(verifyValue, 0));
1145                 }
1146             }
1147 
1148             verifyExpectedApprovedEntries(service);
1149         }
1150     }
1151 
1152     @Test
testIsSameUser()1153     public void testIsSameUser() {
1154         IInterface service = mock(IInterface.class);
1155         when(service.asBinder()).thenReturn(mock(IBinder.class));
1156         ManagedServices services = new TestManagedServices(getContext(), mLock, mUserProfiles,
1157                 mIpm, APPROVAL_BY_PACKAGE);
1158         services.registerSystemService(service, null, 10, 1000);
1159         ManagedServices.ManagedServiceInfo info = services.checkServiceTokenLocked(service);
1160         info.isSystem = true;
1161 
1162         assertFalse(services.isSameUser(service, 0));
1163         assertTrue(services.isSameUser(service, 10));
1164         assertTrue(services.isSameUser(service, UserHandle.USER_ALL));
1165     }
1166 
1167     @Test
testGetAllowedComponents()1168     public void testGetAllowedComponents() throws Exception {
1169         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
1170                 APPROVAL_BY_COMPONENT);
1171         loadXml(service);
1172 
1173         SparseArray<ArraySet<ComponentName>> expected = new SparseArray<>();
1174 
1175         ArraySet<ComponentName> expected10 = new ArraySet<>();
1176         expected10.add(ComponentName.unflattenFromString("this.is.another.package/M1"));
1177         expected10.add(ComponentName.unflattenFromString("this.is.another.package/with.Component"));
1178         expected10.add(ComponentName.unflattenFromString("component/2"));
1179         expected10.add(ComponentName.unflattenFromString("package/component2"));
1180         expected.put(10, expected10);
1181         ArraySet<ComponentName> expected0 = new ArraySet<>();
1182         expected0.add(ComponentName.unflattenFromString("secondary/component.Name"));
1183         expected0.add(ComponentName.unflattenFromString("this.is.a.package.name/Ba"));
1184         expected0.add(ComponentName.unflattenFromString("another.package/B1"));
1185         expected.put(0, expected0);
1186         ArraySet<ComponentName> expected12 = new ArraySet<>();
1187         expected12.add(ComponentName.unflattenFromString("bananas!/Bananas!"));
1188         expected.put(12, expected12);
1189         expected.put(11, new ArraySet<>());
1190         ArraySet<ComponentName> expected13 = new ArraySet<>();
1191         expected13.add(ComponentName.unflattenFromString("non.user.set.package/M1"));
1192         expected.put(13, expected13);
1193 
1194         SparseArray<ArraySet<ComponentName>> actual =
1195                 service.getAllowedComponents(mUserProfiles.getCurrentProfileIds());
1196 
1197         assertContentsInAnyOrder(expected, actual);
1198     }
1199 
1200     @Test
testPopulateComponentsToUnbind_forceRebind()1201     public void testPopulateComponentsToUnbind_forceRebind() {
1202         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
1203                 APPROVAL_BY_COMPONENT);
1204 
1205         IInterface iInterface = mock(IInterface.class);
1206         when(iInterface.asBinder()).thenReturn(mock(IBinder.class));
1207 
1208         ManagedServices.ManagedServiceInfo service0 = service.new ManagedServiceInfo(
1209                 iInterface, ComponentName.unflattenFromString("a/a"), 0, false,
1210                 mock(ServiceConnection.class), 26, 34);
1211         ManagedServices.ManagedServiceInfo service10 = service.new ManagedServiceInfo(
1212                 iInterface, ComponentName.unflattenFromString("b/b"), 10, false,
1213                 mock(ServiceConnection.class), 26, 345);
1214         Set<ManagedServices.ManagedServiceInfo> removableBoundServices = new ArraySet<>();
1215         removableBoundServices.add(service0);
1216         removableBoundServices.add(service10);
1217 
1218         SparseArray<Set<ComponentName>> allowedComponentsToBind = new SparseArray<>();
1219         Set<ComponentName> allowed0 = new ArraySet<>();
1220         allowed0.add(ComponentName.unflattenFromString("a/a"));
1221         allowedComponentsToBind.put(0, allowed0);
1222         Set<ComponentName> allowed10 = new ArraySet<>();
1223         allowed10.add(ComponentName.unflattenFromString("b/b"));
1224         allowedComponentsToBind.put(10, allowed10);
1225 
1226         SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
1227 
1228         service.populateComponentsToUnbind(true, removableBoundServices, allowedComponentsToBind,
1229                 componentsToUnbind);
1230 
1231         assertEquals(2, componentsToUnbind.size());
1232         assertTrue(componentsToUnbind.get(0).contains(ComponentName.unflattenFromString("a/a")));
1233         assertTrue(componentsToUnbind.get(10).contains(ComponentName.unflattenFromString("b/b")));
1234     }
1235 
1236     @Test
testPopulateComponentsToUnbind()1237     public void testPopulateComponentsToUnbind() {
1238         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
1239                 APPROVAL_BY_COMPONENT);
1240 
1241         IInterface iInterface = mock(IInterface.class);
1242         when(iInterface.asBinder()).thenReturn(mock(IBinder.class));
1243 
1244         ManagedServices.ManagedServiceInfo service0 = service.new ManagedServiceInfo(
1245                 iInterface, ComponentName.unflattenFromString("a/a"), 0, false,
1246                 mock(ServiceConnection.class), 26, 345);
1247         ManagedServices.ManagedServiceInfo service0a = service.new ManagedServiceInfo(
1248                 iInterface, ComponentName.unflattenFromString("c/c"), 0, false,
1249                 mock(ServiceConnection.class), 26, 3456);
1250         ManagedServices.ManagedServiceInfo service10 = service.new ManagedServiceInfo(
1251                 iInterface, ComponentName.unflattenFromString("b/b"), 10, false,
1252                 mock(ServiceConnection.class), 26, 34567);
1253         Set<ManagedServices.ManagedServiceInfo> removableBoundServices = new ArraySet<>();
1254         removableBoundServices.add(service0);
1255         removableBoundServices.add(service0a);
1256         removableBoundServices.add(service10);
1257 
1258         SparseArray<Set<ComponentName>> allowedComponentsToBind = new SparseArray<>();
1259         Set<ComponentName> allowed0 = new ArraySet<>();
1260         allowed0.add(ComponentName.unflattenFromString("a/a"));
1261         allowedComponentsToBind.put(0, allowed0);
1262         Set<ComponentName> allowed10 = new ArraySet<>();
1263         allowed10.add(ComponentName.unflattenFromString("b/b"));
1264         allowedComponentsToBind.put(10, allowed10);
1265 
1266         SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
1267 
1268         service.populateComponentsToUnbind(false, removableBoundServices, allowedComponentsToBind,
1269                 componentsToUnbind);
1270 
1271         assertEquals(1, componentsToUnbind.size());
1272         assertEquals(1, componentsToUnbind.get(0).size());
1273         assertTrue(componentsToUnbind.get(0).contains(ComponentName.unflattenFromString("c/c")));
1274     }
1275 
1276     @Test
populateComponentsToBind()1277     public void populateComponentsToBind() {
1278         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
1279                 APPROVAL_BY_COMPONENT);
1280 
1281         SparseArray<ArraySet<ComponentName>> approvedComponentsByUser = new SparseArray<>();
1282         ArraySet<ComponentName> allowed0 = new ArraySet<>();
1283         allowed0.add(ComponentName.unflattenFromString("a/a"));
1284         approvedComponentsByUser.put(0, allowed0);
1285         ArraySet<ComponentName> allowed10 = new ArraySet<>();
1286         allowed10.add(ComponentName.unflattenFromString("b/b"));
1287         allowed10.add(ComponentName.unflattenFromString("c/c"));
1288         approvedComponentsByUser.put(10, allowed10);
1289         ArraySet<ComponentName> allowed15 = new ArraySet<>();
1290         allowed15.add(ComponentName.unflattenFromString("d/d"));
1291         approvedComponentsByUser.put(15, allowed15);
1292 
1293         IntArray users = new IntArray();
1294         users.add(10);
1295         users.add(0);
1296 
1297         SparseArray<Set<ComponentName>> componentsToBind = new SparseArray<>();
1298 
1299         service.populateComponentsToBind(componentsToBind, users, approvedComponentsByUser);
1300 
1301         assertEquals(2, componentsToBind.size());
1302         assertEquals(1, componentsToBind.get(0).size());
1303         assertTrue(componentsToBind.get(0).contains(ComponentName.unflattenFromString("a/a")));
1304         assertEquals(2, componentsToBind.get(10).size());
1305         assertTrue(componentsToBind.get(10).contains(ComponentName.unflattenFromString("b/b")));
1306         assertTrue(componentsToBind.get(10).contains(ComponentName.unflattenFromString("c/c")));
1307     }
1308 
1309     @Test
testOnNullBinding()1310     public void testOnNullBinding() throws Exception {
1311         Context context = mock(Context.class);
1312         PackageManager pm = mock(PackageManager.class);
1313         ApplicationInfo ai = new ApplicationInfo();
1314         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1315 
1316         when(context.getPackageName()).thenReturn(mContext.getPackageName());
1317         when(context.getUserId()).thenReturn(mContext.getUserId());
1318         when(context.getPackageManager()).thenReturn(pm);
1319         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
1320 
1321         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
1322                 APPROVAL_BY_COMPONENT);
1323         ComponentName cn = ComponentName.unflattenFromString("a/a");
1324 
1325         ArgumentCaptor<ServiceConnection> captor = ArgumentCaptor.forClass(ServiceConnection.class);
1326         when(context.bindServiceAsUser(any(), captor.capture(), anyInt(), any()))
1327                 .thenAnswer(invocation -> {
1328                     captor.getValue().onNullBinding(cn);
1329                     return true;
1330                 });
1331 
1332         service.registerSystemService(cn, 0);
1333         verify(context).unbindService(captor.getValue());
1334     }
1335 
1336     @Test
testOnServiceConnected()1337     public void testOnServiceConnected() throws Exception {
1338         Context context = mock(Context.class);
1339         PackageManager pm = mock(PackageManager.class);
1340         ApplicationInfo ai = new ApplicationInfo();
1341         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1342 
1343         when(context.getPackageName()).thenReturn(mContext.getPackageName());
1344         when(context.getUserId()).thenReturn(mContext.getUserId());
1345         when(context.getPackageManager()).thenReturn(pm);
1346         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
1347 
1348         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
1349                 APPROVAL_BY_COMPONENT);
1350         ComponentName cn = ComponentName.unflattenFromString("a/a");
1351 
1352         service.registerSystemService(cn, 0);
1353         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
1354             Object[] args = invocation.getArguments();
1355             ServiceConnection sc = (ServiceConnection) args[1];
1356             sc.onServiceConnected(cn, mock(IBinder.class));
1357             return true;
1358         });
1359 
1360         service.registerSystemService(cn, 0);
1361         assertTrue(service.isBound(cn, 0));
1362     }
1363 
1364     @Test
testOnPackagesChanged_nullValuesPassed_noNullPointers()1365     public void testOnPackagesChanged_nullValuesPassed_noNullPointers() {
1366         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
1367             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
1368                     mIpm, approvalLevel);
1369             // null uid list
1370             service.onPackagesChanged(true, new String[]{"this.is.a.package.name"}, null);
1371 
1372             // null package list
1373             service.onPackagesChanged(true, null, new int[]{103});
1374         }
1375     }
1376 
1377     @Test
loadDefaults_noVersionNoDefaults()1378     public void loadDefaults_noVersionNoDefaults() throws Exception {
1379         resetComponentsAndPackages();
1380         loadXml(mService);
1381         assertEquals(mService.getDefaultComponents().size(), 0);
1382     }
1383 
1384     @Test
loadDefaults_noVersionNoDefaultsOneActive()1385     public void loadDefaults_noVersionNoDefaultsOneActive() throws Exception {
1386         resetComponentsAndPackages();
1387         mService.addDefaultComponentOrPackage("package/class");
1388         loadXml(mService);
1389         assertEquals(1, mService.getDefaultComponents().size());
1390         assertTrue(mService.getDefaultComponents()
1391                 .contains(ComponentName.unflattenFromString("package/class")));
1392     }
1393 
1394     @Test
loadDefaults_noVersionWithDefaults()1395     public void loadDefaults_noVersionWithDefaults() throws Exception {
1396         resetComponentsAndPackages();
1397         mDefaults.add(new ComponentName("default", "class"));
1398         mVersionString = null;
1399         loadXml(mService);
1400         assertEquals(mService.getDefaultComponents(), mDefaults);
1401     }
1402 
1403     @Test
loadDefaults_versionOneWithDefaultsWithActive()1404     public void loadDefaults_versionOneWithDefaultsWithActive() throws Exception {
1405         resetComponentsAndPackages();
1406         mDefaults.add(new ComponentName("default", "class"));
1407         mExpectedPrimaryComponentNames.put(0, "package/class");
1408         mVersionString = "1";
1409         loadXml(mService);
1410         assertEquals(mService.getDefaultComponents(),
1411                 new ArraySet(Arrays.asList(new ComponentName("package", "class"))));
1412     }
1413 
1414     @Test
loadDefaults_versionTwoWithDefaultsWithActive()1415     public void loadDefaults_versionTwoWithDefaultsWithActive() throws Exception {
1416         resetComponentsAndPackages();
1417         mDefaults.add(new ComponentName("default", "class"));
1418         mDefaultsString = "default/class";
1419         mExpectedPrimaryComponentNames.put(0, "package/class");
1420         mVersionString = "2";
1421         loadXml(mService);
1422         assertEquals(1, mService.getDefaultComponents().size());
1423         mDefaults.forEach(pkg -> {
1424             assertTrue(mService.getDefaultComponents().contains(pkg));
1425         });
1426     }
1427 
1428     @Test
loadDefaults_versionOneWithXMLDefaultsWithActive()1429     public void loadDefaults_versionOneWithXMLDefaultsWithActive() throws Exception {
1430         resetComponentsAndPackages();
1431         mDefaults.add(new ComponentName("default", "class"));
1432         mDefaultsString = "xml/class";
1433         mExpectedPrimaryComponentNames.put(0, "package/class");
1434         mVersionString = "1";
1435         loadXml(mService);
1436         assertEquals(mService.getDefaultComponents(),
1437                 new ArraySet(Arrays.asList(new ComponentName("xml", "class"))));
1438     }
1439 
1440     @Test
loadDefaults_versionTwoWithXMLDefaultsWithActive()1441     public void loadDefaults_versionTwoWithXMLDefaultsWithActive() throws Exception {
1442         resetComponentsAndPackages();
1443         mDefaults.add(new ComponentName("default", "class"));
1444         mDefaultsString = "xml/class";
1445         mExpectedPrimaryComponentNames.put(0, "package/class");
1446         mVersionString = "2";
1447         loadXml(mService);
1448         assertEquals(mService.getDefaultComponents(),
1449                 new ArraySet(Arrays.asList(new ComponentName("xml", "class"))));
1450     }
1451 
1452     @Test
loadDefaults_versionLatest_NoLoadDefaults()1453     public void loadDefaults_versionLatest_NoLoadDefaults() throws Exception {
1454         resetComponentsAndPackages();
1455         mDefaults.add(new ComponentName("default", "class"));
1456         mDefaultsString = "xml/class";
1457         loadXml(mService);
1458         assertEquals(mService.getDefaultComponents(),
1459                 new ArraySet(Arrays.asList(new ComponentName("xml", "class"))));
1460     }
1461 
1462     @Test
upgradeUserSet_versionThree()1463     public void upgradeUserSet_versionThree() throws Exception {
1464         resetComponentsAndPackages();
1465 
1466         List<UserInfo> users = new ArrayList<>();
1467         users.add(new UserInfo(98, "98", 0));
1468         users.add(new UserInfo(99, "99", 0));
1469         for (UserInfo user : users) {
1470             when(mUm.getUserInfo(eq(user.id))).thenReturn(user);
1471         }
1472 
1473         mDefaultsString = "xml/class";
1474         mVersionString = "3";
1475         mUserSetString = "xml/class";
1476         loadXml(mService);
1477 
1478         //Test services without overriding upgradeUserSet() remain unchanged
1479         assertEquals(new ArraySet(Arrays.asList(mUserSetString)),
1480                 mService.mUserSetServices.get(98));
1481         assertEquals(new ArraySet(Arrays.asList(mUserSetString)),
1482                 mService.mUserSetServices.get(99));
1483         assertEquals(new ArrayMap(), mService.mIsUserChanged);
1484     }
1485 
resetComponentsAndPackages()1486     private void resetComponentsAndPackages() {
1487         ArrayMap<Integer, ArrayMap<Integer, String>> empty = new ArrayMap(1);
1488         ArrayMap<Integer, String> emptyPkgs = new ArrayMap(0);
1489         empty.append(mService.mApprovalLevel, emptyPkgs);
1490         mExpectedPrimary = empty;
1491         mExpectedPrimaryComponentNames = emptyPkgs;
1492         mExpectedPrimaryPackages = emptyPkgs;
1493         mExpectedSecondary = empty;
1494         mExpectedSecondaryComponentNames = emptyPkgs;
1495         mExpectedSecondaryPackages = emptyPkgs;
1496     }
1497 
loadXml(ManagedServices service)1498     private void loadXml(ManagedServices service) throws Exception {
1499         String xmlString = createXml(service);
1500         TypedXmlPullParser parser = Xml.newFastPullParser();
1501         parser.setInput(new BufferedInputStream(
1502                 new ByteArrayInputStream(xmlString.getBytes())), null);
1503         parser.nextTag();
1504         service.readXml(parser, null, false, UserHandle.USER_ALL);
1505     }
1506 
createXml(ManagedServices service)1507     private String createXml(ManagedServices service) {
1508         final StringBuffer xml = new StringBuffer();
1509         String xmlTag = service.getConfig().xmlTag;
1510         xml.append("<" + xmlTag
1511                 + (mDefaultsString != null ? " defaults=\"" + mDefaultsString + "\" " : "")
1512                 + (mVersionString != null ? " version=\"" + mVersionString + "\" " : "")
1513                 + ">\n");
1514         for (int userId : mExpectedPrimary.get(service.mApprovalLevel).keySet()) {
1515             String pkgOrCmp = mExpectedPrimary.get(service.mApprovalLevel).get(userId);
1516             xml.append(getXmlEntry(
1517                     pkgOrCmp, userId, true,
1518                     !(pkgOrCmp.startsWith("non.user.set.package"))));
1519         }
1520         for (int userId : mExpectedSecondary.get(service.mApprovalLevel).keySet()) {
1521             xml.append(getXmlEntry(
1522                     mExpectedSecondary.get(service.mApprovalLevel).get(userId), userId, false));
1523         }
1524         xml.append("<" + ManagedServices.TAG_MANAGED_SERVICES + " "
1525                         + ManagedServices.ATT_USER_ID + "=\"99\" "
1526                         + ManagedServices.ATT_IS_PRIMARY + "=\"true\" "
1527                         + ManagedServices.ATT_APPROVED_LIST + "=\"990\" "
1528                         + (mUserSetString != null ? ManagedServices.ATT_USER_SET + "=\""
1529                         + mUserSetString + "\" " : "")
1530                         + "/>\n");
1531         xml.append("<" + ManagedServices.TAG_MANAGED_SERVICES + " "
1532                 + ManagedServices.ATT_USER_ID + "=\"98\" "
1533                 + ManagedServices.ATT_IS_PRIMARY + "=\"false\" "
1534                 + ManagedServices.ATT_APPROVED_LIST + "=\"981\" "
1535                 + (mUserSetString != null ? ManagedServices.ATT_USER_SET + "=\""
1536                 + mUserSetString + "\" " : "")
1537                 + " />\n");
1538         xml.append("</" + xmlTag + ">");
1539 
1540         return xml.toString();
1541     }
1542 
getParserWithEntries(ManagedServices service, String... xmlEntries)1543     private TypedXmlPullParser getParserWithEntries(ManagedServices service, String... xmlEntries)
1544             throws Exception {
1545         final StringBuffer xml = new StringBuffer();
1546         xml.append("<" + service.getConfig().xmlTag
1547                 + (mVersionString != null ? " version=\"" + mVersionString + "\" " : "")
1548                 + ">\n");
1549         for (String xmlEntry : xmlEntries) {
1550             xml.append(xmlEntry);
1551         }
1552         xml.append("</" + service.getConfig().xmlTag + ">");
1553 
1554         TypedXmlPullParser parser = Xml.newFastPullParser();
1555         parser.setInput(new BufferedInputStream(
1556                 new ByteArrayInputStream(xml.toString().getBytes())), null);
1557         parser.nextTag();
1558         return parser;
1559     }
1560 
addExpectedServices(final ManagedServices service, final List<String> packages, int userId)1561     private void addExpectedServices(final ManagedServices service, final List<String> packages,
1562             int userId) {
1563         ManagedServices.Config config = service.getConfig();
1564         when(mPm.queryIntentServicesAsUser(any(), anyInt(), eq(userId))).
1565                 thenAnswer(new Answer<List<ResolveInfo>>() {
1566                     @Override
1567                     public List<ResolveInfo> answer(InvocationOnMock invocationOnMock)
1568                             throws Throwable {
1569                         Object[] args = invocationOnMock.getArguments();
1570                         Intent invocationIntent = (Intent) args[0];
1571                         if (invocationIntent != null) {
1572                             if (invocationIntent.getAction().equals(
1573                                     config.serviceInterface)
1574                                     && packages.contains(invocationIntent.getPackage())) {
1575                                 List<ResolveInfo> dummyServices = new ArrayList<>();
1576                                 for (int i = 1; i <= 3; i ++) {
1577                                     ResolveInfo resolveInfo = new ResolveInfo();
1578                                     ServiceInfo serviceInfo = new ServiceInfo();
1579                                     serviceInfo.packageName = invocationIntent.getPackage();
1580                                     serviceInfo.name = "C"+i;
1581                                     serviceInfo.permission = service.getConfig().bindPermission;
1582                                     resolveInfo.serviceInfo = serviceInfo;
1583                                     dummyServices.add(resolveInfo);
1584                                 }
1585                                 return dummyServices;
1586                             }
1587                         }
1588                         return new ArrayList<>();
1589                     }
1590                 });
1591     }
1592 
stringToList(String list)1593     private List<String> stringToList(String list) {
1594         if (list == null) {
1595             list = "";
1596         }
1597         return new ArrayList<>(Lists.newArrayList(list.split(
1598                 ManagedServices.ENABLED_SERVICES_SEPARATOR)));
1599     }
1600 
assertContentsInAnyOrder(Collection<?> expected, Collection<?> actual)1601     private void assertContentsInAnyOrder(Collection<?> expected, Collection<?> actual) {
1602         assertNotNull(actual);
1603         assertEquals(expected + " : " + actual, expected.size(), actual.size());
1604 
1605         for (Object o : expected) {
1606             assertTrue("Actual missing " + o, actual.contains(o));
1607         }
1608 
1609         for (Object o : actual) {
1610             assertTrue("Actual contains extra " + o, expected.contains(o));
1611         }
1612     }
1613 
assertContentsInAnyOrder(SparseArray<ArraySet<ComponentName>> expected, SparseArray<ArraySet<ComponentName>> actual)1614     private void assertContentsInAnyOrder(SparseArray<ArraySet<ComponentName>> expected,
1615             SparseArray<ArraySet<ComponentName>> actual) throws Exception {
1616         assertEquals(expected.size(), actual.size());
1617 
1618         for (int i = 0; i < expected.size(); i++) {
1619             int key = expected.keyAt(i);
1620             assertTrue(actual.indexOfKey(key) >= 0);
1621             try {
1622                 assertContentsInAnyOrder(expected.valueAt(i), actual.get(key));
1623             } catch (Throwable t) {
1624                 throw new Exception("Error validating " + key, t);
1625             }
1626         }
1627     }
1628 
verifyExpectedBoundEntries(ManagedServices service, boolean primary)1629     private void verifyExpectedBoundEntries(ManagedServices service, boolean primary)
1630             throws Exception {
1631         ArrayMap<Integer, String> verifyMap = primary ? mExpectedPrimary.get(service.mApprovalLevel)
1632                 : mExpectedSecondary.get(service.mApprovalLevel);
1633         for (int userId : verifyMap.keySet()) {
1634             for (String packageOrComponent : verifyMap.get(userId).split(":")) {
1635                 if (!TextUtils.isEmpty(packageOrComponent)) {
1636                     if (service.mApprovalLevel == APPROVAL_BY_PACKAGE) {
1637                         assertTrue(packageOrComponent,
1638                                 service.isComponentEnabledForPackage(packageOrComponent));
1639                         for (int i = 1; i <= 3; i++) {
1640                             ComponentName componentName = ComponentName.unflattenFromString(
1641                                     packageOrComponent +"/C" + i);
1642                             assertTrue(service.isComponentEnabledForCurrentProfiles(
1643                                     componentName));
1644                             verify(mIpm, times(1)).getServiceInfo(
1645                                     eq(componentName), anyInt(), anyInt());
1646                         }
1647                     } else {
1648                         ComponentName componentName =
1649                                 ComponentName.unflattenFromString(packageOrComponent);
1650                         assertTrue(service.isComponentEnabledForCurrentProfiles(componentName));
1651                         verify(mIpm, times(1)).getServiceInfo(
1652                                 eq(componentName), anyInt(), anyInt());
1653                     }
1654                 }
1655             }
1656         }
1657     }
1658 
verifyExpectedApprovedEntries(ManagedServices service)1659     private void verifyExpectedApprovedEntries(ManagedServices service) {
1660         verifyExpectedApprovedEntries(service, true);
1661         verifyExpectedApprovedEntries(service, false);
1662     }
1663 
verifyExpectedApprovedEntries(ManagedServices service, boolean primary)1664     private void verifyExpectedApprovedEntries(ManagedServices service, boolean primary) {
1665         ArrayMap<Integer, String> verifyMap = primary
1666                 ? mExpectedPrimary.get(service.mApprovalLevel)
1667                 : mExpectedSecondary.get(service.mApprovalLevel);
1668         verifyExpectedApprovedEntries(service, verifyMap);
1669     }
1670 
verifyExpectedApprovedEntries(ManagedServices service, ArrayMap<Integer, String> verifyMap)1671     private void verifyExpectedApprovedEntries(ManagedServices service,
1672             ArrayMap<Integer, String> verifyMap) {
1673         for (int userId : verifyMap.keySet()) {
1674             for (String verifyValue : verifyMap.get(userId).split(":")) {
1675                 if (!TextUtils.isEmpty(verifyValue)) {
1676                     assertTrue("service type " + service.mApprovalLevel + ":"
1677                                     + verifyValue + " is not allowed for user " + userId,
1678                             service.isPackageOrComponentAllowed(verifyValue, userId));
1679                 }
1680             }
1681         }
1682     }
1683 
1684 
verifyExpectedApprovedPackages(ManagedServices service)1685     private void verifyExpectedApprovedPackages(ManagedServices service) {
1686         verifyExpectedApprovedPackages(service, true);
1687         verifyExpectedApprovedPackages(service, false);
1688     }
1689 
verifyExpectedApprovedPackages(ManagedServices service, boolean primary)1690     private void verifyExpectedApprovedPackages(ManagedServices service, boolean primary) {
1691         ArrayMap<Integer, String> verifyMap = primary
1692                 ? mExpectedPrimary.get(service.mApprovalLevel)
1693                 : mExpectedSecondary.get(service.mApprovalLevel);
1694         verifyExpectedApprovedPackages(service, verifyMap);
1695     }
1696 
verifyExpectedApprovedPackages(ManagedServices service, ArrayMap<Integer, String> verifyMap)1697     private void verifyExpectedApprovedPackages(ManagedServices service,
1698             ArrayMap<Integer, String> verifyMap) {
1699         for (int userId : verifyMap.keySet()) {
1700             for (String verifyValue : verifyMap.get(userId).split(":")) {
1701                 if (!TextUtils.isEmpty(verifyValue)) {
1702                     ComponentName component = ComponentName.unflattenFromString(verifyValue);
1703                     if (component != null ) {
1704                         assertTrue("service type " + service.mApprovalLevel + ":"
1705                                         + verifyValue + " is not allowed for user " + userId,
1706                                 service.isPackageAllowed(component.getPackageName(), userId));
1707                     } else {
1708                         assertTrue("service type " + service.mApprovalLevel + ":"
1709                                         + verifyValue + " is not allowed for user " + userId,
1710                                 service.isPackageAllowed(verifyValue, userId));
1711                     }
1712                 }
1713             }
1714         }
1715     }
1716 
writeExpectedValuesToSettings(int approvalLevel)1717     private void writeExpectedValuesToSettings(int approvalLevel) {
1718         for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) {
1719             Settings.Secure.putStringForUser(getContext().getContentResolver(), SETTING,
1720                     mExpectedPrimary.get(approvalLevel).get(userId), userId);
1721         }
1722         for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) {
1723             Settings.Secure.putStringForUser(getContext().getContentResolver(), SECONDARY_SETTING,
1724                     mExpectedSecondary.get(approvalLevel).get(userId), userId);
1725         }
1726     }
1727 
getXmlEntry(String approved, int userId, boolean isPrimary)1728     private String getXmlEntry(String approved, int userId, boolean isPrimary) {
1729         return getXmlEntry(approved, userId, isPrimary, true);
1730     }
1731 
getXmlEntry(String approved, int userId, boolean isPrimary, boolean userSet)1732     private String getXmlEntry(String approved, int userId, boolean isPrimary, boolean userSet) {
1733         String userSetString = "";
1734         if (mVersionString.equals("4")) {
1735             userSetString =
1736                     ManagedServices.ATT_USER_CHANGED + "=\"" + String.valueOf(userSet) + "\" ";
1737         } else if (mVersionString.equals("3")) {
1738             userSetString =
1739                     ManagedServices.ATT_USER_SET + "=\"" + (userSet ? approved : "") + "\" ";
1740         }
1741         return "<" + ManagedServices.TAG_MANAGED_SERVICES + " "
1742                 + ManagedServices.ATT_USER_ID + "=\"" + userId +"\" "
1743                 + ManagedServices.ATT_IS_PRIMARY + "=\"" + isPrimary +"\" "
1744                 + ManagedServices.ATT_APPROVED_LIST + "=\"" + approved +"\" "
1745                 + userSetString + "/>\n";
1746     }
1747 
1748     class TestManagedServices extends ManagedServices {
1749 
TestManagedServices(Context context, Object mutex, UserProfiles userProfiles, IPackageManager pm, int approvedServiceType)1750         public TestManagedServices(Context context, Object mutex, UserProfiles userProfiles,
1751                 IPackageManager pm, int approvedServiceType) {
1752             super(context, mutex, userProfiles, pm);
1753             mApprovalLevel = approvedServiceType;
1754         }
1755 
1756         @Override
getConfig()1757         protected Config getConfig() {
1758             final Config c = new Config();
1759             c.xmlTag = "test";
1760             c.secureSettingName = SETTING;
1761             c.secondarySettingName = SECONDARY_SETTING;
1762             c.bindPermission = "permission";
1763             c.serviceInterface = "serviceInterface";
1764             return c;
1765         }
1766 
1767         @Override
asInterface(IBinder binder)1768         protected IInterface asInterface(IBinder binder) {
1769             return null;
1770         }
1771 
1772         @Override
checkType(IInterface service)1773         protected boolean checkType(IInterface service) {
1774             return true;
1775         }
1776 
1777         @Override
onServiceAdded(ManagedServiceInfo info)1778         protected void onServiceAdded(ManagedServiceInfo info) {
1779 
1780         }
1781 
1782         @Override
ensureFilters(ServiceInfo si, int userId)1783         protected void ensureFilters(ServiceInfo si, int userId) {
1784 
1785         }
1786 
1787         @Override
loadDefaultsFromConfig()1788         protected void loadDefaultsFromConfig() {
1789             mDefaultComponents.addAll(mDefaults);
1790         }
1791 
1792         @Override
getRequiredPermission()1793         protected String getRequiredPermission() {
1794             return null;
1795         }
1796     }
1797 
1798     class TestManagedServicesSettings extends TestManagedServices {
1799 
TestManagedServicesSettings(Context context, Object mutex, UserProfiles userProfiles, IPackageManager pm, int approvedServiceType)1800         public TestManagedServicesSettings(Context context, Object mutex, UserProfiles userProfiles,
1801                 IPackageManager pm, int approvedServiceType) {
1802             super(context, mutex, userProfiles, pm, approvedServiceType);
1803         }
1804 
1805         @Override
shouldReflectToSettings()1806         public boolean shouldReflectToSettings() {
1807             return true;
1808         }
1809     }
1810 
1811     class TestManagedServicesNoSettings extends TestManagedServices {
1812 
TestManagedServicesNoSettings(Context context, Object mutex, UserProfiles userProfiles, IPackageManager pm, int approvedServiceType)1813         public TestManagedServicesNoSettings(Context context, Object mutex, UserProfiles userProfiles,
1814                 IPackageManager pm, int approvedServiceType) {
1815             super(context, mutex, userProfiles, pm, approvedServiceType);
1816         }
1817 
1818         @Override
getConfig()1819         protected Config getConfig() {
1820             Config c = super.getConfig();
1821             c.secureSettingName = null;
1822             c.secondarySettingName = null;
1823             return c;
1824         }
1825 
1826         @Override
shouldReflectToSettings()1827         public boolean shouldReflectToSettings() {
1828             return false;
1829         }
1830     }
1831 }
1832