• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.app.admin.DevicePolicyManager.NEARBY_STREAMING_DISABLED;
20 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
21 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
22 
23 import static com.android.server.devicepolicy.DevicePolicyManagerService.LOG_TAG;
24 
25 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26 import static org.xmlpull.v1.XmlPullParser.END_TAG;
27 import static org.xmlpull.v1.XmlPullParser.TEXT;
28 
29 import android.annotation.NonNull;
30 import android.annotation.Nullable;
31 import android.app.admin.DeviceAdminInfo;
32 import android.app.admin.DevicePolicyManager;
33 import android.app.admin.FactoryResetProtectionPolicy;
34 import android.app.admin.PasswordPolicy;
35 import android.graphics.Color;
36 import android.os.Bundle;
37 import android.os.PersistableBundle;
38 import android.os.UserHandle;
39 import android.os.UserManager;
40 import android.text.TextUtils;
41 import android.util.ArrayMap;
42 import android.util.ArraySet;
43 import android.util.IndentingPrintWriter;
44 import android.util.TypedXmlPullParser;
45 import android.util.TypedXmlSerializer;
46 
47 import com.android.internal.util.Preconditions;
48 import com.android.internal.util.XmlUtils;
49 import com.android.server.pm.UserRestrictionsUtils;
50 import com.android.server.utils.Slogf;
51 
52 import org.xmlpull.v1.XmlPullParserException;
53 
54 import java.io.IOException;
55 import java.util.ArrayList;
56 import java.util.Collection;
57 import java.util.Collections;
58 import java.util.List;
59 import java.util.Map;
60 import java.util.Set;
61 import java.util.function.Predicate;
62 
63 class ActiveAdmin {
64     private static final String TAG_DISABLE_KEYGUARD_FEATURES = "disable-keyguard-features";
65     private static final String TAG_TEST_ONLY_ADMIN = "test-only-admin";
66     private static final String TAG_DISABLE_CAMERA = "disable-camera";
67     private static final String TAG_DISABLE_CALLER_ID = "disable-caller-id";
68     private static final String TAG_DISABLE_CONTACTS_SEARCH = "disable-contacts-search";
69     private static final String TAG_DISABLE_BLUETOOTH_CONTACT_SHARING =
70             "disable-bt-contacts-sharing";
71     private static final String TAG_DISABLE_SCREEN_CAPTURE = "disable-screen-capture";
72     private static final String TAG_DISABLE_ACCOUNT_MANAGEMENT = "disable-account-management";
73     private static final String TAG_NEARBY_NOTIFICATION_STREAMING_POLICY =
74             "nearby-notification-streaming-policy";
75     private static final String TAG_NEARBY_APP_STREAMING_POLICY =
76             "nearby-app-streaming-policy";
77     private static final String TAG_REQUIRE_AUTO_TIME = "require_auto_time";
78     private static final String TAG_FORCE_EPHEMERAL_USERS = "force_ephemeral_users";
79     private static final String TAG_IS_NETWORK_LOGGING_ENABLED = "is_network_logging_enabled";
80     private static final String TAG_ACCOUNT_TYPE = "account-type";
81     private static final String TAG_PERMITTED_ACCESSIBILITY_SERVICES =
82             "permitted-accessiblity-services";
83     private static final String TAG_ENCRYPTION_REQUESTED = "encryption-requested";
84     private static final String TAG_MANAGE_TRUST_AGENT_FEATURES = "manage-trust-agent-features";
85     private static final String TAG_TRUST_AGENT_COMPONENT_OPTIONS = "trust-agent-component-options";
86     private static final String TAG_TRUST_AGENT_COMPONENT = "component";
87     private static final String TAG_PASSWORD_EXPIRATION_DATE = "password-expiration-date";
88     private static final String TAG_PASSWORD_EXPIRATION_TIMEOUT = "password-expiration-timeout";
89     private static final String TAG_GLOBAL_PROXY_EXCLUSION_LIST = "global-proxy-exclusion-list";
90     private static final String TAG_GLOBAL_PROXY_SPEC = "global-proxy-spec";
91     private static final String TAG_SPECIFIES_GLOBAL_PROXY = "specifies-global-proxy";
92     private static final String TAG_PERMITTED_IMES = "permitted-imes";
93     private static final String TAG_PERMITTED_NOTIFICATION_LISTENERS =
94             "permitted-notification-listeners";
95     private static final String TAG_MAX_FAILED_PASSWORD_WIPE = "max-failed-password-wipe";
96     private static final String TAG_MAX_TIME_TO_UNLOCK = "max-time-to-unlock";
97     private static final String TAG_STRONG_AUTH_UNLOCK_TIMEOUT = "strong-auth-unlock-timeout";
98     private static final String TAG_MIN_PASSWORD_NONLETTER = "min-password-nonletter";
99     private static final String TAG_MIN_PASSWORD_SYMBOLS = "min-password-symbols";
100     private static final String TAG_MIN_PASSWORD_NUMERIC = "min-password-numeric";
101     private static final String TAG_MIN_PASSWORD_LETTERS = "min-password-letters";
102     private static final String TAG_MIN_PASSWORD_LOWERCASE = "min-password-lowercase";
103     private static final String TAG_MIN_PASSWORD_UPPERCASE = "min-password-uppercase";
104     private static final String TAG_PASSWORD_HISTORY_LENGTH = "password-history-length";
105     private static final String TAG_MIN_PASSWORD_LENGTH = "min-password-length";
106     private static final String TAG_PASSWORD_QUALITY = "password-quality";
107     private static final String TAG_POLICIES = "policies";
108     private static final String TAG_CROSS_PROFILE_WIDGET_PROVIDERS =
109             "cross-profile-widget-providers";
110     private static final String TAG_PROVIDER = "provider";
111     private static final String TAG_PACKAGE_LIST_ITEM  = "item";
112     private static final String TAG_KEEP_UNINSTALLED_PACKAGES  = "keep-uninstalled-packages";
113     private static final String TAG_USER_RESTRICTIONS = "user-restrictions";
114     private static final String TAG_DEFAULT_ENABLED_USER_RESTRICTIONS =
115             "default-enabled-user-restrictions";
116     private static final String TAG_RESTRICTION = "restriction";
117     private static final String TAG_SHORT_SUPPORT_MESSAGE = "short-support-message";
118     private static final String TAG_LONG_SUPPORT_MESSAGE = "long-support-message";
119     private static final String TAG_PARENT_ADMIN = "parent-admin";
120     private static final String TAG_ORGANIZATION_COLOR = "organization-color";
121     private static final String TAG_ORGANIZATION_NAME = "organization-name";
122     private static final String TAG_IS_LOGOUT_ENABLED = "is_logout_enabled";
123     private static final String TAG_START_USER_SESSION_MESSAGE = "start_user_session_message";
124     private static final String TAG_END_USER_SESSION_MESSAGE = "end_user_session_message";
125     private static final String TAG_METERED_DATA_DISABLED_PACKAGES =
126             "metered_data_disabled_packages";
127     private static final String TAG_CROSS_PROFILE_CALENDAR_PACKAGES =
128             "cross-profile-calendar-packages";
129     private static final String TAG_CROSS_PROFILE_CALENDAR_PACKAGES_NULL =
130             "cross-profile-calendar-packages-null";
131     private static final String TAG_CROSS_PROFILE_PACKAGES = "cross-profile-packages";
132     private static final String TAG_FACTORY_RESET_PROTECTION_POLICY =
133             "factory_reset_protection_policy";
134     private static final String TAG_SUSPEND_PERSONAL_APPS = "suspend-personal-apps";
135     private static final String TAG_PROFILE_MAXIMUM_TIME_OFF = "profile-max-time-off";
136     private static final String TAG_PROFILE_OFF_DEADLINE = "profile-off-deadline";
137     private static final String TAG_ALWAYS_ON_VPN_PACKAGE = "vpn-package";
138     private static final String TAG_ALWAYS_ON_VPN_LOCKDOWN = "vpn-lockdown";
139     private static final String TAG_COMMON_CRITERIA_MODE = "common-criteria-mode";
140     private static final String TAG_PASSWORD_COMPLEXITY = "password-complexity";
141     private static final String TAG_ORGANIZATION_ID = "organization-id";
142     private static final String TAG_ENROLLMENT_SPECIFIC_ID = "enrollment-specific-id";
143     private static final String TAG_ADMIN_CAN_GRANT_SENSORS_PERMISSIONS =
144             "admin-can-grant-sensors-permissions";
145     private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_ENABLED =
146             "preferential-network-service-enabled";
147     private static final String TAG_USB_DATA_SIGNALING = "usb-data-signaling";
148     private static final String ATTR_VALUE = "value";
149     private static final String ATTR_LAST_NETWORK_LOGGING_NOTIFICATION = "last-notification";
150     private static final String ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS = "num-notifications";
151 
152     DeviceAdminInfo info;
153 
154     static final int DEF_PASSWORD_HISTORY_LENGTH = 0;
155     int passwordHistoryLength = DEF_PASSWORD_HISTORY_LENGTH;
156 
157     @NonNull
158     PasswordPolicy mPasswordPolicy = new PasswordPolicy();
159 
160     @DevicePolicyManager.PasswordComplexity
161     int mPasswordComplexity = PASSWORD_COMPLEXITY_NONE;
162 
163     @DevicePolicyManager.NearbyStreamingPolicy
164     int mNearbyNotificationStreamingPolicy = NEARBY_STREAMING_DISABLED;
165 
166     @DevicePolicyManager.NearbyStreamingPolicy
167     int mNearbyAppStreamingPolicy = NEARBY_STREAMING_DISABLED;
168 
169     @Nullable
170     FactoryResetProtectionPolicy mFactoryResetProtectionPolicy = null;
171 
172     static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0;
173     long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK;
174 
175     long strongAuthUnlockTimeout = 0; // admin doesn't participate by default
176 
177     static final int DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE = 0;
178     int maximumFailedPasswordsForWipe = DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE;
179 
180     static final long DEF_PASSWORD_EXPIRATION_TIMEOUT = 0;
181     long passwordExpirationTimeout = DEF_PASSWORD_EXPIRATION_TIMEOUT;
182 
183     static final long DEF_PASSWORD_EXPIRATION_DATE = 0;
184     long passwordExpirationDate = DEF_PASSWORD_EXPIRATION_DATE;
185 
186     static final int DEF_KEYGUARD_FEATURES_DISABLED = 0; // none
187 
188     int disabledKeyguardFeatures = DEF_KEYGUARD_FEATURES_DISABLED;
189 
190     boolean encryptionRequested = false;
191     boolean testOnlyAdmin = false;
192     boolean disableCamera = false;
193     boolean disableCallerId = false;
194     boolean disableContactsSearch = false;
195     boolean disableBluetoothContactSharing = true;
196     boolean disableScreenCapture = false;
197     boolean requireAutoTime = false;
198     boolean forceEphemeralUsers = false;
199     boolean isNetworkLoggingEnabled = false;
200     boolean isLogoutEnabled = false;
201 
202     // one notification after enabling + one more after reboots
203     static final int DEF_MAXIMUM_NETWORK_LOGGING_NOTIFICATIONS_SHOWN = 2;
204     int numNetworkLoggingNotifications = 0;
205     long lastNetworkLoggingNotificationTimeMs = 0; // Time in milliseconds since epoch
206 
207     ActiveAdmin parentAdmin;
208     final boolean isParent;
209 
210     static class TrustAgentInfo {
211         public PersistableBundle options;
TrustAgentInfo(PersistableBundle bundle)212         TrustAgentInfo(PersistableBundle bundle) {
213             options = bundle;
214         }
215     }
216 
217     // The list of packages which are not allowed to use metered data.
218     List<String> meteredDisabledPackages;
219 
220     final Set<String> accountTypesWithManagementDisabled = new ArraySet<>();
221 
222     // The list of permitted accessibility services package namesas set by a profile
223     // or device owner. Null means all accessibility services are allowed, empty means
224     // none except system services are allowed.
225     List<String> permittedAccessiblityServices;
226 
227     // The list of permitted input methods package names as set by a profile or device owner.
228     // Null means all input methods are allowed, empty means none except system imes are
229     // allowed.
230     List<String> permittedInputMethods;
231 
232     // The list of packages allowed to use a NotificationListenerService to receive events for
233     // notifications from this user. Null means that all packages are allowed. Empty list means
234     // that only packages from the system are allowed.
235     List<String> permittedNotificationListeners;
236 
237     // List of package names to keep cached.
238     List<String> keepUninstalledPackages;
239 
240     // TODO: review implementation decisions with frameworks team
241     boolean specifiesGlobalProxy = false;
242     String globalProxySpec = null;
243     String globalProxyExclusionList = null;
244 
245     @NonNull
246     ArrayMap<String, TrustAgentInfo> trustAgentInfos = new ArrayMap<>();
247 
248     List<String> crossProfileWidgetProviders;
249 
250     Bundle userRestrictions;
251 
252     // User restrictions that have already been enabled by default for this admin (either when
253     // setting the device or profile owner, or during a system update if one of those "enabled
254     // by default" restrictions is newly added).
255     final Set<String> defaultEnabledRestrictionsAlreadySet = new ArraySet<>();
256 
257     // Support text provided by the admin to display to the user.
258     CharSequence shortSupportMessage = null;
259     CharSequence longSupportMessage = null;
260 
261     // Background color of confirm credentials screen. Default: teal.
262     static final int DEF_ORGANIZATION_COLOR = Color.parseColor("#00796B");
263     int organizationColor = DEF_ORGANIZATION_COLOR;
264 
265     // Default title of confirm credentials screen
266     String organizationName = null;
267 
268     // Message for user switcher
269     String startUserSessionMessage = null;
270     String endUserSessionMessage = null;
271 
272     // The allow list of packages that can access cross profile calendar APIs.
273     // This allow list should be in default an empty list, which indicates that no package
274     // is allow listed.
275     List<String> mCrossProfileCalendarPackages = Collections.emptyList();
276 
277     // The allow list of packages that the admin has enabled to be able to request consent from
278     // the user to communicate cross-profile. By default, no packages are allowed, which is
279     // represented as an empty list.
280     List<String> mCrossProfilePackages = Collections.emptyList();
281 
282     // Whether the admin explicitly requires personal apps to be suspended
283     boolean mSuspendPersonalApps = false;
284     // Maximum time the profile owned by this admin can be off.
285     long mProfileMaximumTimeOffMillis = 0;
286     // Time by which the profile should be turned on according to System.currentTimeMillis().
287     long mProfileOffDeadline = 0;
288 
289     public String mAlwaysOnVpnPackage;
290     public boolean mAlwaysOnVpnLockdown;
291     boolean mCommonCriteriaMode;
292     public String mOrganizationId;
293     public String mEnrollmentSpecificId;
294     public boolean mAdminCanGrantSensorsPermissions;
295     public boolean mPreferentialNetworkServiceEnabled =
296             DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT;
297 
298     private static final boolean USB_DATA_SIGNALING_ENABLED_DEFAULT = true;
299     boolean mUsbDataSignalingEnabled = USB_DATA_SIGNALING_ENABLED_DEFAULT;
300 
ActiveAdmin(DeviceAdminInfo info, boolean isParent)301     ActiveAdmin(DeviceAdminInfo info, boolean isParent) {
302         this.info = info;
303         this.isParent = isParent;
304     }
305 
getParentActiveAdmin()306     ActiveAdmin getParentActiveAdmin() {
307         Preconditions.checkState(!isParent);
308 
309         if (parentAdmin == null) {
310             parentAdmin = new ActiveAdmin(info, /* parent */ true);
311         }
312         return parentAdmin;
313     }
314 
hasParentActiveAdmin()315     boolean hasParentActiveAdmin() {
316         return parentAdmin != null;
317     }
318 
getUid()319     int getUid() {
320         return info.getActivityInfo().applicationInfo.uid;
321     }
322 
getUserHandle()323     public UserHandle getUserHandle() {
324         return UserHandle.of(UserHandle.getUserId(info.getActivityInfo().applicationInfo.uid));
325     }
326 
writeToXml(TypedXmlSerializer out)327     void writeToXml(TypedXmlSerializer out)
328             throws IllegalArgumentException, IllegalStateException, IOException {
329         out.startTag(null, TAG_POLICIES);
330         info.writePoliciesToXml(out);
331         out.endTag(null, TAG_POLICIES);
332         if (mPasswordPolicy.quality != PASSWORD_QUALITY_UNSPECIFIED) {
333             writeAttributeValueToXml(
334                     out, TAG_PASSWORD_QUALITY, mPasswordPolicy.quality);
335             if (mPasswordPolicy.length != PasswordPolicy.DEF_MINIMUM_LENGTH) {
336                 writeAttributeValueToXml(
337                         out, TAG_MIN_PASSWORD_LENGTH, mPasswordPolicy.length);
338             }
339             if (mPasswordPolicy.upperCase != PasswordPolicy.DEF_MINIMUM_UPPER_CASE) {
340                 writeAttributeValueToXml(
341                         out, TAG_MIN_PASSWORD_UPPERCASE, mPasswordPolicy.upperCase);
342             }
343             if (mPasswordPolicy.lowerCase != PasswordPolicy.DEF_MINIMUM_LOWER_CASE) {
344                 writeAttributeValueToXml(
345                         out, TAG_MIN_PASSWORD_LOWERCASE, mPasswordPolicy.lowerCase);
346             }
347             if (mPasswordPolicy.letters != PasswordPolicy.DEF_MINIMUM_LETTERS) {
348                 writeAttributeValueToXml(
349                         out, TAG_MIN_PASSWORD_LETTERS, mPasswordPolicy.letters);
350             }
351             if (mPasswordPolicy.numeric != PasswordPolicy.DEF_MINIMUM_NUMERIC) {
352                 writeAttributeValueToXml(
353                         out, TAG_MIN_PASSWORD_NUMERIC, mPasswordPolicy.numeric);
354             }
355             if (mPasswordPolicy.symbols != PasswordPolicy.DEF_MINIMUM_SYMBOLS) {
356                 writeAttributeValueToXml(
357                         out, TAG_MIN_PASSWORD_SYMBOLS, mPasswordPolicy.symbols);
358             }
359             if (mPasswordPolicy.nonLetter > PasswordPolicy.DEF_MINIMUM_NON_LETTER) {
360                 writeAttributeValueToXml(
361                         out, TAG_MIN_PASSWORD_NONLETTER, mPasswordPolicy.nonLetter);
362             }
363         }
364         if (passwordHistoryLength != DEF_PASSWORD_HISTORY_LENGTH) {
365             writeAttributeValueToXml(
366                     out, TAG_PASSWORD_HISTORY_LENGTH, passwordHistoryLength);
367         }
368         if (maximumTimeToUnlock != DEF_MAXIMUM_TIME_TO_UNLOCK) {
369             writeAttributeValueToXml(
370                     out, TAG_MAX_TIME_TO_UNLOCK, maximumTimeToUnlock);
371         }
372         if (strongAuthUnlockTimeout != DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS) {
373             writeAttributeValueToXml(
374                     out, TAG_STRONG_AUTH_UNLOCK_TIMEOUT, strongAuthUnlockTimeout);
375         }
376         if (maximumFailedPasswordsForWipe != DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) {
377             writeAttributeValueToXml(
378                     out, TAG_MAX_FAILED_PASSWORD_WIPE, maximumFailedPasswordsForWipe);
379         }
380         if (specifiesGlobalProxy) {
381             writeAttributeValueToXml(
382                     out, TAG_SPECIFIES_GLOBAL_PROXY, specifiesGlobalProxy);
383             if (globalProxySpec != null) {
384                 writeAttributeValueToXml(out, TAG_GLOBAL_PROXY_SPEC, globalProxySpec);
385             }
386             if (globalProxyExclusionList != null) {
387                 writeAttributeValueToXml(
388                         out, TAG_GLOBAL_PROXY_EXCLUSION_LIST, globalProxyExclusionList);
389             }
390         }
391         if (passwordExpirationTimeout != DEF_PASSWORD_EXPIRATION_TIMEOUT) {
392             writeAttributeValueToXml(
393                     out, TAG_PASSWORD_EXPIRATION_TIMEOUT, passwordExpirationTimeout);
394         }
395         if (passwordExpirationDate != DEF_PASSWORD_EXPIRATION_DATE) {
396             writeAttributeValueToXml(
397                     out, TAG_PASSWORD_EXPIRATION_DATE, passwordExpirationDate);
398         }
399         if (encryptionRequested) {
400             writeAttributeValueToXml(
401                     out, TAG_ENCRYPTION_REQUESTED, encryptionRequested);
402         }
403         if (testOnlyAdmin) {
404             writeAttributeValueToXml(
405                     out, TAG_TEST_ONLY_ADMIN, testOnlyAdmin);
406         }
407         if (disableCamera) {
408             writeAttributeValueToXml(
409                     out, TAG_DISABLE_CAMERA, disableCamera);
410         }
411         if (disableCallerId) {
412             writeAttributeValueToXml(
413                     out, TAG_DISABLE_CALLER_ID, disableCallerId);
414         }
415         if (disableContactsSearch) {
416             writeAttributeValueToXml(
417                     out, TAG_DISABLE_CONTACTS_SEARCH, disableContactsSearch);
418         }
419         if (!disableBluetoothContactSharing) {
420             writeAttributeValueToXml(
421                     out, TAG_DISABLE_BLUETOOTH_CONTACT_SHARING, disableBluetoothContactSharing);
422         }
423         if (disableScreenCapture) {
424             writeAttributeValueToXml(
425                     out, TAG_DISABLE_SCREEN_CAPTURE, disableScreenCapture);
426         }
427         if (requireAutoTime) {
428             writeAttributeValueToXml(
429                     out, TAG_REQUIRE_AUTO_TIME, requireAutoTime);
430         }
431         if (forceEphemeralUsers) {
432             writeAttributeValueToXml(
433                     out, TAG_FORCE_EPHEMERAL_USERS, forceEphemeralUsers);
434         }
435         if (isNetworkLoggingEnabled) {
436             out.startTag(null, TAG_IS_NETWORK_LOGGING_ENABLED);
437             out.attributeBoolean(null, ATTR_VALUE, isNetworkLoggingEnabled);
438             out.attributeInt(null, ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS,
439                     numNetworkLoggingNotifications);
440             out.attributeLong(null, ATTR_LAST_NETWORK_LOGGING_NOTIFICATION,
441                     lastNetworkLoggingNotificationTimeMs);
442             out.endTag(null, TAG_IS_NETWORK_LOGGING_ENABLED);
443         }
444         if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) {
445             writeAttributeValueToXml(
446                     out, TAG_DISABLE_KEYGUARD_FEATURES, disabledKeyguardFeatures);
447         }
448         if (!accountTypesWithManagementDisabled.isEmpty()) {
449             writeAttributeValuesToXml(
450                     out, TAG_DISABLE_ACCOUNT_MANAGEMENT, TAG_ACCOUNT_TYPE,
451                     accountTypesWithManagementDisabled);
452         }
453         if (!trustAgentInfos.isEmpty()) {
454             Set<Map.Entry<String, TrustAgentInfo>> set = trustAgentInfos.entrySet();
455             out.startTag(null, TAG_MANAGE_TRUST_AGENT_FEATURES);
456             for (Map.Entry<String, TrustAgentInfo> entry : set) {
457                 TrustAgentInfo trustAgentInfo = entry.getValue();
458                 out.startTag(null, TAG_TRUST_AGENT_COMPONENT);
459                 out.attribute(null, ATTR_VALUE, entry.getKey());
460                 if (trustAgentInfo.options != null) {
461                     out.startTag(null, TAG_TRUST_AGENT_COMPONENT_OPTIONS);
462                     try {
463                         trustAgentInfo.options.saveToXml(out);
464                     } catch (XmlPullParserException e) {
465                         Slogf.e(LOG_TAG, e, "Failed to save TrustAgent options");
466                     }
467                     out.endTag(null, TAG_TRUST_AGENT_COMPONENT_OPTIONS);
468                 }
469                 out.endTag(null, TAG_TRUST_AGENT_COMPONENT);
470             }
471             out.endTag(null, TAG_MANAGE_TRUST_AGENT_FEATURES);
472         }
473         if (crossProfileWidgetProviders != null && !crossProfileWidgetProviders.isEmpty()) {
474             writeAttributeValuesToXml(
475                     out, TAG_CROSS_PROFILE_WIDGET_PROVIDERS, TAG_PROVIDER,
476                     crossProfileWidgetProviders);
477         }
478         writePackageListToXml(out, TAG_PERMITTED_ACCESSIBILITY_SERVICES,
479                 permittedAccessiblityServices);
480         writePackageListToXml(out, TAG_PERMITTED_IMES, permittedInputMethods);
481         writePackageListToXml(out, TAG_PERMITTED_NOTIFICATION_LISTENERS,
482                 permittedNotificationListeners);
483         writePackageListToXml(out, TAG_KEEP_UNINSTALLED_PACKAGES, keepUninstalledPackages);
484         writePackageListToXml(out, TAG_METERED_DATA_DISABLED_PACKAGES, meteredDisabledPackages);
485         if (hasUserRestrictions()) {
486             UserRestrictionsUtils.writeRestrictions(
487                     out, userRestrictions, TAG_USER_RESTRICTIONS);
488         }
489         if (!defaultEnabledRestrictionsAlreadySet.isEmpty()) {
490             writeAttributeValuesToXml(out, TAG_DEFAULT_ENABLED_USER_RESTRICTIONS,
491                     TAG_RESTRICTION,
492                     defaultEnabledRestrictionsAlreadySet);
493         }
494         if (!TextUtils.isEmpty(shortSupportMessage)) {
495             writeTextToXml(out, TAG_SHORT_SUPPORT_MESSAGE, shortSupportMessage.toString());
496         }
497         if (!TextUtils.isEmpty(longSupportMessage)) {
498             writeTextToXml(out, TAG_LONG_SUPPORT_MESSAGE, longSupportMessage.toString());
499         }
500         if (parentAdmin != null) {
501             out.startTag(null, TAG_PARENT_ADMIN);
502             parentAdmin.writeToXml(out);
503             out.endTag(null, TAG_PARENT_ADMIN);
504         }
505         if (organizationColor != DEF_ORGANIZATION_COLOR) {
506             writeAttributeValueToXml(out, TAG_ORGANIZATION_COLOR, organizationColor);
507         }
508         if (organizationName != null) {
509             writeTextToXml(out, TAG_ORGANIZATION_NAME, organizationName);
510         }
511         if (isLogoutEnabled) {
512             writeAttributeValueToXml(out, TAG_IS_LOGOUT_ENABLED, isLogoutEnabled);
513         }
514         if (startUserSessionMessage != null) {
515             writeTextToXml(out, TAG_START_USER_SESSION_MESSAGE, startUserSessionMessage);
516         }
517         if (endUserSessionMessage != null) {
518             writeTextToXml(out, TAG_END_USER_SESSION_MESSAGE, endUserSessionMessage);
519         }
520         if (mCrossProfileCalendarPackages == null) {
521             out.startTag(null, TAG_CROSS_PROFILE_CALENDAR_PACKAGES_NULL);
522             out.endTag(null, TAG_CROSS_PROFILE_CALENDAR_PACKAGES_NULL);
523         } else {
524             writePackageListToXml(out, TAG_CROSS_PROFILE_CALENDAR_PACKAGES,
525                     mCrossProfileCalendarPackages);
526         }
527         writePackageListToXml(out, TAG_CROSS_PROFILE_PACKAGES, mCrossProfilePackages);
528         if (mFactoryResetProtectionPolicy != null) {
529             out.startTag(null, TAG_FACTORY_RESET_PROTECTION_POLICY);
530             mFactoryResetProtectionPolicy.writeToXml(out);
531             out.endTag(null, TAG_FACTORY_RESET_PROTECTION_POLICY);
532         }
533         if (mSuspendPersonalApps) {
534             writeAttributeValueToXml(out, TAG_SUSPEND_PERSONAL_APPS, mSuspendPersonalApps);
535         }
536         if (mProfileMaximumTimeOffMillis != 0) {
537             writeAttributeValueToXml(out, TAG_PROFILE_MAXIMUM_TIME_OFF,
538                     mProfileMaximumTimeOffMillis);
539         }
540         if (mProfileMaximumTimeOffMillis != 0) {
541             writeAttributeValueToXml(out, TAG_PROFILE_OFF_DEADLINE, mProfileOffDeadline);
542         }
543         if (!TextUtils.isEmpty(mAlwaysOnVpnPackage)) {
544             writeAttributeValueToXml(out, TAG_ALWAYS_ON_VPN_PACKAGE, mAlwaysOnVpnPackage);
545         }
546         if (mAlwaysOnVpnLockdown) {
547             writeAttributeValueToXml(out, TAG_ALWAYS_ON_VPN_LOCKDOWN, mAlwaysOnVpnLockdown);
548         }
549         if (mCommonCriteriaMode) {
550             writeAttributeValueToXml(out, TAG_COMMON_CRITERIA_MODE, mCommonCriteriaMode);
551         }
552 
553         if (mPasswordComplexity != PASSWORD_COMPLEXITY_NONE) {
554             writeAttributeValueToXml(out, TAG_PASSWORD_COMPLEXITY, mPasswordComplexity);
555         }
556         if (mNearbyNotificationStreamingPolicy != NEARBY_STREAMING_DISABLED) {
557             writeAttributeValueToXml(out, TAG_NEARBY_NOTIFICATION_STREAMING_POLICY,
558                     mNearbyNotificationStreamingPolicy);
559         }
560         if (mNearbyAppStreamingPolicy != NEARBY_STREAMING_DISABLED) {
561             writeAttributeValueToXml(out, TAG_NEARBY_APP_STREAMING_POLICY,
562                     mNearbyAppStreamingPolicy);
563         }
564         if (!TextUtils.isEmpty(mOrganizationId)) {
565             writeTextToXml(out, TAG_ORGANIZATION_ID, mOrganizationId);
566         }
567         if (!TextUtils.isEmpty(mEnrollmentSpecificId)) {
568             writeTextToXml(out, TAG_ENROLLMENT_SPECIFIC_ID, mEnrollmentSpecificId);
569         }
570         writeAttributeValueToXml(out, TAG_ADMIN_CAN_GRANT_SENSORS_PERMISSIONS,
571                 mAdminCanGrantSensorsPermissions);
572         writeAttributeValueToXml(out, TAG_PREFERENTIAL_NETWORK_SERVICE_ENABLED,
573                 mPreferentialNetworkServiceEnabled);
574         if (mUsbDataSignalingEnabled != USB_DATA_SIGNALING_ENABLED_DEFAULT) {
575             writeAttributeValueToXml(out, TAG_USB_DATA_SIGNALING, mUsbDataSignalingEnabled);
576         }
577     }
578 
writeTextToXml(TypedXmlSerializer out, String tag, String text)579     void writeTextToXml(TypedXmlSerializer out, String tag, String text) throws IOException {
580         out.startTag(null, tag);
581         out.text(text);
582         out.endTag(null, tag);
583     }
584 
writePackageListToXml(TypedXmlSerializer out, String outerTag, List<String> packageList)585     void writePackageListToXml(TypedXmlSerializer out, String outerTag,
586             List<String> packageList)
587             throws IllegalArgumentException, IllegalStateException, IOException {
588         if (packageList == null) {
589             return;
590         }
591         writeAttributeValuesToXml(out, outerTag, TAG_PACKAGE_LIST_ITEM, packageList);
592     }
593 
writeAttributeValueToXml(TypedXmlSerializer out, String tag, String value)594     void writeAttributeValueToXml(TypedXmlSerializer out, String tag, String value)
595             throws IOException {
596         out.startTag(null, tag);
597         out.attribute(null, ATTR_VALUE, value);
598         out.endTag(null, tag);
599     }
600 
writeAttributeValueToXml(TypedXmlSerializer out, String tag, int value)601     void writeAttributeValueToXml(TypedXmlSerializer out, String tag, int value)
602             throws IOException {
603         out.startTag(null, tag);
604         out.attributeInt(null, ATTR_VALUE, value);
605         out.endTag(null, tag);
606     }
607 
writeAttributeValueToXml(TypedXmlSerializer out, String tag, long value)608     void writeAttributeValueToXml(TypedXmlSerializer out, String tag, long value)
609             throws IOException {
610         out.startTag(null, tag);
611         out.attributeLong(null, ATTR_VALUE, value);
612         out.endTag(null, tag);
613     }
614 
writeAttributeValueToXml(TypedXmlSerializer out, String tag, boolean value)615     void writeAttributeValueToXml(TypedXmlSerializer out, String tag, boolean value)
616             throws IOException {
617         out.startTag(null, tag);
618         out.attributeBoolean(null, ATTR_VALUE, value);
619         out.endTag(null, tag);
620     }
621 
writeAttributeValuesToXml(TypedXmlSerializer out, String outerTag, String innerTag, @NonNull Collection<String> values)622     void writeAttributeValuesToXml(TypedXmlSerializer out, String outerTag, String innerTag,
623             @NonNull Collection<String> values) throws IOException {
624         out.startTag(null, outerTag);
625         for (String value : values) {
626             out.startTag(null, innerTag);
627             out.attribute(null, ATTR_VALUE, value);
628             out.endTag(null, innerTag);
629         }
630         out.endTag(null, outerTag);
631     }
632 
readFromXml(TypedXmlPullParser parser, boolean shouldOverridePolicies)633     void readFromXml(TypedXmlPullParser parser, boolean shouldOverridePolicies)
634             throws XmlPullParserException, IOException {
635         int outerDepth = parser.getDepth();
636         int type;
637         while ((type = parser.next()) != END_DOCUMENT
638                && (type != END_TAG || parser.getDepth() > outerDepth)) {
639             if (type == END_TAG || type == TEXT) {
640                 continue;
641             }
642             String tag = parser.getName();
643             if (TAG_POLICIES.equals(tag)) {
644                 if (shouldOverridePolicies) {
645                     Slogf.d(LOG_TAG, "Overriding device admin policies from XML.");
646                     info.readPoliciesFromXml(parser);
647                 }
648             } else if (TAG_PASSWORD_QUALITY.equals(tag)) {
649                 mPasswordPolicy.quality = parser.getAttributeInt(null, ATTR_VALUE);
650             } else if (TAG_MIN_PASSWORD_LENGTH.equals(tag)) {
651                 mPasswordPolicy.length = parser.getAttributeInt(null, ATTR_VALUE);
652             } else if (TAG_PASSWORD_HISTORY_LENGTH.equals(tag)) {
653                 passwordHistoryLength = parser.getAttributeInt(null, ATTR_VALUE);
654             } else if (TAG_MIN_PASSWORD_UPPERCASE.equals(tag)) {
655                 mPasswordPolicy.upperCase = parser.getAttributeInt(null, ATTR_VALUE);
656             } else if (TAG_MIN_PASSWORD_LOWERCASE.equals(tag)) {
657                 mPasswordPolicy.lowerCase = parser.getAttributeInt(null, ATTR_VALUE);
658             } else if (TAG_MIN_PASSWORD_LETTERS.equals(tag)) {
659                 mPasswordPolicy.letters = parser.getAttributeInt(null, ATTR_VALUE);
660             } else if (TAG_MIN_PASSWORD_NUMERIC.equals(tag)) {
661                 mPasswordPolicy.numeric = parser.getAttributeInt(null, ATTR_VALUE);
662             } else if (TAG_MIN_PASSWORD_SYMBOLS.equals(tag)) {
663                 mPasswordPolicy.symbols = parser.getAttributeInt(null, ATTR_VALUE);
664             } else if (TAG_MIN_PASSWORD_NONLETTER.equals(tag)) {
665                 mPasswordPolicy.nonLetter = parser.getAttributeInt(null, ATTR_VALUE);
666             } else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) {
667                 maximumTimeToUnlock = parser.getAttributeLong(null, ATTR_VALUE);
668             } else if (TAG_STRONG_AUTH_UNLOCK_TIMEOUT.equals(tag)) {
669                 strongAuthUnlockTimeout = parser.getAttributeLong(null, ATTR_VALUE);
670             } else if (TAG_MAX_FAILED_PASSWORD_WIPE.equals(tag)) {
671                 maximumFailedPasswordsForWipe = parser.getAttributeInt(null, ATTR_VALUE);
672             } else if (TAG_SPECIFIES_GLOBAL_PROXY.equals(tag)) {
673                 specifiesGlobalProxy = parser.getAttributeBoolean(null, ATTR_VALUE, false);
674             } else if (TAG_GLOBAL_PROXY_SPEC.equals(tag)) {
675                 globalProxySpec =
676                     parser.getAttributeValue(null, ATTR_VALUE);
677             } else if (TAG_GLOBAL_PROXY_EXCLUSION_LIST.equals(tag)) {
678                 globalProxyExclusionList =
679                     parser.getAttributeValue(null, ATTR_VALUE);
680             } else if (TAG_PASSWORD_EXPIRATION_TIMEOUT.equals(tag)) {
681                 passwordExpirationTimeout = parser.getAttributeLong(null, ATTR_VALUE);
682             } else if (TAG_PASSWORD_EXPIRATION_DATE.equals(tag)) {
683                 passwordExpirationDate = parser.getAttributeLong(null, ATTR_VALUE);
684             } else if (TAG_ENCRYPTION_REQUESTED.equals(tag)) {
685                 encryptionRequested = parser.getAttributeBoolean(null, ATTR_VALUE, false);
686             } else if (TAG_TEST_ONLY_ADMIN.equals(tag)) {
687                 testOnlyAdmin = parser.getAttributeBoolean(null, ATTR_VALUE, false);
688             } else if (TAG_DISABLE_CAMERA.equals(tag)) {
689                 disableCamera = parser.getAttributeBoolean(null, ATTR_VALUE, false);
690             } else if (TAG_DISABLE_CALLER_ID.equals(tag)) {
691                 disableCallerId = parser.getAttributeBoolean(null, ATTR_VALUE, false);
692             } else if (TAG_DISABLE_CONTACTS_SEARCH.equals(tag)) {
693                 disableContactsSearch = parser.getAttributeBoolean(null, ATTR_VALUE, false);
694             } else if (TAG_DISABLE_BLUETOOTH_CONTACT_SHARING.equals(tag)) {
695                 disableBluetoothContactSharing =
696                         parser.getAttributeBoolean(null, ATTR_VALUE, false);
697             } else if (TAG_DISABLE_SCREEN_CAPTURE.equals(tag)) {
698                 disableScreenCapture = parser.getAttributeBoolean(null, ATTR_VALUE, false);
699             } else if (TAG_REQUIRE_AUTO_TIME.equals(tag)) {
700                 requireAutoTime = parser.getAttributeBoolean(null, ATTR_VALUE, false);
701             } else if (TAG_FORCE_EPHEMERAL_USERS.equals(tag)) {
702                 forceEphemeralUsers = parser.getAttributeBoolean(null, ATTR_VALUE, false);
703             } else if (TAG_IS_NETWORK_LOGGING_ENABLED.equals(tag)) {
704                 isNetworkLoggingEnabled = parser.getAttributeBoolean(null, ATTR_VALUE, false);
705                 lastNetworkLoggingNotificationTimeMs = parser.getAttributeLong(null,
706                         ATTR_LAST_NETWORK_LOGGING_NOTIFICATION);
707                 numNetworkLoggingNotifications = parser.getAttributeInt(null,
708                         ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS);
709             } else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) {
710                 disabledKeyguardFeatures = parser.getAttributeInt(null, ATTR_VALUE);
711             } else if (TAG_DISABLE_ACCOUNT_MANAGEMENT.equals(tag)) {
712                 readAttributeValues(
713                         parser, TAG_ACCOUNT_TYPE, accountTypesWithManagementDisabled);
714             } else if (TAG_MANAGE_TRUST_AGENT_FEATURES.equals(tag)) {
715                 trustAgentInfos = getAllTrustAgentInfos(parser, tag);
716             } else if (TAG_CROSS_PROFILE_WIDGET_PROVIDERS.equals(tag)) {
717                 crossProfileWidgetProviders = new ArrayList<>();
718                 readAttributeValues(parser, TAG_PROVIDER, crossProfileWidgetProviders);
719             } else if (TAG_PERMITTED_ACCESSIBILITY_SERVICES.equals(tag)) {
720                 permittedAccessiblityServices = readPackageList(parser, tag);
721             } else if (TAG_PERMITTED_IMES.equals(tag)) {
722                 permittedInputMethods = readPackageList(parser, tag);
723             } else if (TAG_PERMITTED_NOTIFICATION_LISTENERS.equals(tag)) {
724                 permittedNotificationListeners = readPackageList(parser, tag);
725             } else if (TAG_KEEP_UNINSTALLED_PACKAGES.equals(tag)) {
726                 keepUninstalledPackages = readPackageList(parser, tag);
727             } else if (TAG_METERED_DATA_DISABLED_PACKAGES.equals(tag)) {
728                 meteredDisabledPackages = readPackageList(parser, tag);
729             } else if (TAG_USER_RESTRICTIONS.equals(tag)) {
730                 userRestrictions = UserRestrictionsUtils.readRestrictions(parser);
731             } else if (TAG_DEFAULT_ENABLED_USER_RESTRICTIONS.equals(tag)) {
732                 readAttributeValues(
733                         parser, TAG_RESTRICTION, defaultEnabledRestrictionsAlreadySet);
734             } else if (TAG_SHORT_SUPPORT_MESSAGE.equals(tag)) {
735                 type = parser.next();
736                 if (type == TypedXmlPullParser.TEXT) {
737                     shortSupportMessage = parser.getText();
738                 } else {
739                     Slogf.w(LOG_TAG, "Missing text when loading short support message");
740                 }
741             } else if (TAG_LONG_SUPPORT_MESSAGE.equals(tag)) {
742                 type = parser.next();
743                 if (type == TypedXmlPullParser.TEXT) {
744                     longSupportMessage = parser.getText();
745                 } else {
746                     Slogf.w(LOG_TAG, "Missing text when loading long support message");
747                 }
748             } else if (TAG_PARENT_ADMIN.equals(tag)) {
749                 Preconditions.checkState(!isParent);
750                 parentAdmin = new ActiveAdmin(info, /* parent */ true);
751                 parentAdmin.readFromXml(parser, shouldOverridePolicies);
752             } else if (TAG_ORGANIZATION_COLOR.equals(tag)) {
753                 organizationColor = parser.getAttributeInt(null, ATTR_VALUE);
754             } else if (TAG_ORGANIZATION_NAME.equals(tag)) {
755                 type = parser.next();
756                 if (type == TypedXmlPullParser.TEXT) {
757                     organizationName = parser.getText();
758                 } else {
759                     Slogf.w(LOG_TAG, "Missing text when loading organization name");
760                 }
761             } else if (TAG_IS_LOGOUT_ENABLED.equals(tag)) {
762                 isLogoutEnabled = parser.getAttributeBoolean(null, ATTR_VALUE, false);
763             } else if (TAG_START_USER_SESSION_MESSAGE.equals(tag)) {
764                 type = parser.next();
765                 if (type == TypedXmlPullParser.TEXT) {
766                     startUserSessionMessage = parser.getText();
767                 } else {
768                     Slogf.w(LOG_TAG, "Missing text when loading start session message");
769                 }
770             } else if (TAG_END_USER_SESSION_MESSAGE.equals(tag)) {
771                 type = parser.next();
772                 if (type == TypedXmlPullParser.TEXT) {
773                     endUserSessionMessage = parser.getText();
774                 } else {
775                     Slogf.w(LOG_TAG, "Missing text when loading end session message");
776                 }
777             } else if (TAG_CROSS_PROFILE_CALENDAR_PACKAGES.equals(tag)) {
778                 mCrossProfileCalendarPackages = readPackageList(parser, tag);
779             } else if (TAG_CROSS_PROFILE_CALENDAR_PACKAGES_NULL.equals(tag)) {
780                 mCrossProfileCalendarPackages = null;
781             } else if (TAG_CROSS_PROFILE_PACKAGES.equals(tag)) {
782                 mCrossProfilePackages = readPackageList(parser, tag);
783             } else if (TAG_FACTORY_RESET_PROTECTION_POLICY.equals(tag)) {
784                 mFactoryResetProtectionPolicy = FactoryResetProtectionPolicy.readFromXml(
785                             parser);
786             } else if (TAG_SUSPEND_PERSONAL_APPS.equals(tag)) {
787                 mSuspendPersonalApps = parser.getAttributeBoolean(null, ATTR_VALUE, false);
788             } else if (TAG_PROFILE_MAXIMUM_TIME_OFF.equals(tag)) {
789                 mProfileMaximumTimeOffMillis =
790                         parser.getAttributeLong(null, ATTR_VALUE);
791             } else if (TAG_PROFILE_OFF_DEADLINE.equals(tag)) {
792                 mProfileOffDeadline =
793                         parser.getAttributeLong(null, ATTR_VALUE);
794             } else if (TAG_ALWAYS_ON_VPN_PACKAGE.equals(tag)) {
795                 mAlwaysOnVpnPackage = parser.getAttributeValue(null, ATTR_VALUE);
796             } else if (TAG_ALWAYS_ON_VPN_LOCKDOWN.equals(tag)) {
797                 mAlwaysOnVpnLockdown = parser.getAttributeBoolean(null, ATTR_VALUE, false);
798             } else if (TAG_PREFERENTIAL_NETWORK_SERVICE_ENABLED.equals(tag)) {
799                 mPreferentialNetworkServiceEnabled = parser.getAttributeBoolean(null, ATTR_VALUE,
800                         DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT);
801             } else if (TAG_COMMON_CRITERIA_MODE.equals(tag)) {
802                 mCommonCriteriaMode = parser.getAttributeBoolean(null, ATTR_VALUE, false);
803             } else if (TAG_PASSWORD_COMPLEXITY.equals(tag)) {
804                 mPasswordComplexity = parser.getAttributeInt(null, ATTR_VALUE);
805             } else if (TAG_NEARBY_NOTIFICATION_STREAMING_POLICY.equals(tag)) {
806                 mNearbyNotificationStreamingPolicy = parser.getAttributeInt(null, ATTR_VALUE);
807             } else if (TAG_NEARBY_APP_STREAMING_POLICY.equals(tag)) {
808                 mNearbyAppStreamingPolicy = parser.getAttributeInt(null, ATTR_VALUE);
809             } else if (TAG_ORGANIZATION_ID.equals(tag)) {
810                 type = parser.next();
811                 if (type == TypedXmlPullParser.TEXT) {
812                     mOrganizationId = parser.getText();
813                 } else {
814                     Slogf.w(LOG_TAG, "Missing Organization ID.");
815                 }
816             } else if (TAG_ENROLLMENT_SPECIFIC_ID.equals(tag)) {
817                 type = parser.next();
818                 if (type == TypedXmlPullParser.TEXT) {
819                     mEnrollmentSpecificId = parser.getText();
820                 } else {
821                     Slogf.w(LOG_TAG, "Missing Enrollment-specific ID.");
822                 }
823             } else if (TAG_ADMIN_CAN_GRANT_SENSORS_PERMISSIONS.equals(tag)) {
824                 mAdminCanGrantSensorsPermissions = parser.getAttributeBoolean(null, ATTR_VALUE,
825                         false);
826             } else if (TAG_USB_DATA_SIGNALING.equals(tag)) {
827                 mUsbDataSignalingEnabled = parser.getAttributeBoolean(null, ATTR_VALUE,
828                         USB_DATA_SIGNALING_ENABLED_DEFAULT);
829             } else {
830                 Slogf.w(LOG_TAG, "Unknown admin tag: %s", tag);
831                 XmlUtils.skipCurrentTag(parser);
832             }
833         }
834     }
835 
readPackageList(TypedXmlPullParser parser, String tag)836     private List<String> readPackageList(TypedXmlPullParser parser,
837             String tag) throws XmlPullParserException, IOException {
838         List<String> result = new ArrayList<String>();
839         int outerDepth = parser.getDepth();
840         int outerType;
841         while ((outerType = parser.next()) != TypedXmlPullParser.END_DOCUMENT
842                 && (outerType != TypedXmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
843             if (outerType == TypedXmlPullParser.END_TAG || outerType == TypedXmlPullParser.TEXT) {
844                 continue;
845             }
846             String outerTag = parser.getName();
847             if (TAG_PACKAGE_LIST_ITEM.equals(outerTag)) {
848                 String packageName = parser.getAttributeValue(null, ATTR_VALUE);
849                 if (packageName != null) {
850                     result.add(packageName);
851                 } else {
852                     Slogf.w(LOG_TAG, "Package name missing under %s", outerTag);
853                 }
854             } else {
855                 Slogf.w(LOG_TAG, "Unknown tag under %s: ", tag, outerTag);
856             }
857         }
858         return result;
859     }
860 
readAttributeValues( TypedXmlPullParser parser, String tag, Collection<String> result)861     private void readAttributeValues(
862             TypedXmlPullParser parser, String tag, Collection<String> result)
863             throws XmlPullParserException, IOException {
864         result.clear();
865         int outerDepthDAM = parser.getDepth();
866         int typeDAM;
867         while ((typeDAM = parser.next()) != END_DOCUMENT
868                 && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
869             if (typeDAM == END_TAG || typeDAM == TEXT) {
870                 continue;
871             }
872             String tagDAM = parser.getName();
873             if (tag.equals(tagDAM)) {
874                 result.add(parser.getAttributeValue(null, ATTR_VALUE));
875             } else {
876                 Slogf.e(LOG_TAG, "Expected tag %s but found %s", tag, tagDAM);
877             }
878         }
879     }
880 
881     @NonNull
getAllTrustAgentInfos( TypedXmlPullParser parser, String tag)882     private ArrayMap<String, TrustAgentInfo> getAllTrustAgentInfos(
883             TypedXmlPullParser parser, String tag) throws XmlPullParserException, IOException {
884         int outerDepthDAM = parser.getDepth();
885         int typeDAM;
886         final ArrayMap<String, TrustAgentInfo> result = new ArrayMap<>();
887         while ((typeDAM = parser.next()) != END_DOCUMENT
888                 && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
889             if (typeDAM == END_TAG || typeDAM == TEXT) {
890                 continue;
891             }
892             String tagDAM = parser.getName();
893             if (TAG_TRUST_AGENT_COMPONENT.equals(tagDAM)) {
894                 final String component = parser.getAttributeValue(null, ATTR_VALUE);
895                 final TrustAgentInfo trustAgentInfo = getTrustAgentInfo(parser, tag);
896                 result.put(component, trustAgentInfo);
897             } else {
898                 Slogf.w(LOG_TAG, "Unknown tag under %s: %s", tag, tagDAM);
899             }
900         }
901         return result;
902     }
903 
getTrustAgentInfo(TypedXmlPullParser parser, String tag)904     private TrustAgentInfo getTrustAgentInfo(TypedXmlPullParser parser, String tag)
905             throws XmlPullParserException, IOException  {
906         int outerDepthDAM = parser.getDepth();
907         int typeDAM;
908         TrustAgentInfo result = new TrustAgentInfo(null);
909         while ((typeDAM = parser.next()) != END_DOCUMENT
910                 && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
911             if (typeDAM == END_TAG || typeDAM == TEXT) {
912                 continue;
913             }
914             String tagDAM = parser.getName();
915             if (TAG_TRUST_AGENT_COMPONENT_OPTIONS.equals(tagDAM)) {
916                 result.options = PersistableBundle.restoreFromXml(parser);
917             } else {
918                 Slogf.w(LOG_TAG, "Unknown tag under %s: %s", tag, tagDAM);
919             }
920         }
921         return result;
922     }
923 
hasUserRestrictions()924     boolean hasUserRestrictions() {
925         return userRestrictions != null && userRestrictions.size() > 0;
926     }
927 
ensureUserRestrictions()928     Bundle ensureUserRestrictions() {
929         if (userRestrictions == null) {
930             userRestrictions = new Bundle();
931         }
932         return userRestrictions;
933     }
934 
transfer(DeviceAdminInfo deviceAdminInfo)935     public void transfer(DeviceAdminInfo deviceAdminInfo) {
936         if (hasParentActiveAdmin()) {
937             parentAdmin.info = deviceAdminInfo;
938         }
939         info = deviceAdminInfo;
940     }
941 
addSyntheticRestrictions(Bundle restrictions)942     Bundle addSyntheticRestrictions(Bundle restrictions) {
943         if (disableCamera) {
944             restrictions.putBoolean(UserManager.DISALLOW_CAMERA, true);
945         }
946         if (requireAutoTime) {
947             restrictions.putBoolean(UserManager.DISALLOW_CONFIG_DATE_TIME, true);
948         }
949         return restrictions;
950     }
951 
removeDeprecatedRestrictions(Bundle restrictions)952     static Bundle removeDeprecatedRestrictions(Bundle restrictions) {
953         for (String deprecatedRestriction: UserRestrictionsUtils.DEPRECATED_USER_RESTRICTIONS) {
954             restrictions.remove(deprecatedRestriction);
955         }
956         return restrictions;
957     }
958 
filterRestrictions(Bundle restrictions, Predicate<String> filter)959     static Bundle filterRestrictions(Bundle restrictions, Predicate<String> filter) {
960         Bundle result = new Bundle();
961         for (String key : restrictions.keySet()) {
962             if (!restrictions.getBoolean(key)) {
963                 continue;
964             }
965             if (filter.test(key)) {
966                 result.putBoolean(key, true);
967             }
968         }
969         return result;
970     }
971 
getEffectiveRestrictions()972     Bundle getEffectiveRestrictions() {
973         return addSyntheticRestrictions(
974                 removeDeprecatedRestrictions(new Bundle(ensureUserRestrictions())));
975     }
976 
getLocalUserRestrictions(int adminType)977     Bundle getLocalUserRestrictions(int adminType) {
978         return filterRestrictions(getEffectiveRestrictions(),
979                 key -> UserRestrictionsUtils.isLocal(adminType, key));
980     }
981 
getGlobalUserRestrictions(int adminType)982     Bundle getGlobalUserRestrictions(int adminType) {
983         return filterRestrictions(getEffectiveRestrictions(),
984                 key -> UserRestrictionsUtils.isGlobal(adminType, key));
985     }
986 
dump(IndentingPrintWriter pw)987     void dump(IndentingPrintWriter pw) {
988         pw.print("uid=");
989         pw.println(getUid());
990 
991         pw.print("testOnlyAdmin=");
992         pw.println(testOnlyAdmin);
993 
994         pw.println("policies:");
995         ArrayList<DeviceAdminInfo.PolicyInfo> pols = info.getUsedPolicies();
996         if (pols != null) {
997             pw.increaseIndent();
998             for (int i = 0; i < pols.size(); i++) {
999                 pw.println(pols.get(i).tag);
1000             }
1001             pw.decreaseIndent();
1002         }
1003 
1004         pw.print("passwordQuality=0x");
1005         pw.println(Integer.toHexString(mPasswordPolicy.quality));
1006 
1007         pw.print("minimumPasswordLength=");
1008         pw.println(mPasswordPolicy.length);
1009 
1010         pw.print("passwordHistoryLength=");
1011         pw.println(passwordHistoryLength);
1012 
1013         pw.print("minimumPasswordUpperCase=");
1014         pw.println(mPasswordPolicy.upperCase);
1015 
1016         pw.print("minimumPasswordLowerCase=");
1017         pw.println(mPasswordPolicy.lowerCase);
1018 
1019         pw.print("minimumPasswordLetters=");
1020         pw.println(mPasswordPolicy.letters);
1021 
1022         pw.print("minimumPasswordNumeric=");
1023         pw.println(mPasswordPolicy.numeric);
1024 
1025         pw.print("minimumPasswordSymbols=");
1026         pw.println(mPasswordPolicy.symbols);
1027 
1028         pw.print("minimumPasswordNonLetter=");
1029         pw.println(mPasswordPolicy.nonLetter);
1030 
1031         pw.print("maximumTimeToUnlock=");
1032         pw.println(maximumTimeToUnlock);
1033 
1034         pw.print("strongAuthUnlockTimeout=");
1035         pw.println(strongAuthUnlockTimeout);
1036 
1037         pw.print("maximumFailedPasswordsForWipe=");
1038         pw.println(maximumFailedPasswordsForWipe);
1039 
1040         pw.print("specifiesGlobalProxy=");
1041         pw.println(specifiesGlobalProxy);
1042 
1043         pw.print("passwordExpirationTimeout=");
1044         pw.println(passwordExpirationTimeout);
1045 
1046         pw.print("passwordExpirationDate=");
1047         pw.println(passwordExpirationDate);
1048 
1049         if (globalProxySpec != null) {
1050             pw.print("globalProxySpec=");
1051             pw.println(globalProxySpec);
1052         }
1053         if (globalProxyExclusionList != null) {
1054             pw.print("globalProxyEclusionList=");
1055             pw.println(globalProxyExclusionList);
1056         }
1057         pw.print("encryptionRequested=");
1058         pw.println(encryptionRequested);
1059 
1060         pw.print("disableCamera=");
1061         pw.println(disableCamera);
1062 
1063         pw.print("disableCallerId=");
1064         pw.println(disableCallerId);
1065 
1066         pw.print("disableContactsSearch=");
1067         pw.println(disableContactsSearch);
1068 
1069         pw.print("disableBluetoothContactSharing=");
1070         pw.println(disableBluetoothContactSharing);
1071 
1072         pw.print("disableScreenCapture=");
1073         pw.println(disableScreenCapture);
1074 
1075         pw.print("requireAutoTime=");
1076         pw.println(requireAutoTime);
1077 
1078         pw.print("forceEphemeralUsers=");
1079         pw.println(forceEphemeralUsers);
1080 
1081         pw.print("isNetworkLoggingEnabled=");
1082         pw.println(isNetworkLoggingEnabled);
1083 
1084         pw.print("disabledKeyguardFeatures=");
1085         pw.println(disabledKeyguardFeatures);
1086 
1087         pw.print("crossProfileWidgetProviders=");
1088         pw.println(crossProfileWidgetProviders);
1089 
1090         if (permittedAccessiblityServices != null) {
1091             pw.print("permittedAccessibilityServices=");
1092             pw.println(permittedAccessiblityServices);
1093         }
1094 
1095         if (permittedInputMethods != null) {
1096             pw.print("permittedInputMethods=");
1097             pw.println(permittedInputMethods);
1098         }
1099 
1100         if (permittedNotificationListeners != null) {
1101             pw.print("permittedNotificationListeners=");
1102             pw.println(permittedNotificationListeners);
1103         }
1104 
1105         if (keepUninstalledPackages != null) {
1106             pw.print("keepUninstalledPackages=");
1107             pw.println(keepUninstalledPackages);
1108         }
1109 
1110         pw.print("organizationColor=");
1111         pw.println(organizationColor);
1112 
1113         if (organizationName != null) {
1114             pw.print("organizationName=");
1115             pw.println(organizationName);
1116         }
1117 
1118         pw.println("userRestrictions:");
1119         UserRestrictionsUtils.dumpRestrictions(pw, "  ", userRestrictions);
1120 
1121         pw.print("defaultEnabledRestrictionsAlreadySet=");
1122         pw.println(defaultEnabledRestrictionsAlreadySet);
1123 
1124         pw.print("isParent=");
1125         pw.println(isParent);
1126 
1127         if (parentAdmin != null) {
1128             pw.println("parentAdmin:");
1129             pw.increaseIndent();
1130             parentAdmin.dump(pw);
1131             pw.decreaseIndent();
1132         }
1133 
1134         if (mCrossProfileCalendarPackages != null) {
1135             pw.print("mCrossProfileCalendarPackages=");
1136             pw.println(mCrossProfileCalendarPackages);
1137         }
1138 
1139         pw.print("mCrossProfilePackages=");
1140         pw.println(mCrossProfilePackages);
1141 
1142         pw.print("mSuspendPersonalApps=");
1143         pw.println(mSuspendPersonalApps);
1144 
1145         pw.print("mProfileMaximumTimeOffMillis=");
1146         pw.println(mProfileMaximumTimeOffMillis);
1147 
1148         pw.print("mProfileOffDeadline=");
1149         pw.println(mProfileOffDeadline);
1150 
1151         pw.print("mAlwaysOnVpnPackage=");
1152         pw.println(mAlwaysOnVpnPackage);
1153 
1154         pw.print("mAlwaysOnVpnLockdown=");
1155         pw.println(mAlwaysOnVpnLockdown);
1156 
1157         pw.print("mPreferentialNetworkServiceEnabled=");
1158         pw.println(mPreferentialNetworkServiceEnabled);
1159 
1160         pw.print("mCommonCriteriaMode=");
1161         pw.println(mCommonCriteriaMode);
1162 
1163         pw.print("mPasswordComplexity=");
1164         pw.println(mPasswordComplexity);
1165 
1166         pw.print("mNearbyNotificationStreamingPolicy=");
1167         pw.println(mNearbyNotificationStreamingPolicy);
1168 
1169         pw.print("mNearbyAppStreamingPolicy=");
1170         pw.println(mNearbyAppStreamingPolicy);
1171 
1172         if (!TextUtils.isEmpty(mOrganizationId)) {
1173             pw.print("mOrganizationId=");
1174             pw.println(mOrganizationId);
1175         }
1176 
1177         if (!TextUtils.isEmpty(mEnrollmentSpecificId)) {
1178             pw.print("mEnrollmentSpecificId=");
1179             pw.println(mEnrollmentSpecificId);
1180         }
1181 
1182         pw.print("mAdminCanGrantSensorsPermissions=");
1183         pw.println(mAdminCanGrantSensorsPermissions);
1184 
1185         pw.print("mUsbDataSignaling=");
1186         pw.println(mUsbDataSignalingEnabled);
1187     }
1188 }
1189