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