blob: a8c2c567ad75fc55856c2eb954c114ab774fb0ac [file] [log] [blame]
/*
* Copyright 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Camera 1 API is deprecated, suppress warnings as Antelope expressly tests it
@file:Suppress("deprecation")
package androidx.camera.integration.antelope.cameracontrollers
import android.hardware.Camera
import android.util.Size
import androidx.camera.integration.antelope.CameraParams
import androidx.camera.integration.antelope.CompareSizesByArea
import androidx.camera.integration.antelope.FocusMode
import androidx.camera.integration.antelope.ImageCaptureSize
import androidx.camera.integration.antelope.MainActivity
import androidx.camera.integration.antelope.MainActivity.Companion.logd
import androidx.camera.integration.antelope.PrefHelper
import androidx.camera.integration.antelope.TestConfig
import androidx.camera.integration.antelope.TestType
import androidx.camera.integration.antelope.testEnded
import androidx.camera.integration.antelope.writeFile
import java.util.Collections
internal var camera1: Camera? = null
/**
* Opens the camera using the Camera1 API and measures the open time synchronously. For init tests,
* this is the only measurement needed so end the test. Otherwise, move on to open the camera
* preview.
*/
fun camera1OpenCamera(activity: MainActivity, params: CameraParams, testConfig: TestConfig) {
try {
logd("openCamera: " + params.id)
params.isOpen = true
params.timer.openStart = System.currentTimeMillis()
logd("Camera1Switch Open camera: " + testConfig.switchTestCurrentCamera.toInt())
if ((testConfig.currentRunningTest == TestType.SWITCH_CAMERA) ||
(testConfig.currentRunningTest == TestType.MULTI_SWITCH)
)
camera1 = Camera.open(testConfig.switchTestCurrentCamera.toInt())
else
camera1 = Camera.open(testConfig.camera.toInt())
params.timer.openEnd = System.currentTimeMillis()
// Due to the synchronous nature of Camera1, set up Camera1 specific parameters here
val camera1Params: Camera.Parameters? = camera1?.parameters
params.cam1AFSupported =
camera1Params?.supportedFocusModes?.contains(Camera.Parameters.FOCUS_MODE_AUTO)
?: false
when (testConfig.currentRunningTest) {
TestType.INIT -> {
// Camera opened, we're done
testEnded(activity, params, testConfig)
}
else -> {
startCamera1Preview(activity, params, testConfig)
}
}
} catch (e: Exception) {
logd("camera1OpenCamera exception: " + params.id + ". Error: " + e.printStackTrace())
camera1 = null
}
}
/**
* Begin the preview using the Camera 1 API and synchronously measure the time to begin the stream.
*/
fun startCamera1Preview(activity: MainActivity, params: CameraParams, testConfig: TestConfig) {
val camera1Params: Camera.Parameters? = camera1?.parameters
params.cam1AFSupported =
camera1Params?.supportedFocusModes?.contains(Camera.Parameters.FOCUS_MODE_AUTO) ?: false
// Get Camera1 image capture sizes
// Cannot be done this before the camera is device opened
val cam1Sizes = camera1Params?.getSupportedPictureSizes()
if (null != cam1Sizes) {
val saneSizes: ArrayList<Size> = ArrayList()
for (size in cam1Sizes) {
saneSizes.add(Size(size.width, size.height))
}
params.cam1MaxSize = Collections.max(saneSizes, CompareSizesByArea())
params.cam1MinSize = Collections.min(saneSizes, CompareSizesByArea())
}
if (ImageCaptureSize.MIN == testConfig.imageCaptureSize)
camera1Params?.setPictureSize(params.cam1MinSize.width, params.cam1MinSize.height)
else
camera1Params?.setPictureSize(params.cam1MaxSize.width, params.cam1MaxSize.height)
if (params.cam1AFSupported) {
if (FocusMode.CONTINUOUS == testConfig.focusMode)
camera1Params?.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE
else
camera1Params?.focusMode = Camera.Parameters.FOCUS_MODE_AUTO
} else {
camera1Params?.focusMode = Camera.Parameters.FOCUS_MODE_FIXED
}
// After changing camera parameters, set them
camera1?.parameters = camera1Params
logd("startCamera1Preview: starting Camera1 preview.")
params.isPreviewing = true
params.timer.previewStart = System.currentTimeMillis()
camera1?.startPreview()
camera1?.setPreviewDisplay(params.previewSurfaceView?.holder)
params.timer.previewEnd = System.currentTimeMillis()
when (testConfig.currentRunningTest) {
TestType.PREVIEW -> {
testConfig.testFinished = true
closePreviewAndCamera(activity, params, testConfig)
}
TestType.SWITCH_CAMERA, TestType.MULTI_SWITCH -> {
logd("Camera1Switch preview running:")
if (testConfig.switchTestCurrentCamera == testConfig.switchTestCameras.get(0)) {
if (testConfig.testFinished) {
logd("Camera1Switch preview. On 1st camera, test finished. Closing 1st camera")
params.timer.switchToFirstEnd = System.currentTimeMillis()
Thread.sleep(PrefHelper.getPreviewBuffer(activity)) // Let preview run
closePreviewAndCamera(activity, params, testConfig)
} else {
logd("Camera1Switch preview. On 1st camera, Closing 1st camera, then open 2nd")
Thread.sleep(PrefHelper.getPreviewBuffer(activity)) // Let preview run
params.timer.switchToSecondStart = System.currentTimeMillis()
closePreviewAndCamera(activity, params, testConfig)
}
} else {
logd(
"Camera1Switch preview. On 2nd camera. Closing, ready to open first 1st " +
"camera"
)
params.timer.switchToSecondEnd = System.currentTimeMillis()
Thread.sleep(PrefHelper.getPreviewBuffer(activity)) // Let preview run
params.timer.switchToFirstStart = System.currentTimeMillis()
closePreviewAndCamera(activity, params, testConfig)
}
}
TestType.NONE -> {
closeAllCameras(activity, testConfig)
}
else -> {
camera1TakePicturePrep(activity, params, testConfig)
}
}
}
/**
* Set up timers and focus mode for taking a picture with the Camera 1 API. If auto-focus is
* requested, begin the auto-focus timer and asynchronously begin the auto-focus routine.
*/
fun camera1TakePicturePrep(activity: MainActivity, params: CameraParams, testConfig: TestConfig) {
if (params.timer.isFirstPhoto) {
logd(
"camera1TakePicturePrep: 1st photo in multi-chain test. Pausing for " +
PrefHelper.getPreviewBuffer(activity) + "ms to let preview run."
)
params.timer.previewFillStart = System.currentTimeMillis()
Thread.sleep(PrefHelper.getPreviewBuffer(activity))
params.timer.previewFillEnd = System.currentTimeMillis()
params.timer.isFirstPhoto = false
}
params.timer.captureStart = System.currentTimeMillis()
if (params.cam1AFSupported &&
FocusMode.AUTO == testConfig.focusMode
) {
MainActivity.logd("camera1TakePicturePrep: starting autofocus.")
params.timer.autofocusStart = System.currentTimeMillis()
camera1?.autoFocus(Camera1AutofocusCallback(activity, params, testConfig))
} else {
camera1TakePicture(activity, params, testConfig)
}
}
/**
* Initiate the capture request
*/
fun camera1TakePicture(activity: MainActivity, params: CameraParams, testConfig: TestConfig) {
val camera1JpegCallback = Camera1PictureCallback(activity, params, testConfig)
try {
MainActivity.logd("camera1TakePicture: capture start. ")
camera1?.takePicture(null, null, camera1JpegCallback)
} catch (e: RuntimeException) {
MainActivity.logd("camera1TakePicture: runtime exception: " + e.printStackTrace())
}
}
/**
* Close preview stream and camera device. If this is a switch test, begin the next step
*/
fun camera1CloseCamera(activity: MainActivity, params: CameraParams?, testConfig: TestConfig) {
if (params == null)
return
if (params.isPreviewing) {
params.timer.previewCloseStart = System.currentTimeMillis()
camera1?.stopPreview()
params.timer.previewCloseEnd = System.currentTimeMillis()
params.isPreviewing = false
}
params.timer.cameraCloseStart = System.currentTimeMillis()
camera1?.release()
params.timer.cameraCloseEnd = System.currentTimeMillis()
params.isOpen = false
logd("Camera 1 Close camera: camera released.")
if (testConfig.testFinished) {
logd("Camera 1 Close camera: Test finished, returning")
testEnded(activity, params, testConfig)
return
}
when (testConfig.currentRunningTest) {
TestType.SWITCH_CAMERA, TestType.MULTI_SWITCH -> {
logd("Camera1Switch Close camera")
// First camera closed, now start the second
if (testConfig.switchTestCurrentCamera == testConfig.switchTestCameras.get(0)) {
testConfig.switchTestCurrentCamera = testConfig.switchTestCameras.get(1)
logd("Camera1Switch Close camera 1st camera is closed, opening the second")
camera1OpenCamera(activity, params, testConfig)
}
// Second camera closed, now start the first
else if (testConfig.switchTestCurrentCamera == testConfig.switchTestCameras.get(1)) {
logd("Camera1Switch Close camera 2nd camera is closed, opening the first")
testConfig.switchTestCurrentCamera = testConfig.switchTestCameras.get(0)
testConfig.testFinished = true
camera1OpenCamera(activity, params, testConfig)
}
}
else -> {
Unit // no-op
}
}
}
/**
* Auto-focus is complete, record the elapsed time and request the capture
*/
class Camera1AutofocusCallback internal constructor(
internal val activity: MainActivity,
internal val params: CameraParams,
internal val testConfig: TestConfig
) : Camera.AutoFocusCallback {
override fun onAutoFocus(p0: Boolean, p1: Camera?) {
MainActivity.logd("camera1AutofocusCallback: autofocus complete.")
params.timer.autofocusEnd = System.currentTimeMillis()
camera1TakePicture(activity, params, testConfig)
}
}
/**
* Image capture has completed. Record the time taken, synchronously write file to disk and measure
* the time required. This test run is finished, call to finalize test or continue the test run.
*/
class Camera1PictureCallback internal constructor(
internal val activity: MainActivity,
internal val params: CameraParams,
internal val testConfig: TestConfig
) : Camera.PictureCallback {
override fun onPictureTaken(bytes: ByteArray?, p1: Camera?) {
params.timer.captureEnd = System.currentTimeMillis()
// With the Camera1 API, calling takePicture() stops the preview. In order to make sure the
// close timings are comparable across APIs, restart it here.
camera1?.startPreview()
logd("in Camera1PictureCallback onPictureTaken")
params.timer.imageReaderStart = System.currentTimeMillis()
params.timer.imageReaderEnd = System.currentTimeMillis()
params.timer.imageSaveStart = System.currentTimeMillis()
if (null != bytes)
writeFile(activity, bytes)
params.timer.imageSaveEnd = System.currentTimeMillis()
testConfig.testFinished = true
closePreviewAndCamera(activity, params, testConfig)
}
}