1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.android.bedstead.enterprise.annotations
18
19 import com.android.bedstead.harrier.HarrierRule
20 import com.android.bedstead.harrier.UserType
21 import com.android.bedstead.harrier.UserType.INITIAL_USER
22 import com.android.bedstead.harrier.annotations.AnnotationPriorityRunPrecedence.REQUIRE_RUN_ON_PRECEDENCE
23 import com.android.bedstead.harrier.annotations.RequireFeature
24 import com.android.bedstead.harrier.annotations.UsesAnnotationExecutor
25 import com.android.bedstead.nene.types.OptionalBoolean
26 import com.android.bedstead.nene.types.OptionalBoolean.ANY
27 import com.android.bedstead.nene.types.OptionalBoolean.FALSE
28 import com.android.queryable.annotations.Query
29 import com.google.auto.value.AutoAnnotation
30
31 /**
32 * Mark that a test method should run on a user which has a work profile.
33 *
34 * Use of this annotation implies
35 * [RequireFeature("android.software.managed_users", SKIP)].
36 *
37 * Your test configuration may be configured so that this test is only run on a user which has
38 * a work profile. Otherwise, you can use [DeviceState] to ensure that the device enters
39 * the correct state for the method.
40 *
41 * @param forUser Which user type the work profile should be attached to.
42 * @param installInstrumentedApp Whether the instrumented test app should be installed in the work profile.
43 * @param dpcKey The key used to identify the profile owner.
44 * This can be used with [AdditionalQueryParameters] to modify the requirements for
45 * the DPC.
46 * @param dpc Requirements for the Profile Owner. Defaults to the default version of RemoteDPC.
47 * @param dpcIsPrimary Whether the profile owner's DPC should be returned by calls to [DeviceState#dpc()].
48 * Only one device policy controller per test should be marked as primary.
49 * @param isOrganizationOwned Whether the work profile device will be in COPE mode.
50 * @param useParentInstanceOfDpc If true, uses the [DevicePolicyManager#getParentProfileInstance(ComponentName)]
51 * instance of the dpc when calling to .dpc(). Only used if [dpcIsPrimary] is true.
52 * @param switchedToParentUser Should we ensure that we are switched to the parent of the profile.
53 * @param isQuietModeEnabled Is the profile in quiet mode?
54 * @param priority Priority sets the order that annotations will be resolved.
55 * Annotations with a lower priority will be resolved before annotations with a higher
56 * priority.
57 *
58 * If there is an order requirement between annotations, ensure that the priority of the
59 * annotation which must be resolved first is lower than the one which must be resolved later.
60 *
61 * Priority can be set to a [AnnotationPriorityRunPrecedence] constant, or to any [int].
62 */
63 @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE)
64 @Retention(AnnotationRetention.RUNTIME)
65 @RequireFeature("android.software.managed_users")
66 @EnsureHasNoDeviceOwner // TODO: This should only apply on Android R+
67 @UsesAnnotationExecutor(UsesAnnotationExecutor.ENTERPRISE)
68 annotation class EnsureHasWorkProfile(
69 val forUser: UserType = INITIAL_USER,
70 val installInstrumentedApp: OptionalBoolean = ANY,
71 val dpcKey: String = DEFAULT_DPC_KEY,
72 val dpc: Query = Query(),
73 val dpcIsPrimary: Boolean = false,
74 val isOrganizationOwned: Boolean = false,
75 val useParentInstanceOfDpc: Boolean = false,
76 val switchedToParentUser: OptionalBoolean = ANY,
77 val isQuietModeEnabled: OptionalBoolean = FALSE,
78 val priority: Int = ENSURE_HAS_WORK_PROFILE_PRIORITY
79 ) {
80 companion object {
81 const val PROFILE_TYPE = "android.os.usertype.profile.MANAGED"
82 }
83 }
84
85 const val ENSURE_HAS_WORK_PROFILE_PRIORITY = REQUIRE_RUN_ON_PRECEDENCE - 1
86
87 const val DEFAULT_DPC_KEY = "profileOwner"
88
89 /**
90 * Return an instance of the generated class that conforms to the specification of
91 * [EnsureHasWorkProfile]. See [AutoAnnotation].
92 */
ensureHasWorkProfilenull93 fun ensureHasWorkProfile(): EnsureHasWorkProfile {
94 return ensureHasWorkProfile(query())
95 }
96
97 @AutoAnnotation
ensureHasWorkProfilenull98 private fun ensureHasWorkProfile(dpc: Query): EnsureHasWorkProfile {
99 return AutoAnnotation_EnsureHasWorkProfileKt_ensureHasWorkProfile(dpc)
100 }
101
102 /**
103 * A workaround to create an [AutoAnnotation] of [EnsureHasWorkProfile]. [AutoAnnotation]
104 * cannot set default values for fields of type Annotation, hence we create an object of [Query]
105 * explicitly to pass as the default value of the [dpc] field.
106 */
querynull107 private fun query(): Query {
108 return HarrierRule::class.java.getAnnotation(Query::class.java)!!
109 }
110