Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ dependencies {
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(libs.androidx.rules)
androidTestImplementation(libs.androidx.uiautomator)
androidTestImplementation(libs.camera.lifecycle) // to reset CameraX between tests
androidTestImplementation(libs.truth)
androidTestImplementation(project(":ui:components:capture"))
androidTestUtil(libs.androidx.orchestrator)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import com.google.common.truth.TruthJUnit.assume
import com.google.jetpackcamera.ui.components.capture.FLIP_CAMERA_BUTTON
import com.google.jetpackcamera.utils.CameraXResetRule
import com.google.jetpackcamera.utils.TEST_REQUIRED_PERMISSIONS
import com.google.jetpackcamera.utils.isEmulatorWithFakeFrontCamera
import com.google.jetpackcamera.utils.runMainActivityScenarioTest
Expand All @@ -35,6 +36,9 @@ import org.junit.runners.Parameterized

@RunWith(Parameterized::class)
class SingleLensModeTest(private val lensFacing: String) {
@get:Rule
val cameraXResetRule = CameraXResetRule()

@get:Rule
val permissionsRule: GrantPermissionRule =
GrantPermissionRule.grant(*(TEST_REQUIRED_PERMISSIONS).toTypedArray())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,53 @@ import android.os.Environment
import android.provider.BaseColumns
import android.provider.MediaStore
import android.util.Log
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.test.platform.app.InstrumentationRegistry
import java.io.File
import java.util.concurrent.TimeUnit
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.transform
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement

private const val TAG = "AppTestUtil"
private const val CAMERAX_RESET_TIMEOUT_SECONDS = 10L

/**
* A [TestRule] that resets CameraX before each test.
*
* This is useful for tests that need to configure CameraX (e.g. using
* [ProcessCameraProvider.configureInstance]), which can only be done once per process.
*/
class CameraXResetRule : TestRule {
override fun apply(base: Statement, description: Description): Statement {
return object : Statement() {
override fun evaluate() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
initializeAndShutdown(context)
try {
base.evaluate()
} finally {
initializeAndShutdown(context)
}
}
}
}

private fun initializeAndShutdown(context: android.content.Context) {
try {
ProcessCameraProvider.getInstance(context)
.get(CAMERAX_RESET_TIMEOUT_SECONDS, TimeUnit.SECONDS)
.shutdownAsync()
.get(CAMERAX_RESET_TIMEOUT_SECONDS, TimeUnit.SECONDS)
} catch (e: Exception) {
Log.w(TAG, "Failed to shutdown CameraX", e)
}
}
}

internal val APP_REQUIRED_PERMISSIONS: List<String> = buildList {
add(android.Manifest.permission.CAMERA)
Expand Down
Loading