1 /*
2  * Copyright 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 androidx.camera.testing.impl
18 
19 import android.util.Log
20 import androidx.camera.core.CameraSelector
21 import androidx.camera.testing.impl.LabTestRule.LabTestFrontCamera
22 import androidx.camera.testing.impl.LabTestRule.LabTestOnly
23 import androidx.camera.testing.impl.LabTestRule.LabTestRearCamera
24 import org.junit.Assume.assumeTrue
25 import org.junit.rules.TestRule
26 import org.junit.runner.Description
27 import org.junit.runners.model.Statement
28 
29 /**
30  * A [TestRule] which can be used to limit the test only run in the CameraX lab environment. It
31  * throws the AssumptionViolatedException to ignore the test if the test environment is not in the
32  * lab. Useful for the tests not needed to run on the PostSubmit.
33  *
34  * To use this [TestRule], do the following. Add the Rule to your JUnit test:
35  * ```
36  * @get:Rule
37  * val labTestRule = LabTestRule()
38  * ```
39  *
40  * Add only one of [LabTestOnly], [LabTestFrontCamera] or, [LabTestRearCamera] annotation to your
41  * test case like:
42  * ```
43  *  @LabTestOnly
44  *  fun yourTestCase() {
45  *
46  *  }
47  * ```
48  *
49  * To local run the test with the [LabTestOnly] annotation, please run the following command on the
50  * DUT:
51  * ```
52  * adb shell setprop log.tag.MH DEBUG
53  * ```
54  *
55  * [LabTestFrontCamera] and [LabTestRearCamera] can be tested on local DUT with the following debug
56  * options:
57  * ```
58  * adb shell setprop log.tag.frontCameraE2E DEBUG
59  * adb shell setprop log.tag.rearCameraE2E DEBUG
60  * ```
61  */
62 public class LabTestRule : TestRule {
63 
64     /**
65      * The annotation for tests that only want to run on the CameraX lab environment. Local device
66      * testing will ignore the tests with this annotation. Please reference the doc of [LabTestRule]
67      * to test on local devices.
68      */
69     @Target(AnnotationTarget.FUNCTION)
70     @Retention(AnnotationRetention.RUNTIME)
71     public annotation class LabTestOnly()
72 
73     /**
74      * The annotation for tests that only want to run on the CameraX lab environment with enabling
75      * front camera. Local device testing will ignore the tests with this annotation. Please
76      * reference the doc of [LabTestRule] to test on local devices.
77      */
78     @Target(AnnotationTarget.FUNCTION)
79     @Retention(AnnotationRetention.RUNTIME)
80     public annotation class LabTestFrontCamera()
81 
82     /**
83      * The annotation for tests that only want to run on the CameraX lab environment with enabling
84      * rear camera. Local device testing will ignore the tests with this annotation. Please
85      * reference the doc of [LabTestRule] to test on local devices.
86      */
87     @Target(AnnotationTarget.FUNCTION)
88     @Retention(AnnotationRetention.RUNTIME)
89     public annotation class LabTestRearCamera()
90 
91     public class LabTestStatement(private val statement: Statement) : Statement() {
92 
93         @Throws(Throwable::class)
evaluatenull94         override fun evaluate() {
95             // Only test in CameraX lab environment and throw AssumptionViolatedException if not
96             // in the lab environment. The loggable tag will be set when running the CameraX
97             // daily testing.
98             assumeTrue(isInLabTest())
99             statement.evaluate()
100         }
101     }
102 
103     public class LabTestFrontCameraStatement(private val statement: Statement) : Statement() {
104 
105         @Throws(Throwable::class)
evaluatenull106         override fun evaluate() {
107             // Only test in CameraX lab environment and the loggable tag will be set when running
108             // the CameraX e2e test with enabling front camera.
109             assumeTrue(Log.isLoggable("frontCameraE2E", Log.DEBUG))
110             statement.evaluate()
111         }
112     }
113 
114     public class LabTestRearCameraStatement(private val statement: Statement) : Statement() {
115 
116         @Throws(Throwable::class)
evaluatenull117         override fun evaluate() {
118             // Only test in CameraX lab environment and the loggable tag will be set when running
119             // the CameraX e2e test with enabling rear camera.
120             assumeTrue(Log.isLoggable("rearCameraE2E", Log.DEBUG))
121             statement.evaluate()
122         }
123     }
124 
applynull125     override fun apply(base: Statement, description: Description): Statement {
126 
127         return if (description.getAnnotation(LabTestOnly::class.java) != null) {
128             LabTestStatement(base)
129         } else if (description.getAnnotation(LabTestFrontCamera::class.java) != null) {
130             LabTestFrontCameraStatement(base)
131         } else if (description.getAnnotation(LabTestRearCamera::class.java) != null) {
132             LabTestRearCameraStatement(base)
133         } else {
134             base
135         }
136     }
137 
138     public companion object {
139         @JvmStatic
isInLabTestnull140         public fun isInLabTest(): Boolean {
141             return Log.isLoggable("MH", Log.DEBUG)
142         }
143 
144         /**
145          * Checks if it is CameraX lab environment where the enabled camera uses the specified
146          * [lensFacing] direction.
147          *
148          * For example, if [lensFacing] is [CameraSelector.LENS_FACING_BACK], this method will
149          * return true if the rear camera is enabled on a device in CameraX lab environment.
150          *
151          * @param lensFacing the required camera direction relative to the device screen.
152          * @return if enabled camera is in same direction as [lensFacing] in CameraX lab environment
153          */
154         @JvmStatic
isLensFacingEnabledInLabTestnull155         public fun isLensFacingEnabledInLabTest(
156             @CameraSelector.LensFacing lensFacing: Int
157         ): Boolean =
158             when (lensFacing) {
159                 CameraSelector.LENS_FACING_BACK -> Log.isLoggable("rearCameraE2E", Log.DEBUG)
160                 CameraSelector.LENS_FACING_FRONT -> Log.isLoggable("frontCameraE2E", Log.DEBUG)
161                 else -> false
162             }
163     }
164 }
165