• 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 package com.google.jetpackcamera
17 
18 import android.os.Build
19 import androidx.compose.ui.test.isDisplayed
20 import androidx.compose.ui.test.isEnabled
21 import androidx.compose.ui.test.junit4.createEmptyComposeRule
22 import androidx.compose.ui.test.onNodeWithTag
23 import androidx.compose.ui.test.performClick
24 import androidx.test.ext.junit.runners.AndroidJUnit4
25 import androidx.test.platform.app.InstrumentationRegistry
26 import androidx.test.rule.GrantPermissionRule
27 import androidx.test.uiautomator.UiDevice
28 import com.google.common.truth.Truth.assertThat
29 import com.google.common.truth.TruthJUnit.assume
30 import com.google.jetpackcamera.feature.preview.quicksettings.ui.QUICK_SETTINGS_DROP_DOWN
31 import com.google.jetpackcamera.feature.preview.quicksettings.ui.QUICK_SETTINGS_FLASH_BUTTON
32 import com.google.jetpackcamera.feature.preview.ui.CAPTURE_BUTTON
33 import com.google.jetpackcamera.feature.preview.ui.FLIP_CAMERA_BUTTON
34 import com.google.jetpackcamera.feature.preview.ui.IMAGE_CAPTURE_SUCCESS_TAG
35 import com.google.jetpackcamera.feature.preview.ui.SCREEN_FLASH_OVERLAY
36 import com.google.jetpackcamera.settings.model.LensFacing
37 import org.junit.Before
38 import org.junit.Rule
39 import org.junit.Test
40 import org.junit.runner.RunWith
41 
42 @RunWith(AndroidJUnit4::class)
43 internal class FlashDeviceTest {
44 
45     @get:Rule
46     val permissionsRule: GrantPermissionRule =
47         GrantPermissionRule.grant(*(APP_REQUIRED_PERMISSIONS).toTypedArray())
48 
49     @get:Rule
50     val composeTestRule = createEmptyComposeRule()
51 
52     private val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
53 
54     @Before
setUpnull55     fun setUp() {
56         assertThat(uiDevice.isScreenOn).isTrue()
57     }
58 
59     @Test
<lambda>null60     fun set_flash_on() = runScenarioTest<MainActivity> {
61         // Wait for the capture button to be displayed
62         composeTestRule.waitUntil(timeoutMillis = APP_START_TIMEOUT_MILLIS) {
63             composeTestRule.onNodeWithTag(CAPTURE_BUTTON).isDisplayed()
64         }
65 
66         // Navigate to quick settings
67         composeTestRule.onNodeWithTag(QUICK_SETTINGS_DROP_DOWN)
68             .assertExists()
69             .performClick()
70 
71         // Click the flash button to switch to ON
72         composeTestRule.onNodeWithTag(QUICK_SETTINGS_FLASH_BUTTON)
73             .assertExists()
74             .performClick()
75 
76         composeTestRule.onNodeWithTag(QUICK_SETTINGS_FLASH_BUTTON)
77             .assertExists()
78         composeTestRule.onNodeWithContentDescription(
79             com.google.jetpackcamera.feature.preview.R.string.quick_settings_flash_on_description
80         )
81     }
82 
83     @Test
<lambda>null84     fun set_flash_auto() = runScenarioTest<MainActivity> {
85         // Wait for the capture button to be displayed
86         composeTestRule.waitUntil(timeoutMillis = APP_START_TIMEOUT_MILLIS) {
87             composeTestRule.onNodeWithTag(CAPTURE_BUTTON).isDisplayed()
88         }
89 
90         // Navigate to quick settings
91         composeTestRule.onNodeWithTag(QUICK_SETTINGS_DROP_DOWN)
92             .assertExists()
93             .performClick()
94 
95         // Click the flash button twice to switch to AUTO
96         composeTestRule.onNodeWithTag(QUICK_SETTINGS_FLASH_BUTTON)
97             .assertExists()
98             .performClick()
99             .performClick()
100 
101         composeTestRule.onNodeWithContentDescription(
102             com.google.jetpackcamera.feature.preview.R.string.quick_settings_flash_auto_description
103         )
104     }
105 
106     @Test
<lambda>null107     fun set_flash_off() = runScenarioTest<MainActivity> {
108         // Wait for the capture button to be displayed
109         composeTestRule.waitUntil(timeoutMillis = APP_START_TIMEOUT_MILLIS) {
110             composeTestRule.onNodeWithTag(CAPTURE_BUTTON).isDisplayed()
111         }
112 
113         composeTestRule.onNodeWithContentDescription(
114             com.google.jetpackcamera.feature.preview.R.string.quick_settings_flash_off_description
115         )
116 
117         // Navigate to quick settings
118         composeTestRule.onNodeWithTag(QUICK_SETTINGS_DROP_DOWN)
119             .assertExists()
120             .performClick()
121 
122         // Click the flash button three times to switch to OFF
123         composeTestRule.onNodeWithTag(QUICK_SETTINGS_FLASH_BUTTON)
124             .assertExists()
125             .performClick()
126             .performClick()
127             .performClick()
128 
129         composeTestRule.onNodeWithContentDescription(
130             com.google.jetpackcamera.feature.preview.R.string.quick_settings_flash_off_description
131         )
132     }
133 
assumeHalStableOnImageCapturenull134     private fun assumeHalStableOnImageCapture() {
135         // The GMD emulators with API <=31 will often crash the HAL when taking an image capture.
136         // See b/195122056
137         assume().that(Build.HARDWARE == "ranchu" && Build.VERSION.SDK_INT <= 31).isFalse()
138     }
139 
140     @Test
<lambda>null141     fun set_flash_and_capture_successfully() = runScenarioTest<MainActivity> {
142         // Skip test on unstable devices
143         assumeHalStableOnImageCapture()
144 
145         // Wait for the capture button to be displayed
146         composeTestRule.waitUntil(timeoutMillis = APP_START_TIMEOUT_MILLIS) {
147             composeTestRule.onNodeWithTag(CAPTURE_BUTTON).isDisplayed()
148         }
149 
150         // Ensure camera has a back camera and flip to it
151         val lensFacing = composeTestRule.getCurrentLensFacing()
152         if (lensFacing != LensFacing.BACK) {
153             composeTestRule.onNodeWithTag(FLIP_CAMERA_BUTTON).assume(isEnabled()) {
154                 "Device does not have a back camera to flip to."
155             }.performClick()
156         }
157 
158         // Navigate to quick settings
159         composeTestRule.onNodeWithTag(QUICK_SETTINGS_DROP_DOWN)
160             .assertExists()
161             .performClick()
162 
163         // Click the flash button to switch to ON
164         composeTestRule.onNodeWithTag(QUICK_SETTINGS_FLASH_BUTTON)
165             .assertExists()
166             .performClick()
167 
168         // Exit quick settings
169         composeTestRule.onNodeWithTag(QUICK_SETTINGS_DROP_DOWN)
170             .assertExists()
171             .performClick()
172 
173         composeTestRule.onNodeWithTag(CAPTURE_BUTTON)
174             .assertExists()
175             .performClick()
176 
177         composeTestRule.waitUntil(timeoutMillis = IMAGE_CAPTURE_TIMEOUT_MILLIS) {
178             composeTestRule.onNodeWithTag(IMAGE_CAPTURE_SUCCESS_TAG).isDisplayed()
179         }
180     }
181 
182     @Test
set_screen_flash_and_capture_with_screen_change_overlay_shownnull183     fun set_screen_flash_and_capture_with_screen_change_overlay_shown() =
184         runScenarioTest<MainActivity> {
185             // Wait for the capture button to be displayed
186             composeTestRule.waitUntil(timeoutMillis = APP_START_TIMEOUT_MILLIS) {
187                 composeTestRule.onNodeWithTag(CAPTURE_BUTTON).isDisplayed()
188             }
189 
190             // Ensure camera has a front camera and flip to it
191             val lensFacing = composeTestRule.getCurrentLensFacing()
192             if (lensFacing != LensFacing.FRONT) {
193                 composeTestRule.onNodeWithTag(FLIP_CAMERA_BUTTON).assume(isEnabled()) {
194                     "Device does not have a front camera to flip to."
195                 }.performClick()
196             }
197 
198             // Navigate to quick settings
199             composeTestRule.onNodeWithTag(QUICK_SETTINGS_DROP_DOWN)
200                 .assertExists()
201                 .performClick()
202 
203             // Click the flash button to switch to ON
204             composeTestRule.onNodeWithTag(QUICK_SETTINGS_FLASH_BUTTON)
205                 .assertExists()
206                 .performClick()
207 
208             // Exit quick settings
209             composeTestRule.onNodeWithTag(QUICK_SETTINGS_DROP_DOWN)
210                 .assertExists()
211                 .performClick()
212 
213             // Perform a capture to enable screen flash
214             composeTestRule.onNodeWithTag(CAPTURE_BUTTON)
215                 .assertExists()
216                 .performClick()
217 
218             composeTestRule.waitUntil(timeoutMillis = IMAGE_CAPTURE_TIMEOUT_MILLIS) {
219                 composeTestRule.onNodeWithTag(SCREEN_FLASH_OVERLAY).isDisplayed()
220             }
221         }
222 }
223