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 android.content.Context.DEVICE_POLICY_SERVICE;
19 import static android.os.UserManager.USER_TYPE_FULL_SECONDARY;
20 import static android.os.UserManager.USER_TYPE_PROFILE_CLONE;
21 import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
22 import static android.service.notification.NotificationListenerService.META_DATA_DEFAULT_AUTOBIND;
23 
24 import static com.android.server.notification.ManagedServices.APPROVAL_BY_COMPONENT;
25 import static com.android.server.notification.ManagedServices.APPROVAL_BY_PACKAGE;
26 
27 import static com.google.common.truth.Truth.assertThat;
28 
29 import static junit.framework.Assert.assertEquals;
30 import static junit.framework.Assert.assertFalse;
31 import static junit.framework.Assert.assertNotNull;
32 import static junit.framework.Assert.assertTrue;
33 
34 import static org.mockito.ArgumentMatchers.anyString;
35 import static org.mockito.Matchers.any;
36 import static org.mockito.Matchers.anyInt;
37 import static org.mockito.Matchers.anyLong;
38 import static org.mockito.Matchers.eq;
39 import static org.mockito.Mockito.mock;
40 import static org.mockito.Mockito.never;
41 import static org.mockito.Mockito.spy;
42 import static org.mockito.Mockito.times;
43 import static org.mockito.Mockito.verify;
44 import static org.mockito.Mockito.when;
45 
46 import android.app.ActivityManager;
47 import android.app.admin.DevicePolicyManager;
48 import android.content.ComponentName;
49 import android.content.Context;
50 import android.content.Intent;
51 import android.content.ServiceConnection;
52 import android.content.pm.ApplicationInfo;
53 import android.content.pm.IPackageManager;
54 import android.content.pm.PackageManager;
55 import android.content.pm.ResolveInfo;
56 import android.content.pm.ServiceInfo;
57 import android.content.pm.UserInfo;
58 import android.os.Build;
59 import android.os.Bundle;
60 import android.os.IBinder;
61 import android.os.IInterface;
62 import android.os.RemoteException;
63 import android.os.UserHandle;
64 import android.os.UserManager;
65 import android.provider.Settings;
66 import android.text.TextUtils;
67 import android.util.ArrayMap;
68 import android.util.ArraySet;
69 import android.util.IntArray;
70 import android.util.SparseArray;
71 import android.util.Xml;
72 
73 import com.android.internal.util.XmlUtils;
74 import com.android.modules.utils.TypedXmlPullParser;
75 import com.android.modules.utils.TypedXmlSerializer;
76 import com.android.server.UiServiceTestCase;
77 
78 import com.google.android.collect.Lists;
79 
80 import org.junit.Before;
81 import org.junit.Test;
82 import org.mockito.ArgumentCaptor;
83 import org.mockito.Mock;
84 import org.mockito.MockitoAnnotations;
85 import org.mockito.invocation.InvocationOnMock;
86 import org.mockito.stubbing.Answer;
87 
88 import java.io.BufferedInputStream;
89 import java.io.BufferedOutputStream;
90 import java.io.ByteArrayInputStream;
91 import java.io.ByteArrayOutputStream;
92 import java.nio.charset.StandardCharsets;
93 import java.util.ArrayList;
94 import java.util.Arrays;
95 import java.util.Collection;
96 import java.util.Collections;
97 import java.util.List;
98 import java.util.Set;
99 import java.util.concurrent.CountDownLatch;
100 
101 public class ManagedServicesTest extends UiServiceTestCase {
102 
103     @Mock
104     private IPackageManager mIpm;
105     @Mock
106     private PackageManager mPm;
107     @Mock
108     private UserManager mUm;
109     @Mock
110     private ManagedServices.UserProfiles mUserProfiles;
111     @Mock private DevicePolicyManager mDpm;
112     Object mLock = new Object();
113 
114     UserInfo mZero = new UserInfo(0, "zero", 0);
115     UserInfo mTen = new UserInfo(10, "ten", 0);
116     private String mDefaultsString;
117     private String mVersionString;
118     private final Set<ComponentName> mDefaults = new ArraySet();
119     private ManagedServices mService;
120     private String mUserSetString;
121 
122     private static final String SETTING = "setting";
123     private static final String SECONDARY_SETTING = "secondary_setting";
124 
125     private ArrayMap<Integer, String> mExpectedPrimaryPackages;
126     private ArrayMap<Integer, String> mExpectedPrimaryComponentNames;
127     private ArrayMap<Integer, String> mExpectedSecondaryPackages;
128     private ArrayMap<Integer, String> mExpectedSecondaryComponentNames;
129 
130     // type : user : list of approved
131     private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedPrimary;
132     private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedSecondary;
133 
134     private UserHandle mUser;
135     private String mPkg;
136 
137     @Before
setUp()138     public void setUp() throws Exception {
139         MockitoAnnotations.initMocks(this);
140 
141         mContext.setMockPackageManager(mPm);
142         mContext.addMockSystemService(Context.USER_SERVICE, mUm);
143         mContext.addMockSystemService(DEVICE_POLICY_SERVICE, mDpm);
144         mUser = mContext.getUser();
145         mPkg = mContext.getPackageName();
146 
147         List<UserInfo> users = new ArrayList<>();
148         users.add(mZero);
149         users.add(mTen);
150         users.add(new UserInfo(11, "11", 0));
151         users.add(new UserInfo(12, "12", 0));
152         users.add(new UserInfo(13, "13", 0));
153         for (UserInfo user : users) {
154             when(mUm.getUserInfo(eq(user.id))).thenReturn(user);
155         }
156         when(mUm.getUsers()).thenReturn(users);
157         IntArray profileIds = new IntArray();
158         profileIds.add(0);
159         profileIds.add(11);
160         profileIds.add(10);
161         profileIds.add(12);
162         profileIds.add(13);
163         when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
164 
165         mVersionString = "4";
166         mExpectedPrimary = new ArrayMap<>();
167         mExpectedSecondary = new ArrayMap<>();
168         mExpectedPrimaryPackages = new ArrayMap<>();
169         mExpectedPrimaryPackages.put(0, "this.is.a.package.name:another.package");
170         mExpectedPrimaryPackages.put(10, "this.is.another.package");
171         mExpectedPrimaryPackages.put(11, "");
172         mExpectedPrimaryPackages.put(12, "bananas!");
173         mExpectedPrimaryPackages.put(13, "non.user.set.package");
174         mExpectedPrimaryComponentNames = new ArrayMap<>();
175         mExpectedPrimaryComponentNames.put(0, "this.is.a.package.name/Ba:another.package/B1");
176         mExpectedPrimaryComponentNames.put(10, "this.is.another.package/M1");
177         mExpectedPrimaryComponentNames.put(11, "");
178         mExpectedPrimaryComponentNames.put(12, "bananas!/Bananas!");
179         mExpectedPrimaryComponentNames.put(13, "non.user.set.package/M1");
180         mExpectedPrimary.put(APPROVAL_BY_PACKAGE, mExpectedPrimaryPackages);
181         mExpectedPrimary.put(APPROVAL_BY_COMPONENT, mExpectedPrimaryComponentNames);
182 
183         mExpectedSecondaryComponentNames = new ArrayMap<>();
184         mExpectedSecondaryComponentNames.put(0, "secondary/component.Name");
185         mExpectedSecondaryComponentNames.put(10,
186                 "this.is.another.package/with.Component:component/2:package/component2");
187         mExpectedSecondaryPackages = new ArrayMap<>();
188         mExpectedSecondaryPackages.put(0, "secondary");
189         mExpectedSecondaryPackages.put(10,
190                 "this.is.another.package:component:package");
191         mExpectedSecondary.put(APPROVAL_BY_PACKAGE, mExpectedSecondaryPackages);
192         mExpectedSecondary.put(APPROVAL_BY_COMPONENT, mExpectedSecondaryComponentNames);
193         mService = new TestManagedServices(getContext(), mLock, mUserProfiles,
194                 mIpm, APPROVAL_BY_COMPONENT);
195     }
196 
197     @Test
testBackupAndRestore_migration()198     public void testBackupAndRestore_migration() throws Exception {
199         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
200             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
201                     mIpm, approvalLevel);
202 
203             for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) {
204                 service.onSettingRestored(
205                         service.getConfig().secureSettingName,
206                         mExpectedPrimary.get(approvalLevel).get(userId),
207                         Build.VERSION_CODES.O, userId);
208             }
209             verifyExpectedApprovedEntries(service, true);
210 
211             for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) {
212                 service.onSettingRestored(service.getConfig().secondarySettingName,
213                         mExpectedSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.O,
214                         userId);
215             }
216             verifyExpectedApprovedEntries(service);
217         }
218     }
219 
220     @Test
testBackupAndRestore_migration_preO()221     public void testBackupAndRestore_migration_preO() throws Exception {
222         ArrayMap<Integer, String> backupPrimaryPackages = new ArrayMap<>();
223         backupPrimaryPackages.put(0, "backup.0:backup:0a");
224         backupPrimaryPackages.put(10, "10.backup");
225         backupPrimaryPackages.put(11, "eleven");
226         backupPrimaryPackages.put(12, "");
227         ArrayMap<Integer, String> backupPrimaryComponentNames = new ArrayMap<>();
228         backupPrimaryComponentNames.put(0, "backup.first/whatever:a/b");
229         backupPrimaryComponentNames.put(10, "again/M1");
230         backupPrimaryComponentNames.put(11, "orange/youglad:itisnot/banana");
231         backupPrimaryComponentNames.put(12, "");
232         ArrayMap<Integer, ArrayMap<Integer, String>> backupPrimary = new ArrayMap<>();
233         backupPrimary.put(APPROVAL_BY_PACKAGE, backupPrimaryPackages);
234         backupPrimary.put(APPROVAL_BY_COMPONENT, backupPrimaryComponentNames);
235 
236         ArrayMap<Integer, String> backupSecondaryComponentNames = new ArrayMap<>();
237         backupSecondaryComponentNames.put(0, "secondary.1/component.Name");
238         backupSecondaryComponentNames.put(10,
239                 "this.is.another.package.backup/with.Component:component.backup/2");
240         ArrayMap<Integer, String> backupSecondaryPackages = new ArrayMap<>();
241         backupSecondaryPackages.put(0, "");
242         backupSecondaryPackages.put(10,
243                 "this.is.another.package.backup:package.backup");
244         ArrayMap<Integer, ArrayMap<Integer, String>> backupSecondary = new ArrayMap<>();
245         backupSecondary.put(APPROVAL_BY_PACKAGE, backupSecondaryPackages);
246         backupSecondary.put(APPROVAL_BY_COMPONENT, backupSecondaryComponentNames);
247 
248         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
249             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
250                     mIpm, approvalLevel);
251 
252             // not an expected flow but a way to get data into the settings
253             for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) {
254                 service.onSettingRestored(
255                         service.getConfig().secureSettingName,
256                         mExpectedPrimary.get(approvalLevel).get(userId),
257                         Build.VERSION_CODES.O, userId);
258             }
259 
260             for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) {
261                 service.onSettingRestored(service.getConfig().secondarySettingName,
262                         mExpectedSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.O,
263                         userId);
264             }
265 
266             // actual test
267             for (int userId : backupPrimary.get(approvalLevel).keySet()) {
268                 service.onSettingRestored(
269                         service.getConfig().secureSettingName,
270                         backupPrimary.get(approvalLevel).get(userId),
271                         Build.VERSION_CODES.N_MR1, userId);
272             }
273 
274             for (int userId : backupSecondary.get(approvalLevel).keySet()) {
275                 service.onSettingRestored(service.getConfig().secondarySettingName,
276                         backupSecondary.get(approvalLevel).get(userId),
277                         Build.VERSION_CODES.N_MR1, userId);
278             }
279             // both sets of approved entries should be allowed
280             verifyExpectedApprovedEntries(service);
281             verifyExpectedApprovedEntries(service, backupPrimary.get(approvalLevel));
282             verifyExpectedApprovedEntries(service, backupSecondary.get(approvalLevel));
283         }
284     }
285 
286     @Test
testReadXml_migrationFromSettings()287     public void testReadXml_migrationFromSettings() throws Exception {
288         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
289             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
290                     mIpm, approvalLevel);
291 
292             // approved services aren't in xml
293             TypedXmlPullParser parser = Xml.newFastPullParser();
294             parser.setInput(new BufferedInputStream(new ByteArrayInputStream(new byte[]{})),
295                     null);
296             writeExpectedValuesToSettings(approvalLevel);
297 
298             service.migrateToXml();
299 
300             verifyExpectedApprovedEntries(service);
301         }
302     }
303 
304     @Test
testReadXml_noLongerMigrateFromSettings()305     public void testReadXml_noLongerMigrateFromSettings() throws Exception {
306         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
307             ManagedServices service = new TestManagedServicesNoSettings(getContext(), mLock,
308                     mUserProfiles, mIpm, approvalLevel);
309 
310             // approved services aren't in xml
311             TypedXmlPullParser parser = Xml.newFastPullParser();
312             parser.setInput(new BufferedInputStream(new ByteArrayInputStream(new byte[]{})),
313                     null);
314             writeExpectedValuesToSettings(approvalLevel);
315 
316             service.migrateToXml();
317             // No crash? success
318 
319             ArrayMap<Integer, String> verifyMap = approvalLevel == APPROVAL_BY_COMPONENT
320                     ? mExpectedPrimary.get(service.mApprovalLevel)
321                     : mExpectedSecondary.get(service.mApprovalLevel);
322             for (int userId : verifyMap.keySet()) {
323                 for (String verifyValue : verifyMap.get(userId).split(":")) {
324                     if (!TextUtils.isEmpty(verifyValue)) {
325                         assertFalse("service type " + service.mApprovalLevel + ":"
326                                         + verifyValue + " is allowed for user " + userId,
327                                 service.isPackageOrComponentAllowed(verifyValue, userId));
328                     }
329                 }
330             }
331         }
332     }
333 
334     @Test
testReadXml()335     public void testReadXml() throws Exception {
336         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
337             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
338                     mIpm, approvalLevel);
339 
340             loadXml(service);
341 
342             verifyExpectedApprovedEntries(service);
343 
344             int[] invalidUsers = new int[] {98, 99};
345             for (int invalidUser : invalidUsers) {
346                 assertFalse("service type " + service.mApprovalLevel + ":"
347                                 + invalidUser + " is allowed for user " + invalidUser,
348                         service.isPackageOrComponentAllowed(
349                                 String.valueOf(invalidUser), invalidUser));
350             }
351         }
352     }
353 
354     @Test
testReadXml_appendsListOfApprovedComponents()355     public void testReadXml_appendsListOfApprovedComponents() throws Exception {
356         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
357             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
358                     mIpm, approvalLevel);
359 
360             String preApprovedPackage = "some.random.package";
361             String preApprovedComponent = "some.random.package/C1";
362 
363             List<String> packages = new ArrayList<>();
364             packages.add(preApprovedPackage);
365             addExpectedServices(service, packages, 0);
366 
367             service.setPackageOrComponentEnabled(preApprovedComponent, 0, true, true);
368 
369             loadXml(service);
370 
371             verifyExpectedApprovedEntries(service);
372 
373             String verifyValue  = (approvalLevel == APPROVAL_BY_COMPONENT)
374                     ? preApprovedComponent
375                     : preApprovedPackage;
376             assertTrue(service.isPackageOrComponentAllowed(verifyValue, 0));
377         }
378     }
379 
380     /** Test that restore ignores the user id attribute and applies the data to the target user. */
381     @Test
testReadXml_onlyRestoresForTargetUser()382     public void testReadXml_onlyRestoresForTargetUser() throws Exception {
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             TypedXmlPullParser parser =
392                     getParserWithEntries(service, getXmlEntry(resolvedValue, 0, true));
393 
394             service.readXml(parser, null, true, 10);
395 
396             assertFalse(service.isPackageOrComponentAllowed(resolvedValue, 0));
397             assertTrue(service.isPackageOrComponentAllowed(resolvedValue, 10));
398         }
399     }
400 
401     /** Test that restore correctly parses the user_set attribute. */
402     @Test
testReadXml_restoresUserSet()403     public void testReadXml_restoresUserSet() throws Exception {
404         mVersionString = "4";
405         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
406             ManagedServices service =
407                     new TestManagedServices(
408                             getContext(), mLock, mUserProfiles, mIpm, approvalLevel);
409             String testPackage = "user.test.package";
410             String testComponent = "user.test.component/C1";
411             String resolvedValue =
412                     (approvalLevel == APPROVAL_BY_COMPONENT) ? testComponent : testPackage;
413             String xmlEntry = getXmlEntry(resolvedValue, 0, true, false);
414             TypedXmlPullParser parser = getParserWithEntries(service, xmlEntry);
415 
416             service.readXml(parser, null, true, 0);
417 
418             assertFalse("Failed while parsing xml:\n" + xmlEntry,
419                     service.isPackageOrComponentUserSet(resolvedValue, 0));
420 
421             xmlEntry = getXmlEntry(resolvedValue, 0, true, true);
422             parser = getParserWithEntries(service, xmlEntry);
423 
424             service.readXml(parser, null, true, 0);
425 
426             assertTrue("Failed while parsing xml:\n" + xmlEntry,
427                     service.isPackageOrComponentUserSet(resolvedValue, 0));
428         }
429     }
430 
431     /** Test that restore ignores the user id attribute and applies the data to the target user. */
432     @Test
testWriteReadXml_writeReadDefaults()433     public void testWriteReadXml_writeReadDefaults() throws Exception {
434         // setup
435         ManagedServices service1 =
436                 new TestManagedServices(
437                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
438         ManagedServices service2 =
439                 new TestManagedServices(
440                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
441         TypedXmlSerializer serializer = Xml.newFastSerializer();
442         ByteArrayOutputStream baos = new ByteArrayOutputStream();
443         BufferedOutputStream outStream = new BufferedOutputStream(baos);
444         serializer.setOutput(outStream, "utf-8");
445 
446         //data setup
447         service1.addDefaultComponentOrPackage("package/class");
448         serializer.startDocument(null, true);
449         service1.writeXml(serializer, false, 0);
450         serializer.endDocument();
451         outStream.flush();
452 
453         final TypedXmlPullParser parser = Xml.newFastPullParser();
454         BufferedInputStream input = new BufferedInputStream(
455                 new ByteArrayInputStream(baos.toByteArray()));
456 
457         parser.setInput(input, StandardCharsets.UTF_8.name());
458         XmlUtils.beginDocument(parser, "test");
459         service2.readXml(parser, null, false, 0);
460         ArraySet<ComponentName> defaults = service2.getDefaultComponents();
461 
462         assertEquals(1, defaults.size());
463         assertEquals(new ComponentName("package", "class"), defaults.valueAt(0));
464     }
465 
466     @Test
resetPackage_enableDefaultsOnly()467     public void resetPackage_enableDefaultsOnly() {
468         // setup
469         ManagedServices service =
470                 new TestManagedServices(
471                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
472         service.addApprovedList(
473                 "package/not-default:another-package/not-default:package2/default",
474                 0, true);
475         service.addDefaultComponentOrPackage("package/default");
476         service.addDefaultComponentOrPackage("package2/default");
477 
478         ArrayMap<Boolean, ArrayList<ComponentName>> componentsToActivate =
479                 service.resetComponents("package", 0);
480 
481         assertEquals(1, componentsToActivate.get(true).size());
482         assertEquals(new ComponentName("package", "default"),
483                 componentsToActivate.get(true).get(0));
484     }
485 
486 
487     @Test
resetPackage_nonDefaultsRemoved()488     public void resetPackage_nonDefaultsRemoved() {
489         // setup
490         ManagedServices service =
491                 new TestManagedServices(
492                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
493         service.addApprovedList(
494                 "package/not-default:another-package/not-default:package2/default",
495                 0, true);
496         service.addDefaultComponentOrPackage("package/default");
497         service.addDefaultComponentOrPackage("package2/default");
498 
499         ArrayMap<Boolean, ArrayList<ComponentName>> componentsToActivate =
500                 service.resetComponents("package", 0);
501 
502         assertEquals(1, componentsToActivate.get(true).size());
503         assertEquals(new ComponentName("package", "not-default"),
504                 componentsToActivate.get(false).get(0));
505     }
506 
507     @Test
resetPackage_onlyDefaultsOnly()508     public void resetPackage_onlyDefaultsOnly() {
509         // setup
510         ManagedServices service =
511                 new TestManagedServices(
512                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
513         service.addApprovedList(
514                 "package/not-default:another-package/not-default:package2/default",
515                 0, true);
516         service.addDefaultComponentOrPackage("package/default");
517         service.addDefaultComponentOrPackage("package2/default");
518 
519         assertEquals(3, service.getAllowedComponents(0).size());
520 
521         service.resetComponents("package", 0);
522 
523         List<ComponentName> components =  service.getAllowedComponents(0);
524         assertEquals(3, components.size());
525         assertTrue(components.contains(new ComponentName("package", "default")));
526     }
527 
528     @Test
resetPackage_affectCurrentUserOnly()529     public void resetPackage_affectCurrentUserOnly() {
530         // setup
531         ManagedServices service =
532                 new TestManagedServices(
533                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
534         service.addApprovedList(
535                 "package/not-default:another-package/not-default:package2/default",
536                 0, true);
537         service.addApprovedList(
538                 "package/not-default:another-package/not-default:package2/default",
539                 1, true);
540         service.addDefaultComponentOrPackage("package/default");
541         service.addDefaultComponentOrPackage("package2/default");
542 
543         service.resetComponents("package", 0);
544 
545         List<ComponentName> components =  service.getAllowedComponents(1);
546         assertEquals(3, components.size());
547     }
548 
549     @Test
resetPackage_samePackageMultipleClasses()550     public void resetPackage_samePackageMultipleClasses() {
551         // setup
552         ManagedServices service =
553                 new TestManagedServices(
554                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
555         service.addApprovedList(
556                 "package/not-default:another-package/not-default:package2/default",
557                 0, true);
558         service.addApprovedList(
559                 "package/class:another-package/class:package2/class",
560                 0, true);
561         service.addDefaultComponentOrPackage("package/default");
562         service.addDefaultComponentOrPackage("package2/default");
563 
564         service.resetComponents("package", 0);
565 
566         List<ComponentName> components =  service.getAllowedComponents(0);
567         assertEquals(5, components.size());
568         assertTrue(components.contains(new ComponentName("package", "default")));
569     }
570 
571     @Test
resetPackage_clearsUserSet()572     public void resetPackage_clearsUserSet() {
573         // setup
574         ManagedServices service =
575                 new TestManagedServices(
576                         getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_COMPONENT);
577         String componentName = "package/user-allowed";
578         service.addApprovedList(componentName, 0, true);
579 
580         service.resetComponents("package", 0);
581 
582         assertFalse(service.isPackageOrComponentUserSet(componentName, 0));
583     }
584 
585     /** Test that backup only writes packages/components that belong to the target user. */
586     @Test
testWriteXml_onlyBackupsForTargetUser()587     public void testWriteXml_onlyBackupsForTargetUser() throws Exception {
588         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
589             ManagedServices service =
590                     new TestManagedServices(
591                             getContext(), mLock, mUserProfiles, mIpm, approvalLevel);
592             // Set up components.
593             String testPackage0 = "user0.test.package";
594             String testComponent0 = "user0.test.component/C1";
595             String testPackage10 = "user10.test.package";
596             String testComponent10 = "user10.test.component/C1";
597             String resolvedValue0 =
598                     (approvalLevel == APPROVAL_BY_COMPONENT) ? testComponent0 : testPackage0;
599             String resolvedValue10 =
600                     (approvalLevel == APPROVAL_BY_COMPONENT) ? testComponent10 : testPackage10;
601             addExpectedServices(
602                     service, Collections.singletonList(service.getPackageName(resolvedValue0)), 0);
603             addExpectedServices(
604                     service,
605                     Collections.singletonList(service.getPackageName(resolvedValue10)),
606                     10);
607             TypedXmlPullParser parser =
608                     getParserWithEntries(
609                             service,
610                             getXmlEntry(resolvedValue0, 0, true),
611                             getXmlEntry(resolvedValue10, 10, true));
612             service.readXml(parser, null, false, UserHandle.USER_ALL);
613 
614             // Write backup.
615             TypedXmlSerializer serializer = Xml.newFastSerializer();
616             ByteArrayOutputStream baos = new ByteArrayOutputStream();
617             serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
618             serializer.startDocument(null, true);
619             service.writeXml(serializer, true, 10);
620             serializer.endDocument();
621             serializer.flush();
622 
623             // Reset values.
624             service.setPackageOrComponentEnabled(resolvedValue0, 0, true, false);
625             service.setPackageOrComponentEnabled(resolvedValue10, 10, true, false);
626 
627             // Parse backup via restore.
628             TypedXmlPullParser restoreParser = Xml.newFastPullParser();
629             restoreParser.setInput(
630                     new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), null);
631             restoreParser.nextTag();
632             service.readXml(restoreParser, null, true, 10);
633 
634             assertFalse(service.isPackageOrComponentAllowed(resolvedValue0, 0));
635             assertFalse(service.isPackageOrComponentAllowed(resolvedValue0, 10));
636             assertTrue(service.isPackageOrComponentAllowed(resolvedValue10, 10));
637         }
638     }
639 
640     @Test
testWriteXml_trimsMissingServices()641     public void testWriteXml_trimsMissingServices() throws Exception {
642         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
643             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
644                     mIpm, approvalLevel);
645             loadXml(service);
646 
647             // remove missing
648             mExpectedPrimaryPackages.put(0, "another.package");
649             mExpectedPrimaryPackages.remove(12);
650             mExpectedPrimaryComponentNames.put(0, "another.package/B1");
651             mExpectedPrimaryComponentNames.remove(12);
652             mExpectedSecondaryPackages.put(10, "this.is.another.package:component");
653             mExpectedSecondaryComponentNames.put(
654                     10, "this.is.another.package/with.Component:component/2");
655 
656             for (UserInfo userInfo : mUm.getUsers()) {
657                 List<String> entriesExpectedToHaveServices = new ArrayList<>();
658                 if (mExpectedPrimary.get(approvalLevel).containsKey(userInfo.id)) {
659                     for (String packageOrComponent :
660                             mExpectedPrimary.get(approvalLevel).get(userInfo.id).split(":")) {
661                         if (!TextUtils.isEmpty(packageOrComponent)) {
662                             entriesExpectedToHaveServices.add(
663                                     service.getPackageName(packageOrComponent));
664                         }
665                     }
666                 }
667                 if (mExpectedSecondary.get(approvalLevel).containsKey(userInfo.id)) {
668                     for (String packageOrComponent :
669                             mExpectedSecondary.get(approvalLevel).get(userInfo.id).split(":")) {
670                         if (!TextUtils.isEmpty(packageOrComponent)) {
671                             entriesExpectedToHaveServices.add(
672                                     service.getPackageName(packageOrComponent));
673                         }
674                     }
675                 }
676                 addExpectedServices(service, entriesExpectedToHaveServices, userInfo.id);
677             }
678 
679             TypedXmlSerializer serializer = Xml.newFastSerializer();
680             ByteArrayOutputStream baos = new ByteArrayOutputStream();
681             serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
682             serializer.startDocument(null, true);
683             for (UserInfo userInfo : mUm.getUsers()) {
684                 service.writeXml(serializer, true, userInfo.id);
685             }
686             serializer.endDocument();
687             serializer.flush();
688 
689             TypedXmlPullParser parser = Xml.newFastPullParser();
690             parser.setInput(new BufferedInputStream(
691                     new ByteArrayInputStream(baos.toByteArray())), null);
692             parser.nextTag();
693             for (UserInfo userInfo : mUm.getUsers()) {
694                 service.readXml(parser, null, true, userInfo.id);
695             }
696 
697             verifyExpectedApprovedEntries(service);
698             assertFalse(service.isPackageOrComponentAllowed("this.is.a.package.name", 0));
699             assertFalse(service.isPackageOrComponentAllowed("bananas!", 12));
700             assertFalse(service.isPackageOrComponentAllowed("package/component2", 10));
701         }
702     }
703 
704     @Test
testWriteXml_writesSetting()705     public void testWriteXml_writesSetting() throws Exception {
706         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
707             ManagedServices service = new TestManagedServicesSettings(getContext(), mLock,
708                     mUserProfiles, mIpm, approvalLevel);
709             loadXml(service);
710 
711             TypedXmlSerializer serializer = Xml.newFastSerializer();
712             ByteArrayOutputStream baos = new ByteArrayOutputStream();
713             serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
714             serializer.startDocument(null, true);
715             service.writeXml(serializer, false, UserHandle.USER_ALL);
716             serializer.endDocument();
717             serializer.flush();
718 
719             for (int userId : mUserProfiles.getCurrentProfileIds().toArray()) {
720                 List<String> expected =
721                         stringToList(mExpectedPrimary.get(approvalLevel).get(userId));
722                 List<String> actual = stringToList(Settings.Secure.getStringForUser(
723                         getContext().getContentResolver(),
724                         service.getConfig().secureSettingName, userId));
725                 assertContentsInAnyOrder(actual, expected);
726             }
727         }
728     }
729 
730     @Test
testWriteXml_doesNotWriteSetting()731     public void testWriteXml_doesNotWriteSetting() throws Exception {
732         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
733             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
734                     mIpm, approvalLevel);
735 
736             for (int userId : mUserProfiles.getCurrentProfileIds().toArray()) {
737                 Settings.Secure.putStringForUser(
738                         getContext().getContentResolver(),
739                         service.getConfig().secureSettingName, null, userId);
740             }
741             loadXml(service);
742 
743             TypedXmlSerializer serializer = Xml.newFastSerializer();
744             ByteArrayOutputStream baos = new ByteArrayOutputStream();
745             serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
746             serializer.startDocument(null, true);
747             service.writeXml(serializer, false, UserHandle.USER_ALL);
748             serializer.endDocument();
749             serializer.flush();
750 
751             for (int userId : mUserProfiles.getCurrentProfileIds().toArray()) {
752                 String actual = Settings.Secure.getStringForUser(
753                         getContext().getContentResolver(),
754                         service.getConfig().secureSettingName, userId);
755                 assertTrue(TextUtils.isEmpty(actual));
756             }
757         }
758     }
759 
760     @Test
testWriteXml_writesUserSet()761     public void testWriteXml_writesUserSet() throws Exception {
762         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
763             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
764                     mIpm, approvalLevel);
765             loadXml(service);
766 
767             TypedXmlSerializer serializer = Xml.newFastSerializer();
768             ByteArrayOutputStream baos = new ByteArrayOutputStream();
769             serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
770             serializer.startDocument(null, true);
771             service.writeXml(serializer, false, UserHandle.USER_ALL);
772             serializer.endDocument();
773             serializer.flush();
774 
775             TypedXmlPullParser parser = Xml.newFastPullParser();
776             byte[] rawOutput = baos.toByteArray();
777             parser.setInput(new BufferedInputStream(
778                     new ByteArrayInputStream(rawOutput)), null);
779             parser.nextTag();
780             for (UserInfo userInfo : mUm.getUsers()) {
781                 service.readXml(parser, null, true, userInfo.id);
782             }
783 
784             String resolvedUserSetComponent = approvalLevel == APPROVAL_BY_PACKAGE
785                     ? mExpectedPrimaryPackages.get(10)
786                     : mExpectedPrimaryComponentNames.get(10);
787             String resolvedNonUserSetComponent = approvalLevel == APPROVAL_BY_PACKAGE
788                     ? mExpectedPrimaryPackages.get(13)
789                     : mExpectedPrimaryComponentNames.get(13);
790 
791             try {
792                 assertFalse(service.isPackageOrComponentUserSet(resolvedNonUserSetComponent, 13));
793                 assertTrue(service.isPackageOrComponentUserSet(resolvedUserSetComponent, 10));
794             } catch (AssertionError e) {
795                 throw new AssertionError(
796                         "Assertion failed while parsing xml:\n" + new String(rawOutput), e);
797             }
798         }
799     }
800 
801     @Test
rebindServices_onlyBindsExactMatchesIfComponent()802     public void rebindServices_onlyBindsExactMatchesIfComponent() throws Exception {
803         // If the primary and secondary lists contain component names, only those components within
804         // the package should be matched
805         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
806                 mIpm,
807                 ManagedServices.APPROVAL_BY_COMPONENT);
808 
809         List<String> packages = new ArrayList<>();
810         packages.add("package");
811         packages.add("anotherPackage");
812         addExpectedServices(service, packages, 0);
813 
814         // only 2 components are approved per package
815         mExpectedPrimaryComponentNames.clear();
816         mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2");
817         mExpectedSecondaryComponentNames.clear();
818         mExpectedSecondaryComponentNames.put(0, "anotherPackage/C1:anotherPackage/C2");
819 
820         loadXml(service);
821 
822         // verify the 2 components per package are enabled (bound)
823         verifyExpectedBoundEntries(service, true);
824         verifyExpectedBoundEntries(service, false);
825 
826         // verify the last component per package is not enabled/we don't try to bind to it
827         for (String pkg : packages) {
828             ComponentName unapprovedAdditionalComponent =
829                     ComponentName.unflattenFromString(pkg + "/C3");
830             assertFalse(
831                     service.isComponentEnabledForCurrentProfiles(
832                             unapprovedAdditionalComponent));
833             verify(mIpm, never()).getServiceInfo(
834                     eq(unapprovedAdditionalComponent), anyLong(), anyInt());
835         }
836     }
837 
838     @Test
rebindServices_bindsEverythingInAPackage()839     public void rebindServices_bindsEverythingInAPackage() throws Exception {
840         // If the primary and secondary lists contain packages, all components within those packages
841         // should be bound
842         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
843                 APPROVAL_BY_PACKAGE);
844 
845         List<String> packages = new ArrayList<>();
846         packages.add("package");
847         packages.add("packagea");
848         addExpectedServices(service, packages, 0);
849 
850         // 2 approved packages
851         mExpectedPrimaryPackages.clear();
852         mExpectedPrimaryPackages.put(0, "package");
853         mExpectedSecondaryPackages.clear();
854         mExpectedSecondaryPackages.put(0, "packagea");
855 
856         loadXml(service);
857 
858         // verify the 3 components per package are enabled (bound)
859         verifyExpectedBoundEntries(service, true);
860         verifyExpectedBoundEntries(service, false);
861     }
862 
863     @Test
reregisterService_checksAppIsApproved_pkg()864     public void reregisterService_checksAppIsApproved_pkg() throws Exception {
865         Context context = mock(Context.class);
866         PackageManager pm = mock(PackageManager.class);
867         ApplicationInfo ai = new ApplicationInfo();
868         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
869 
870         when(context.getPackageName()).thenReturn(mPkg);
871         when(context.getUserId()).thenReturn(mUser.getIdentifier());
872         when(context.getPackageManager()).thenReturn(pm);
873         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
874 
875         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
876                 APPROVAL_BY_PACKAGE);
877         ComponentName cn = ComponentName.unflattenFromString("a/a");
878 
879         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
880             Object[] args = invocation.getArguments();
881             ServiceConnection sc = (ServiceConnection) args[1];
882             sc.onServiceConnected(cn, mock(IBinder.class));
883             return true;
884         });
885 
886         service.addApprovedList("a", 0, true);
887 
888         service.reregisterService(cn, 0);
889 
890         assertTrue(service.isBound(cn, 0));
891     }
892 
893     @Test
reregisterService_checksAppIsApproved_pkg_secondary()894     public void reregisterService_checksAppIsApproved_pkg_secondary() throws Exception {
895         Context context = mock(Context.class);
896         PackageManager pm = mock(PackageManager.class);
897         ApplicationInfo ai = new ApplicationInfo();
898         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
899 
900         when(context.getPackageName()).thenReturn(mPkg);
901         when(context.getUserId()).thenReturn(mUser.getIdentifier());
902         when(context.getPackageManager()).thenReturn(pm);
903         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
904 
905         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
906                 APPROVAL_BY_PACKAGE);
907         ComponentName cn = ComponentName.unflattenFromString("a/a");
908 
909         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
910             Object[] args = invocation.getArguments();
911             ServiceConnection sc = (ServiceConnection) args[1];
912             sc.onServiceConnected(cn, mock(IBinder.class));
913             return true;
914         });
915 
916         service.addApprovedList("a", 0, false);
917 
918         service.reregisterService(cn, 0);
919 
920         assertTrue(service.isBound(cn, 0));
921     }
922 
923     @Test
reregisterService_checksAppIsApproved_cn()924     public void reregisterService_checksAppIsApproved_cn() throws Exception {
925         Context context = mock(Context.class);
926         PackageManager pm = mock(PackageManager.class);
927         ApplicationInfo ai = new ApplicationInfo();
928         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
929 
930         when(context.getPackageName()).thenReturn(mPkg);
931         when(context.getUserId()).thenReturn(mUser.getIdentifier());
932         when(context.getPackageManager()).thenReturn(pm);
933         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
934 
935         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
936                 APPROVAL_BY_COMPONENT);
937         ComponentName cn = ComponentName.unflattenFromString("a/a");
938 
939         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
940             Object[] args = invocation.getArguments();
941             ServiceConnection sc = (ServiceConnection) args[1];
942             sc.onServiceConnected(cn, mock(IBinder.class));
943             return true;
944         });
945 
946         service.addApprovedList("a/a", 0, true);
947 
948         service.reregisterService(cn, 0);
949 
950         assertTrue(service.isBound(cn, 0));
951     }
952 
953     @Test
reregisterService_checksAppIsApproved_cn_secondary()954     public void reregisterService_checksAppIsApproved_cn_secondary() throws Exception {
955         Context context = mock(Context.class);
956         PackageManager pm = mock(PackageManager.class);
957         ApplicationInfo ai = new ApplicationInfo();
958         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
959 
960         when(context.getPackageName()).thenReturn(mPkg);
961         when(context.getUserId()).thenReturn(mUser.getIdentifier());
962         when(context.getPackageManager()).thenReturn(pm);
963         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
964 
965         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
966                 APPROVAL_BY_COMPONENT);
967         ComponentName cn = ComponentName.unflattenFromString("a/a");
968 
969         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
970             Object[] args = invocation.getArguments();
971             ServiceConnection sc = (ServiceConnection) args[1];
972             sc.onServiceConnected(cn, mock(IBinder.class));
973             return true;
974         });
975 
976         service.addApprovedList("a/a", 0, false);
977 
978         service.reregisterService(cn, 0);
979 
980         assertTrue(service.isBound(cn, 0));
981     }
982 
983     @Test
reregisterService_checksAppIsNotApproved_cn_secondary()984     public void reregisterService_checksAppIsNotApproved_cn_secondary() throws Exception {
985         Context context = mock(Context.class);
986         PackageManager pm = mock(PackageManager.class);
987         ApplicationInfo ai = new ApplicationInfo();
988         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
989 
990         when(context.getPackageName()).thenReturn(mPkg);
991         when(context.getUserId()).thenReturn(mUser.getIdentifier());
992         when(context.getPackageManager()).thenReturn(pm);
993         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
994 
995         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
996                 APPROVAL_BY_COMPONENT);
997         ComponentName cn = ComponentName.unflattenFromString("a/a");
998 
999         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
1000             Object[] args = invocation.getArguments();
1001             ServiceConnection sc = (ServiceConnection) args[1];
1002             sc.onServiceConnected(cn, mock(IBinder.class));
1003             return true;
1004         });
1005 
1006         service.addApprovedList("b/b", 0, false);
1007 
1008         service.reregisterService(cn, 0);
1009 
1010         assertFalse(service.isBound(cn, 0));
1011     }
1012 
1013     @Test
unbindOtherUserServices()1014     public void unbindOtherUserServices() throws PackageManager.NameNotFoundException {
1015         Context context = mock(Context.class);
1016         PackageManager pm = mock(PackageManager.class);
1017         ApplicationInfo ai = new ApplicationInfo();
1018         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1019 
1020         when(context.getPackageName()).thenReturn(mPkg);
1021         when(context.getUserId()).thenReturn(mUser.getIdentifier());
1022         when(context.getPackageManager()).thenReturn(pm);
1023         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
1024 
1025         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
1026                 APPROVAL_BY_COMPONENT);
1027         ComponentName cn = ComponentName.unflattenFromString("a/a");
1028 
1029         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
1030             Object[] args = invocation.getArguments();
1031             ServiceConnection sc = (ServiceConnection) args[1];
1032             sc.onServiceConnected(cn, mock(IBinder.class));
1033             return true;
1034         });
1035 
1036         service.registerService(cn, 0);
1037         service.registerService(cn, 10);
1038         service.registerService(cn, 11);
1039         service.unbindOtherUserServices(11);
1040 
1041         assertFalse(service.isBound(cn, 0));
1042         assertFalse(service.isBound(cn, 10));
1043         assertTrue(service.isBound(cn, 11));
1044     }
1045 
1046     @Test
testPackageUninstall_packageNoLongerInApprovedList()1047     public void testPackageUninstall_packageNoLongerInApprovedList() throws Exception {
1048         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
1049             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
1050                     mIpm, approvalLevel);
1051             writeExpectedValuesToSettings(approvalLevel);
1052             service.migrateToXml();
1053 
1054             mExpectedPrimaryPackages.put(0, "another.package");
1055             mExpectedPrimaryComponentNames.put(0, "another.package/B1");
1056             service.onPackagesChanged(true, new String[]{"this.is.a.package.name"}, new int[]{103});
1057 
1058             verifyExpectedApprovedEntries(service);
1059         }
1060     }
1061 
1062     @Test
testPackageUninstall_componentNoLongerInApprovedList()1063     public void testPackageUninstall_componentNoLongerInApprovedList() throws Exception {
1064         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
1065             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
1066                     mIpm, approvalLevel);
1067             writeExpectedValuesToSettings(approvalLevel);
1068             service.migrateToXml();
1069 
1070             mExpectedSecondaryComponentNames.put(10, "component/2");
1071             mExpectedSecondaryPackages.put(10, "component");
1072             service.onPackagesChanged(true, new String[]{"this.is.another.package"}, new int[]{
1073                     UserHandle.PER_USER_RANGE + 1});
1074 
1075             verifyExpectedApprovedEntries(service);
1076         }
1077     }
1078 
1079     @Test
testIsPackageAllowed()1080     public void testIsPackageAllowed() {
1081         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
1082             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
1083                     mIpm, approvalLevel);
1084             writeExpectedValuesToSettings(approvalLevel);
1085             service.migrateToXml();
1086 
1087             verifyExpectedApprovedPackages(service);
1088         }
1089     }
1090 
1091     @Test
testUpgradeAppBindsNewServices()1092     public void testUpgradeAppBindsNewServices() throws Exception {
1093         // If the primary and secondary lists contain component names, only those components within
1094         // the package should be matched
1095         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
1096                 mIpm,
1097                 ManagedServices.APPROVAL_BY_PACKAGE);
1098 
1099         List<String> packages = new ArrayList<>();
1100         packages.add("package");
1101         addExpectedServices(service, packages, 0);
1102 
1103         // only 2 components are approved per package
1104         mExpectedPrimaryComponentNames.clear();
1105         mExpectedPrimaryPackages.clear();
1106         mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2");
1107         mExpectedSecondaryComponentNames.clear();
1108         mExpectedSecondaryPackages.clear();
1109 
1110         loadXml(service);
1111 
1112         // new component expected
1113         mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2:package/C3");
1114 
1115         service.onPackagesChanged(false, new String[]{"package"}, new int[]{0});
1116 
1117         // verify the 3 components per package are enabled (bound)
1118         verifyExpectedBoundEntries(service, true);
1119 
1120         // verify the last component per package is not enabled/we don't try to bind to it
1121         for (String pkg : packages) {
1122             ComponentName unapprovedAdditionalComponent =
1123                     ComponentName.unflattenFromString(pkg + "/C3");
1124             assertFalse(
1125                     service.isComponentEnabledForCurrentProfiles(
1126                             unapprovedAdditionalComponent));
1127             verify(mIpm, never()).getServiceInfo(
1128                     eq(unapprovedAdditionalComponent), anyLong(), anyInt());
1129         }
1130     }
1131 
1132     @Test
testSetPackageOrComponentEnabled()1133     public void testSetPackageOrComponentEnabled() throws Exception {
1134         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
1135             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
1136                     mIpm, approvalLevel);
1137             ArrayMap<Integer, ArrayList<String>> expectedEnabled = new ArrayMap<>();
1138             expectedEnabled.put(0,
1139                     Lists.newArrayList(new String[]{"package/Comp", "package/C2", "again/M4"}));
1140             expectedEnabled.put(10,
1141                     Lists.newArrayList(new String[]{"user10package/B", "user10/Component",
1142                             "user10package1/K", "user10.3/Component", "user10package2/L",
1143                             "user10.4/Component"}));
1144 
1145             for (int userId : expectedEnabled.keySet()) {
1146                 ArrayList<String> expectedForUser = expectedEnabled.get(userId);
1147                 for (int i = 0; i < expectedForUser.size(); i++) {
1148                     boolean primary = i % 2 == 0;
1149                     service.setPackageOrComponentEnabled(expectedForUser.get(i), userId, primary,
1150                             true);
1151                 }
1152             }
1153 
1154             // verify everything added is approved
1155             for (int userId : expectedEnabled.keySet()) {
1156                 ArrayList<String> expectedForUser = expectedEnabled.get(userId);
1157                 for (int i = 0; i < expectedForUser.size(); i++) {
1158                     String verifyValue  = (approvalLevel == APPROVAL_BY_COMPONENT)
1159                             ? expectedForUser.get(i)
1160                             : service.getPackageName(expectedForUser.get(i));
1161                     assertTrue("Not allowed: user: " + userId + " entry: " + verifyValue
1162                             + " for approval level " + approvalLevel,
1163                             service.isPackageOrComponentAllowed(verifyValue, userId));
1164                 }
1165             }
1166 
1167             ArrayMap<Integer, ArrayList<String>> expectedNoAccess = new ArrayMap<>();
1168             for (int userId : expectedEnabled.keySet()) {
1169                 ArrayList<String> expectedForUser = expectedEnabled.get(userId);
1170                 for (int i = expectedForUser.size() - 1; i >= 0; i--) {
1171                     ArrayList<String> removed = new ArrayList<>();
1172                     if (i % 3 == 0) {
1173                         String revokeAccessFor = expectedForUser.remove(i);
1174                         removed.add(revokeAccessFor);
1175                         service.setPackageOrComponentEnabled(
1176                                 revokeAccessFor, userId, i % 2 == 0, false);
1177                     }
1178                     expectedNoAccess.put(userId, removed);
1179                 }
1180             }
1181 
1182             // verify everything still there is approved
1183             for (int userId : expectedEnabled.keySet()) {
1184                 ArrayList<String> expectedForUser = expectedEnabled.get(userId);
1185                 for (int i = 0; i < expectedForUser.size(); i++) {
1186                     String verifyValue  = (approvalLevel == APPROVAL_BY_COMPONENT)
1187                             ? expectedForUser.get(i)
1188                             : service.getPackageName(expectedForUser.get(i));
1189                     assertTrue("Not allowed: user: " + userId + " entry: " + verifyValue,
1190                             service.isPackageOrComponentAllowed(verifyValue, userId));
1191                 }
1192             }
1193             // verify everything removed isn't
1194             for (int userId : expectedNoAccess.keySet()) {
1195                 ArrayList<String> notExpectedForUser = expectedNoAccess.get(userId);
1196                 for (int i = 0; i < notExpectedForUser.size(); i++) {
1197                     assertFalse(
1198                             "Is allowed: user: " + userId + " entry: " + notExpectedForUser.get(i),
1199                             service.isPackageOrComponentAllowed(notExpectedForUser.get(i), userId));
1200                 }
1201             }
1202         }
1203     }
1204 
1205     @Test
testGetAllowedPackages_byUser()1206     public void testGetAllowedPackages_byUser() throws Exception {
1207         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
1208             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
1209                     mIpm, approvalLevel);
1210             loadXml(service);
1211 
1212             assertThat(service.getAllowedPackages(0)).containsExactly("this.is.a.package.name",
1213                     "another.package", "secondary");
1214             assertThat(service.getAllowedPackages(10)).containsExactly("this.is.another.package",
1215                     "package", "this.is.another.package", "component");
1216             assertThat(service.getAllowedPackages(999)).isEmpty();
1217         }
1218     }
1219 
1220     @Test
testGetAllowedComponentsByUser()1221     public void testGetAllowedComponentsByUser() throws Exception {
1222         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
1223                 APPROVAL_BY_COMPONENT);
1224         loadXml(service);
1225 
1226         List<ComponentName> expected = new ArrayList<>();
1227         expected.add(ComponentName.unflattenFromString("this.is.another.package/M1"));
1228         expected.add(ComponentName.unflattenFromString("this.is.another.package/with.Component"));
1229         expected.add(ComponentName.unflattenFromString("component/2"));
1230         expected.add(ComponentName.unflattenFromString("package/component2"));
1231 
1232         List<ComponentName> actual = service.getAllowedComponents(10);
1233 
1234         assertContentsInAnyOrder(expected, actual);
1235 
1236         assertEquals(expected.size(), actual.size());
1237 
1238         for (ComponentName cn : expected) {
1239             assertTrue("Actual missing " + cn, actual.contains(cn));
1240         }
1241 
1242         for (ComponentName cn : actual) {
1243             assertTrue("Actual contains extra " + cn, expected.contains(cn));
1244         }
1245     }
1246 
1247     @Test
testGetAllowedComponents_approvalByPackage()1248     public void testGetAllowedComponents_approvalByPackage() throws Exception {
1249         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
1250                 APPROVAL_BY_PACKAGE);
1251         loadXml(service);
1252 
1253         assertEquals(0, service.getAllowedComponents(10).size());
1254     }
1255 
1256     @Test
testOnUserRemoved()1257     public void testOnUserRemoved() throws Exception {
1258         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
1259             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
1260                     mIpm, approvalLevel);
1261             loadXml(service);
1262 
1263             ArrayMap<Integer, String> verifyMap = mExpectedPrimary.get(service.mApprovalLevel);
1264             String user0 = verifyMap.remove(0);
1265             verifyMap = mExpectedSecondary.get(service.mApprovalLevel);
1266             user0 = user0 + ":" + verifyMap.remove(0);
1267 
1268             service.onUserRemoved(0);
1269 
1270             for (String verifyValue : user0.split(":")) {
1271                 if (!TextUtils.isEmpty(verifyValue)) {
1272                     assertFalse("service type " + service.mApprovalLevel + ":" + verifyValue
1273                             + " is still allowed",
1274                             service.isPackageOrComponentAllowed(verifyValue, 0));
1275                 }
1276             }
1277 
1278             verifyExpectedApprovedEntries(service);
1279         }
1280     }
1281 
1282     @Test
testIsSameUser()1283     public void testIsSameUser() {
1284         IInterface service = mock(IInterface.class);
1285         when(service.asBinder()).thenReturn(mock(IBinder.class));
1286         ManagedServices services = new TestManagedServices(getContext(), mLock, mUserProfiles,
1287                 mIpm, APPROVAL_BY_PACKAGE);
1288         services.registerSystemService(service, null, 10, 1000);
1289         ManagedServices.ManagedServiceInfo info = services.checkServiceTokenLocked(service);
1290         info.isSystem = true;
1291 
1292         assertFalse(services.isSameUser(service, 0));
1293         assertTrue(services.isSameUser(service, 10));
1294         assertTrue(services.isSameUser(service, UserHandle.USER_ALL));
1295     }
1296 
1297     @Test
testGetAllowedComponents()1298     public void testGetAllowedComponents() throws Exception {
1299         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
1300                 APPROVAL_BY_COMPONENT);
1301         loadXml(service);
1302 
1303         SparseArray<ArraySet<ComponentName>> expected = new SparseArray<>();
1304 
1305         ArraySet<ComponentName> expected10 = new ArraySet<>();
1306         expected10.add(ComponentName.unflattenFromString("this.is.another.package/M1"));
1307         expected10.add(ComponentName.unflattenFromString("this.is.another.package/with.Component"));
1308         expected10.add(ComponentName.unflattenFromString("component/2"));
1309         expected10.add(ComponentName.unflattenFromString("package/component2"));
1310         expected.put(10, expected10);
1311         ArraySet<ComponentName> expected0 = new ArraySet<>();
1312         expected0.add(ComponentName.unflattenFromString("secondary/component.Name"));
1313         expected0.add(ComponentName.unflattenFromString("this.is.a.package.name/Ba"));
1314         expected0.add(ComponentName.unflattenFromString("another.package/B1"));
1315         expected.put(0, expected0);
1316         ArraySet<ComponentName> expected12 = new ArraySet<>();
1317         expected12.add(ComponentName.unflattenFromString("bananas!/Bananas!"));
1318         expected.put(12, expected12);
1319         expected.put(11, new ArraySet<>());
1320         ArraySet<ComponentName> expected13 = new ArraySet<>();
1321         expected13.add(ComponentName.unflattenFromString("non.user.set.package/M1"));
1322         expected.put(13, expected13);
1323 
1324         SparseArray<ArraySet<ComponentName>> actual =
1325                 service.getAllowedComponents(mUserProfiles.getCurrentProfileIds());
1326 
1327         assertContentsInAnyOrder(expected, actual);
1328     }
1329 
1330     @Test
testPopulateComponentsToUnbind_forceRebind()1331     public void testPopulateComponentsToUnbind_forceRebind() {
1332         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
1333                 APPROVAL_BY_COMPONENT);
1334 
1335         IInterface iInterface = mock(IInterface.class);
1336         when(iInterface.asBinder()).thenReturn(mock(IBinder.class));
1337 
1338         ManagedServices.ManagedServiceInfo service0 = service.new ManagedServiceInfo(
1339                 iInterface, ComponentName.unflattenFromString("a/a"), 0, false,
1340                 mock(ServiceConnection.class), 26, 34);
1341         ManagedServices.ManagedServiceInfo service10 = service.new ManagedServiceInfo(
1342                 iInterface, ComponentName.unflattenFromString("b/b"), 10, false,
1343                 mock(ServiceConnection.class), 26, 345);
1344         Set<ManagedServices.ManagedServiceInfo> removableBoundServices = new ArraySet<>();
1345         removableBoundServices.add(service0);
1346         removableBoundServices.add(service10);
1347 
1348         SparseArray<Set<ComponentName>> allowedComponentsToBind = new SparseArray<>();
1349         Set<ComponentName> allowed0 = new ArraySet<>();
1350         allowed0.add(ComponentName.unflattenFromString("a/a"));
1351         allowedComponentsToBind.put(0, allowed0);
1352         Set<ComponentName> allowed10 = new ArraySet<>();
1353         allowed10.add(ComponentName.unflattenFromString("b/b"));
1354         allowedComponentsToBind.put(10, allowed10);
1355 
1356         SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
1357 
1358         service.populateComponentsToUnbind(true, removableBoundServices, allowedComponentsToBind,
1359                 componentsToUnbind);
1360 
1361         assertEquals(2, componentsToUnbind.size());
1362         assertTrue(componentsToUnbind.get(0).contains(ComponentName.unflattenFromString("a/a")));
1363         assertTrue(componentsToUnbind.get(10).contains(ComponentName.unflattenFromString("b/b")));
1364     }
1365 
1366     @Test
testPopulateComponentsToUnbind()1367     public void testPopulateComponentsToUnbind() {
1368         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
1369                 APPROVAL_BY_COMPONENT);
1370 
1371         IInterface iInterface = mock(IInterface.class);
1372         when(iInterface.asBinder()).thenReturn(mock(IBinder.class));
1373 
1374         ManagedServices.ManagedServiceInfo service0 = service.new ManagedServiceInfo(
1375                 iInterface, ComponentName.unflattenFromString("a/a"), 0, false,
1376                 mock(ServiceConnection.class), 26, 345);
1377         ManagedServices.ManagedServiceInfo service0a = service.new ManagedServiceInfo(
1378                 iInterface, ComponentName.unflattenFromString("c/c"), 0, false,
1379                 mock(ServiceConnection.class), 26, 3456);
1380         ManagedServices.ManagedServiceInfo service10 = service.new ManagedServiceInfo(
1381                 iInterface, ComponentName.unflattenFromString("b/b"), 10, false,
1382                 mock(ServiceConnection.class), 26, 34567);
1383         Set<ManagedServices.ManagedServiceInfo> removableBoundServices = new ArraySet<>();
1384         removableBoundServices.add(service0);
1385         removableBoundServices.add(service0a);
1386         removableBoundServices.add(service10);
1387 
1388         SparseArray<Set<ComponentName>> allowedComponentsToBind = new SparseArray<>();
1389         Set<ComponentName> allowed0 = new ArraySet<>();
1390         allowed0.add(ComponentName.unflattenFromString("a/a"));
1391         allowedComponentsToBind.put(0, allowed0);
1392         Set<ComponentName> allowed10 = new ArraySet<>();
1393         allowed10.add(ComponentName.unflattenFromString("b/b"));
1394         allowedComponentsToBind.put(10, allowed10);
1395 
1396         SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
1397 
1398         service.populateComponentsToUnbind(false, removableBoundServices, allowedComponentsToBind,
1399                 componentsToUnbind);
1400 
1401         assertEquals(1, componentsToUnbind.size());
1402         assertEquals(1, componentsToUnbind.get(0).size());
1403         assertTrue(componentsToUnbind.get(0).contains(ComponentName.unflattenFromString("c/c")));
1404     }
1405 
1406     @Test
populateComponentsToBind()1407     public void populateComponentsToBind() {
1408         ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm,
1409                 APPROVAL_BY_COMPONENT);
1410 
1411         SparseArray<ArraySet<ComponentName>> approvedComponentsByUser = new SparseArray<>();
1412         ArraySet<ComponentName> allowed0 = new ArraySet<>();
1413         allowed0.add(ComponentName.unflattenFromString("a/a"));
1414         approvedComponentsByUser.put(0, allowed0);
1415         ArraySet<ComponentName> allowed10 = new ArraySet<>();
1416         allowed10.add(ComponentName.unflattenFromString("b/b"));
1417         allowed10.add(ComponentName.unflattenFromString("c/c"));
1418         approvedComponentsByUser.put(10, allowed10);
1419         ArraySet<ComponentName> allowed15 = new ArraySet<>();
1420         allowed15.add(ComponentName.unflattenFromString("d/d"));
1421         approvedComponentsByUser.put(15, allowed15);
1422 
1423         IntArray users = new IntArray();
1424         users.add(10);
1425         users.add(0);
1426 
1427         SparseArray<Set<ComponentName>> componentsToBind = new SparseArray<>();
1428 
1429         service.populateComponentsToBind(componentsToBind, users, approvedComponentsByUser);
1430 
1431         assertEquals(2, componentsToBind.size());
1432         assertEquals(1, componentsToBind.get(0).size());
1433         assertTrue(componentsToBind.get(0).contains(ComponentName.unflattenFromString("a/a")));
1434         assertEquals(2, componentsToBind.get(10).size());
1435         assertTrue(componentsToBind.get(10).contains(ComponentName.unflattenFromString("b/b")));
1436         assertTrue(componentsToBind.get(10).contains(ComponentName.unflattenFromString("c/c")));
1437     }
1438 
1439     @Test
testOnNullBinding()1440     public void testOnNullBinding() throws Exception {
1441         Context context = mock(Context.class);
1442         PackageManager pm = mock(PackageManager.class);
1443         ApplicationInfo ai = new ApplicationInfo();
1444         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1445 
1446         when(context.getPackageName()).thenReturn(mPkg);
1447         when(context.getUserId()).thenReturn(mUser.getIdentifier());
1448         when(context.getPackageManager()).thenReturn(pm);
1449         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
1450 
1451         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
1452                 APPROVAL_BY_COMPONENT);
1453         ComponentName cn = ComponentName.unflattenFromString("a/a");
1454 
1455         ArgumentCaptor<ServiceConnection> captor = ArgumentCaptor.forClass(ServiceConnection.class);
1456         when(context.bindServiceAsUser(any(), captor.capture(), anyInt(), any()))
1457                 .thenAnswer(invocation -> {
1458                     captor.getValue().onNullBinding(cn);
1459                     return true;
1460                 });
1461 
1462         service.registerSystemService(cn, 0);
1463         verify(context).unbindService(captor.getValue());
1464     }
1465 
1466     @Test
testOnServiceConnected()1467     public void testOnServiceConnected() throws Exception {
1468         Context context = mock(Context.class);
1469         PackageManager pm = mock(PackageManager.class);
1470         ApplicationInfo ai = new ApplicationInfo();
1471         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1472 
1473         when(context.getPackageName()).thenReturn(mPkg);
1474         when(context.getUserId()).thenReturn(mUser.getIdentifier());
1475         when(context.getPackageManager()).thenReturn(pm);
1476         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
1477 
1478         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
1479                 APPROVAL_BY_COMPONENT);
1480         ComponentName cn = ComponentName.unflattenFromString("a/a");
1481 
1482         service.registerSystemService(cn, 0);
1483         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
1484             Object[] args = invocation.getArguments();
1485             ServiceConnection sc = (ServiceConnection) args[1];
1486             sc.onServiceConnected(cn, mock(IBinder.class));
1487             return true;
1488         });
1489 
1490         service.registerSystemService(cn, 0);
1491         assertTrue(service.isBound(cn, 0));
1492     }
1493 
1494     @Test
testSetComponentState()1495     public void testSetComponentState() throws Exception {
1496         Context context = mock(Context.class);
1497         PackageManager pm = mock(PackageManager.class);
1498         ApplicationInfo ai = new ApplicationInfo();
1499         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1500 
1501         when(context.getPackageName()).thenReturn(mPkg);
1502         when(context.getUserId()).thenReturn(mUser.getIdentifier());
1503         when(context.getPackageManager()).thenReturn(pm);
1504         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
1505 
1506         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
1507                 APPROVAL_BY_COMPONENT);
1508         ComponentName cn = ComponentName.unflattenFromString("a/a");
1509 
1510         service.registerSystemService(cn, 0);
1511         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
1512             Object[] args = invocation.getArguments();
1513             ServiceConnection sc = (ServiceConnection) args[1];
1514             sc.onServiceConnected(cn, mock(IBinder.class));
1515             return true;
1516         });
1517 
1518         service.registerSystemService(cn, mZero.id);
1519 
1520         service.setComponentState(cn, mZero.id, false);
1521         verify(context).unbindService(any());
1522     }
1523 
1524     @Test
testSetComponentState_workProfile()1525     public void testSetComponentState_workProfile() throws Exception {
1526         Context context = mock(Context.class);
1527         PackageManager pm = mock(PackageManager.class);
1528         ApplicationInfo ai = new ApplicationInfo();
1529         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1530 
1531         when(context.getPackageName()).thenReturn(mPkg);
1532         when(context.getUserId()).thenReturn(mUser.getIdentifier());
1533         when(context.getPackageManager()).thenReturn(pm);
1534         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
1535 
1536         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
1537                 APPROVAL_BY_COMPONENT);
1538         ComponentName cn = ComponentName.unflattenFromString("a/a");
1539 
1540         service.registerSystemService(cn, 0);
1541         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
1542             Object[] args = invocation.getArguments();
1543             ServiceConnection sc = (ServiceConnection) args[1];
1544             sc.onServiceConnected(cn, mock(IBinder.class));
1545             return true;
1546         });
1547 
1548         service.registerSystemService(cn, mZero.id);
1549 
1550         service.setComponentState(cn, mTen.id, false);
1551         verify(context, never()).unbindService(any());
1552     }
1553 
1554     @Test
testSetComponentState_differentUsers()1555     public void testSetComponentState_differentUsers() throws Exception {
1556         Context context = mock(Context.class);
1557         PackageManager pm = mock(PackageManager.class);
1558         ApplicationInfo ai = new ApplicationInfo();
1559         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1560 
1561         when(context.getPackageName()).thenReturn(mPkg);
1562         when(context.getUserId()).thenReturn(mUser.getIdentifier());
1563         when(context.getPackageManager()).thenReturn(pm);
1564         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
1565 
1566         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
1567                 APPROVAL_BY_COMPONENT);
1568         ComponentName cn = ComponentName.unflattenFromString("a/a");
1569 
1570         addExpectedServices(service, Arrays.asList("a"), mZero.id);
1571         addExpectedServices(service, Arrays.asList("a"), mTen.id);
1572         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
1573             Object[] args = invocation.getArguments();
1574             ServiceConnection sc = (ServiceConnection) args[1];
1575             sc.onServiceConnected(cn, mock(IBinder.class));
1576             return true;
1577         });
1578         service.addApprovedList("a/a", 0, true);
1579         service.addApprovedList("a/a", 10, false);
1580 
1581         service.registerService(cn, mZero.id);
1582         assertTrue(service.isBound(cn, mZero.id));
1583 
1584         service.onUserSwitched(mTen.id);
1585         assertFalse(service.isBound(cn, mZero.id));
1586         service.registerService(cn, mTen.id);
1587         assertTrue(service.isBound(cn, mTen.id));
1588 
1589         service.setComponentState(cn, mTen.id, false);
1590         assertFalse(service.isBound(cn, mZero.id));
1591         assertFalse(service.isBound(cn, mTen.id));
1592 
1593         // Service should be rebound on user 0, since it was only disabled for user 10.
1594         service.onUserSwitched(mZero.id);
1595         assertTrue(service.isBound(cn, mZero.id));
1596         assertFalse(service.isBound(cn, mTen.id));
1597 
1598         // Service should stay unbound on going back to user 10.
1599         service.onUserSwitched(mTen.id);
1600         assertFalse(service.isBound(cn, mZero.id));
1601         assertFalse(service.isBound(cn, mTen.id));
1602     }
1603     @Test
testOnPackagesChanged_nullValuesPassed_noNullPointers()1604     public void testOnPackagesChanged_nullValuesPassed_noNullPointers() {
1605         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
1606             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
1607                     mIpm, approvalLevel);
1608             // null uid list
1609             service.onPackagesChanged(true, new String[]{"this.is.a.package.name"}, null);
1610 
1611             // null package list
1612             service.onPackagesChanged(true, null, new int[]{103});
1613         }
1614     }
1615 
1616     @Test
loadDefaults_noVersionNoDefaults()1617     public void loadDefaults_noVersionNoDefaults() throws Exception {
1618         resetComponentsAndPackages();
1619         loadXml(mService);
1620         assertEquals(mService.getDefaultComponents().size(), 0);
1621     }
1622 
1623     @Test
loadDefaults_noVersionNoDefaultsOneActive()1624     public void loadDefaults_noVersionNoDefaultsOneActive() throws Exception {
1625         resetComponentsAndPackages();
1626         mService.addDefaultComponentOrPackage("package/class");
1627         loadXml(mService);
1628         assertEquals(1, mService.getDefaultComponents().size());
1629         assertTrue(mService.getDefaultComponents()
1630                 .contains(ComponentName.unflattenFromString("package/class")));
1631     }
1632 
1633     @Test
loadDefaults_noVersionWithDefaults()1634     public void loadDefaults_noVersionWithDefaults() throws Exception {
1635         resetComponentsAndPackages();
1636         mDefaults.add(new ComponentName("default", "class"));
1637         mVersionString = null;
1638         loadXml(mService);
1639         assertEquals(mService.getDefaultComponents(), mDefaults);
1640     }
1641 
1642     @Test
loadDefaults_versionOneWithDefaultsWithActive()1643     public void loadDefaults_versionOneWithDefaultsWithActive() throws Exception {
1644         resetComponentsAndPackages();
1645         mDefaults.add(new ComponentName("default", "class"));
1646         mExpectedPrimaryComponentNames.put(0, "package/class");
1647         mVersionString = "1";
1648         loadXml(mService);
1649         assertEquals(mService.getDefaultComponents(),
1650                 new ArraySet(Arrays.asList(new ComponentName("package", "class"))));
1651     }
1652 
1653     @Test
loadDefaults_versionTwoWithDefaultsWithActive()1654     public void loadDefaults_versionTwoWithDefaultsWithActive() throws Exception {
1655         resetComponentsAndPackages();
1656         mDefaults.add(new ComponentName("default", "class"));
1657         mDefaultsString = "default/class";
1658         mExpectedPrimaryComponentNames.put(0, "package/class");
1659         mVersionString = "2";
1660         loadXml(mService);
1661         assertEquals(1, mService.getDefaultComponents().size());
1662         mDefaults.forEach(pkg -> {
1663             assertTrue(mService.getDefaultComponents().contains(pkg));
1664         });
1665     }
1666 
1667     @Test
loadDefaults_versionOneWithXMLDefaultsWithActive()1668     public void loadDefaults_versionOneWithXMLDefaultsWithActive() throws Exception {
1669         resetComponentsAndPackages();
1670         mDefaults.add(new ComponentName("default", "class"));
1671         mDefaultsString = "xml/class";
1672         mExpectedPrimaryComponentNames.put(0, "package/class");
1673         mVersionString = "1";
1674         loadXml(mService);
1675         assertEquals(mService.getDefaultComponents(),
1676                 new ArraySet(Arrays.asList(new ComponentName("xml", "class"))));
1677     }
1678 
1679     @Test
loadDefaults_versionTwoWithXMLDefaultsWithActive()1680     public void loadDefaults_versionTwoWithXMLDefaultsWithActive() throws Exception {
1681         resetComponentsAndPackages();
1682         mDefaults.add(new ComponentName("default", "class"));
1683         mDefaultsString = "xml/class";
1684         mExpectedPrimaryComponentNames.put(0, "package/class");
1685         mVersionString = "2";
1686         loadXml(mService);
1687         assertEquals(mService.getDefaultComponents(),
1688                 new ArraySet(Arrays.asList(new ComponentName("xml", "class"))));
1689     }
1690 
1691     @Test
loadDefaults_versionLatest_NoLoadDefaults()1692     public void loadDefaults_versionLatest_NoLoadDefaults() throws Exception {
1693         resetComponentsAndPackages();
1694         mDefaults.add(new ComponentName("default", "class"));
1695         mDefaultsString = "xml/class";
1696         loadXml(mService);
1697         assertEquals(mService.getDefaultComponents(),
1698                 new ArraySet(Arrays.asList(new ComponentName("xml", "class"))));
1699     }
1700 
1701     @Test
upgradeUserSet_versionThree()1702     public void upgradeUserSet_versionThree() throws Exception {
1703         resetComponentsAndPackages();
1704 
1705         List<UserInfo> users = new ArrayList<>();
1706         users.add(new UserInfo(98, "98", 0));
1707         users.add(new UserInfo(99, "99", 0));
1708         for (UserInfo user : users) {
1709             when(mUm.getUserInfo(eq(user.id))).thenReturn(user);
1710         }
1711 
1712         mDefaultsString = "xml/class";
1713         mVersionString = "3";
1714         mUserSetString = "xml/class";
1715         loadXml(mService);
1716 
1717         //Test services without overriding upgradeUserSet() remain unchanged
1718         assertEquals(new ArraySet(Arrays.asList(mUserSetString)),
1719                 mService.mUserSetServices.get(98));
1720         assertEquals(new ArraySet(Arrays.asList(mUserSetString)),
1721                 mService.mUserSetServices.get(99));
1722         assertEquals(new ArrayMap(), mService.mIsUserChanged);
1723     }
1724 
1725     @Test
testInfoIsPermittedForProfile_notProfile()1726     public void testInfoIsPermittedForProfile_notProfile() {
1727         when(mUserProfiles.isProfileUser(anyInt())).thenReturn(false);
1728 
1729         IInterface service = mock(IInterface.class);
1730         when(service.asBinder()).thenReturn(mock(IBinder.class));
1731         ManagedServices services = new TestManagedServices(getContext(), mLock, mUserProfiles,
1732                 mIpm, APPROVAL_BY_PACKAGE);
1733         services.registerSystemService(service, null, 10, 1000);
1734         ManagedServices.ManagedServiceInfo info = services.checkServiceTokenLocked(service);
1735 
1736         assertTrue(info.isPermittedForProfile(0));
1737     }
1738 
1739     @Test
testInfoIsPermittedForProfile_profileAndDpmAllows()1740     public void testInfoIsPermittedForProfile_profileAndDpmAllows() {
1741         when(mUserProfiles.isProfileUser(anyInt())).thenReturn(true);
1742         when(mDpm.isNotificationListenerServicePermitted(anyString(), anyInt())).thenReturn(true);
1743 
1744         IInterface service = mock(IInterface.class);
1745         when(service.asBinder()).thenReturn(mock(IBinder.class));
1746         ManagedServices services = new TestManagedServices(getContext(), mLock, mUserProfiles,
1747                 mIpm, APPROVAL_BY_PACKAGE);
1748         services.registerSystemService(service, null, 10, 1000);
1749         ManagedServices.ManagedServiceInfo info = services.checkServiceTokenLocked(service);
1750         info.component = new ComponentName("a","b");
1751 
1752         assertTrue(info.isPermittedForProfile(0));
1753     }
1754 
1755     @Test
testInfoIsPermittedForProfile_profileAndDpmDenies()1756     public void testInfoIsPermittedForProfile_profileAndDpmDenies() {
1757         when(mUserProfiles.isProfileUser(anyInt())).thenReturn(true);
1758         when(mDpm.isNotificationListenerServicePermitted(anyString(), anyInt())).thenReturn(false);
1759 
1760         IInterface service = mock(IInterface.class);
1761         when(service.asBinder()).thenReturn(mock(IBinder.class));
1762         ManagedServices services = new TestManagedServices(getContext(), mLock, mUserProfiles,
1763                 mIpm, APPROVAL_BY_PACKAGE);
1764         services.registerSystemService(service, null, 10, 1000);
1765         ManagedServices.ManagedServiceInfo info = services.checkServiceTokenLocked(service);
1766         info.component = new ComponentName("a","b");
1767 
1768         assertFalse(info.isPermittedForProfile(0));
1769     }
1770 
1771     @Test
testUserProfiles_canProfileUseBoundServices_managedProfile()1772     public void testUserProfiles_canProfileUseBoundServices_managedProfile() {
1773         List<UserInfo> users = new ArrayList<>();
1774         UserInfo profile = new UserInfo(ActivityManager.getCurrentUser(), "current", 0);
1775         profile.userType = USER_TYPE_FULL_SECONDARY;
1776         users.add(profile);
1777         UserInfo managed = new UserInfo(12, "12", 0);
1778         managed.userType = USER_TYPE_PROFILE_MANAGED;
1779         users.add(managed);
1780         UserInfo clone = new UserInfo(13, "13", 0);
1781         clone.userType = USER_TYPE_PROFILE_CLONE;
1782         users.add(clone);
1783         when(mUm.getProfiles(ActivityManager.getCurrentUser())).thenReturn(users);
1784 
1785         ManagedServices.UserProfiles profiles = new ManagedServices.UserProfiles();
1786         profiles.updateCache(mContext);
1787 
1788         assertFalse(profiles.isProfileUser(ActivityManager.getCurrentUser()));
1789         assertTrue(profiles.isProfileUser(12));
1790         assertTrue(profiles.isProfileUser(13));
1791     }
1792 
1793     @Test
rebindServices_onlyBindsIfAutobindMetaDataTrue()1794     public void rebindServices_onlyBindsIfAutobindMetaDataTrue() throws Exception {
1795         Context context = mock(Context.class);
1796         PackageManager pm = mock(PackageManager.class);
1797         ApplicationInfo ai = new ApplicationInfo();
1798         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1799 
1800         when(context.getPackageName()).thenReturn(mPkg);
1801         when(context.getUserId()).thenReturn(mUser.getIdentifier());
1802         when(context.getPackageManager()).thenReturn(pm);
1803         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
1804 
1805         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
1806                 APPROVAL_BY_COMPONENT);
1807         final ComponentName cn_allowed = ComponentName.unflattenFromString("anotherPackage/C1");
1808         final ComponentName cn_disallowed = ComponentName.unflattenFromString("package/C1");
1809 
1810         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
1811             Object[] args = invocation.getArguments();
1812             ServiceConnection sc = (ServiceConnection) args[1];
1813             sc.onServiceConnected(cn_allowed, mock(IBinder.class));
1814             return true;
1815         });
1816 
1817         List<ComponentName> componentNames = new ArrayList<>();
1818         componentNames.add(cn_allowed);
1819         componentNames.add(cn_disallowed);
1820         ArrayMap<ComponentName, Bundle> metaDatas = new ArrayMap<>();
1821         Bundle metaDataAutobindDisallow = new Bundle();
1822         metaDataAutobindDisallow.putBoolean(META_DATA_DEFAULT_AUTOBIND, false);
1823         metaDatas.put(cn_disallowed, metaDataAutobindDisallow);
1824         Bundle metaDataAutobindAllow = new Bundle();
1825         metaDataAutobindAllow.putBoolean(META_DATA_DEFAULT_AUTOBIND, true);
1826         metaDatas.put(cn_allowed, metaDataAutobindAllow);
1827 
1828         mockServiceInfoWithMetaData(componentNames, service, metaDatas);
1829 
1830         service.addApprovedList(cn_allowed.flattenToString(), 0, true);
1831         service.addApprovedList(cn_disallowed.flattenToString(), 0, true);
1832 
1833         service.rebindServices(true, 0);
1834 
1835         assertTrue(service.isBound(cn_allowed, 0));
1836         assertFalse(service.isBound(cn_disallowed, 0));
1837     }
1838 
1839     @Test
rebindServices_bindsIfAutobindMetaDataFalseWhenServiceBound()1840     public void rebindServices_bindsIfAutobindMetaDataFalseWhenServiceBound() throws Exception {
1841         Context context = mock(Context.class);
1842         PackageManager pm = mock(PackageManager.class);
1843         ApplicationInfo ai = new ApplicationInfo();
1844         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1845 
1846         when(context.getPackageName()).thenReturn(mPkg);
1847         when(context.getUserId()).thenReturn(mUser.getIdentifier());
1848         when(context.getPackageManager()).thenReturn(pm);
1849         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
1850 
1851         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
1852                 APPROVAL_BY_COMPONENT);
1853         final ComponentName cn_disallowed = ComponentName.unflattenFromString("package/C1");
1854 
1855         // mock isBoundOrRebinding => consider listener service bound
1856         service = spy(service);
1857         when(service.isBoundOrRebinding(cn_disallowed, 0)).thenReturn(true);
1858 
1859         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
1860             Object[] args = invocation.getArguments();
1861             ServiceConnection sc = (ServiceConnection) args[1];
1862             sc.onServiceConnected(cn_disallowed, mock(IBinder.class));
1863             return true;
1864         });
1865 
1866         List<ComponentName> componentNames = new ArrayList<>();
1867         componentNames.add(cn_disallowed);
1868         ArrayMap<ComponentName, Bundle> metaDatas = new ArrayMap<>();
1869         Bundle metaDataAutobindDisallow = new Bundle();
1870         metaDataAutobindDisallow.putBoolean(META_DATA_DEFAULT_AUTOBIND, false);
1871         metaDatas.put(cn_disallowed, metaDataAutobindDisallow);
1872 
1873         mockServiceInfoWithMetaData(componentNames, service, metaDatas);
1874 
1875         service.addApprovedList(cn_disallowed.flattenToString(), 0, true);
1876 
1877         // Listener service should be bound by rebindService when forceRebind is false
1878         service.rebindServices(false, 0);
1879         assertTrue(service.isBound(cn_disallowed, 0));
1880     }
1881 
1882     @Test
setComponentState_ignoresAutobindMetaData()1883     public void setComponentState_ignoresAutobindMetaData() throws Exception {
1884         Context context = mock(Context.class);
1885         PackageManager pm = mock(PackageManager.class);
1886         ApplicationInfo ai = new ApplicationInfo();
1887         ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1888 
1889         when(context.getPackageName()).thenReturn(mPkg);
1890         when(context.getUserId()).thenReturn(mUser.getIdentifier());
1891         when(context.getPackageManager()).thenReturn(pm);
1892         when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
1893 
1894         ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
1895                 APPROVAL_BY_COMPONENT);
1896         final ComponentName cn_disallowed = ComponentName.unflattenFromString("package/C1");
1897 
1898         when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
1899             Object[] args = invocation.getArguments();
1900             ServiceConnection sc = (ServiceConnection) args[1];
1901             sc.onServiceConnected(cn_disallowed, mock(IBinder.class));
1902             return true;
1903         });
1904 
1905         List<ComponentName> componentNames = new ArrayList<>();
1906         componentNames.add(cn_disallowed);
1907         ArrayMap<ComponentName, Bundle> metaDatas = new ArrayMap<>();
1908         Bundle metaDataAutobindDisallow = new Bundle();
1909         metaDataAutobindDisallow.putBoolean(META_DATA_DEFAULT_AUTOBIND, false);
1910         metaDatas.put(cn_disallowed, metaDataAutobindDisallow);
1911 
1912         mockServiceInfoWithMetaData(componentNames, service, metaDatas);
1913 
1914         service.addApprovedList(cn_disallowed.flattenToString(), 0, true);
1915 
1916         // add component to snoozing list
1917         service.setComponentState(cn_disallowed, 0, false);
1918 
1919         // Test that setComponentState overrides the meta-data and service is bound
1920         service.setComponentState(cn_disallowed, 0, true);
1921         assertTrue(service.isBound(cn_disallowed, 0));
1922     }
1923 
1924     @Test
isComponentEnabledForCurrentProfiles_isThreadSafe()1925     public void isComponentEnabledForCurrentProfiles_isThreadSafe() throws InterruptedException {
1926         for (UserInfo userInfo : mUm.getUsers()) {
1927             mService.addApprovedList("pkg1/cmp1:pkg2/cmp2:pkg3/cmp3", userInfo.id, true);
1928         }
1929         testThreadSafety(() -> {
1930             mService.rebindServices(false, 0);
1931             assertThat(mService.isComponentEnabledForCurrentProfiles(
1932                     new ComponentName("pkg1", "cmp1"))).isTrue();
1933         }, 20, 30);
1934     }
1935 
1936     @Test
isComponentEnabledForCurrentProfiles_profileUserId()1937     public void isComponentEnabledForCurrentProfiles_profileUserId() {
1938         final int profileUserId = 10;
1939         when(mUserProfiles.isProfileUser(profileUserId)).thenReturn(true);
1940         // Only approve for parent user (0)
1941         mService.addApprovedList("pkg1/cmp1:pkg2/cmp2:pkg3/cmp3", 0, true);
1942 
1943         // Test that the component is enabled after calling rebindServices with profile userId (10)
1944         mService.rebindServices(false, profileUserId);
1945         assertThat(mService.isComponentEnabledForCurrentProfiles(
1946                 new ComponentName("pkg1", "cmp1"))).isTrue();
1947     }
1948 
1949     @Test
isComponentEnabledForCurrentProfiles_profileUserId_NAS()1950     public void isComponentEnabledForCurrentProfiles_profileUserId_NAS() {
1951         final int profileUserId = 10;
1952         when(mUserProfiles.isProfileUser(profileUserId)).thenReturn(true);
1953         // Do not rebind for parent users (NAS use-case)
1954         ManagedServices service = spy(mService);
1955         when(service.allowRebindForParentUser()).thenReturn(false);
1956 
1957         // Only approve for parent user (0)
1958         service.addApprovedList("pkg1/cmp1:pkg2/cmp2:pkg3/cmp3", 0, true);
1959 
1960         // Test that the component is disabled after calling rebindServices with profile userId (10)
1961         service.rebindServices(false, profileUserId);
1962         assertThat(service.isComponentEnabledForCurrentProfiles(
1963                 new ComponentName("pkg1", "cmp1"))).isFalse();
1964     }
1965 
mockServiceInfoWithMetaData(List<ComponentName> componentNames, ManagedServices service, ArrayMap<ComponentName, Bundle> metaDatas)1966     private void mockServiceInfoWithMetaData(List<ComponentName> componentNames,
1967             ManagedServices service, ArrayMap<ComponentName, Bundle> metaDatas)
1968             throws RemoteException {
1969         when(mIpm.getServiceInfo(any(), anyLong(), anyInt())).thenAnswer(
1970                 (Answer<ServiceInfo>) invocation -> {
1971                     ComponentName invocationCn = invocation.getArgument(0);
1972                     if (invocationCn != null && componentNames.contains(invocationCn)) {
1973                         ServiceInfo serviceInfo = new ServiceInfo();
1974                         serviceInfo.packageName = invocationCn.getPackageName();
1975                         serviceInfo.name = invocationCn.getClassName();
1976                         serviceInfo.permission = service.getConfig().bindPermission;
1977                         serviceInfo.metaData = metaDatas.get(invocationCn);
1978                         return serviceInfo;
1979                     }
1980                     return null;
1981                 }
1982         );
1983     }
1984 
resetComponentsAndPackages()1985     private void resetComponentsAndPackages() {
1986         ArrayMap<Integer, ArrayMap<Integer, String>> empty = new ArrayMap(1);
1987         ArrayMap<Integer, String> emptyPkgs = new ArrayMap(0);
1988         empty.append(mService.mApprovalLevel, emptyPkgs);
1989         mExpectedPrimary = empty;
1990         mExpectedPrimaryComponentNames = emptyPkgs;
1991         mExpectedPrimaryPackages = emptyPkgs;
1992         mExpectedSecondary = empty;
1993         mExpectedSecondaryComponentNames = emptyPkgs;
1994         mExpectedSecondaryPackages = emptyPkgs;
1995     }
1996 
loadXml(ManagedServices service)1997     private void loadXml(ManagedServices service) throws Exception {
1998         String xmlString = createXml(service);
1999         TypedXmlPullParser parser = Xml.newFastPullParser();
2000         parser.setInput(new BufferedInputStream(
2001                 new ByteArrayInputStream(xmlString.getBytes())), null);
2002         parser.nextTag();
2003         service.readXml(parser, null, false, UserHandle.USER_ALL);
2004     }
2005 
createXml(ManagedServices service)2006     private String createXml(ManagedServices service) {
2007         final StringBuffer xml = new StringBuffer();
2008         String xmlTag = service.getConfig().xmlTag;
2009         xml.append("<" + xmlTag
2010                 + (mDefaultsString != null ? " defaults=\"" + mDefaultsString + "\" " : "")
2011                 + (mVersionString != null ? " version=\"" + mVersionString + "\" " : "")
2012                 + ">\n");
2013         for (int userId : mExpectedPrimary.get(service.mApprovalLevel).keySet()) {
2014             String pkgOrCmp = mExpectedPrimary.get(service.mApprovalLevel).get(userId);
2015             xml.append(getXmlEntry(
2016                     pkgOrCmp, userId, true,
2017                     !(pkgOrCmp.startsWith("non.user.set.package"))));
2018         }
2019         for (int userId : mExpectedSecondary.get(service.mApprovalLevel).keySet()) {
2020             xml.append(getXmlEntry(
2021                     mExpectedSecondary.get(service.mApprovalLevel).get(userId), userId, false));
2022         }
2023         xml.append("<" + ManagedServices.TAG_MANAGED_SERVICES + " "
2024                         + ManagedServices.ATT_USER_ID + "=\"99\" "
2025                         + ManagedServices.ATT_IS_PRIMARY + "=\"true\" "
2026                         + ManagedServices.ATT_APPROVED_LIST + "=\"990\" "
2027                         + (mUserSetString != null ? ManagedServices.ATT_USER_SET + "=\""
2028                         + mUserSetString + "\" " : "")
2029                         + "/>\n");
2030         xml.append("<" + ManagedServices.TAG_MANAGED_SERVICES + " "
2031                 + ManagedServices.ATT_USER_ID + "=\"98\" "
2032                 + ManagedServices.ATT_IS_PRIMARY + "=\"false\" "
2033                 + ManagedServices.ATT_APPROVED_LIST + "=\"981\" "
2034                 + (mUserSetString != null ? ManagedServices.ATT_USER_SET + "=\""
2035                 + mUserSetString + "\" " : "")
2036                 + " />\n");
2037         xml.append("</" + xmlTag + ">");
2038 
2039         return xml.toString();
2040     }
2041 
getParserWithEntries(ManagedServices service, String... xmlEntries)2042     private TypedXmlPullParser getParserWithEntries(ManagedServices service, String... xmlEntries)
2043             throws Exception {
2044         final StringBuffer xml = new StringBuffer();
2045         xml.append("<" + service.getConfig().xmlTag
2046                 + (mVersionString != null ? " version=\"" + mVersionString + "\" " : "")
2047                 + ">\n");
2048         for (String xmlEntry : xmlEntries) {
2049             xml.append(xmlEntry);
2050         }
2051         xml.append("</" + service.getConfig().xmlTag + ">");
2052 
2053         TypedXmlPullParser parser = Xml.newFastPullParser();
2054         parser.setInput(new BufferedInputStream(
2055                 new ByteArrayInputStream(xml.toString().getBytes())), null);
2056         parser.nextTag();
2057         return parser;
2058     }
2059 
addExpectedServices(final ManagedServices service, final List<String> packages, int userId)2060     private void addExpectedServices(final ManagedServices service, final List<String> packages,
2061             int userId) throws Exception {
2062         ManagedServices.Config config = service.getConfig();
2063         when(mPm.queryIntentServicesAsUser(any(), anyInt(), eq(userId))).
2064                 thenAnswer(new Answer<List<ResolveInfo>>() {
2065                     @Override
2066                     public List<ResolveInfo> answer(InvocationOnMock invocationOnMock)
2067                             throws Throwable {
2068                         Object[] args = invocationOnMock.getArguments();
2069                         Intent invocationIntent = (Intent) args[0];
2070                         if (invocationIntent != null) {
2071                             if (invocationIntent.getAction().equals(
2072                                     config.serviceInterface)
2073                                     && packages.contains(invocationIntent.getPackage())) {
2074                                 List<ResolveInfo> dummyServices = new ArrayList<>();
2075                                 for (int i = 1; i <= 3; i ++) {
2076                                     ResolveInfo resolveInfo = new ResolveInfo();
2077                                     ServiceInfo serviceInfo = new ServiceInfo();
2078                                     serviceInfo.packageName = invocationIntent.getPackage();
2079                                     serviceInfo.name = "C"+i;
2080                                     serviceInfo.permission = service.getConfig().bindPermission;
2081                                     resolveInfo.serviceInfo = serviceInfo;
2082                                     dummyServices.add(resolveInfo);
2083                                 }
2084                                 return dummyServices;
2085                             }
2086                         }
2087                         return new ArrayList<>();
2088                     }
2089                 });
2090 
2091         when(mIpm.getServiceInfo(any(), anyLong(), anyInt())).thenAnswer(
2092                 (Answer<ServiceInfo>) invocation -> {
2093                     ComponentName invocationCn = invocation.getArgument(0);
2094                     if (invocationCn != null && packages.contains(invocationCn.getPackageName())) {
2095                         ServiceInfo serviceInfo = new ServiceInfo();
2096                         serviceInfo.packageName = invocationCn.getPackageName();
2097                         serviceInfo.name = invocationCn.getClassName();
2098                         serviceInfo.permission = service.getConfig().bindPermission;
2099                         return serviceInfo;
2100                     }
2101                     return null;
2102                 }
2103         );
2104     }
2105 
stringToList(String list)2106     private List<String> stringToList(String list) {
2107         if (list == null) {
2108             list = "";
2109         }
2110         return new ArrayList<>(Lists.newArrayList(list.split(
2111                 ManagedServices.ENABLED_SERVICES_SEPARATOR)));
2112     }
2113 
assertContentsInAnyOrder(Collection<?> expected, Collection<?> actual)2114     private void assertContentsInAnyOrder(Collection<?> expected, Collection<?> actual) {
2115         assertNotNull(actual);
2116         assertEquals(expected + " : " + actual, expected.size(), actual.size());
2117 
2118         for (Object o : expected) {
2119             assertTrue("Actual missing " + o, actual.contains(o));
2120         }
2121 
2122         for (Object o : actual) {
2123             assertTrue("Actual contains extra " + o, expected.contains(o));
2124         }
2125     }
2126 
assertContentsInAnyOrder(SparseArray<ArraySet<ComponentName>> expected, SparseArray<ArraySet<ComponentName>> actual)2127     private void assertContentsInAnyOrder(SparseArray<ArraySet<ComponentName>> expected,
2128             SparseArray<ArraySet<ComponentName>> actual) throws Exception {
2129         assertEquals(expected.size(), actual.size());
2130 
2131         for (int i = 0; i < expected.size(); i++) {
2132             int key = expected.keyAt(i);
2133             assertTrue(actual.indexOfKey(key) >= 0);
2134             try {
2135                 assertContentsInAnyOrder(expected.valueAt(i), actual.get(key));
2136             } catch (Throwable t) {
2137                 throw new Exception("Error validating " + key, t);
2138             }
2139         }
2140     }
2141 
verifyExpectedBoundEntries(ManagedServices service, boolean primary)2142     private void verifyExpectedBoundEntries(ManagedServices service, boolean primary)
2143             throws Exception {
2144         ArrayMap<Integer, String> verifyMap = primary ? mExpectedPrimary.get(service.mApprovalLevel)
2145                 : mExpectedSecondary.get(service.mApprovalLevel);
2146         for (int userId : verifyMap.keySet()) {
2147             for (String packageOrComponent : verifyMap.get(userId).split(":")) {
2148                 if (!TextUtils.isEmpty(packageOrComponent)) {
2149                     if (service.mApprovalLevel == APPROVAL_BY_PACKAGE) {
2150                         assertTrue(packageOrComponent,
2151                                 service.isComponentEnabledForPackage(packageOrComponent));
2152                         for (int i = 1; i <= 3; i++) {
2153                             ComponentName componentName = ComponentName.unflattenFromString(
2154                                     packageOrComponent +"/C" + i);
2155                             assertTrue(service.isComponentEnabledForCurrentProfiles(
2156                                     componentName));
2157                             verify(mIpm, times(1)).getServiceInfo(
2158                                     eq(componentName), anyLong(), anyInt());
2159                         }
2160                     } else {
2161                         ComponentName componentName =
2162                                 ComponentName.unflattenFromString(packageOrComponent);
2163                         assertTrue(service.isComponentEnabledForCurrentProfiles(componentName));
2164                         verify(mIpm, times(1)).getServiceInfo(
2165                                 eq(componentName), anyLong(), anyInt());
2166                     }
2167                 }
2168             }
2169         }
2170     }
2171 
verifyExpectedApprovedEntries(ManagedServices service)2172     private void verifyExpectedApprovedEntries(ManagedServices service) {
2173         verifyExpectedApprovedEntries(service, true);
2174         verifyExpectedApprovedEntries(service, false);
2175     }
2176 
verifyExpectedApprovedEntries(ManagedServices service, boolean primary)2177     private void verifyExpectedApprovedEntries(ManagedServices service, boolean primary) {
2178         ArrayMap<Integer, String> verifyMap = primary
2179                 ? mExpectedPrimary.get(service.mApprovalLevel)
2180                 : mExpectedSecondary.get(service.mApprovalLevel);
2181         verifyExpectedApprovedEntries(service, verifyMap);
2182     }
2183 
verifyExpectedApprovedEntries(ManagedServices service, ArrayMap<Integer, String> verifyMap)2184     private void verifyExpectedApprovedEntries(ManagedServices service,
2185             ArrayMap<Integer, String> verifyMap) {
2186         for (int userId : verifyMap.keySet()) {
2187             for (String verifyValue : verifyMap.get(userId).split(":")) {
2188                 if (!TextUtils.isEmpty(verifyValue)) {
2189                     assertTrue("service type " + service.mApprovalLevel + ":"
2190                                     + verifyValue + " is not allowed for user " + userId,
2191                             service.isPackageOrComponentAllowed(verifyValue, userId));
2192                 }
2193             }
2194         }
2195     }
2196 
2197 
verifyExpectedApprovedPackages(ManagedServices service)2198     private void verifyExpectedApprovedPackages(ManagedServices service) {
2199         verifyExpectedApprovedPackages(service, true);
2200         verifyExpectedApprovedPackages(service, false);
2201     }
2202 
verifyExpectedApprovedPackages(ManagedServices service, boolean primary)2203     private void verifyExpectedApprovedPackages(ManagedServices service, boolean primary) {
2204         ArrayMap<Integer, String> verifyMap = primary
2205                 ? mExpectedPrimary.get(service.mApprovalLevel)
2206                 : mExpectedSecondary.get(service.mApprovalLevel);
2207         verifyExpectedApprovedPackages(service, verifyMap);
2208     }
2209 
verifyExpectedApprovedPackages(ManagedServices service, ArrayMap<Integer, String> verifyMap)2210     private void verifyExpectedApprovedPackages(ManagedServices service,
2211             ArrayMap<Integer, String> verifyMap) {
2212         for (int userId : verifyMap.keySet()) {
2213             for (String verifyValue : verifyMap.get(userId).split(":")) {
2214                 if (!TextUtils.isEmpty(verifyValue)) {
2215                     ComponentName component = ComponentName.unflattenFromString(verifyValue);
2216                     if (component != null ) {
2217                         assertTrue("service type " + service.mApprovalLevel + ":"
2218                                         + verifyValue + " is not allowed for user " + userId,
2219                                 service.isPackageAllowed(component.getPackageName(), userId));
2220                     } else {
2221                         assertTrue("service type " + service.mApprovalLevel + ":"
2222                                         + verifyValue + " is not allowed for user " + userId,
2223                                 service.isPackageAllowed(verifyValue, userId));
2224                     }
2225                 }
2226             }
2227         }
2228     }
2229 
writeExpectedValuesToSettings(int approvalLevel)2230     private void writeExpectedValuesToSettings(int approvalLevel) {
2231         for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) {
2232             Settings.Secure.putStringForUser(getContext().getContentResolver(), SETTING,
2233                     mExpectedPrimary.get(approvalLevel).get(userId), userId);
2234         }
2235         for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) {
2236             Settings.Secure.putStringForUser(getContext().getContentResolver(), SECONDARY_SETTING,
2237                     mExpectedSecondary.get(approvalLevel).get(userId), userId);
2238         }
2239     }
2240 
getXmlEntry(String approved, int userId, boolean isPrimary)2241     private String getXmlEntry(String approved, int userId, boolean isPrimary) {
2242         return getXmlEntry(approved, userId, isPrimary, true);
2243     }
2244 
getXmlEntry(String approved, int userId, boolean isPrimary, boolean userSet)2245     private String getXmlEntry(String approved, int userId, boolean isPrimary, boolean userSet) {
2246         String userSetString = "";
2247         if (mVersionString.equals("4")) {
2248             userSetString =
2249                     ManagedServices.ATT_USER_CHANGED + "=\"" + String.valueOf(userSet) + "\" ";
2250         } else if (mVersionString.equals("3")) {
2251             userSetString =
2252                     ManagedServices.ATT_USER_SET + "=\"" + (userSet ? approved : "") + "\" ";
2253         }
2254         return "<" + ManagedServices.TAG_MANAGED_SERVICES + " "
2255                 + ManagedServices.ATT_USER_ID + "=\"" + userId +"\" "
2256                 + ManagedServices.ATT_IS_PRIMARY + "=\"" + isPrimary +"\" "
2257                 + ManagedServices.ATT_APPROVED_LIST + "=\"" + approved +"\" "
2258                 + userSetString + "/>\n";
2259     }
2260 
2261     class TestManagedServices extends ManagedServices {
2262 
TestManagedServices(Context context, Object mutex, UserProfiles userProfiles, IPackageManager pm, int approvedServiceType)2263         public TestManagedServices(Context context, Object mutex, UserProfiles userProfiles,
2264                 IPackageManager pm, int approvedServiceType) {
2265             super(context, mutex, userProfiles, pm);
2266             mApprovalLevel = approvedServiceType;
2267         }
2268 
2269         @Override
getConfig()2270         protected Config getConfig() {
2271             final Config c = new Config();
2272             c.xmlTag = "test";
2273             c.secureSettingName = SETTING;
2274             c.secondarySettingName = SECONDARY_SETTING;
2275             c.bindPermission = "permission";
2276             c.serviceInterface = "serviceInterface";
2277             return c;
2278         }
2279 
2280         @Override
asInterface(IBinder binder)2281         protected IInterface asInterface(IBinder binder) {
2282             return null;
2283         }
2284 
2285         @Override
checkType(IInterface service)2286         protected boolean checkType(IInterface service) {
2287             return true;
2288         }
2289 
2290         @Override
onServiceAdded(ManagedServiceInfo info)2291         protected void onServiceAdded(ManagedServiceInfo info) {
2292 
2293         }
2294 
2295         @Override
ensureFilters(ServiceInfo si, int userId)2296         protected void ensureFilters(ServiceInfo si, int userId) {
2297 
2298         }
2299 
2300         @Override
loadDefaultsFromConfig()2301         protected void loadDefaultsFromConfig() {
2302             mDefaultComponents.addAll(mDefaults);
2303         }
2304 
2305         @Override
getRequiredPermission()2306         protected String getRequiredPermission() {
2307             return null;
2308         }
2309 
2310         @Override
allowRebindForParentUser()2311         protected boolean allowRebindForParentUser() {
2312             return true;
2313         }
2314     }
2315 
2316     class TestManagedServicesSettings extends TestManagedServices {
2317 
TestManagedServicesSettings(Context context, Object mutex, UserProfiles userProfiles, IPackageManager pm, int approvedServiceType)2318         public TestManagedServicesSettings(Context context, Object mutex, UserProfiles userProfiles,
2319                 IPackageManager pm, int approvedServiceType) {
2320             super(context, mutex, userProfiles, pm, approvedServiceType);
2321         }
2322 
2323         @Override
shouldReflectToSettings()2324         public boolean shouldReflectToSettings() {
2325             return true;
2326         }
2327     }
2328 
2329     class TestManagedServicesNoSettings extends TestManagedServices {
2330 
TestManagedServicesNoSettings(Context context, Object mutex, UserProfiles userProfiles, IPackageManager pm, int approvedServiceType)2331         public TestManagedServicesNoSettings(Context context, Object mutex, UserProfiles userProfiles,
2332                 IPackageManager pm, int approvedServiceType) {
2333             super(context, mutex, userProfiles, pm, approvedServiceType);
2334         }
2335 
2336         @Override
getConfig()2337         protected Config getConfig() {
2338             Config c = super.getConfig();
2339             c.secureSettingName = null;
2340             c.secondarySettingName = null;
2341             return c;
2342         }
2343 
2344         @Override
shouldReflectToSettings()2345         public boolean shouldReflectToSettings() {
2346             return false;
2347         }
2348     }
2349 
2350     /**
2351      * Helper method to test the thread safety of some operations.
2352      *
2353      * <p>Runs the supplied {@code operationToTest}, {@code nRunsPerThread} times,
2354      * concurrently using {@code nThreads} threads, and waits for all of them to finish.
2355      */
testThreadSafety(Runnable operationToTest, int nThreads, int nRunsPerThread)2356     private static void testThreadSafety(Runnable operationToTest, int nThreads,
2357             int nRunsPerThread) throws InterruptedException {
2358         final CountDownLatch startLatch = new CountDownLatch(1);
2359         final CountDownLatch doneLatch = new CountDownLatch(nThreads);
2360 
2361         for (int i = 0; i < nThreads; i++) {
2362             Runnable threadRunnable = () -> {
2363                 try {
2364                     startLatch.await();
2365                     for (int j = 0; j < nRunsPerThread; j++) {
2366                         operationToTest.run();
2367                     }
2368                 } catch (InterruptedException e) {
2369                     e.printStackTrace();
2370                 } finally {
2371                     doneLatch.countDown();
2372                 }
2373             };
2374             new Thread(threadRunnable, "Test Thread #" + i).start();
2375         }
2376 
2377         // Ready set go
2378         startLatch.countDown();
2379 
2380         // Wait for all test threads to be done.
2381         doneLatch.await();
2382     }
2383 }
2384