[Extensions] Set the sessionType in SessionConfig from the v1.4 OEM implementation.
- Update Client extensions-interface verion to v1.4
- For Advanced Extender, get the sessionType information from OEMs
and set it to the SessionConfig.
- For Basic Extender, set sessionType to REGULAR
Bug: 306663504
Test: AdvancedSessionProcessorTest
Change-Id: I3c7c31f8a008833239a7b48f1814bc81628bf608
diff --git a/camera/camera-extensions-stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java b/camera/camera-extensions-stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
index 12bf312..50f5c4a 100644
--- a/camera/camera-extensions-stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
+++ b/camera/camera-extensions-stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
@@ -69,6 +69,15 @@
}
/**
+ * Sets the session type for the session.
+ */
+ @NonNull
+ public Camera2SessionConfigImplBuilder setSessionType(int sessionType) {
+ mSessionType = sessionType;
+ return this;
+ }
+
+ /**
* Gets the session template id.
*/
public int getSessionTemplateId() {
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/AdvancedSessionProcessorTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/AdvancedSessionProcessorTest.kt
index d780b54..28563e3 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/AdvancedSessionProcessorTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/AdvancedSessionProcessorTest.kt
@@ -41,6 +41,7 @@
import android.hardware.camera2.CaptureRequest
import android.hardware.camera2.CaptureResult
import android.hardware.camera2.TotalCaptureResult
+import android.hardware.camera2.params.SessionConfiguration
import android.media.ImageReader
import android.media.ImageWriter
import android.os.Build
@@ -50,6 +51,8 @@
import androidx.annotation.RequiresApi
import androidx.camera.camera2.Camera2Config
import androidx.camera.camera2.impl.Camera2ImplConfig
+import androidx.camera.camera2.internal.Camera2CameraInfoImpl
+import androidx.camera.camera2.internal.compat.CameraManagerCompat
import androidx.camera.camera2.internal.compat.params.OutputConfigurationCompat
import androidx.camera.camera2.interop.Camera2CameraInfo
import androidx.camera.core.CameraFilter
@@ -66,6 +69,7 @@
import androidx.camera.core.impl.ExtendedCameraConfigProviderStore
import androidx.camera.core.impl.Identifier
import androidx.camera.core.impl.MutableOptionsBundle
+import androidx.camera.core.impl.OutputSurface
import androidx.camera.core.impl.SessionProcessor
import androidx.camera.core.impl.utils.executor.CameraXExecutors
import androidx.camera.extensions.impl.advanced.Camera2OutputConfigImpl
@@ -387,6 +391,51 @@
.isEqualTo(physicalCameraId)
}
+ private fun createOutputSurface(width: Int, height: Int, format: Int): OutputSurface {
+ val captureImageReader = ImageReader.newInstance(width, height, format, 1);
+ return OutputSurface.create(captureImageReader.surface, Size(width, height), format)
+ }
+
+ @Test
+ fun canSetSessionTypeFromOemImpl() {
+ assumeTrue(ExtensionVersion.isMinimumCompatibleVersion(Version.VERSION_1_4))
+ // 1. Arrange.
+ val sessionTypeToVerify = 4;
+ val fakeSessionProcessImpl = FakeSessionProcessImpl()
+ fakeSessionProcessImpl.sessionType = sessionTypeToVerify;
+ val advancedSessionProcessor = AdvancedSessionProcessor(fakeSessionProcessImpl,
+ emptyList(), context)
+ val fakeCameraInfo = Camera2CameraInfoImpl("0", CameraManagerCompat.from(context));
+ val previewOutputSurface = createOutputSurface(640, 480, ImageFormat.YUV_420_888);
+ val imageCaptureSurface = createOutputSurface(640, 480, ImageFormat.JPEG);
+
+ // 2. Act.
+ val sessionConfig = advancedSessionProcessor
+ .initSession(fakeCameraInfo, previewOutputSurface, imageCaptureSurface, null);
+
+ // 3. Assert.
+ assertThat(sessionConfig.sessionType).isEqualTo(sessionTypeToVerify)
+ }
+
+ @Test
+ fun defaultSessionType() {
+ // 1. Arrange.
+ val fakeSessionProcessImpl = FakeSessionProcessImpl()
+ fakeSessionProcessImpl.sessionType = -1;
+ val advancedSessionProcessor = AdvancedSessionProcessor(fakeSessionProcessImpl,
+ emptyList(), context)
+ val fakeCameraInfo = Camera2CameraInfoImpl("0", CameraManagerCompat.from(context));
+ val previewOutputSurface = createOutputSurface(640, 480, ImageFormat.YUV_420_888);
+ val imageCaptureSurface = createOutputSurface(640, 480, ImageFormat.JPEG);
+
+ // 2. Act.
+ val sessionConfig = advancedSessionProcessor
+ .initSession(fakeCameraInfo, previewOutputSurface, imageCaptureSurface, null);
+
+ // 3. Assert.
+ assertThat(sessionConfig.sessionType).isEqualTo(SessionConfiguration.SESSION_REGULAR)
+ }
+
/**
* Verify if the given use cases have expected output.
* 1) Preview frame is received
@@ -474,6 +523,7 @@
* to allow tests to access the [RequestProcessorImpl] to receive the Image for
* [ImageReaderOutputConfigImpl].
*/
+@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
class FakeSessionProcessImpl(
var previewConfigBlock: (OutputSurfaceImpl) -> Camera2OutputConfigImpl = { outputSurfaceImpl ->
Camera2OutputConfigImplBuilder
@@ -497,6 +547,7 @@
private var startTriggerParametersDeferred =
CompletableDeferred<MutableMap<CaptureRequest.Key<*>, Any>>()
+ var sessionType: Int = -1;
override fun initSession(
cameraId: String,
cameraCharacteristicsMap: MutableMap<String, CameraCharacteristics>,
@@ -522,6 +573,10 @@
addOutputConfig(captureOutputConfig)
analysisOutputConfig?.let { addOutputConfig(it) }
}
+
+ if (ExtensionVersion.isMinimumCompatibleVersion(Version.VERSION_1_4)) {
+ sessionBuilder.setSessionType(sessionType);
+ }
return sessionBuilder.build()
}
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt
index b082271..c26ed45 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt
@@ -25,6 +25,7 @@
import android.hardware.camera2.TotalCaptureResult
import android.hardware.camera2.params.SessionConfiguration
import android.media.Image
+import android.media.ImageReader
import android.media.ImageWriter
import android.os.Build
import android.os.Handler
@@ -33,6 +34,8 @@
import android.util.Size
import android.view.Surface
import androidx.camera.camera2.Camera2Config
+import androidx.camera.camera2.internal.Camera2CameraInfoImpl
+import androidx.camera.camera2.internal.compat.CameraManagerCompat
import androidx.camera.camera2.interop.Camera2CameraInfo
import androidx.camera.camera2.interop.Camera2Interop
import androidx.camera.core.Camera
@@ -207,6 +210,61 @@
)
}
+ private fun createOutputSurface(width: Int, height: Int, format: Int): OutputSurface {
+ val captureImageReader = ImageReader.newInstance(width, height, format, 1);
+ return OutputSurface.create(captureImageReader.surface, Size(width, height), format)
+ }
+
+ @Test
+ fun canSetSessionTypeFromOem() {
+ assumeTrue(ExtensionVersion.isMinimumCompatibleVersion(Version.VERSION_1_4));
+ val sessionTypeToVerify = 4
+ fakeCaptureExtenderImpl.sessionType = sessionTypeToVerify
+ fakePreviewExtenderImpl.sessionType = sessionTypeToVerify
+
+ val fakeCameraInfo = Camera2CameraInfoImpl("0", CameraManagerCompat.from(context));
+ val previewOutputSurface = createOutputSurface(640, 480, ImageFormat.YUV_420_888);
+ val imageCaptureSurface = createOutputSurface(640, 480, ImageFormat.JPEG);
+
+ val sessionConfig = basicExtenderSessionProcessor.initSession(
+ fakeCameraInfo, previewOutputSurface, imageCaptureSurface, null)
+
+ assertThat(sessionConfig.sessionType).isEqualTo(sessionTypeToVerify)
+ }
+
+ @Test
+ fun setDifferentSessionTypes_throwException() {
+ assumeTrue(ExtensionVersion.isMinimumCompatibleVersion(Version.VERSION_1_4));
+ fakeCaptureExtenderImpl.sessionType = 2
+ fakePreviewExtenderImpl.sessionType = 3
+
+ val fakeCameraInfo = Camera2CameraInfoImpl("0", CameraManagerCompat.from(context));
+ val previewOutputSurface = createOutputSurface(640, 480, ImageFormat.YUV_420_888);
+ val imageCaptureSurface = createOutputSurface(640, 480, ImageFormat.JPEG);
+
+ assertThrows<IllegalArgumentException> {
+ basicExtenderSessionProcessor.initSession(
+ fakeCameraInfo, previewOutputSurface, imageCaptureSurface, null
+ )
+ }
+ }
+
+ @Test
+ fun defaultSessionType() {
+ assumeTrue(ExtensionVersion.isMinimumCompatibleVersion(Version.VERSION_1_4));
+ fakeCaptureExtenderImpl.sessionType = -1
+ fakePreviewExtenderImpl.sessionType = -1
+
+ val fakeCameraInfo = Camera2CameraInfoImpl("0", CameraManagerCompat.from(context));
+ val previewOutputSurface = createOutputSurface(640, 480, ImageFormat.YUV_420_888);
+ val imageCaptureSurface = createOutputSurface(640, 480, ImageFormat.JPEG);
+
+ val sessionConfig = basicExtenderSessionProcessor.initSession(
+ fakeCameraInfo, previewOutputSurface, imageCaptureSurface, null)
+
+ assertThat(sessionConfig.sessionType).isEqualTo(SessionConfiguration.SESSION_REGULAR)
+ }
+
@Test
fun imageCaptureError(): Unit = runBlocking {
assumeTrue(hasCaptureProcessor)
@@ -800,6 +858,7 @@
) : PreviewExtenderImpl, FakeExtenderStateListener() {
var fakePreviewImageProcessorImpl: FakePreviewImageProcessorImpl? = null
var fakeRequestUpdateProcessor: FakeRequestUpdateProcessor? = null
+ var sessionType: Int = -1
init {
when (processorType) {
@@ -843,6 +902,10 @@
_captureStage = captureStage
}
+ override fun onSessionType(): Int {
+ return sessionType
+ }
+
override fun getProcessorType() = processorType
override fun getProcessor() =
when (processorType) {
@@ -869,6 +932,7 @@
null
}
}
+ var sessionType = -1
override fun isExtensionAvailable(
cameraId: String,
@@ -909,7 +973,7 @@
}
override fun onSessionType(): Int {
- return SessionConfiguration.SESSION_REGULAR
+ return sessionType
}
override fun getSupportedPostviewResolutions(captureSize: Size):
@@ -922,7 +986,7 @@
}
override fun getRealtimeCaptureLatency(): Pair<Long, Long>? {
- return null;
+ return null
}
override fun isPostviewAvailable(): Boolean {
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ClientVersion.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ClientVersion.java
index 931d754..d4c9a0b 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ClientVersion.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ClientVersion.java
@@ -27,7 +27,7 @@
public class ClientVersion {
// Current version of vendor library implementation that the CameraX extension supports. This
// needs to be increased along with the version of vendor library interface.
- private static ClientVersion sCurrent = new ClientVersion("1.3.0");
+ private static ClientVersion sCurrent = new ClientVersion("1.4.0");
@NonNull
public static ClientVersion getCurrentVersion() {
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/AdvancedSessionProcessor.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/AdvancedSessionProcessor.java
index 85c344d..c2adbf76e 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/AdvancedSessionProcessor.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/AdvancedSessionProcessor.java
@@ -22,6 +22,7 @@
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.SessionConfiguration;
import android.media.Image;
import android.util.Pair;
import android.util.Size;
@@ -113,6 +114,14 @@
}
camera2SessionConfigBuilder
.setSessionTemplateId(sessionConfigImpl.getSessionTemplateId());
+ if (ClientVersion.isMinimumCompatibleVersion(Version.VERSION_1_4)
+ && ExtensionVersion.isMinimumCompatibleVersion(Version.VERSION_1_4)) {
+ int sessionType = sessionConfigImpl.getSessionType();
+ if (sessionType == -1) { // -1 means using default value
+ sessionType = SessionConfiguration.SESSION_REGULAR;
+ }
+ camera2SessionConfigBuilder.setSessionType(sessionType);
+ }
return camera2SessionConfigBuilder.build();
}
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessor.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessor.java
index 0a8ca6c..bb1b67d 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessor.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessor.java
@@ -26,6 +26,7 @@
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.SessionConfiguration;
import android.util.Pair;
import androidx.annotation.GuardedBy;
@@ -186,6 +187,19 @@
.addOutputConfig(mCaptureOutputConfig)
.setSessionTemplateId(CameraDevice.TEMPLATE_PREVIEW);
+ if (ClientVersion.isMinimumCompatibleVersion(Version.VERSION_1_4)
+ && ExtensionVersion.isMinimumCompatibleVersion(Version.VERSION_1_4)) {
+ int previewSessionType = mPreviewExtenderImpl.onSessionType();
+ int captureSessionType = mImageCaptureExtenderImpl.onSessionType();
+ Preconditions.checkArgument(previewSessionType == captureSessionType,
+ "Needs same session type in both PreviewExtenderImpl and "
+ + "ImageCaptureExtenderImpl");
+ if (previewSessionType == -1) { // -1 means using default value
+ previewSessionType = SessionConfiguration.SESSION_REGULAR;
+ }
+ builder.setSessionType(previewSessionType);
+ }
+
if (mAnalysisOutputConfig != null) {
builder.addOutputConfig(mAnalysisOutputConfig);
}
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2SessionConfig.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2SessionConfig.java
index 4ba35a5..24b0eec2 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2SessionConfig.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2SessionConfig.java
@@ -17,6 +17,7 @@
package androidx.camera.extensions.internal.sessionprocessor;
import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.SessionConfiguration;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
@@ -47,4 +48,11 @@
* {@link android.hardware.camera2.params.SessionConfiguration#setSessionParameters}.
*/
int getSessionTemplateId();
+
+ /**
+ * Gets the session type
+ */
+ default int getSessionType() {
+ return SessionConfiguration.SESSION_REGULAR;
+ }
}
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2SessionConfigBuilder.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2SessionConfigBuilder.java
index 57baff7..08950dc 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2SessionConfigBuilder.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2SessionConfigBuilder.java
@@ -18,6 +18,7 @@
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.SessionConfiguration;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -35,6 +36,7 @@
@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
class Camera2SessionConfigBuilder {
private int mSessionTemplateId = CameraDevice.TEMPLATE_PREVIEW;
+ private int mSessionType = SessionConfiguration.SESSION_REGULAR;
private Map<CaptureRequest.Key<?>, Object> mSessionParameters = new HashMap<>();
private List<Camera2OutputConfig> mCamera2OutputConfigs = new ArrayList<>();
@@ -71,6 +73,15 @@
}
/**
+ * Sets the session type for the session.
+ */
+ @NonNull
+ Camera2SessionConfigBuilder setSessionType(int sessionType) {
+ mSessionType = sessionType;
+ return this;
+ }
+
+ /**
* Gets the session template id.
*/
int getSessionTemplateId() {
@@ -98,18 +109,22 @@
*/
@NonNull
Camera2SessionConfig build() {
- return new SessionConfigImpl(mSessionTemplateId, mSessionParameters, mCamera2OutputConfigs);
+ return new SessionConfigImpl(
+ mSessionTemplateId, mSessionType, mSessionParameters, mCamera2OutputConfigs);
}
private static class SessionConfigImpl implements Camera2SessionConfig {
private final int mSessionTemplateId;
+ private final int mSessionType;
private final Map<CaptureRequest.Key<?>, Object> mSessionParameters;
private final List<Camera2OutputConfig> mCamera2OutputConfigs;
SessionConfigImpl(int sessionTemplateId,
+ int sessionType,
Map<CaptureRequest.Key<?>, Object> sessionParameters,
List<Camera2OutputConfig> camera2OutputConfigs) {
mSessionTemplateId = sessionTemplateId;
+ mSessionType = sessionType;
mSessionParameters = sessionParameters;
mCamera2OutputConfigs = camera2OutputConfigs;
}
@@ -130,5 +145,10 @@
public int getSessionTemplateId() {
return mSessionTemplateId;
}
+
+ @Override
+ public int getSessionType() {
+ return mSessionType;
+ }
}
}
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/SessionProcessorBase.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/SessionProcessorBase.java
index f02f5fa..d57f6a9 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/SessionProcessorBase.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/SessionProcessorBase.java
@@ -220,6 +220,7 @@
}
sessionConfigBuilder.setImplementationOptions(camera2ConfigurationBuilder.build());
sessionConfigBuilder.setTemplateType(camera2SessionConfig.getSessionTemplateId());
+ sessionConfigBuilder.setSessionType(camera2SessionConfig.getSessionType());
mImageReaderHandlerThread = new HandlerThread(
CameraXThreads.TAG + "extensions_image_reader");
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
index d1bb69a..5843dc0 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
@@ -69,6 +69,15 @@
}
/**
+ * Sets the session type for the session.
+ */
+ @NonNull
+ public Camera2SessionConfigImplBuilder setSessionType(int sessionType) {
+ mSessionType = sessionType;
+ return this;
+ }
+
+ /**
* Gets the session template id.
*/
public int getSessionTemplateId() {