1 /*
2  * Copyright (C) 2021 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 
17 package com.android.server.devicepolicy;
18 
19 import static android.content.pm.UserInfo.FLAG_PRIMARY;
20 import static android.os.UserManager.USER_TYPE_FULL_SYSTEM;
21 import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
22 
23 import static com.android.server.devicepolicy.DevicePolicyManagerService.DEVICE_POLICIES_XML;
24 import static com.android.server.devicepolicy.DevicePolicyManagerService.POLICIES_VERSION_XML;
25 
26 import static com.google.common.truth.Truth.assertThat;
27 
28 import android.app.admin.DeviceAdminInfo;
29 import android.content.ComponentName;
30 import android.content.Context;
31 import android.content.pm.ActivityInfo;
32 import android.content.pm.ApplicationInfo;
33 import android.os.IpcDataCache;
34 import android.os.Parcel;
35 import android.os.UserHandle;
36 import android.util.ArraySet;
37 import android.util.Xml;
38 
39 import androidx.test.InstrumentationRegistry;
40 
41 import com.android.internal.util.JournaledFile;
42 import com.android.modules.utils.TypedXmlPullParser;
43 import com.android.server.SystemService;
44 
45 import com.google.common.io.Files;
46 
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 import org.junit.runners.JUnit4;
51 import org.w3c.dom.Document;
52 import org.w3c.dom.Element;
53 import org.w3c.dom.NodeList;
54 import org.xmlpull.v1.XmlPullParser;
55 import org.xmlpull.v1.XmlPullParserException;
56 import org.xmlpull.v1.XmlSerializer;
57 
58 import java.io.ByteArrayInputStream;
59 import java.io.ByteArrayOutputStream;
60 import java.io.File;
61 import java.io.FileInputStream;
62 import java.io.IOException;
63 import java.io.InputStream;
64 import java.nio.charset.Charset;
65 import java.nio.charset.StandardCharsets;
66 import java.util.ArrayList;
67 import java.util.HashMap;
68 import java.util.List;
69 import java.util.Map;
70 import java.util.Set;
71 import java.util.function.Function;
72 
73 import javax.xml.parsers.DocumentBuilderFactory;
74 
75 @RunWith(JUnit4.class)
76 public class PolicyVersionUpgraderTest extends DpmTestBase {
77     // NOTE: Only change this value if the corresponding CL also adds a test to test the upgrade
78     // to the new version.
79     private static final int LATEST_TESTED_VERSION = 6;
80     public static final String PERMISSIONS_TAG = "admin-can-grant-sensors-permissions";
81     public static final String DEVICE_OWNER_XML = "device_owner_2.xml";
82     private ComponentName mFakeAdmin;
83 
84     private class FakePolicyUpgraderDataProvider implements PolicyUpgraderDataProvider {
85         Map<ComponentName, DeviceAdminInfo> mComponentToDeviceAdminInfo = new HashMap<>();
86         ArrayList<String> mPlatformSuspendedPackages = new ArrayList<>();
87         int[] mUsers;
88 
makeJournaledFile(int userId, String fileName)89         private JournaledFile makeJournaledFile(int userId, String fileName) {
90             File parentDir = getServices().environment.getUserSystemDirectory(userId);
91 
92             final String base = new File(parentDir, fileName).getAbsolutePath();
93             return new JournaledFile(new File(base), new File(base + ".tmp"));
94         }
95 
96         @Override
makeDevicePoliciesJournaledFile(int userId)97         public JournaledFile makeDevicePoliciesJournaledFile(int userId) {
98             return makeJournaledFile(userId, DEVICE_POLICIES_XML);
99         }
100 
101         @Override
makePoliciesVersionJournaledFile(int userId)102         public JournaledFile makePoliciesVersionJournaledFile(int userId) {
103             return makeJournaledFile(userId, POLICIES_VERSION_XML);
104         }
105 
106         @Override
getAdminInfoSupplier(int userId)107         public Function<ComponentName, DeviceAdminInfo> getAdminInfoSupplier(int userId) {
108             return componentName -> mComponentToDeviceAdminInfo.get(componentName);
109         }
110 
111         @Override
getUsersForUpgrade()112         public int[] getUsersForUpgrade() {
113             return mUsers;
114         }
115 
116         @Override
getPlatformSuspendedPackages(int userId)117         public List<String> getPlatformSuspendedPackages(int userId) {
118             return mPlatformSuspendedPackages;
119         }
120     }
121 
122     private final Context mRealTestContext = InstrumentationRegistry.getTargetContext();
123     private FakePolicyUpgraderDataProvider mProvider;
124     private PolicyVersionUpgrader mUpgrader;
125 
126     @Before
setUp()127     public void setUp() {
128         // Disable caches in this test process. This must happen early, since some of the
129         // following initialization steps invalidate caches.
130         IpcDataCache.disableForTestMode();
131 
132         mProvider = new FakePolicyUpgraderDataProvider();
133         mUpgrader = new PolicyVersionUpgrader(mProvider, getServices().pathProvider);
134         mFakeAdmin = new ComponentName(
135                 "com.android.frameworks.servicestests",
136                 "com.android.server.devicepolicy.DummyDeviceAdmins$Admin1");
137         ActivityInfo activityInfo = createActivityInfo(mFakeAdmin);
138         DeviceAdminInfo dai = createDeviceAdminInfo(activityInfo);
139         mProvider.mComponentToDeviceAdminInfo.put(mFakeAdmin, dai);
140         mProvider.mUsers = new int[]{0};
141     }
142 
143     @Test
testSameVersionDoesNothing()144     public void testSameVersionDoesNothing() throws IOException {
145         writeVersionToXml(DevicePolicyManagerService.DPMS_VERSION);
146         final int userId = mProvider.mUsers[0];
147         preparePoliciesFile(userId, "device_policies.xml");
148         String oldContents = readPoliciesFile(userId);
149 
150         mUpgrader.upgradePolicy(DevicePolicyManagerService.DPMS_VERSION);
151 
152         String newContents = readPoliciesFile(0);
153         assertThat(newContents).isEqualTo(oldContents);
154     }
155 
156     @Test
testUpgrade0To1RemovesPasswordMetrics()157     public void testUpgrade0To1RemovesPasswordMetrics() throws IOException, XmlPullParserException {
158         final String activePasswordTag = "active-password";
159         mProvider.mUsers = new int[]{0, 10};
160         getServices().addUser(10, /* flags= */ 0, USER_TYPE_PROFILE_MANAGED);
161         writeVersionToXml(0);
162         for (int userId : mProvider.mUsers) {
163             preparePoliciesFile(userId, "device_policies.xml");
164         }
165         // Validate test set-up.
166         assertThat(isTagPresent(readPoliciesFileToStream(0), activePasswordTag)).isTrue();
167 
168         mUpgrader.upgradePolicy(1);
169 
170         assertThat(readVersionFromXml()).isAtLeast(1);
171         for (int user : mProvider.mUsers) {
172             assertThat(isTagPresent(readPoliciesFileToStream(user), activePasswordTag)).isFalse();
173         }
174     }
175 
176     @Test
testUpgrade1To2MarksDoForPermissionControl()177     public void testUpgrade1To2MarksDoForPermissionControl()
178             throws IOException, XmlPullParserException {
179         final int ownerUser = 10;
180         mProvider.mUsers = new int[]{0, ownerUser};
181         getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM);
182         writeVersionToXml(1);
183         for (int userId : mProvider.mUsers) {
184             preparePoliciesFile(userId, "device_policies.xml");
185         }
186         prepareDeviceOwnerFile(ownerUser, "device_owner_2.xml");
187 
188         mUpgrader.upgradePolicy(2);
189 
190         assertThat(readVersionFromXml()).isAtLeast(2);
191         assertThat(getBooleanValueTag(readPoliciesFileToStream(mProvider.mUsers[0]),
192                 PERMISSIONS_TAG)).isFalse();
193         assertThat(getBooleanValueTag(readPoliciesFileToStream(ownerUser),
194                 PERMISSIONS_TAG)).isTrue();
195     }
196 
197     @Test
testNoStaleDataInCacheAfterUpgrade()198     public void testNoStaleDataInCacheAfterUpgrade() throws Exception {
199         final int ownerUser = 0;
200         getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM);
201         setUpPackageManagerForAdmin(admin1, UserHandle.getUid(ownerUser, 123 /* admin app ID */));
202         writeVersionToXml(0);
203         preparePoliciesFile(ownerUser, "device_policies.xml");
204         prepareDeviceOwnerFile(ownerUser, "device_owner_2.xml");
205 
206         DevicePolicyManagerServiceTestable dpms;
207         final long ident = getContext().binder.clearCallingIdentity();
208         try {
209             dpms = new DevicePolicyManagerServiceTestable(getServices(), getContext());
210 
211             // Simulate access that would cause policy data to be cached in mUserData.
212             dpms.isCommonCriteriaModeEnabled(null);
213 
214             dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
215         } finally {
216             getContext().binder.restoreCallingIdentity(ident);
217         }
218 
219         assertThat(readVersionFromXml()).isEqualTo(DevicePolicyManagerService.DPMS_VERSION);
220 
221         // DO should be marked as able to grant sensors permission during upgrade and should be
222         // reported as such via the API.
223         assertThat(dpms.canAdminGrantSensorsPermissions()).isTrue();
224     }
225 
226     /**
227      * Up to Android R DO protected packages were stored in DevicePolicyData, verify that they are
228      * moved to ActiveAdmin.
229      */
230     @Test
testUserControlDisabledPackagesFromR()231     public void testUserControlDisabledPackagesFromR() throws Exception {
232         final String oldTag = "protected-packages";
233         final String newTag = "protected_packages";
234         final int ownerUser = 0;
235         mProvider.mUsers = new int[]{0};
236         getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM);
237         writeVersionToXml(2);
238         preparePoliciesFile(ownerUser, "protected_packages_device_policies.xml");
239         prepareDeviceOwnerFile(ownerUser, "device_owner_2.xml");
240 
241         // Validate the setup.
242         assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), oldTag)).isTrue();
243         assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isFalse();
244 
245         mUpgrader.upgradePolicy(3);
246 
247         assertThat(readVersionFromXml()).isAtLeast(3);
248         assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), oldTag)).isFalse();
249         assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isTrue();
250     }
251 
252     /**
253      * In Android S DO protected packages were stored in Owners, verify that they are moved to
254      * ActiveAdmin.
255      */
256     @Test
testUserControlDisabledPackagesFromS()257     public void testUserControlDisabledPackagesFromS() throws Exception {
258         final String oldTag = "device-owner-protected-packages";
259         final String newTag = "protected_packages";
260         final int ownerUser = 0;
261         mProvider.mUsers = new int[]{0};
262         getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM);
263         writeVersionToXml(2);
264         preparePoliciesFile(ownerUser, "device_policies.xml");
265         prepareDeviceOwnerFile(ownerUser, "protected_packages_device_owner_2.xml");
266 
267         // Validate the setup.
268         assertThat(isTagPresent(readDoToStream(), oldTag)).isTrue();
269         assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isFalse();
270 
271         mUpgrader.upgradePolicy(3);
272 
273         assertThat(readVersionFromXml()).isAtLeast(3);
274         assertThat(isTagPresent(readDoToStream(), oldTag)).isFalse();
275         assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isTrue();
276     }
277 
278     @Test
testAdminPackageSuspensionSaved()279     public void testAdminPackageSuspensionSaved() throws Exception {
280         final int ownerUser = 0;
281         mProvider.mUsers = new int[]{ownerUser};
282         getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM);
283         setUpPackageManagerForAdmin(admin1, UserHandle.getUid(ownerUser, 123 /* admin app ID */));
284         writeVersionToXml(3);
285         preparePoliciesFile(ownerUser, "device_policies.xml");
286         prepareDeviceOwnerFile(ownerUser, "device_owner_2.xml");
287 
288         // Pretend package manager thinks these packages are suspended by the platform.
289         Set<String> suspendedPkgs = Set.of("com.some.app", "foo.bar.baz");
290         mProvider.mPlatformSuspendedPackages.addAll(suspendedPkgs);
291 
292         mUpgrader.upgradePolicy(4);
293 
294         assertThat(readVersionFromXml()).isAtLeast(4);
295 
296         assertAdminSuspendedPackages(ownerUser, suspendedPkgs);
297     }
298 
assertAdminSuspendedPackages(int ownerUser, Set<String> suspendedPkgs)299     private void assertAdminSuspendedPackages(int ownerUser, Set<String> suspendedPkgs)
300             throws Exception {
301         Document policies = readPolicies(ownerUser);
302         Element adminElem =
303                 (Element) policies.getDocumentElement().getElementsByTagName("admin").item(0);
304         Element suspendedElem =
305                 (Element) adminElem.getElementsByTagName("suspended-packages").item(0);
306         NodeList pkgsNodes = suspendedElem.getElementsByTagName("item");
307         Set<String> storedSuspendedPkgs = new ArraySet<>();
308         for (int i = 0; i < pkgsNodes.getLength(); i++) {
309             Element item = (Element) pkgsNodes.item(i);
310             storedSuspendedPkgs.add(item.getAttribute("value"));
311         }
312         assertThat(storedSuspendedPkgs).isEqualTo(suspendedPkgs);
313     }
314 
315     @Test
testEffectiveKeepProfilesRunningSetToFalse4To5()316     public void testEffectiveKeepProfilesRunningSetToFalse4To5() throws Exception {
317         writeVersionToXml(4);
318 
319         final int userId = UserHandle.USER_SYSTEM;
320         mProvider.mUsers = new int[]{userId};
321         preparePoliciesFile(userId, "device_policies.xml");
322 
323         mUpgrader.upgradePolicy(5);
324 
325         assertThat(readVersionFromXml()).isAtLeast(5);
326 
327         Document policies = readPolicies(userId);
328         Element keepProfilesRunning = (Element) policies.getDocumentElement()
329                 .getElementsByTagName("keep-profiles-running").item(0);
330 
331         // Default value (false) is not serialized.
332         assertThat(keepProfilesRunning).isNull();
333     }
334     @Test
testEffectiveKeepProfilesRunningIsToFalse4To6()335     public void testEffectiveKeepProfilesRunningIsToFalse4To6() throws Exception {
336         writeVersionToXml(4);
337 
338         final int userId = UserHandle.USER_SYSTEM;
339         mProvider.mUsers = new int[]{userId};
340         preparePoliciesFile(userId, "device_policies.xml");
341 
342         mUpgrader.upgradePolicy(6);
343 
344         assertThat(readVersionFromXml()).isAtLeast(6);
345 
346         Document policies = readPolicies(userId);
347         Element keepProfilesRunning = (Element) policies.getDocumentElement()
348                 .getElementsByTagName("keep-profiles-running").item(0);
349 
350         // Default value (false) is not serialized.
351         assertThat(keepProfilesRunning).isNull();
352     }
353 
354     /**
355      * Verify correct behaviour when upgrading from Android 13
356      */
357     @Test
testEffectiveKeepProfilesRunningIsToFalse3To6()358     public void testEffectiveKeepProfilesRunningIsToFalse3To6() throws Exception {
359         writeVersionToXml(3);
360 
361         final int userId = UserHandle.USER_SYSTEM;
362         mProvider.mUsers = new int[]{userId};
363         preparePoliciesFile(userId, "device_policies.xml");
364 
365         mUpgrader.upgradePolicy(6);
366 
367         assertThat(readVersionFromXml()).isAtLeast(6);
368 
369         Document policies = readPolicies(userId);
370         Element keepProfilesRunning = (Element) policies.getDocumentElement()
371                 .getElementsByTagName("keep-profiles-running").item(0);
372 
373         // Default value (false) is not serialized.
374         assertThat(keepProfilesRunning).isNull();
375     }
376 
377     @Test
testEffectiveKeepProfilesRunningMissingInV5()378     public void testEffectiveKeepProfilesRunningMissingInV5() throws Exception {
379         writeVersionToXml(5);
380 
381         final int userId = UserHandle.USER_SYSTEM;
382         mProvider.mUsers = new int[]{userId};
383         preparePoliciesFile(userId, "device_policies.xml");
384 
385         mUpgrader.upgradePolicy(6);
386 
387         assertThat(readVersionFromXml()).isAtLeast(6);
388 
389         Document policies = readPolicies(userId);
390         Element keepProfilesRunning = (Element) policies.getDocumentElement()
391                 .getElementsByTagName("keep-profiles-running").item(0);
392         assertThat(keepProfilesRunning.getAttribute("value")).isEqualTo("true");
393     }
394 
395     @Test
testEffectiveKeepProfilesRunningTrueInV5()396     public void testEffectiveKeepProfilesRunningTrueInV5() throws Exception {
397         writeVersionToXml(5);
398 
399         final int userId = UserHandle.USER_SYSTEM;
400         mProvider.mUsers = new int[]{userId};
401         preparePoliciesFile(userId, "device_policies_keep_profiles_running_true.xml");
402 
403         mUpgrader.upgradePolicy(6);
404 
405         assertThat(readVersionFromXml()).isAtLeast(6);
406 
407         Document policies = readPolicies(userId);
408         Element keepProfilesRunning = (Element) policies.getDocumentElement()
409                 .getElementsByTagName("keep-profiles-running").item(0);
410         assertThat(keepProfilesRunning.getAttribute("value")).isEqualTo("true");
411     }
412 
413     @Test
testEffectiveKeepProfilesRunningFalseInV5()414     public void testEffectiveKeepProfilesRunningFalseInV5() throws Exception {
415         writeVersionToXml(5);
416 
417         final int userId = UserHandle.USER_SYSTEM;
418         mProvider.mUsers = new int[]{userId};
419         preparePoliciesFile(userId, "device_policies_keep_profiles_running_false.xml");
420 
421         mUpgrader.upgradePolicy(6);
422 
423         assertThat(readVersionFromXml()).isAtLeast(6);
424 
425         Document policies = readPolicies(userId);
426         Element keepProfilesRunning = (Element) policies.getDocumentElement()
427                 .getElementsByTagName("keep-profiles-running").item(0);
428 
429         // Default value (false) is not serialized.
430         assertThat(keepProfilesRunning).isNull();
431     }
432 
433 
434     @Test
isLatestVersionTested()435     public void isLatestVersionTested() {
436         assertThat(DevicePolicyManagerService.DPMS_VERSION).isEqualTo(LATEST_TESTED_VERSION);
437     }
438 
439     /**
440      * Reads ABX binary XML, converts it to text, and returns as an input stream.
441      */
abxToXmlStream(File file)442     private InputStream abxToXmlStream(File file) throws Exception {
443         FileInputStream fileIn = new FileInputStream(file);
444         XmlPullParser in = Xml.newBinaryPullParser();
445         in.setInput(fileIn, StandardCharsets.UTF_8.name());
446 
447         ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
448         XmlSerializer out = Xml.newSerializer();
449         out.setOutput(byteOut, StandardCharsets.UTF_8.name());
450 
451         Xml.copy(in, out);
452         out.flush();
453 
454         return new ByteArrayInputStream(byteOut.toByteArray());
455     }
456 
readPolicies(int userId)457     private Document readPolicies(int userId) throws Exception {
458         File policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId).chooseForRead();
459         InputStream is = abxToXmlStream(policiesFile);
460         return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
461     }
462 
writeVersionToXml(int dpmsVersion)463     private void writeVersionToXml(int dpmsVersion) throws IOException {
464         JournaledFile versionFile = mProvider.makePoliciesVersionJournaledFile(0);
465         Files.asCharSink(versionFile.chooseForWrite(), Charset.defaultCharset()).write(
466                 String.format("%d\n", dpmsVersion));
467         versionFile.commit();
468     }
469 
readVersionFromXml()470     private int readVersionFromXml() throws IOException {
471         File versionFile = mProvider.makePoliciesVersionJournaledFile(0).chooseForRead();
472         String versionString = Files.asCharSource(versionFile,
473                 Charset.defaultCharset()).readFirstLine();
474         return Integer.parseInt(versionString);
475     }
476 
preparePoliciesFile(int userId, String assetFile)477     private void preparePoliciesFile(int userId, String assetFile) throws IOException {
478         JournaledFile policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId);
479         DpmTestUtils.writeToFile(
480                 policiesFile.chooseForWrite(),
481                 DpmTestUtils.readAsset(mRealTestContext, "PolicyVersionUpgraderTest/" + assetFile));
482         policiesFile.commit();
483     }
484 
prepareDeviceOwnerFile(int userId, String assetFile)485     private void prepareDeviceOwnerFile(int userId, String assetFile) throws IOException {
486         File doFilePath = getDoFilePath();
487         String doFileContent = DpmTestUtils.readAsset(mRealTestContext,
488                         "PolicyVersionUpgraderTest/" + assetFile)
489                 // Substitute the right DO userId, XML in resources has 0
490                 .replace("userId=\"0\"", "userId=\"" + userId + "\"");
491         DpmTestUtils.writeToFile(doFilePath, doFileContent);
492     }
493 
getDoFilePath()494     private File getDoFilePath() {
495         File parentDir = getServices().pathProvider.getDataSystemDirectory();
496         File doFilePath = (new File(parentDir, DEVICE_OWNER_XML)).getAbsoluteFile();
497         return doFilePath;
498     }
499 
readPoliciesFile(int userId)500     private String readPoliciesFile(int userId) throws IOException {
501         File policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId).chooseForRead();
502         return new String(Files.asByteSource(policiesFile).read(), Charset.defaultCharset());
503     }
504 
readDoToStream()505     private InputStream readDoToStream() throws IOException {
506         return new FileInputStream(getDoFilePath());
507     }
508 
readPoliciesFileToStream(int userId)509     private InputStream readPoliciesFileToStream(int userId) throws IOException {
510         File policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId).chooseForRead();
511         return new FileInputStream(policiesFile);
512     }
513 
getBooleanValueTag(InputStream inputXml, String tagName)514     private boolean getBooleanValueTag(InputStream inputXml, String tagName)
515             throws IOException, XmlPullParserException {
516         TypedXmlPullParser parser = Xml.resolvePullParser(inputXml);
517 
518         int eventType = parser.getEventType();
519         while (eventType != XmlPullParser.END_DOCUMENT) {
520             if (eventType == XmlPullParser.START_TAG) {
521                 String tag = parser.getName();
522                 if (tagName.equals(tag)) {
523                     String res = parser.getAttributeValue(null, "value");
524                     return Boolean.parseBoolean(res);
525                 }
526             }
527             eventType = parser.next();
528         }
529 
530         throw new IllegalStateException("Could not find " + tagName);
531     }
532 
isTagPresent(InputStream inputXml, String tagName)533     private boolean isTagPresent(InputStream inputXml, String tagName)
534             throws IOException, XmlPullParserException {
535         TypedXmlPullParser parser = Xml.resolvePullParser(inputXml);
536 
537         int eventType = parser.getEventType();
538         while (eventType != XmlPullParser.END_DOCUMENT) {
539             if (eventType == XmlPullParser.START_TAG) {
540                 String tag = parser.getName();
541                 if (tagName.equals(tag)) {
542                     return true;
543                 }
544             }
545             eventType = parser.next();
546         }
547 
548         return false;
549     }
550 
createActivityInfo(ComponentName admin)551     private ActivityInfo createActivityInfo(ComponentName admin) {
552         ActivityInfo ai = new ActivityInfo();
553         ApplicationInfo applicationInfo = new ApplicationInfo();
554         applicationInfo.className = admin.getClassName();
555         applicationInfo.uid = 2222;
556         ai.applicationInfo = applicationInfo;
557         ai.name = admin.getClassName();
558         ai.packageName = admin.getPackageName();
559         return ai;
560     }
561 
createDeviceAdminInfo(ActivityInfo activityInfo)562     private DeviceAdminInfo createDeviceAdminInfo(ActivityInfo activityInfo) {
563         Parcel parcel = Parcel.obtain();
564         activityInfo.writeToParcel(parcel, 0);
565         parcel.writeInt(0);
566         parcel.writeBoolean(true);
567         parcel.setDataPosition(0);
568 
569         return DeviceAdminInfo.CREATOR.createFromParcel(parcel);
570     }
571 }
572