• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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