1 /* 2 * Copyright (C) 2023 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.bedstead.enterprise; 18 19 import static com.android.bedstead.harrier.UserType.INITIAL_USER; 20 import static com.android.bedstead.harrier.UserType.INSTRUMENTED_USER; 21 import static com.android.bedstead.harrier.UserType.SECONDARY_USER; 22 import static com.android.bedstead.harrier.UserType.SYSTEM_USER; 23 import static com.android.bedstead.harrier.UserType.WORK_PROFILE; 24 import static com.android.bedstead.enterprise.annotations.EnsureHasDelegate.DELEGATE_KEY; 25 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIED_BY_AFFILIATED_PROFILE_OWNER; 26 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIED_BY_AFFILIATED_PROFILE_OWNER_PROFILE; 27 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIED_BY_AFFILIATED_PROFILE_OWNER_USER; 28 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIED_BY_DPM_ROLE_HOLDER; 29 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIED_BY_FINANCED_DEVICE_OWNER; 30 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIED_BY_ORGANIZATION_OWNED_PROFILE_OWNER_PROFILE; 31 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIED_BY_PARENT_INSTANCE_OF_NON_ORGANIZATIONAL_OWNED_PROFILE_OWNER_PROFILE; 32 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIED_BY_PARENT_INSTANCE_OF_ORGANIZATIONAL_OWNED_PROFILE_OWNER_PROFILE; 33 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIED_BY_PROFILE_OWNER_USER_WITH_NO_DO; 34 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIED_BY_SINGLE_DEVICE_OWNER; 35 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIED_BY_SYSTEM_DEVICE_OWNER; 36 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_PROFILE; 37 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_USER; 38 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIES_IN_BACKGROUND; 39 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIES_TO_AFFILIATED_OTHER_USERS; 40 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIES_TO_OWN_USER; 41 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIES_TO_PARENT; 42 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIES_TO_UNAFFILIATED_CHILD_PROFILES_WITHOUT_INHERITANCE; 43 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.APPLIES_TO_UNAFFILIATED_OTHER_USERS; 44 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.CANNOT_BE_APPLIED_BY_ROLE_HOLDER; 45 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.CAN_BE_DELEGATED; 46 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.DO_NOT_APPLY_TO_CANNOT_SET_POLICY_TESTS; 47 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.DO_NOT_APPLY_TO_POLICY_DOES_NOT_APPLY_TESTS; 48 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.INHERITABLE; 49 import static com.android.bedstead.enterprise.annotations.EnterprisePolicy.NO; 50 import static com.android.bedstead.nene.devicepolicy.CommonDevicePolicy.DELEGATION_APP_RESTRICTIONS; 51 import static com.android.bedstead.nene.devicepolicy.CommonDevicePolicy.DELEGATION_BLOCK_UNINSTALL; 52 import static com.android.bedstead.nene.devicepolicy.CommonDevicePolicy.DELEGATION_CERT_INSTALL; 53 import static com.android.bedstead.nene.devicepolicy.CommonDevicePolicy.DELEGATION_CERT_SELECTION; 54 import static com.android.bedstead.nene.devicepolicy.CommonDevicePolicy.DELEGATION_ENABLE_SYSTEM_APP; 55 import static com.android.bedstead.nene.devicepolicy.CommonDevicePolicy.DELEGATION_INSTALL_EXISTING_PACKAGE; 56 import static com.android.bedstead.nene.devicepolicy.CommonDevicePolicy.DELEGATION_KEEP_UNINSTALLED_PACKAGES; 57 import static com.android.bedstead.nene.devicepolicy.CommonDevicePolicy.DELEGATION_NETWORK_LOGGING; 58 import static com.android.bedstead.nene.devicepolicy.CommonDevicePolicy.DELEGATION_PACKAGE_ACCESS; 59 import static com.android.bedstead.nene.devicepolicy.CommonDevicePolicy.DELEGATION_PERMISSION_GRANT; 60 import static com.android.bedstead.nene.devicepolicy.CommonDevicePolicy.DELEGATION_SECURITY_LOGGING; 61 import static com.android.bedstead.testapp.TestAppQueryBuilder.queryBuilder; 62 import static com.android.xts.root.annotations.RequireRootInstrumentationKt.requireRootInstrumentation; 63 64 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnDevicePolicyManagementRoleHolderSecondaryUser; 65 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnDevicePolicyManagementRoleHolderUser; 66 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnSingleDeviceOwnerUser; 67 import com.android.bedstead.harrier.BedsteadJUnit4; 68 import com.android.bedstead.harrier.DynamicParameterizedAnnotation; 69 import com.android.bedstead.harrier.EnterprisePolicyWrapper; 70 import com.android.bedstead.harrier.UserType; 71 import com.android.bedstead.harrier.annotations.EnsureTestAppDoesNotHavePermission; 72 import com.android.bedstead.harrier.annotations.EnsureTestAppHasAppOp; 73 import com.android.bedstead.harrier.annotations.EnsureTestAppHasPermission; 74 import com.android.bedstead.harrier.annotations.EnsureTestAppInstalled; 75 import com.android.bedstead.enterprise.annotations.EnsureTestAppInstalledAsPrimaryDPC; 76 import com.android.bedstead.harrier.annotations.FailureMode; 77 import com.android.bedstead.enterprise.annotations.EnsureHasDelegate; 78 import com.android.bedstead.enterprise.annotations.EnsureHasDevicePolicyManagerRoleHolder; 79 import com.android.bedstead.enterprise.annotations.EnsureHasNoDelegate; 80 import com.android.bedstead.enterprise.annotations.EnterprisePolicy; 81 import com.android.bedstead.enterprise.annotations.EnterprisePolicy.AppOp; 82 import com.android.bedstead.enterprise.annotations.EnterprisePolicy.Permission; 83 import com.android.bedstead.harrier.annotations.meta.ParameterizedAnnotation; 84 import com.android.bedstead.harrier.annotations.parameterized.IncludeNone; 85 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnAffiliatedDeviceOwnerSecondaryUser; 86 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnAffiliatedProfileOwnerAdditionalUser; 87 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnBackgroundDeviceOwnerUser; 88 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnCloneProfileAlongsideManagedProfile; 89 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnCloneProfileAlongsideManagedProfileUsingParentInstance; 90 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnCloneProfileAlongsideOrganizationOwnedProfile; 91 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnCloneProfileAlongsideOrganizationOwnedProfileUsingParentInstance; 92 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnDevicePolicyManagementRoleHolderProfile; 93 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnFinancedDeviceOwnerUser; 94 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnOrganizationOwnedProfileOwner; 95 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnParentOfOrganizationOwnedProfileOwner; 96 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnParentOfOrganizationOwnedProfileOwnerUsingParentInstance; 97 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnParentOfProfileOwnerUsingParentInstance; 98 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnParentOfProfileOwnerWithNoDeviceOwner; 99 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnPrivateProfileAlongsideManagedProfile; 100 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnPrivateProfileAlongsideManagedProfileUsingParentInstance; 101 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnPrivateProfileAlongsideOrganizationOwnedProfile; 102 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnPrivateProfileAlongsideOrganizationOwnedProfileUsingParentInstance; 103 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnProfileOwnerPrimaryUser; 104 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnProfileOwnerProfileWithNoDeviceOwner; 105 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnSecondaryUserInDifferentProfileGroupToOrganizationOwnedProfileOwnerProfileUsingParentInstance; 106 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnSecondaryUserInDifferentProfileGroupToProfileOwnerProfile; 107 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnSystemDeviceOwnerUser; 108 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnUnaffiliatedDeviceOwnerSecondaryUser; 109 import com.android.bedstead.enterprise.annotations.parameterized.IncludeRunOnUnaffiliatedProfileOwnerAdditionalUser; 110 import com.android.queryable.annotations.Query; 111 112 import com.google.auto.value.AutoAnnotation; 113 import com.google.common.collect.ImmutableMap; 114 import com.google.common.collect.ImmutableSet; 115 116 import java.lang.annotation.Annotation; 117 import java.util.ArrayList; 118 import java.util.Arrays; 119 import java.util.Comparator; 120 import java.util.HashMap; 121 import java.util.HashSet; 122 import java.util.List; 123 import java.util.Map; 124 import java.util.Set; 125 import java.util.function.BiFunction; 126 import java.util.function.Function; 127 import java.util.stream.Collectors; 128 129 /** 130 * Utility class for enterprise policy tests. 131 */ 132 public final class Policy { 133 134 private static final String DELEGATE_PACKAGE_NAME = "com.android.Delegate"; 135 136 // Delegate scopes to be used for a "CannotSet" state. All delegate scopes except the ones which 137 // should allow use of the API will be granted 138 private static final ImmutableSet<String> ALL_DELEGATE_SCOPES = ImmutableSet.of( 139 DELEGATION_CERT_INSTALL, 140 DELEGATION_APP_RESTRICTIONS, 141 DELEGATION_BLOCK_UNINSTALL, 142 DELEGATION_PERMISSION_GRANT, 143 DELEGATION_PACKAGE_ACCESS, 144 DELEGATION_ENABLE_SYSTEM_APP, 145 DELEGATION_INSTALL_EXISTING_PACKAGE, 146 DELEGATION_KEEP_UNINSTALLED_PACKAGES, 147 DELEGATION_NETWORK_LOGGING, 148 DELEGATION_CERT_SELECTION, 149 DELEGATION_SECURITY_LOGGING 150 ); 151 152 // This is a map containing all Include* annotations and the flags which lead to them 153 // This is not validated - every state must have a single APPLIED_BY annotation 154 private static final ImmutableMap<Integer, Function<EnterprisePolicy, Set<Annotation>>> 155 STATE_ANNOTATIONS = 156 ImmutableMap.<Integer, Function<EnterprisePolicy, Set<Annotation>>>builder() 157 .put(APPLIED_BY_SYSTEM_DEVICE_OWNER | APPLIES_TO_OWN_USER, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnSystemDeviceOwnerUser(), /* roleHolderUser= */ SYSTEM_USER)) 158 .put(APPLIED_BY_SYSTEM_DEVICE_OWNER | APPLIES_TO_OWN_USER | CAN_BE_DELEGATED, generateDelegateAnnotation(includeRunOnSystemDeviceOwnerUser(), /* isPrimary= */ true)) 159 .put(APPLIED_BY_SYSTEM_DEVICE_OWNER | APPLIES_TO_OWN_USER | APPLIES_IN_BACKGROUND, singleAnnotation(includeRunOnBackgroundDeviceOwnerUser())) 160 .put(APPLIED_BY_SYSTEM_DEVICE_OWNER | APPLIES_TO_OWN_USER | APPLIES_IN_BACKGROUND | CAN_BE_DELEGATED, generateDelegateAnnotation(includeRunOnBackgroundDeviceOwnerUser(), /* isPrimary= */ true)) 161 162 .put(APPLIED_BY_SYSTEM_DEVICE_OWNER | APPLIES_TO_UNAFFILIATED_OTHER_USERS, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnNonAffiliatedDeviceOwnerSecondaryUser(), /* roleHolderUser= */ SYSTEM_USER)) 163 .put(APPLIED_BY_SYSTEM_DEVICE_OWNER | APPLIES_TO_UNAFFILIATED_OTHER_USERS | CAN_BE_DELEGATED, generateDelegateAnnotation(includeRunOnNonAffiliatedDeviceOwnerSecondaryUser(), /* isPrimary= */ true)) 164 .put(APPLIED_BY_SYSTEM_DEVICE_OWNER | APPLIES_TO_AFFILIATED_OTHER_USERS, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnAffiliatedDeviceOwnerSecondaryUser(), /* roleHolderUser= */ SYSTEM_USER)) 165 .put(APPLIED_BY_SYSTEM_DEVICE_OWNER | APPLIES_TO_AFFILIATED_OTHER_USERS | CAN_BE_DELEGATED, generateDelegateAnnotation(includeRunOnAffiliatedDeviceOwnerSecondaryUser(), /* isPrimary= */ true)) 166 167 .put(APPLIED_BY_SINGLE_DEVICE_OWNER | APPLIES_TO_OWN_USER, generateDevicePolicyManagerRoleHolderAnnotation( 168 includeRunOnSingleDeviceOwnerUser(), /* roleHolderUser= */ SECONDARY_USER)) 169 .put(APPLIED_BY_SINGLE_DEVICE_OWNER | APPLIES_TO_OWN_USER | CAN_BE_DELEGATED, 170 generateDelegateAnnotation( 171 includeRunOnSingleDeviceOwnerUser(), /* isPrimary= */ true)) 172 .put(APPLIED_BY_SINGLE_DEVICE_OWNER | APPLIES_TO_OWN_USER | APPLIES_IN_BACKGROUND, singleAnnotation(includeRunOnBackgroundDeviceOwnerUser())) 173 .put(APPLIED_BY_SINGLE_DEVICE_OWNER | APPLIES_TO_OWN_USER | APPLIES_IN_BACKGROUND | CAN_BE_DELEGATED, generateDelegateAnnotation(includeRunOnBackgroundDeviceOwnerUser(), /* isPrimary= */ true)) 174 175 .put(APPLIED_BY_DPM_ROLE_HOLDER | APPLIES_TO_OWN_USER, singleAnnotation(includeRunOnDevicePolicyManagementRoleHolderUser())) 176 .put(APPLIED_BY_DPM_ROLE_HOLDER | APPLIES_TO_UNAFFILIATED_OTHER_USERS, singleAnnotation(includeRunOnDevicePolicyManagementRoleHolderSecondaryUser())) 177 .put(APPLIED_BY_DPM_ROLE_HOLDER | APPLIES_TO_UNAFFILIATED_CHILD_PROFILES_WITHOUT_INHERITANCE, singleAnnotation(includeRunOnDevicePolicyManagementRoleHolderProfile())) 178 179 .put(APPLIED_BY_AFFILIATED_PROFILE_OWNER_USER | APPLIES_TO_OWN_USER, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnAffiliatedProfileOwnerAdditionalUser(), /* roleHolderUser= */ SECONDARY_USER)) 180 .put(APPLIED_BY_AFFILIATED_PROFILE_OWNER_USER | APPLIES_TO_OWN_USER | CAN_BE_DELEGATED, generateDelegateAnnotation(includeRunOnAffiliatedProfileOwnerAdditionalUser(), /* isPrimary= */ true)) 181 .put(APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_USER | APPLIES_TO_OWN_USER, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnUnaffiliatedProfileOwnerAdditionalUser(), /* roleHolderUser= */ SECONDARY_USER)) 182 .put(APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_USER | APPLIES_TO_OWN_USER | CAN_BE_DELEGATED, generateDelegateAnnotation(includeRunOnUnaffiliatedProfileOwnerAdditionalUser(), /* isPrimary= */ true)) 183 .put(APPLIED_BY_PROFILE_OWNER_USER_WITH_NO_DO | APPLIES_TO_OWN_USER, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnProfileOwnerPrimaryUser(), /* roleHolderUser= */ SYSTEM_USER)) 184 .put(APPLIED_BY_PROFILE_OWNER_USER_WITH_NO_DO | APPLIES_TO_OWN_USER | CAN_BE_DELEGATED, generateDelegateAnnotation(includeRunOnProfileOwnerPrimaryUser(), /* isPrimary= */ true)) 185 186 .put(APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_PROFILE | APPLIES_TO_OWN_USER, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnProfileOwnerProfileWithNoDeviceOwner(), /* roleHolderUser= */ WORK_PROFILE)) 187 .put(APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_PROFILE | APPLIES_TO_OWN_USER | CAN_BE_DELEGATED, generateDelegateAnnotation(includeRunOnProfileOwnerProfileWithNoDeviceOwner(), /* isPrimary= */ true)) 188 .put(APPLIED_BY_ORGANIZATION_OWNED_PROFILE_OWNER_PROFILE | APPLIES_TO_OWN_USER, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnOrganizationOwnedProfileOwner(), /* roleHolderUser= */ WORK_PROFILE)) 189 .put(APPLIED_BY_ORGANIZATION_OWNED_PROFILE_OWNER_PROFILE | APPLIES_TO_OWN_USER | CAN_BE_DELEGATED, generateDelegateAnnotation(includeRunOnOrganizationOwnedProfileOwner(), /* isPrimary= */ true)) 190 191 .put(APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_PROFILE | APPLIES_TO_PARENT, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnParentOfProfileOwnerWithNoDeviceOwner(), /* roleHolderUser= */ WORK_PROFILE)) 192 .put(APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_PROFILE | APPLIES_TO_PARENT | CAN_BE_DELEGATED, generateDelegateAnnotation(includeRunOnParentOfProfileOwnerWithNoDeviceOwner(), /* isPrimary= */ true)) 193 .put(APPLIED_BY_ORGANIZATION_OWNED_PROFILE_OWNER_PROFILE | APPLIES_TO_PARENT, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnParentOfOrganizationOwnedProfileOwner(), /* roleHolderUser= */ WORK_PROFILE)) 194 .put(APPLIED_BY_ORGANIZATION_OWNED_PROFILE_OWNER_PROFILE | APPLIES_TO_PARENT | CAN_BE_DELEGATED, generateDelegateAnnotation(includeRunOnParentOfOrganizationOwnedProfileOwner(), /* isPrimary= */ true)) 195 196 .put(APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_PROFILE | APPLIES_TO_UNAFFILIATED_OTHER_USERS, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnSecondaryUserInDifferentProfileGroupToProfileOwnerProfile(), /* roleHolderUser= */ WORK_PROFILE)) 197 .put(APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_PROFILE | APPLIES_TO_UNAFFILIATED_OTHER_USERS | CAN_BE_DELEGATED, generateDelegateAnnotation(includeRunOnSecondaryUserInDifferentProfileGroupToProfileOwnerProfile(), /* isPrimary= */ true)) 198 199 .put(APPLIED_BY_PARENT_INSTANCE_OF_ORGANIZATIONAL_OWNED_PROFILE_OWNER_PROFILE | APPLIES_TO_UNAFFILIATED_OTHER_USERS, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnSecondaryUserInDifferentProfileGroupToOrganizationOwnedProfileOwnerProfileUsingParentInstance(), /* roleHolderUser= */ WORK_PROFILE)) 200 201 // The model here is that APPLIED_BY_PARENT + APPLIES_TO_OWN_USER means it applies to the parent of the DPC - I'm not sure this is the best model (APPLIES_TO_PARENT would also be reasonable) 202 .put(APPLIED_BY_PARENT_INSTANCE_OF_NON_ORGANIZATIONAL_OWNED_PROFILE_OWNER_PROFILE 203 | APPLIES_TO_OWN_USER, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnParentOfProfileOwnerUsingParentInstance(), /* roleHolderUser= */ INITIAL_USER)) 204 .put(APPLIED_BY_PARENT_INSTANCE_OF_ORGANIZATIONAL_OWNED_PROFILE_OWNER_PROFILE | APPLIES_TO_OWN_USER, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnParentOfOrganizationOwnedProfileOwnerUsingParentInstance(), /* roleHolderUser= */ INITIAL_USER)) 205 206 .put(APPLIED_BY_FINANCED_DEVICE_OWNER | APPLIES_TO_OWN_USER, generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnFinancedDeviceOwnerUser(), /* roleHolderUser= */ SYSTEM_USER)) 207 208 .put(APPLIED_BY_PARENT_INSTANCE_OF_NON_ORGANIZATIONAL_OWNED_PROFILE_OWNER_PROFILE | APPLIES_TO_OWN_USER | INHERITABLE, multipleAnnotations(includeRunOnCloneProfileAlongsideManagedProfileUsingParentInstance(), includeRunOnPrivateProfileAlongsideManagedProfileUsingParentInstance())) 209 .put(APPLIED_BY_PARENT_INSTANCE_OF_ORGANIZATIONAL_OWNED_PROFILE_OWNER_PROFILE | APPLIES_TO_OWN_USER | INHERITABLE, multipleAnnotations(includeRunOnCloneProfileAlongsideOrganizationOwnedProfileUsingParentInstance(), includeRunOnPrivateProfileAlongsideOrganizationOwnedProfileUsingParentInstance())) 210 .put(APPLIED_BY_ORGANIZATION_OWNED_PROFILE_OWNER_PROFILE | APPLIES_TO_PARENT | INHERITABLE, multipleAnnotations(includeRunOnCloneProfileAlongsideOrganizationOwnedProfile(), includeRunOnPrivateProfileAlongsideOrganizationOwnedProfile())) 211 .put(APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_PROFILE | APPLIES_TO_PARENT | INHERITABLE, multipleAnnotations(includeRunOnCloneProfileAlongsideManagedProfile(), includeRunOnPrivateProfileAlongsideManagedProfile())) 212 .build(); 213 // This must contain one key for every APPLIED_BY that is being used, and maps to the 214 // "default" for testing that DPC type 215 // in general this will be a state which runs on the same user as the dpc. 216 // The key is the APPLIED_BY annotation and the value is a function which takes the policy and 217 // a boolean indicating if this is the "can set" state (if it is false - it must be the 218 // "cannot set" state). It should return a set of annotations to use. 219 private static final ImmutableMap<Integer, BiFunction<EnterprisePolicy, Boolean, Set<Annotation>>> 220 DPC_STATE_ANNOTATIONS_BASE = 221 ImmutableMap.<Integer, BiFunction<EnterprisePolicy, Boolean, Set<Annotation>>>builder() 222 .put(APPLIED_BY_SYSTEM_DEVICE_OWNER, (flags, canSet) -> hasFlag(flags.dpc(), APPLIED_BY_SYSTEM_DEVICE_OWNER | APPLIES_IN_BACKGROUND) ? generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnBackgroundDeviceOwnerUser(), /* roleHolderUser= */ SYSTEM_USER).apply(flags) : generateDevicePolicyManagerRoleHolderAnnotation( 223 includeRunOnSystemDeviceOwnerUser(), /* roleHolderUser= */ SYSTEM_USER).apply(flags)) 224 .put(APPLIED_BY_SINGLE_DEVICE_OWNER, (flags, canSet) -> hasFlag(flags.dpc(), APPLIED_BY_SINGLE_DEVICE_OWNER 225 | APPLIES_IN_BACKGROUND) ? generateDevicePolicyManagerRoleHolderAnnotation(includeRunOnBackgroundDeviceOwnerUser(), /* roleHolderUser= */ SECONDARY_USER).apply(flags) : generateDevicePolicyManagerRoleHolderAnnotation( 226 includeRunOnSingleDeviceOwnerUser(), /* roleHolderUser= */ SECONDARY_USER).apply(flags)) 227 .put(APPLIED_BY_AFFILIATED_PROFILE_OWNER, devicePolicyManagerRoleHolderIfCanSet(includeRunOnAffiliatedProfileOwnerAdditionalUser(), /* roleHolderUser= */ SECONDARY_USER)) 228 .put(APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_USER, devicePolicyManagerRoleHolderIfCanSet(includeRunOnProfileOwnerPrimaryUser(), /* roleHolderUser= */ SYSTEM_USER)) 229 .put(APPLIED_BY_PROFILE_OWNER_USER_WITH_NO_DO, devicePolicyManagerRoleHolderIfCanSet(includeRunOnProfileOwnerPrimaryUser(), /* roleHolderUser= */ SYSTEM_USER)) 230 .put(APPLIED_BY_ORGANIZATION_OWNED_PROFILE_OWNER_PROFILE, devicePolicyManagerRoleHolderIfCanSet(includeRunOnOrganizationOwnedProfileOwner(), /* roleHolderUser= */ WORK_PROFILE)) 231 .put(APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_PROFILE, devicePolicyManagerRoleHolderIfCanSet(includeRunOnProfileOwnerProfileWithNoDeviceOwner(), /* roleHolderUser= */ WORK_PROFILE)) 232 .put(APPLIED_BY_FINANCED_DEVICE_OWNER, devicePolicyManagerRoleHolderIfCanSet(includeRunOnFinancedDeviceOwnerUser(), /* roleHolderUser= */ SYSTEM_USER)) 233 .put(APPLIED_BY_PARENT_INSTANCE_OF_ORGANIZATIONAL_OWNED_PROFILE_OWNER_PROFILE, (flags, canSet) -> singleAnnotation(includeRunOnParentOfOrganizationOwnedProfileOwnerUsingParentInstance()).apply(flags)) 234 .put(APPLIED_BY_PARENT_INSTANCE_OF_NON_ORGANIZATIONAL_OWNED_PROFILE_OWNER_PROFILE, (flags, canSet) -> singleAnnotation(includeRunOnParentOfProfileOwnerUsingParentInstance()).apply(flags)) 235 .put(APPLIED_BY_DPM_ROLE_HOLDER, (flags, canSet) -> singleAnnotation(includeRunOnDevicePolicyManagementRoleHolderUser()).apply(flags)) 236 .build(); 237 devicePolicyManagerRoleHolderIfCanSet(Annotation annotation, UserType roleHolderUser)238 private static BiFunction<EnterprisePolicy, Boolean, Set<Annotation>> devicePolicyManagerRoleHolderIfCanSet(Annotation annotation, UserType roleHolderUser) { 239 return (flags, canSet) -> { 240 // If the policy already allows the DPM to set it - no need to add the special-cased test 241 if (canSet && (!hasFlag(flags.dpc(), APPLIED_BY_DPM_ROLE_HOLDER))) { 242 return generateDevicePolicyManagerRoleHolderAnnotation(annotation, roleHolderUser).apply(flags); 243 } else { 244 return singleAnnotation(annotation).apply(flags); 245 } 246 }; 247 } 248 private static final Map<Integer, BiFunction<EnterprisePolicy, Boolean, Set<Annotation>>> 249 DPC_STATE_ANNOTATIONS = DPC_STATE_ANNOTATIONS_BASE.entrySet().stream() 250 .collect(Collectors.toMap(Map.Entry::getKey, Policy::addGeneratedStates)); 251 private static final int APPLIED_BY_FLAGS = 252 APPLIED_BY_SYSTEM_DEVICE_OWNER | APPLIED_BY_SINGLE_DEVICE_OWNER 253 | APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_PROFILE 254 | APPLIED_BY_AFFILIATED_PROFILE_OWNER_PROFILE 255 | APPLIED_BY_UNAFFILIATED_PROFILE_OWNER_USER 256 | APPLIED_BY_AFFILIATED_PROFILE_OWNER_USER 257 | APPLIED_BY_FINANCED_DEVICE_OWNER 258 | APPLIED_BY_ORGANIZATION_OWNED_PROFILE_OWNER_PROFILE 259 | APPLIED_BY_PARENT_INSTANCE_OF_NON_ORGANIZATIONAL_OWNED_PROFILE_OWNER_PROFILE 260 | APPLIED_BY_PARENT_INSTANCE_OF_ORGANIZATIONAL_OWNED_PROFILE_OWNER_PROFILE 261 | APPLIED_BY_DPM_ROLE_HOLDER; 262 private static final Map<Function<EnterprisePolicy, Set<Annotation>>, Set<Integer>> 263 ANNOTATIONS_MAP = calculateAnnotationsMap(STATE_ANNOTATIONS); 264 265 private Policy() { 266 267 } 268 269 @AutoAnnotation 270 public static EnterprisePolicy enterprisePolicy(int[] dpc, Permission[] permissions, 271 AppOp[] appOps, String[] delegatedScopes) { 272 return new AutoAnnotation_Policy_enterprisePolicy( 273 dpc, permissions, appOps, delegatedScopes); 274 } 275 276 @AutoAnnotation 277 private static EnsureTestAppInstalled ensureTestAppInstalled( 278 String key, Query query, UserType onUser) { 279 return new AutoAnnotation_Policy_ensureTestAppInstalled( 280 key, query, onUser); 281 } 282 283 @AutoAnnotation 284 private static EnsureTestAppInstalledAsPrimaryDPC ensureTestAppInstalledAsPrimaryDPC( 285 String key, Query query, UserType onUser) { 286 return new AutoAnnotation_Policy_ensureTestAppInstalledAsPrimaryDPC( 287 key, query, onUser); 288 } 289 290 @AutoAnnotation 291 private static EnsureTestAppHasPermission ensureTestAppHasPermission( 292 String testAppKey, String[] value, FailureMode failureMode) { 293 return new AutoAnnotation_Policy_ensureTestAppHasPermission(testAppKey, value, failureMode); 294 } 295 296 @AutoAnnotation 297 private static EnsureTestAppDoesNotHavePermission ensureTestAppDoesNotHavePermission( 298 String testAppKey, String[] value, FailureMode failureMode) { 299 return new AutoAnnotation_Policy_ensureTestAppDoesNotHavePermission( 300 testAppKey, value, failureMode); 301 } 302 303 @AutoAnnotation 304 private static EnsureTestAppHasAppOp ensureTestAppHasAppOp(String testAppKey, String[] value) { 305 return new AutoAnnotation_Policy_ensureTestAppHasAppOp(testAppKey, value); 306 } 307 308 @AutoAnnotation 309 private static IncludeNone includeNone() { 310 return new AutoAnnotation_Policy_includeNone(); 311 } 312 313 @AutoAnnotation 314 public static IncludeRunOnSystemDeviceOwnerUser includeRunOnSystemDeviceOwnerUser() { 315 return new AutoAnnotation_Policy_includeRunOnSystemDeviceOwnerUser(); 316 } 317 318 @AutoAnnotation 319 public static IncludeRunOnSingleDeviceOwnerUser includeRunOnSingleDeviceOwnerUser() { 320 return new AutoAnnotation_Policy_includeRunOnSingleDeviceOwnerUser(); 321 } 322 323 @AutoAnnotation 324 private static IncludeRunOnUnaffiliatedDeviceOwnerSecondaryUser includeRunOnNonAffiliatedDeviceOwnerSecondaryUser() { 325 return new AutoAnnotation_Policy_includeRunOnNonAffiliatedDeviceOwnerSecondaryUser(); 326 } 327 328 @AutoAnnotation 329 public static IncludeRunOnAffiliatedDeviceOwnerSecondaryUser includeRunOnAffiliatedDeviceOwnerSecondaryUser() { 330 return new AutoAnnotation_Policy_includeRunOnAffiliatedDeviceOwnerSecondaryUser(); 331 } 332 333 @AutoAnnotation 334 public static IncludeRunOnAffiliatedProfileOwnerAdditionalUser includeRunOnAffiliatedProfileOwnerAdditionalUser() { 335 return new AutoAnnotation_Policy_includeRunOnAffiliatedProfileOwnerAdditionalUser(); 336 } 337 338 @AutoAnnotation 339 public static IncludeRunOnUnaffiliatedProfileOwnerAdditionalUser includeRunOnUnaffiliatedProfileOwnerAdditionalUser() { 340 return new AutoAnnotation_Policy_includeRunOnUnaffiliatedProfileOwnerAdditionalUser(); 341 } 342 343 @AutoAnnotation 344 public static IncludeRunOnProfileOwnerProfileWithNoDeviceOwner includeRunOnProfileOwnerProfileWithNoDeviceOwner() { 345 return new AutoAnnotation_Policy_includeRunOnProfileOwnerProfileWithNoDeviceOwner(); 346 } 347 348 @AutoAnnotation 349 private static IncludeRunOnSecondaryUserInDifferentProfileGroupToProfileOwnerProfile includeRunOnSecondaryUserInDifferentProfileGroupToProfileOwnerProfile() { 350 return new AutoAnnotation_Policy_includeRunOnSecondaryUserInDifferentProfileGroupToProfileOwnerProfile(); 351 } 352 353 @AutoAnnotation 354 public static IncludeRunOnSecondaryUserInDifferentProfileGroupToOrganizationOwnedProfileOwnerProfileUsingParentInstance includeRunOnSecondaryUserInDifferentProfileGroupToOrganizationOwnedProfileOwnerProfileUsingParentInstance() { 355 return new AutoAnnotation_Policy_includeRunOnSecondaryUserInDifferentProfileGroupToOrganizationOwnedProfileOwnerProfileUsingParentInstance(); 356 } 357 358 @AutoAnnotation 359 private static IncludeRunOnParentOfProfileOwnerWithNoDeviceOwner includeRunOnParentOfProfileOwnerWithNoDeviceOwner() { 360 return new AutoAnnotation_Policy_includeRunOnParentOfProfileOwnerWithNoDeviceOwner(); 361 } 362 363 @AutoAnnotation 364 private static IncludeRunOnOrganizationOwnedProfileOwner includeRunOnOrganizationOwnedProfileOwner() { 365 return new AutoAnnotation_Policy_includeRunOnOrganizationOwnedProfileOwner(); 366 } 367 368 @AutoAnnotation 369 public static IncludeRunOnParentOfOrganizationOwnedProfileOwner includeRunOnParentOfOrganizationOwnedProfileOwner() { 370 return new AutoAnnotation_Policy_includeRunOnParentOfOrganizationOwnedProfileOwner(); 371 } 372 373 @AutoAnnotation 374 public static IncludeRunOnProfileOwnerPrimaryUser includeRunOnProfileOwnerPrimaryUser() { 375 return new AutoAnnotation_Policy_includeRunOnProfileOwnerPrimaryUser(); 376 } 377 378 @AutoAnnotation 379 private static IncludeRunOnBackgroundDeviceOwnerUser includeRunOnBackgroundDeviceOwnerUser() { 380 return new AutoAnnotation_Policy_includeRunOnBackgroundDeviceOwnerUser(); 381 } 382 383 @AutoAnnotation 384 private static EnsureHasDelegate ensureHasDelegate(EnsureHasDelegate.AdminType admin, 385 String[] scopes, boolean isPrimary) { 386 return new AutoAnnotation_Policy_ensureHasDelegate(admin, scopes, isPrimary); 387 } 388 389 @AutoAnnotation 390 private static EnsureHasDevicePolicyManagerRoleHolder ensureHasDevicePolicyManagerRoleHolder( 391 UserType onUser, boolean isPrimary) { 392 return new AutoAnnotation_Policy_ensureHasDevicePolicyManagerRoleHolder(onUser, isPrimary); 393 } 394 395 @AutoAnnotation 396 private static IncludeRunOnParentOfProfileOwnerUsingParentInstance includeRunOnParentOfProfileOwnerUsingParentInstance() { 397 return new AutoAnnotation_Policy_includeRunOnParentOfProfileOwnerUsingParentInstance(); 398 } 399 400 @AutoAnnotation 401 public static IncludeRunOnParentOfOrganizationOwnedProfileOwnerUsingParentInstance includeRunOnParentOfOrganizationOwnedProfileOwnerUsingParentInstance() { 402 return new AutoAnnotation_Policy_includeRunOnParentOfOrganizationOwnedProfileOwnerUsingParentInstance(); 403 } 404 405 @AutoAnnotation 406 public static IncludeRunOnFinancedDeviceOwnerUser includeRunOnFinancedDeviceOwnerUser() { 407 return new AutoAnnotation_Policy_includeRunOnFinancedDeviceOwnerUser(); 408 } 409 410 @AutoAnnotation 411 private static IncludeRunOnCloneProfileAlongsideManagedProfileUsingParentInstance includeRunOnCloneProfileAlongsideManagedProfileUsingParentInstance() { 412 return new AutoAnnotation_Policy_includeRunOnCloneProfileAlongsideManagedProfileUsingParentInstance(); 413 } 414 415 @AutoAnnotation 416 private static IncludeRunOnCloneProfileAlongsideOrganizationOwnedProfileUsingParentInstance includeRunOnCloneProfileAlongsideOrganizationOwnedProfileUsingParentInstance() { 417 return new AutoAnnotation_Policy_includeRunOnCloneProfileAlongsideOrganizationOwnedProfileUsingParentInstance(); 418 } 419 420 @AutoAnnotation 421 private static IncludeRunOnCloneProfileAlongsideManagedProfile includeRunOnCloneProfileAlongsideManagedProfile() { 422 return new AutoAnnotation_Policy_includeRunOnCloneProfileAlongsideManagedProfile(); 423 } 424 425 @AutoAnnotation 426 public static IncludeRunOnCloneProfileAlongsideOrganizationOwnedProfile includeRunOnCloneProfileAlongsideOrganizationOwnedProfile() { 427 return new AutoAnnotation_Policy_includeRunOnCloneProfileAlongsideOrganizationOwnedProfile(); 428 } 429 430 @AutoAnnotation 431 private static IncludeRunOnPrivateProfileAlongsideManagedProfileUsingParentInstance includeRunOnPrivateProfileAlongsideManagedProfileUsingParentInstance() { 432 return new AutoAnnotation_Policy_includeRunOnPrivateProfileAlongsideManagedProfileUsingParentInstance(); 433 } 434 435 @AutoAnnotation 436 private static IncludeRunOnPrivateProfileAlongsideOrganizationOwnedProfileUsingParentInstance includeRunOnPrivateProfileAlongsideOrganizationOwnedProfileUsingParentInstance() { 437 return new AutoAnnotation_Policy_includeRunOnPrivateProfileAlongsideOrganizationOwnedProfileUsingParentInstance(); 438 } 439 440 @AutoAnnotation 441 private static IncludeRunOnPrivateProfileAlongsideManagedProfile includeRunOnPrivateProfileAlongsideManagedProfile() { 442 return new AutoAnnotation_Policy_includeRunOnPrivateProfileAlongsideManagedProfile(); 443 } 444 445 @AutoAnnotation 446 public static IncludeRunOnPrivateProfileAlongsideOrganizationOwnedProfile includeRunOnPrivateProfileAlongsideOrganizationOwnedProfile() { 447 return new AutoAnnotation_Policy_includeRunOnPrivateProfileAlongsideOrganizationOwnedProfile(); 448 } 449 450 @AutoAnnotation 451 private static IncludeRunOnDevicePolicyManagementRoleHolderProfile includeRunOnDevicePolicyManagementRoleHolderProfile() { 452 return new AutoAnnotation_Policy_includeRunOnDevicePolicyManagementRoleHolderProfile(); 453 } 454 455 @AutoAnnotation 456 private static IncludeRunOnDevicePolicyManagementRoleHolderUser includeRunOnDevicePolicyManagementRoleHolderUser() { 457 return new AutoAnnotation_Policy_includeRunOnDevicePolicyManagementRoleHolderUser(); 458 } 459 460 @AutoAnnotation 461 private static IncludeRunOnDevicePolicyManagementRoleHolderSecondaryUser includeRunOnDevicePolicyManagementRoleHolderSecondaryUser() { 462 return new AutoAnnotation_Policy_includeRunOnDevicePolicyManagementRoleHolderSecondaryUser(); 463 } 464 private static Function<EnterprisePolicy, Set<Annotation>> singleAnnotation( 465 Annotation annotation) { 466 return (i) -> ImmutableSet.of(annotation); 467 } 468 469 private static Function<EnterprisePolicy, Set<Annotation>> multipleAnnotations( 470 Annotation... annotations) { 471 return (i) -> ImmutableSet.copyOf(annotations); 472 } 473 474 private static Function<EnterprisePolicy, Set<Annotation>> generateDevicePolicyManagerRoleHolderAnnotation( 475 Annotation annotation, UserType roleHolderUser) { 476 return (policy) -> { 477 if (true) { 478 // Temporarily disabling enforcement of third-party coexistence 479 return ImmutableSet.of(annotation); 480 } 481 482 // If DPM role holder is handled elsewhere - we don't special case it here 483 if (hasFlag(policy.dpc(), CANNOT_BE_APPLIED_BY_ROLE_HOLDER) 484 || hasFlag(policy.dpc(), APPLIED_BY_DPM_ROLE_HOLDER)) { 485 return ImmutableSet.of(annotation); 486 } 487 Annotation[] existingAnnotations = annotation.annotationType().getAnnotations(); 488 Annotation[] newAnnotations = Arrays.copyOf(existingAnnotations, 489 existingAnnotations.length + 1); 490 newAnnotations[newAnnotations.length - 1] = ensureHasDevicePolicyManagerRoleHolder( 491 roleHolderUser, /* isPrimary= */ true); 492 return new HashSet<>(Arrays.asList(annotation, 493 new DynamicParameterizedAnnotation( 494 annotation.annotationType().getSimpleName() + "_DPMRH", 495 newAnnotations 496 ))); 497 }; 498 } 499 500 private static Function<EnterprisePolicy, Set<Annotation>> generateDelegateAnnotation( 501 Annotation annotation, boolean isPrimary) { 502 return (policy) -> { 503 Annotation[] existingAnnotations = filterAnnotations( 504 annotation.annotationType().getAnnotations(), EnsureHasNoDelegate.class); 505 return Arrays.stream(policy.delegatedScopes()) 506 .map(scope -> { 507 Annotation[] newAnnotations = Arrays.copyOf(existingAnnotations, 508 existingAnnotations.length + 1); 509 newAnnotations[newAnnotations.length - 1] = ensureHasDelegate( 510 EnsureHasDelegate.AdminType.PRIMARY, new String[]{scope}, 511 isPrimary); 512 513 return new DynamicParameterizedAnnotation( 514 annotation.annotationType().getSimpleName() + "Delegate_" + scope, 515 newAnnotations); 516 }).collect(Collectors.toSet()); 517 }; 518 } 519 520 private static Map<Function<EnterprisePolicy, Set<Annotation>>, Set<Integer>> calculateAnnotationsMap( 521 Map<Integer, Function<EnterprisePolicy, Set<Annotation>>> annotations) { 522 Map<Function<EnterprisePolicy, Set<Annotation>>, Set<Integer>> b = new HashMap<>(); 523 524 for (Map.Entry<Integer, Function<EnterprisePolicy, Set<Annotation>>> i : 525 annotations.entrySet()) { 526 if (!b.containsKey(i.getValue())) { 527 b.put(i.getValue(), new HashSet<>()); 528 } 529 530 b.get(i.getValue()).add(i.getKey()); 531 } 532 533 return b; 534 } 535 536 private static BiFunction<EnterprisePolicy, Boolean, Set<Annotation>> addGeneratedStates( 537 ImmutableMap.Entry<Integer, BiFunction<EnterprisePolicy, Boolean, Set<Annotation>>> entry) { 538 return (policy, canSet) -> { 539 if (hasFlag(policy.dpc(), entry.getKey() | CAN_BE_DELEGATED)) { 540 Set<Annotation> results = new HashSet<>(entry.getValue().apply(policy, canSet)); 541 results.addAll(results.stream().flatMap( 542 t -> generateDelegateAnnotation(t, /* isPrimary= */ true).apply( 543 policy).stream()) 544 .collect(Collectors.toSet())); 545 return results; 546 } 547 548 return entry.getValue().apply(policy, canSet); 549 }; 550 } 551 552 /** 553 * Get annotations that were derived against each passed in {@link EnterprisePolicy} 554 */ 555 public static Map<String, Set<Annotation>> getAnnotationsForPolicies( 556 List<EnterprisePolicyWrapper> enterprisePolicies) { 557 Map<String, Set<Annotation>> policyClassToAnnotationsMap = new HashMap<>(); 558 559 for (EnterprisePolicyWrapper enterprisePolicyWrapper : enterprisePolicies) { 560 EnterprisePolicy enterprisePolicyAnnotation = enterprisePolicy( 561 enterprisePolicyWrapper.dpc(), 562 enterprisePolicyWrapper.permissions(), 563 enterprisePolicyWrapper.appOps(), 564 enterprisePolicyWrapper.delegatedScopes()); 565 Set<Annotation> annotations = new HashSet<>(); 566 567 for (Map.Entry<Function<EnterprisePolicy, Set<Annotation>>, Set<Integer>> annotation : 568 ANNOTATIONS_MAP.entrySet()) { 569 if (policyWillApply(enterprisePolicyAnnotation.dpc(), annotation.getValue())) { 570 if (policyClassToAnnotationsMap.get( 571 enterprisePolicyWrapper.policyClass()) == null) { 572 annotations.addAll(annotation.getKey().apply(enterprisePolicyAnnotation)); 573 policyClassToAnnotationsMap.put( 574 enterprisePolicyWrapper.policyClass(), annotations); 575 } else { 576 policyClassToAnnotationsMap.get(enterprisePolicyWrapper.policyClass()) 577 .addAll(annotation.getKey().apply(enterprisePolicyAnnotation)); 578 } 579 } 580 } 581 } 582 583 return policyClassToAnnotationsMap; 584 } 585 586 /** 587 * Get {@link EnterprisePolicy} values along with the class it was annotated on 588 */ 589 public static List<EnterprisePolicyWrapper> getEnterprisePolicyWithCallingClass( 590 Class<?>[] policies) { 591 if (policies.length == 0) { 592 throw new IllegalStateException("Cannot get EnterprisePolicy for zero policy classes"); 593 } 594 595 List<EnterprisePolicyWrapper> enterprisePolicies = new ArrayList<>(); 596 597 for (Class<?> policy : policies) { 598 EnterprisePolicy enterprisePolicy = policy.getAnnotation(EnterprisePolicy.class); 599 if (enterprisePolicy == null) { 600 throw new IllegalStateException( 601 "Policy class must be annotated with EnterprisePolicy"); 602 } 603 604 Policy.validateFlags(policy.getName(), enterprisePolicy.dpc()); 605 606 enterprisePolicies.add( 607 new EnterprisePolicyWrapper( 608 policy.getName(), 609 enterprisePolicy.dpc(), 610 enterprisePolicy.permissions(), 611 enterprisePolicy.appOps(), 612 enterprisePolicy.delegatedScopes())); 613 } 614 615 return enterprisePolicies; 616 } 617 618 /** 619 * Get parameterized test runs for the given policy. 620 * 621 * <p>These are states which should be run where the policy is able to be applied. 622 */ 623 public static List<Annotation> policyAppliesStates(EnterprisePolicy enterprisePolicy) { 624 Set<Annotation> annotations = new HashSet<>(); 625 626 for (Map.Entry<Function<EnterprisePolicy, Set<Annotation>>, Set<Integer>> annotation : 627 ANNOTATIONS_MAP.entrySet()) { 628 if (policyWillApply(enterprisePolicy.dpc(), annotation.getValue())) { 629 annotations.addAll(annotation.getKey().apply(enterprisePolicy)); 630 } 631 } 632 633 for (AppOp appOp : enterprisePolicy.appOps()) { 634 // TODO(b/219750042): Currently we only test that app ops apply to the current user 635 Annotation[] withAppOpAnnotations = new Annotation[]{ 636 ensureTestAppInstalledAsPrimaryDPC(DELEGATE_KEY, queryBuilder() 637 .wherePackageName().isEqualTo(DELEGATE_PACKAGE_NAME) 638 .toAnnotation(), 639 INSTRUMENTED_USER), 640 ensureTestAppHasAppOp(DELEGATE_KEY, new String[]{appOp.appliedWith()}) 641 }; 642 annotations.add( 643 new DynamicParameterizedAnnotation( 644 "AppOp_" + appOp.appliedWith(), withAppOpAnnotations)); 645 } 646 647 for (Permission permission : enterprisePolicy.permissions()) { 648 // TODO(b/219750042): Currently we only test that permissions apply to the current user 649 Annotation[] withPermissionAnnotations = 650 new Annotation[] { 651 ensureTestAppInstalledAsPrimaryDPC( 652 DELEGATE_KEY, 653 queryBuilder() 654 .wherePackageName() 655 .isEqualTo(DELEGATE_PACKAGE_NAME) 656 .toAnnotation(), 657 INSTRUMENTED_USER), 658 ensureTestAppHasPermission( 659 DELEGATE_KEY, 660 new String[] {permission.appliedWith()}, 661 FailureMode.SKIP), 662 requireRootInstrumentation( 663 "Use of device policy permission", FailureMode.SKIP) 664 }; 665 annotations.add( 666 new DynamicParameterizedAnnotation( 667 "Permission_" + formatPermissionForTestName(permission.appliedWith()), 668 withPermissionAnnotations)); 669 } 670 671 removeShadowingAnnotations(annotations); 672 673 if (annotations.isEmpty()) { 674 // Don't run the original test unparameterized 675 annotations.add(includeNone()); 676 } 677 678 return new ArrayList<>(annotations); 679 } 680 681 private static boolean policyWillApply(int[] policyFlags, Set<Integer> annotationFlags) { 682 for (int annotationFlag : annotationFlags) { 683 if (hasFlag(policyFlags, annotationFlag)) { 684 return true; 685 } 686 } 687 return false; 688 } 689 690 private static boolean policyWillNotApply(int[] policyFlags, Set<Integer> annotationFlags) { 691 for (int annotationFlag : annotationFlags) { 692 if (hasFlag(annotationFlag, 693 DO_NOT_APPLY_TO_POLICY_DOES_NOT_APPLY_TESTS, /* nonMatchingFlag= */ NO)) { 694 return false; // We don't support using this annotation for PolicyDoesNotApply tests 695 } 696 697 int appliedByFlag = APPLIED_BY_FLAGS & annotationFlag; 698 int otherFlags = annotationFlag ^ appliedByFlag; // remove the appliedByFlag 699 if (hasFlag(policyFlags, /* matchingFlag= */ appliedByFlag, /* nonMatchingFlag= */ 700 otherFlags)) { 701 return true; 702 } 703 } 704 705 return false; 706 } 707 708 /** 709 * Get parameterized test runs for the given policy. 710 * 711 * <p>These are states which should be run where the policy is not able to be applied. 712 */ 713 public static List<Annotation> policyDoesNotApplyStates(EnterprisePolicy enterprisePolicy) { 714 Set<Annotation> annotations = new HashSet<>(); 715 716 for (Map.Entry<Function<EnterprisePolicy, Set<Annotation>>, Set<Integer>> annotation : 717 ANNOTATIONS_MAP.entrySet()) { 718 if (policyWillNotApply(enterprisePolicy.dpc(), annotation.getValue())) { 719 annotations.addAll(annotation.getKey().apply(enterprisePolicy)); 720 } 721 } 722 723 removeShadowedAnnotations(annotations); 724 725 if (annotations.isEmpty()) { 726 // Don't run the original test unparameterized 727 annotations.add(includeNone()); 728 } 729 730 return new ArrayList<>(annotations); 731 } 732 733 /** 734 * Get parameterized test runs where the policy cannot be set for the given policy. 735 */ 736 public static List<Annotation> cannotSetPolicyStates( 737 EnterprisePolicy enterprisePolicy, 738 boolean includeDeviceAdminStates, boolean includeNonDeviceAdminStates) { 739 740 Set<Annotation> annotations = new HashSet<>(); 741 if (includeDeviceAdminStates) { 742 int allFlags = 0; 743 for (int p : enterprisePolicy.dpc()) { 744 allFlags = allFlags | p; 745 } 746 747 for (Map.Entry<Integer, BiFunction<EnterprisePolicy, Boolean, Set<Annotation>>> appliedByFlag : 748 DPC_STATE_ANNOTATIONS.entrySet()) { 749 750 if ((appliedByFlag.getKey() 751 & APPLIED_BY_DPM_ROLE_HOLDER) == APPLIED_BY_DPM_ROLE_HOLDER) { 752 if (!includeNonDeviceAdminStates) { 753 // Temp fix to avoid random failing tests 754 continue; 755 } 756 } 757 758 if (hasFlag(appliedByFlag.getKey(), 759 DO_NOT_APPLY_TO_CANNOT_SET_POLICY_TESTS, /* nonMatchingFlag= */ NO)) { 760 continue; 761 } 762 763 if ((appliedByFlag.getKey() & allFlags) == 0) { 764 annotations.addAll(appliedByFlag.getValue().apply(enterprisePolicy, /* canSet= */ false)); 765 } 766 } 767 } 768 769 if (includeNonDeviceAdminStates) { 770 Set<String> validScopes = ImmutableSet.copyOf(enterprisePolicy.delegatedScopes()); 771 String[] scopes = ALL_DELEGATE_SCOPES.stream() 772 .filter(i -> !validScopes.contains(i)) 773 .toArray(String[]::new); 774 Annotation[] existingAnnotations = filterAnnotations( 775 IncludeRunOnSystemDeviceOwnerUser.class.getAnnotations(), EnsureHasNoDelegate.class); 776 777 String[] validPermissions = Arrays.stream(enterprisePolicy.permissions()) 778 .map(p -> p.appliedWith()).toArray(String[]::new); 779 780 if (BedsteadJUnit4.isDebug()) { 781 // Add a non-DPC with no delegate scopes 782 Annotation[] newAnnotations = Arrays.copyOf(existingAnnotations, 783 existingAnnotations.length + 2); 784 newAnnotations[newAnnotations.length - 2] = ensureHasDelegate( 785 EnsureHasDelegate.AdminType.PRIMARY, new String[]{}, 786 /* isPrimary= */ true); 787 newAnnotations[newAnnotations.length - 1] = ensureTestAppDoesNotHavePermission( 788 DELEGATE_KEY, validPermissions, FailureMode.SKIP); 789 annotations.add( 790 new DynamicParameterizedAnnotation("DelegateWithNoScopes", newAnnotations)); 791 792 for (String scope : scopes) { 793 newAnnotations = Arrays.copyOf(existingAnnotations, 794 existingAnnotations.length + 1); 795 newAnnotations[newAnnotations.length - 1] = ensureHasDelegate( 796 EnsureHasDelegate.AdminType.PRIMARY, new String[]{scope}, 797 /* isPrimary= */ true); 798 annotations.add( 799 new DynamicParameterizedAnnotation( 800 "DelegateWithScope:" + scope, newAnnotations)); 801 } 802 } else { 803 Annotation[] newAnnotations = Arrays.copyOf(existingAnnotations, 804 existingAnnotations.length + 2); 805 newAnnotations[newAnnotations.length - 2] = ensureHasDelegate( 806 EnsureHasDelegate.AdminType.PRIMARY, scopes, /* isPrimary= */ true); 807 // TODO: We should add @RequireRootInstrumentation if the permission is root-only 808 // - but we need to be able to determine that from the host 809 newAnnotations[newAnnotations.length - 1] = 810 ensureTestAppDoesNotHavePermission( 811 DELEGATE_KEY, validPermissions, FailureMode.SKIP); 812 annotations.add( 813 new DynamicParameterizedAnnotation("DelegateWithoutValidScope", 814 newAnnotations)); 815 } 816 } 817 818 removeShadowedAnnotations(annotations); 819 820 if (annotations.isEmpty()) { 821 // Don't run the original test unparameterized 822 annotations.add(includeNone()); 823 } 824 825 return new ArrayList<>(annotations); 826 } 827 828 /** Return {@code annotations} excluding any which are of type 829 * {@code filteredAnnotationClass}. */ 830 private static Annotation[] filterAnnotations(Annotation[] annotations, 831 Class<? extends Annotation> filteredAnnotationClass) { 832 return Arrays.stream(annotations).filter( 833 f -> !f.annotationType().equals(filteredAnnotationClass)) 834 .toArray(Annotation[]::new); 835 } 836 837 /** 838 * Get state annotations where the policy can be set for the given policy. 839 */ 840 public static List<Annotation> canSetPolicyStates( 841 EnterprisePolicy enterprisePolicy, boolean singleTestOnly) { 842 Set<Annotation> annotations = new HashSet<>(); 843 844 int allFlags = 0; 845 for (int p : enterprisePolicy.dpc()) { 846 allFlags = allFlags | p; 847 } 848 849 for (Map.Entry<Integer, BiFunction<EnterprisePolicy, Boolean, Set<Annotation>>> appliedByFlag : 850 DPC_STATE_ANNOTATIONS.entrySet()) { 851 if ((appliedByFlag.getKey() & allFlags) == appliedByFlag.getKey()) { 852 annotations.addAll(appliedByFlag.getValue().apply(enterprisePolicy, /* canSet= */ true)); 853 } 854 } 855 856 for (AppOp appOp : enterprisePolicy.appOps()) { 857 // TODO(b/219750042): Currently we only test that app ops can be set as the primary user 858 Annotation[] withAppOpAnnotations = new Annotation[]{ 859 ensureTestAppInstalledAsPrimaryDPC(DELEGATE_KEY, 860 queryBuilder() 861 .wherePackageName().isEqualTo(DELEGATE_PACKAGE_NAME) 862 .toAnnotation(), INSTRUMENTED_USER), 863 ensureTestAppHasAppOp(DELEGATE_KEY, new String[]{appOp.appliedWith()}) 864 }; 865 annotations.add( 866 new DynamicParameterizedAnnotation( 867 "AppOp_" + appOp.appliedWith(), withAppOpAnnotations)); 868 } 869 870 for (Permission permission : enterprisePolicy.permissions()) { 871 // TODO(b/219750042): Currently we only test that permissions can be set as the primary 872 // user 873 Annotation[] withPermissionAnnotations = 874 new Annotation[] { 875 ensureTestAppInstalledAsPrimaryDPC( 876 DELEGATE_KEY, 877 queryBuilder() 878 .wherePackageName() 879 .isEqualTo(DELEGATE_PACKAGE_NAME) 880 .toAnnotation(), 881 INSTRUMENTED_USER), 882 ensureTestAppHasPermission( 883 DELEGATE_KEY, 884 new String[] {permission.appliedWith()}, 885 FailureMode.SKIP), 886 requireRootInstrumentation( 887 "Use of device policy permission", FailureMode.SKIP) 888 }; 889 annotations.add( 890 new DynamicParameterizedAnnotation( 891 "Permission_" + formatPermissionForTestName(permission.appliedWith()), 892 withPermissionAnnotations)); 893 } 894 895 removeShadowingAnnotations(annotations); 896 897 if (annotations.isEmpty()) { 898 // Don't run the original test unparameterized 899 annotations.add(includeNone()); 900 } 901 902 List<Annotation> annotationList = new ArrayList<>(annotations); 903 904 if (singleTestOnly) { 905 // We select one annotation in an arbitrary but deterministic way 906 annotationList.sort(Comparator.comparing( 907 a -> a instanceof DynamicParameterizedAnnotation 908 ? "DynamicParameterizedAnnotation" : a.annotationType().getName())); 909 910 // We don't want a delegate to be the representative test 911 Annotation firstAnnotation = annotationList.stream() 912 .filter(i -> !(i instanceof DynamicParameterizedAnnotation)) 913 .findFirst().get(); 914 annotationList.clear(); 915 annotationList.add(firstAnnotation); 916 } 917 918 return annotationList; 919 } 920 921 /** Validate flags used by a DPC policy. */ 922 public static void validateFlags(String policyName, int[] values) { 923 int usedAppliedByFlags = 0; 924 925 for (int value : values) { 926 validateFlags(policyName, value); 927 int newUsedAppliedByFlags = usedAppliedByFlags | (value & APPLIED_BY_FLAGS); 928 if (newUsedAppliedByFlags == usedAppliedByFlags) { 929 throw new IllegalStateException( 930 "Cannot have more than one policy flag APPLIED by the same component. " 931 + "Error in policy " + policyName); 932 } 933 usedAppliedByFlags = newUsedAppliedByFlags; 934 } 935 } 936 937 private static void validateFlags(String policyName, int value) { 938 int matchingAppliedByFlags = APPLIED_BY_FLAGS & value; 939 940 if (matchingAppliedByFlags == 0) { 941 throw new IllegalStateException( 942 "All policy flags must specify 1 APPLIED_BY flag. Policy " + policyName 943 + " did not."); 944 } 945 } 946 947 private static boolean hasFlag(int[] values, int matchingFlag) { 948 return hasFlag(values, matchingFlag, /* nonMatchingFlag= */ NO); 949 } 950 951 private static boolean hasFlag(int[] values, int matchingFlag, int nonMatchingFlag) { 952 for (int value : values) { 953 if (hasFlag(value, matchingFlag, nonMatchingFlag)) { 954 return true; 955 } 956 } 957 return false; 958 } 959 960 private static boolean hasFlag(int value, int matchingFlag, int nonMatchingFlag) { 961 if (!((value & matchingFlag) == matchingFlag)) { 962 return false; 963 } 964 965 if (nonMatchingFlag != NO) { 966 return (value & nonMatchingFlag) != nonMatchingFlag; 967 } 968 969 return true; 970 } 971 972 /** 973 * Remove entries from {@code annotations} which are shadowed by another entry 974 * in {@code annotations} (directly or indirectly). 975 */ 976 private static void removeShadowedAnnotations(Set<Annotation> annotations) { 977 Set<Class<? extends Annotation>> shadowedAnnotations = new HashSet<>(); 978 for (Annotation annotation : annotations) { 979 if (annotation instanceof DynamicParameterizedAnnotation) { 980 continue; // Doesn't shadow anything 981 } 982 983 ParameterizedAnnotation parameterizedAnnotation = 984 annotation.annotationType().getAnnotation(ParameterizedAnnotation.class); 985 986 if (parameterizedAnnotation == null) { 987 continue; // Not parameterized 988 } 989 990 for (Class<? extends Annotation> shadowedAnnotationClass 991 : parameterizedAnnotation.shadows()) { 992 addShadowed(shadowedAnnotations, shadowedAnnotationClass); 993 } 994 } 995 annotations.removeIf(a -> shadowedAnnotations.contains(a.annotationType())); 996 } 997 998 private static void addShadowed(Set<Class<? extends Annotation>> shadowedAnnotations, 999 Class<? extends Annotation> annotationClass) { 1000 shadowedAnnotations.add(annotationClass); 1001 ParameterizedAnnotation parameterizedAnnotation = 1002 annotationClass.getAnnotation(ParameterizedAnnotation.class); 1003 1004 if (parameterizedAnnotation == null) { 1005 return; 1006 } 1007 1008 for (Class<? extends Annotation> shadowedAnnotationClass 1009 : parameterizedAnnotation.shadows()) { 1010 addShadowed(shadowedAnnotations, shadowedAnnotationClass); 1011 } 1012 } 1013 1014 // This maps classes to classes which shadow them - we just need to ensure it contains all 1015 // annotation classes we encounter 1016 private static Map<Class<? extends Annotation>, Set<Class<? extends Annotation>>> 1017 sReverseShadowMap = new HashMap<>(); 1018 1019 /** 1020 * Remove entries from {@code annotations} which are shadowing another entry 1021 * in {@code annotatipns} (directly or indirectly). 1022 */ 1023 private static void removeShadowingAnnotations(Set<Annotation> annotations) { 1024 for (Annotation annotation : annotations) { 1025 recordInReverseShadowMap(annotation); 1026 } 1027 1028 Set<Class<? extends Annotation>> shadowingAnnotations = new HashSet<>(); 1029 1030 for (Annotation annotation : annotations) { 1031 shadowingAnnotations.addAll( 1032 sReverseShadowMap.getOrDefault(annotation.annotationType(), new HashSet<>())); 1033 } 1034 1035 annotations.removeIf(a -> shadowingAnnotations.contains(a.annotationType())); 1036 } 1037 1038 private static void recordInReverseShadowMap(Annotation annotation) { 1039 if (annotation instanceof DynamicParameterizedAnnotation) { 1040 return; // Not shadowed by anything 1041 } 1042 1043 ParameterizedAnnotation parameterizedAnnotation = 1044 annotation.annotationType().getAnnotation(ParameterizedAnnotation.class); 1045 1046 if (parameterizedAnnotation == null) { 1047 return; // Not parameterized 1048 } 1049 1050 if (parameterizedAnnotation.shadows().length == 0) { 1051 return; // Doesn't shadow anything 1052 } 1053 1054 recordShadowedInReverseShadowMap(annotation.annotationType(), parameterizedAnnotation); 1055 } 1056 1057 private static void recordShadowedInReverseShadowMap(Class<? extends Annotation> annotation, 1058 ParameterizedAnnotation parameterizedAnnotation) { 1059 for (Class<? extends Annotation> shadowedAnnotation : parameterizedAnnotation.shadows()) { 1060 ParameterizedAnnotation shadowedParameterizedAnnotation = 1061 shadowedAnnotation.getAnnotation(ParameterizedAnnotation.class); 1062 1063 if (shadowedParameterizedAnnotation == null) { 1064 continue; // Not parameterized 1065 } 1066 1067 if (!sReverseShadowMap.containsKey(shadowedAnnotation)) { 1068 sReverseShadowMap.put(shadowedAnnotation, new HashSet<>()); 1069 } 1070 1071 sReverseShadowMap.get(shadowedAnnotation).add(annotation); 1072 1073 recordShadowedInReverseShadowMap(annotation, shadowedParameterizedAnnotation); 1074 } 1075 } 1076 1077 private static String formatPermissionForTestName(String permission) { 1078 if (permission.startsWith("android.permission.")) { 1079 return permission.substring(19); 1080 } 1081 return permission; 1082 } 1083 } 1084