minSdk -> RequiresApi for camera-extensions
This rolls back the minSdkVersion to the AndroidX default (14) and
instead enforces SDK requirements with lint and the @RequiresApi(21)
annotation.
Also includes the same change for camera-testlib-extensions.
For camera-extensions-stub, we are able to remove the minSdkVersion,
but because this library only contains stubs and no implementation
code, we do not need to annotate any of the classes.
See aosp/1838237 for more information.
Bug: 198449102
Test: ./gradlew camera:camera-extensions:lint
&& ./gradlew camera:camera-extensions-stub:lint
&& ./gradlew camera:camera-testlib-extensions:lint
Change-Id: I1f903da70a330ba7f9e9c183699d10fc8e3ed73f
diff --git a/camera/camera-extensions-stub/build.gradle b/camera/camera-extensions-stub/build.gradle
index 6d234f3..2ed55c3 100644
--- a/camera/camera-extensions-stub/build.gradle
+++ b/camera/camera-extensions-stub/build.gradle
@@ -26,12 +26,6 @@
api("androidx.annotation:annotation:1.0.0")
}
-android {
- defaultConfig {
- minSdkVersion 21
- }
-}
-
androidx {
name = "Jetpack Camera Library OEM Extensions Stub"
publish = Publish.NONE
diff --git a/camera/camera-extensions/build.gradle b/camera/camera-extensions/build.gradle
index 6830280..e137b58 100644
--- a/camera/camera-extensions/build.gradle
+++ b/camera/camera-extensions/build.gradle
@@ -54,6 +54,7 @@
androidTestImplementation(libs.kotlinStdlib)
androidTestImplementation(libs.mockitoCore, excludes.bytebuddy) // DexMaker has its own MockMaker
androidTestImplementation(libs.truth)
+ androidTestImplementation(libs.multidex)
androidTestImplementation(project(":camera:camera-lifecycle"))
androidTestImplementation(project(":camera:camera-testing"))
androidTestImplementation(project(":internal-testutils-truth"))
@@ -63,7 +64,7 @@
android {
defaultConfig {
- minSdkVersion 21
+ multiDexEnabled = true
}
buildTypes.all {
diff --git a/camera/camera-extensions/lint.xml b/camera/camera-extensions/lint.xml
new file mode 100644
index 0000000..0843ecf
--- /dev/null
+++ b/camera/camera-extensions/lint.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+ <!-- Disable NewApi lint check temporarily for unit tests.
+ This file can be removed once b/200599470 is resolved. -->
+ <issue id="NewApi">
+ <ignore path="src/test/**" />
+ </issue>
+</lint>
\ No newline at end of file
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsManagerTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsManagerTest.kt
index e15deb5..65b0b5c 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsManagerTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsManagerTest.kt
@@ -30,6 +30,7 @@
import androidx.camera.testing.CameraUtil
import androidx.camera.testing.fakes.FakeLifecycleOwner
import androidx.camera.testing.fakes.FakeUseCase
+import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.assertThrows
@@ -48,6 +49,7 @@
@SmallTest
@RunWith(Parameterized::class)
+@SdkSuppress(minSdkVersion = 21)
class ExtensionsManagerTest(
@field:ExtensionMode.Mode @param:ExtensionMode.Mode private val extensionMode: Int,
@field:CameraSelector.LensFacing @param:CameraSelector.LensFacing private val lensFacing: Int
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureExtenderValidationTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureExtenderValidationTest.kt
index a0c448b..7753a7e 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureExtenderValidationTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ImageCaptureExtenderValidationTest.kt
@@ -51,6 +51,7 @@
@SmallTest
@RunWith(Parameterized::class)
+@SdkSuppress(minSdkVersion = 21)
class ImageCaptureExtenderValidationTest(
@field:Mode @param:Mode private val extensionMode: Int,
@field:CameraSelector.LensFacing @param:CameraSelector.LensFacing private val lensFacing: Int
@@ -137,7 +138,7 @@
}
@Test
- @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
+ @SdkSuppress(minSdkVersion = 21, maxSdkVersion = Build.VERSION_CODES.O_MR1)
fun returnsNullFromOnPresetSession_whenAPILevelOlderThan28() {
// Creates the ImageCaptureExtenderImpl to check that onPresetSession() returns null when
// API level is older than 28.
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderValidationTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderValidationTest.kt
index d5da017..e68cfb8 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderValidationTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderValidationTest.kt
@@ -48,6 +48,7 @@
@SmallTest
@RunWith(Parameterized::class)
+@SdkSuppress(minSdkVersion = 21)
class PreviewExtenderValidationTest(
@field:Mode @param:Mode private val extensionMode: Int,
@field:CameraSelector.LensFacing @param:CameraSelector.LensFacing private val lensFacing: Int
@@ -131,7 +132,7 @@
}
@Test
- @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O_MR1)
+ @SdkSuppress(minSdkVersion = 21, maxSdkVersion = Build.VERSION_CODES.O_MR1)
fun returnsNullFromOnPresetSession_whenAPILevelOlderThan28() {
// Creates the ImageCaptureExtenderImpl to check that onPresetSession() returns null when
// API level is older than 28.
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/ImageCaptureConfigProviderTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/ImageCaptureConfigProviderTest.kt
index cef523b..cd987ab 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/ImageCaptureConfigProviderTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/ImageCaptureConfigProviderTest.kt
@@ -36,6 +36,7 @@
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
@@ -56,7 +57,7 @@
@MediumTest
@RunWith(AndroidJUnit4::class)
-
+@SdkSuppress(minSdkVersion = 21)
class ImageCaptureConfigProviderTest {
@get:Rule
val useCamera = CameraUtil.grantCameraPermissionAndPreTest()
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/PreviewConfigProviderTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/PreviewConfigProviderTest.kt
index 7be9086..1f25c2c 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/PreviewConfigProviderTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/PreviewConfigProviderTest.kt
@@ -42,6 +42,7 @@
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
@@ -64,6 +65,7 @@
@MediumTest
@RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = 21)
class PreviewConfigProviderTest {
@get:Rule
val useCamera = CameraUtil.grantCameraPermissionAndPreTest()
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java
index c4d0e15..4f61e65 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/util/ExtensionsTestUtil.java
@@ -27,6 +27,7 @@
import android.hardware.camera2.CameraCharacteristics;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
import androidx.camera.core.CameraSelector;
import androidx.camera.extensions.ExtensionMode;
import androidx.camera.extensions.impl.AutoImageCaptureExtenderImpl;
@@ -48,6 +49,7 @@
/**
* Extension test util functions.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public class ExtensionsTestUtil {
@NonNull
public static Collection<Object[]> getAllExtensionsLensFacingCombinations() {
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionCameraFilter.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionCameraFilter.java
index 73e7c9e..0da3b2b 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionCameraFilter.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionCameraFilter.java
@@ -20,6 +20,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.OptIn;
+import androidx.annotation.RequiresApi;
import androidx.camera.camera2.interop.Camera2CameraInfo;
import androidx.camera.camera2.interop.ExperimentalCamera2Interop;
import androidx.camera.core.CameraFilter;
@@ -37,6 +38,7 @@
* A filter that filters camera based on extender implementation. If the implementation is
* unavailable, the camera will be considered available.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
final class ExtensionCameraFilter implements CameraFilter {
private final Identifier mId;
private final VendorExtender mVendorExtender;
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionMode.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionMode.java
index d14c35b..89bc006 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionMode.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionMode.java
@@ -17,6 +17,7 @@
package androidx.camera.extensions;
import androidx.annotation.IntDef;
+import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraProvider;
@@ -28,6 +29,7 @@
/**
* The available modes for the extensions.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class ExtensionMode {
/** Normal mode without any specific effect applied. */
public static final int NONE = 0;
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsConfig.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsConfig.java
index e44e5cc..5aab6b2 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsConfig.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsConfig.java
@@ -17,6 +17,7 @@
package androidx.camera.extensions;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
import androidx.camera.core.impl.CameraConfig;
import androidx.camera.core.impl.Config;
import androidx.camera.core.impl.Identifier;
@@ -27,6 +28,7 @@
/**
* Implementation of CameraConfig which provides the extensions capability.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
class ExtensionsConfig implements CameraConfig {
// Option Declarations:
// *********************************************************************************************
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsInfo.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsInfo.java
index 8a0d53c..059eb4e 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsInfo.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsInfo.java
@@ -23,6 +23,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
+import androidx.annotation.RequiresApi;
import androidx.camera.camera2.interop.ExperimentalCamera2Interop;
import androidx.camera.core.CameraFilter;
import androidx.camera.core.CameraInfo;
@@ -53,6 +54,7 @@
* call can be used to get the specified {@link CameraSelector} to bind use cases and enable the
* extension mode on the camera.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
final class ExtensionsInfo {
private static final String EXTENDED_CAMERA_CONFIG_PROVIDER_ID_PREFIX = ":camera:camera"
+ "-extensions-";
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
index 47e658a..7748d56 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
@@ -22,6 +22,7 @@
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting;
import androidx.camera.core.CameraProvider;
@@ -82,6 +83,7 @@
* }
* </pre>
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class ExtensionsManager {
private static final String TAG = "ExtensionsManager";
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingCaptureProcessor.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingCaptureProcessor.java
index 07799cd..88c4207 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingCaptureProcessor.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingCaptureProcessor.java
@@ -24,6 +24,7 @@
import android.view.Surface;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
import androidx.camera.camera2.impl.Camera2CameraCaptureResultConverter;
import androidx.camera.core.ExperimentalGetImage;
import androidx.camera.core.ImageInfo;
@@ -46,6 +47,7 @@
/**
* A {@link CaptureProcessor} that calls a vendor provided implementation.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class AdaptingCaptureProcessor implements CaptureProcessor {
private final CaptureProcessorImpl mImpl;
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingCaptureStage.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingCaptureStage.java
index 3276023..225da9a 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingCaptureStage.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingCaptureStage.java
@@ -20,12 +20,14 @@
import android.util.Pair;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
import androidx.camera.camera2.impl.Camera2ImplConfig;
import androidx.camera.core.impl.CaptureConfig;
import androidx.camera.core.impl.CaptureStage;
import androidx.camera.extensions.impl.CaptureStageImpl;
/** A {@link CaptureStage} that calls a vendor provided implementation. */
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class AdaptingCaptureStage implements CaptureStage {
private final CaptureConfig mCaptureRequestConfiguration;
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingPreviewProcessor.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingPreviewProcessor.java
index fad4afa..2b2a6b3 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingPreviewProcessor.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingPreviewProcessor.java
@@ -24,6 +24,7 @@
import android.view.Surface;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
import androidx.camera.camera2.impl.Camera2CameraCaptureResultConverter;
import androidx.camera.core.ExperimentalGetImage;
import androidx.camera.core.ImageInfo;
@@ -44,6 +45,7 @@
/**
* A {@link CaptureProcessor} that calls a vendor provided preview processing implementation.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class AdaptingPreviewProcessor implements CaptureProcessor, CloseableProcessor {
private static final String TAG = "AdaptingPreviewProcesso";
private final PreviewImageProcessorImpl mImpl;
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingRequestUpdateProcessor.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingRequestUpdateProcessor.java
index c1445b9..c8ff32f 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingRequestUpdateProcessor.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdaptingRequestUpdateProcessor.java
@@ -21,6 +21,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.camera.camera2.impl.Camera2CameraCaptureResultConverter;
import androidx.camera.core.ImageInfo;
import androidx.camera.core.impl.CameraCaptureResult;
@@ -35,6 +36,7 @@
/**
* A {@link ImageInfoProcessor} that calls a vendor provided preview processing implementation.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class AdaptingRequestUpdateProcessor implements ImageInfoProcessor,
CloseableProcessor {
private final PreviewExtenderImpl mPreviewExtenderImpl;
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdvancedVendorExtender.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdvancedVendorExtender.java
index 7915f33..08a60e7 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdvancedVendorExtender.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/AdvancedVendorExtender.java
@@ -26,6 +26,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
+import androidx.annotation.RequiresApi;
import androidx.camera.camera2.interop.Camera2CameraInfo;
import androidx.camera.camera2.interop.ExperimentalCamera2Interop;
import androidx.camera.core.CameraInfo;
@@ -48,6 +49,7 @@
/**
* Advanced vendor interface implementation
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public class AdvancedVendorExtender implements VendorExtender {
private final AdvancedExtenderImpl mAdvancedExtenderImpl;
private String mCameraId;
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/BasicVendorExtender.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/BasicVendorExtender.java
index 783554f..e31e8d9 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/BasicVendorExtender.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/BasicVendorExtender.java
@@ -27,6 +27,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
+import androidx.annotation.RequiresApi;
import androidx.camera.camera2.interop.Camera2CameraInfo;
import androidx.camera.camera2.interop.ExperimentalCamera2Interop;
import androidx.camera.core.CameraInfo;
@@ -54,6 +55,7 @@
/**
* Basic vendor interface implementation
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public class BasicVendorExtender implements VendorExtender {
private static final String TAG = "BasicVendorExtender";
private final @ExtensionMode.Mode int mMode;
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/BlockingCloseAccessCounter.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/BlockingCloseAccessCounter.java
index dc03bef..b41659e 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/BlockingCloseAccessCounter.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/BlockingCloseAccessCounter.java
@@ -17,6 +17,7 @@
package androidx.camera.extensions.internal;
import androidx.annotation.GuardedBy;
+import androidx.annotation.RequiresApi;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
@@ -45,6 +46,7 @@
* }
* }</pre>
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
final class BlockingCloseAccessCounter {
@GuardedBy("mLock")
private AtomicInteger mAccessCount = new AtomicInteger(0);
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/CloseableProcessor.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/CloseableProcessor.java
index 5fb4252..495a6b8d 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/CloseableProcessor.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/CloseableProcessor.java
@@ -16,10 +16,13 @@
package androidx.camera.extensions.internal;
+import androidx.annotation.RequiresApi;
+
/**
* A processor that can be closed so that the underlying processing implementation is skipped,
* if it has been closed.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface CloseableProcessor {
/**
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ExtensionVersion.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ExtensionVersion.java
index cf7a8fb..6b58434 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ExtensionVersion.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ExtensionVersion.java
@@ -17,12 +17,14 @@
package androidx.camera.extensions.internal;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.camera.core.Logger;
import androidx.camera.extensions.impl.ExtensionVersionImpl;
/**
* Provides interfaces to check the extension version.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public abstract class ExtensionVersion {
private static final String TAG = "ExtenderVersion";
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ExtensionsUseCaseConfigFactory.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ExtensionsUseCaseConfigFactory.java
index d3180d1..b792fe7 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ExtensionsUseCaseConfigFactory.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ExtensionsUseCaseConfigFactory.java
@@ -20,6 +20,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.camera.core.impl.Config;
import androidx.camera.core.impl.MutableOptionsBundle;
import androidx.camera.core.impl.OptionsBundle;
@@ -30,6 +31,7 @@
* Implementation of UseCaseConfigFactory to provide the default extensions configurations for use
* cases.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class ExtensionsUseCaseConfigFactory implements UseCaseConfigFactory {
private final ImageCaptureConfigProvider mImageCaptureConfigProvider;
private final PreviewConfigProvider mPreviewConfigProvider;
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ImageCaptureConfigProvider.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ImageCaptureConfigProvider.java
index c51e759..d3a3bea 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ImageCaptureConfigProvider.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/ImageCaptureConfigProvider.java
@@ -26,6 +26,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
+import androidx.annotation.RequiresApi;
import androidx.camera.camera2.impl.Camera2ImplConfig;
import androidx.camera.camera2.impl.CameraEventCallback;
import androidx.camera.camera2.impl.CameraEventCallbacks;
@@ -53,6 +54,7 @@
/**
* Provides extensions related configs for image capture
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public class ImageCaptureConfigProvider implements ConfigProvider<ImageCaptureConfig> {
private static final String TAG = "ImageCaptureConfigProvider";
static final Config.Option<Integer> OPTION_IMAGE_CAPTURE_CONFIG_PROVIDER_MODE =
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/PreviewConfigProvider.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/PreviewConfigProvider.java
index 0d21105..14e3138a 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/PreviewConfigProvider.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/PreviewConfigProvider.java
@@ -26,6 +26,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
+import androidx.annotation.RequiresApi;
import androidx.camera.camera2.impl.Camera2ImplConfig;
import androidx.camera.camera2.impl.CameraEventCallback;
import androidx.camera.camera2.impl.CameraEventCallbacks;
@@ -49,6 +50,7 @@
/**
* For providing extensions config for preview.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public class PreviewConfigProvider implements ConfigProvider<PreviewConfig> {
private static final String TAG = "PreviewConfigProvider";
static final Config.Option<Integer> OPTION_PREVIEW_CONFIG_PROVIDER_MODE = Config.Option.create(
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/VendorExtender.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/VendorExtender.java
index 81b5807..e1f7380 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/VendorExtender.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/VendorExtender.java
@@ -25,6 +25,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.camera.core.CameraInfo;
import androidx.camera.core.impl.SessionProcessor;
@@ -35,6 +36,7 @@
* A unified vendor extensions interface which interacts with both basic and advanced extender
* vendor implementation.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface VendorExtender {
/**
* Indicates whether the extension is supported on the device.
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/Version.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/Version.java
index 7f13db4..d37eeb4 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/Version.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/Version.java
@@ -20,6 +20,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import com.google.auto.value.AutoValue;
@@ -31,6 +32,7 @@
/**
* Class encapsulating a version with major, minor, patch and description values.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
@AutoValue
public abstract class Version implements Comparable<Version> {
public static final Version VERSION_1_0 = Version.create(1, 0, 0, "");
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/VersionName.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/VersionName.java
index 19a4e1d..99ad205 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/VersionName.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/VersionName.java
@@ -17,10 +17,12 @@
package androidx.camera.extensions.internal;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
/**
* The version of CameraX extension releases.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public class VersionName {
// Current version of vendor library implementation that the CameraX extension supports. This
// needs to be increased along with the version of vendor library interface.
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 b4a33c9..a9dc65d 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
@@ -28,6 +28,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.camera.camera2.impl.Camera2CameraCaptureResultConverter;
import androidx.camera.camera2.impl.Camera2ImplConfig;
import androidx.camera.camera2.interop.CaptureRequestOptions;
@@ -54,6 +55,7 @@
/**
* A {@link SessionProcessor} based on OEMs' {@link SessionProcessorImpl}.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public class AdvancedSessionProcessor extends SessionProcessorBase {
private final SessionProcessorImpl mImpl;
private final Context mContext;
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2OutputConfig.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2OutputConfig.java
index 712026f..7ffecb8 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2OutputConfig.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2OutputConfig.java
@@ -18,6 +18,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.util.List;
@@ -25,6 +26,7 @@
* A config representing a {@link android.hardware.camera2.params.OutputConfiguration} where
* Surface will be created by the information in this config.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
interface Camera2OutputConfig {
/**
* Gets the id of this output config. The id can be used to identify the stream in vendor
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2OutputConfigBuilder.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2OutputConfigBuilder.java
index 5bd3240..c461f5b 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2OutputConfigBuilder.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/Camera2OutputConfigBuilder.java
@@ -21,6 +21,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.camera.extensions.impl.advanced.Camera2OutputConfigImpl;
import androidx.camera.extensions.impl.advanced.ImageReaderOutputConfigImpl;
import androidx.camera.extensions.impl.advanced.MultiResolutionImageReaderOutputConfigImpl;
@@ -36,6 +37,7 @@
/**
* A builder for building {@link Camera2OutputConfig}.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
class Camera2OutputConfigBuilder {
private static AtomicInteger sLastId = new AtomicInteger(0);
private OutputConfig mOutputConfig;
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 c077ee1..4ba35a5 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
@@ -19,6 +19,7 @@
import android.hardware.camera2.CaptureRequest;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
import java.util.List;
import java.util.Map;
@@ -26,6 +27,7 @@
/**
* A config representing a {@link android.hardware.camera2.params.SessionConfiguration}
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
interface Camera2SessionConfig {
/**
* Returns all the {@link Camera2OutputConfig}s that will be used to create
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 c178bee..60e13b7 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
@@ -21,6 +21,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.camera.extensions.impl.advanced.Camera2SessionConfigImpl;
import java.util.ArrayList;
@@ -31,6 +32,7 @@
/**
* A builder implementation to build the {@link Camera2SessionConfig} instance.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
class Camera2SessionConfigBuilder {
private int mSessionTemplateId = CameraDevice.TEMPLATE_PREVIEW;
private Map<CaptureRequest.Key<?>, Object> mSessionParameters = new HashMap<>();
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/ImageProcessor.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/ImageProcessor.java
index fac650f..4ab0374 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/ImageProcessor.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/ImageProcessor.java
@@ -18,10 +18,12 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
/**
* An interface to receive and process the upcoming next available Image.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface ImageProcessor {
/**
* The reference count will be decremented when this method returns. If an extension wants
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/ImageReaderOutputConfig.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/ImageReaderOutputConfig.java
index 98f4249..79965c9 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/ImageReaderOutputConfig.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/ImageReaderOutputConfig.java
@@ -19,10 +19,12 @@
import android.util.Size;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
/**
* Surface will be created by constructing an ImageReader.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface ImageReaderOutputConfig extends Camera2OutputConfig {
/**
* Returns the size of the surface.
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/ImageReference.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/ImageReference.java
index 43d866f..c3b88c6 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/ImageReference.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/ImageReference.java
@@ -19,6 +19,7 @@
import android.media.Image;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
/**
* An Image reference container that enables the Image sharing between Camera2/CameraX and OEM
@@ -27,6 +28,7 @@
*
* <p>Implemented by Camera2/CameraX.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface ImageReference {
/**
* Increment the reference count. Returns true if the value was incremented.
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/MultiResolutionImageReaderOutputConfig.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/MultiResolutionImageReaderOutputConfig.java
index 21fd271..7a33619 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/MultiResolutionImageReaderOutputConfig.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/MultiResolutionImageReaderOutputConfig.java
@@ -16,9 +16,12 @@
package androidx.camera.extensions.internal.sessionprocessor;
+import androidx.annotation.RequiresApi;
+
/**
* Surface will be created by constructing a MultiResolutionImageReader.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface MultiResolutionImageReaderOutputConfig extends Camera2OutputConfig {
/**
* Gets the image format of the surface.
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 1ec8a84..7b61ff4 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
@@ -27,6 +27,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
+import androidx.annotation.RequiresApi;
import androidx.camera.camera2.impl.Camera2ImplConfig;
import androidx.camera.camera2.interop.Camera2CameraInfo;
import androidx.camera.camera2.interop.ExperimentalCamera2Interop;
@@ -49,6 +50,7 @@
* Base class for SessionProcessor implementation. It is responsible for creating image readers and
* maintaining the {@link ImageProcessor} associated with the image reader.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
abstract class SessionProcessorBase implements SessionProcessor {
private static final String TAG = "SessionProcessorBase";
@NonNull
@@ -190,6 +192,7 @@
protected abstract void deInitSessionInternal();
+ @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
private static class ImageRefHolder implements ImageReference {
private int mRefCount;
private Image mImage;
diff --git a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/SurfaceOutputConfig.java b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/SurfaceOutputConfig.java
index 15f494b..4881283 100644
--- a/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/SurfaceOutputConfig.java
+++ b/camera/camera-extensions/src/main/java/androidx/camera/extensions/internal/sessionprocessor/SurfaceOutputConfig.java
@@ -19,10 +19,12 @@
import android.view.Surface;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
/**
* Use Surface directly to create the OutputConfiguration.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface SurfaceOutputConfig extends Camera2OutputConfig {
/**
* Get the {@link Surface}. It'll return a valid surface only when type is TYPE_SURFACE.
diff --git a/camera/camera-testlib-extensions/build.gradle b/camera/camera-testlib-extensions/build.gradle
index deb9bbd..077c748 100644
--- a/camera/camera-testlib-extensions/build.gradle
+++ b/camera/camera-testlib-extensions/build.gradle
@@ -29,7 +29,6 @@
android {
defaultConfig {
- minSdkVersion 21
versionCode 1
multiDexEnabled true
}
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
index 6154482..e1f6033 100755
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
@@ -30,6 +30,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -44,6 +45,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class AutoImageCaptureExtenderImpl implements ImageCaptureExtenderImpl {
private static final String TAG = "AutoICExtender";
private static final int DEFAULT_STAGE_ID = 0;
@@ -84,59 +86,11 @@
@Override
public CaptureProcessorImpl getCaptureProcessor() {
- CaptureProcessorImpl captureProcessor =
- new CaptureProcessorImpl() {
- private ImageWriter mImageWriter;
-
- @Override
- public void onOutputSurface(Surface surface, int imageFormat) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- mImageWriter = ImageWriter.newInstance(surface, 1);
- }
- }
-
- @Override
- public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results) {
- Log.d(TAG, "Started auto CaptureProcessor");
-
- Pair<Image, TotalCaptureResult> result = results.get(DEFAULT_STAGE_ID);
-
- if (result == null) {
- Log.w(TAG,
- "Unable to process since images does not contain all stages.");
- return;
- } else {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- Image image = mImageWriter.dequeueInputImage();
-
- // Do processing here
- ByteBuffer yByteBuffer = image.getPlanes()[0].getBuffer();
- ByteBuffer uByteBuffer = image.getPlanes()[2].getBuffer();
- ByteBuffer vByteBuffer = image.getPlanes()[1].getBuffer();
-
- // Sample here just simply copy/paste the capture image result
- yByteBuffer.put(result.first.getPlanes()[0].getBuffer());
- uByteBuffer.put(result.first.getPlanes()[2].getBuffer());
- vByteBuffer.put(result.first.getPlanes()[1].getBuffer());
-
- mImageWriter.queueInputImage(image);
- }
- }
-
- Log.d(TAG, "Completed auto CaptureProcessor");
- }
-
- @Override
- public void onResolutionUpdate(Size size) {
-
- }
-
- @Override
- public void onImageFormatUpdate(int imageFormat) {
-
- }
- };
- return captureProcessor;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ return new AutoImageCaptureExtenderCaptureProcessorImpl();
+ } else {
+ return new NoOpCaptureProcessorImpl();
+ }
}
@Override
@@ -201,4 +155,54 @@
public Range<Long> getEstimatedCaptureLatencyRange(@Nullable Size captureOutputSize) {
return new Range<>(300L, 1000L);
}
+
+ @RequiresApi(23)
+ static final class AutoImageCaptureExtenderCaptureProcessorImpl implements
+ CaptureProcessorImpl {
+ private ImageWriter mImageWriter;
+
+ @Override
+ public void onOutputSurface(Surface surface, int imageFormat) {
+ mImageWriter = ImageWriter.newInstance(surface, 1);
+ }
+
+ @Override
+ public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results) {
+ Log.d(TAG, "Started auto CaptureProcessor");
+
+ Pair<Image, TotalCaptureResult> result = results.get(DEFAULT_STAGE_ID);
+
+ if (result == null) {
+ Log.w(TAG,
+ "Unable to process since images does not contain all stages.");
+ return;
+ } else {
+ Image image = mImageWriter.dequeueInputImage();
+
+ // Do processing here
+ ByteBuffer yByteBuffer = image.getPlanes()[0].getBuffer();
+ ByteBuffer uByteBuffer = image.getPlanes()[2].getBuffer();
+ ByteBuffer vByteBuffer = image.getPlanes()[1].getBuffer();
+
+ // Sample here just simply copy/paste the capture image result
+ yByteBuffer.put(result.first.getPlanes()[0].getBuffer());
+ uByteBuffer.put(result.first.getPlanes()[2].getBuffer());
+ vByteBuffer.put(result.first.getPlanes()[1].getBuffer());
+
+ mImageWriter.queueInputImage(image);
+ }
+
+ Log.d(TAG, "Completed auto CaptureProcessor");
+ }
+
+ @Override
+ public void onResolutionUpdate(Size size) {
+
+ }
+
+ @Override
+ public void onImageFormatUpdate(int imageFormat) {
+
+ }
+ }
}
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
index 0814b3d..e2aabfa 100755
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
@@ -24,6 +24,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.util.List;
@@ -35,6 +36,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class AutoPreviewExtenderImpl implements PreviewExtenderImpl {
private static final int DEFAULT_STAGE_ID = 0;
private static final int SESSION_STAGE_ID = 101;
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
index 8380a7f..89871c8 100755
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
@@ -32,6 +32,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -46,6 +47,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class BeautyImageCaptureExtenderImpl implements ImageCaptureExtenderImpl {
private static final String TAG = "BeautyICExtender";
private static final int DEFAULT_STAGE_ID = 0;
@@ -89,59 +91,11 @@
@Override
public CaptureProcessorImpl getCaptureProcessor() {
- CaptureProcessorImpl captureProcessor =
- new CaptureProcessorImpl() {
- private ImageWriter mImageWriter;
-
- @Override
- public void onOutputSurface(Surface surface, int imageFormat) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- mImageWriter = ImageWriter.newInstance(surface, 1);
- }
- }
-
- @Override
- public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results) {
- Log.d(TAG, "Started beauty CaptureProcessor");
-
- Pair<Image, TotalCaptureResult> result = results.get(DEFAULT_STAGE_ID);
-
- if (result == null) {
- Log.w(TAG,
- "Unable to process since images does not contain all stages.");
- return;
- } else {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- Image image = mImageWriter.dequeueInputImage();
-
- // Do processing here
- ByteBuffer yByteBuffer = image.getPlanes()[0].getBuffer();
- ByteBuffer uByteBuffer = image.getPlanes()[2].getBuffer();
- ByteBuffer vByteBuffer = image.getPlanes()[1].getBuffer();
-
- // Sample here just simply copy/paste the capture image result
- yByteBuffer.put(result.first.getPlanes()[0].getBuffer());
- uByteBuffer.put(result.first.getPlanes()[2].getBuffer());
- vByteBuffer.put(result.first.getPlanes()[1].getBuffer());
-
- mImageWriter.queueInputImage(image);
- }
- }
-
- Log.d(TAG, "Completed beauty CaptureProcessor");
- }
-
- @Override
- public void onResolutionUpdate(Size size) {
-
- }
-
- @Override
- public void onImageFormatUpdate(int imageFormat) {
-
- }
- };
- return captureProcessor;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ return new BeautyImageCaptureExtenderCaptureProcessorImpl();
+ } else {
+ return new NoOpCaptureProcessorImpl();
+ }
}
@Override
@@ -227,4 +181,54 @@
public Range<Long> getEstimatedCaptureLatencyRange(@Nullable Size captureOutputSize) {
return new Range<>(300L, 1000L);
}
+
+ @RequiresApi(23)
+ static final class BeautyImageCaptureExtenderCaptureProcessorImpl implements
+ CaptureProcessorImpl {
+ private ImageWriter mImageWriter;
+
+ @Override
+ public void onOutputSurface(Surface surface, int imageFormat) {
+ mImageWriter = ImageWriter.newInstance(surface, 1);
+ }
+
+ @Override
+ public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results) {
+ Log.d(TAG, "Started beauty CaptureProcessor");
+
+ Pair<Image, TotalCaptureResult> result = results.get(DEFAULT_STAGE_ID);
+
+ if (result == null) {
+ Log.w(TAG,
+ "Unable to process since images does not contain all stages.");
+ return;
+ } else {
+ Image image = mImageWriter.dequeueInputImage();
+
+ // Do processing here
+ ByteBuffer yByteBuffer = image.getPlanes()[0].getBuffer();
+ ByteBuffer uByteBuffer = image.getPlanes()[2].getBuffer();
+ ByteBuffer vByteBuffer = image.getPlanes()[1].getBuffer();
+
+ // Sample here just simply copy/paste the capture image result
+ yByteBuffer.put(result.first.getPlanes()[0].getBuffer());
+ uByteBuffer.put(result.first.getPlanes()[2].getBuffer());
+ vByteBuffer.put(result.first.getPlanes()[1].getBuffer());
+
+ mImageWriter.queueInputImage(image);
+ }
+
+ Log.d(TAG, "Completed beauty CaptureProcessor");
+ }
+
+ @Override
+ public void onResolutionUpdate(Size size) {
+
+ }
+
+ @Override
+ public void onImageFormatUpdate(int imageFormat) {
+
+ }
+ }
}
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
index 4801055..a49c0e6 100755
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
@@ -26,6 +26,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.util.ArrayList;
import java.util.List;
@@ -38,6 +39,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class BeautyPreviewExtenderImpl implements PreviewExtenderImpl {
private static final int DEFAULT_STAGE_ID = 0;
private static final int SESSION_STAGE_ID = 101;
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
index f0f7c59..df88d11 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
@@ -30,6 +30,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -44,6 +45,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtenderImpl {
private static final String TAG = "BokehICExtender";
private static final int DEFAULT_STAGE_ID = 0;
@@ -84,60 +86,11 @@
@Override
public CaptureProcessorImpl getCaptureProcessor() {
- CaptureProcessorImpl captureProcessor =
- new CaptureProcessorImpl() {
- private ImageWriter mImageWriter;
-
- @Override
- public void onOutputSurface(Surface surface, int imageFormat) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- mImageWriter = ImageWriter.newInstance(surface, 1);
- }
- }
-
- @Override
- public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results) {
- Log.d(TAG, "Started bokeh CaptureProcessor");
-
- Pair<Image, TotalCaptureResult> result = results.get(DEFAULT_STAGE_ID);
-
- if (result == null) {
- Log.w(TAG,
- "Unable to process since images does not contain all stages.");
- return;
- } else {
- if (android.os.Build.VERSION.SDK_INT
- >= android.os.Build.VERSION_CODES.M) {
- Image image = mImageWriter.dequeueInputImage();
-
- // Do processing here
- ByteBuffer yByteBuffer = image.getPlanes()[0].getBuffer();
- ByteBuffer uByteBuffer = image.getPlanes()[2].getBuffer();
- ByteBuffer vByteBuffer = image.getPlanes()[1].getBuffer();
-
- // Sample here just simply copy/paste the capture image result
- yByteBuffer.put(result.first.getPlanes()[0].getBuffer());
- uByteBuffer.put(result.first.getPlanes()[2].getBuffer());
- vByteBuffer.put(result.first.getPlanes()[1].getBuffer());
-
- mImageWriter.queueInputImage(image);
- }
- }
-
- Log.d(TAG, "Completed bokeh CaptureProcessor");
- }
-
- @Override
- public void onResolutionUpdate(Size size) {
-
- }
-
- @Override
- public void onImageFormatUpdate(int imageFormat) {
-
- }
- };
- return captureProcessor;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ return new BokehImageCaptureExtenderCaptureProcessorImpl();
+ } else {
+ return new NoOpCaptureProcessorImpl();
+ }
}
@Override
@@ -202,4 +155,54 @@
public Range<Long> getEstimatedCaptureLatencyRange(@Nullable Size captureOutputSize) {
return new Range<>(300L, 1000L);
}
+
+ @RequiresApi(23)
+ static final class BokehImageCaptureExtenderCaptureProcessorImpl implements
+ CaptureProcessorImpl {
+ private ImageWriter mImageWriter;
+
+ @Override
+ public void onOutputSurface(Surface surface, int imageFormat) {
+ mImageWriter = ImageWriter.newInstance(surface, 1);
+ }
+
+ @Override
+ public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results) {
+ Log.d(TAG, "Started bokeh CaptureProcessor");
+
+ Pair<Image, TotalCaptureResult> result = results.get(DEFAULT_STAGE_ID);
+
+ if (result == null) {
+ Log.w(TAG,
+ "Unable to process since images does not contain all stages.");
+ return;
+ } else {
+ Image image = mImageWriter.dequeueInputImage();
+
+ // Do processing here
+ ByteBuffer yByteBuffer = image.getPlanes()[0].getBuffer();
+ ByteBuffer uByteBuffer = image.getPlanes()[2].getBuffer();
+ ByteBuffer vByteBuffer = image.getPlanes()[1].getBuffer();
+
+ // Sample here just simply copy/paste the capture image result
+ yByteBuffer.put(result.first.getPlanes()[0].getBuffer());
+ uByteBuffer.put(result.first.getPlanes()[2].getBuffer());
+ vByteBuffer.put(result.first.getPlanes()[1].getBuffer());
+
+ mImageWriter.queueInputImage(image);
+ }
+
+ Log.d(TAG, "Completed bokeh CaptureProcessor");
+ }
+
+ @Override
+ public void onResolutionUpdate(Size size) {
+
+ }
+
+ @Override
+ public void onImageFormatUpdate(int imageFormat) {
+
+ }
+ }
}
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
index ca6a8da..7d72e9b 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
@@ -26,6 +26,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.util.List;
@@ -37,6 +38,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class BokehPreviewExtenderImpl implements PreviewExtenderImpl {
private static final int DEFAULT_STAGE_ID = 0;
private static final int SESSION_STAGE_ID = 101;
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/CameraCharacteristicAvailability.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/CameraCharacteristicAvailability.java
index f4d6ddd..277cc61 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/CameraCharacteristicAvailability.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/CameraCharacteristicAvailability.java
@@ -20,12 +20,14 @@
import android.util.Log;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
import java.util.Arrays;
/**
* A utility class to check the availabilities of camera characteristics.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
final class CameraCharacteristicAvailability {
private static final String TAG = "CharacteristicAbility";
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
index 564e941..68731c4 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
@@ -23,6 +23,8 @@
import android.util.Size;
import android.view.Surface;
+import androidx.annotation.RequiresApi;
+
import java.util.Map;
/**
@@ -30,6 +32,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface CaptureProcessorImpl {
/**
* This gets called to update where the CaptureProcessor should write the output of {@link
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/CaptureStageImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/CaptureStageImpl.java
index c4796c2..27adb97a 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/CaptureStageImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/CaptureStageImpl.java
@@ -19,6 +19,8 @@
import android.hardware.camera2.CaptureRequest;
import android.util.Pair;
+import androidx.annotation.RequiresApi;
+
import java.util.List;
/**
@@ -26,6 +28,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface CaptureStageImpl {
/** Returns the identifier for the {@link CaptureStageImpl}. */
int getId();
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtenderStateListener.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtenderStateListener.java
index 010ce68..935673b 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtenderStateListener.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtenderStateListener.java
@@ -22,11 +22,14 @@
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.SessionConfiguration;
+import androidx.annotation.RequiresApi;
+
/**
* Provides interfaces that the OEM needs to implement to handle the state change.
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface ExtenderStateListener {
/**
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
index d3618e48..a524aea 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
@@ -18,6 +18,8 @@
import android.util.Log;
+import androidx.annotation.RequiresApi;
+
/**
* Implementation for extension version check.
*
@@ -26,6 +28,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public class ExtensionVersionImpl {
private static final String TAG = "ExtenderVersionImpl";
private static final String VERSION = "1.2.0";
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/GLImage2SurfaceRenderer.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/GLImage2SurfaceRenderer.java
index 99a3513..f35a47c 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/GLImage2SurfaceRenderer.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/GLImage2SurfaceRenderer.java
@@ -54,6 +54,8 @@
import android.util.Size;
import android.view.Surface;
+import androidx.annotation.RequiresApi;
+
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
@@ -68,6 +70,7 @@
* take as input a {@link Image} and write to a {@link android.graphics.SurfaceTexture}. It has only
* been tested on a Pixel 2XL.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
final class GLImage2SurfaceRenderer {
private static final String TAG = "GLImage2SurfaceRenderer";
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
index e41ad73..8469b34 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
@@ -32,6 +32,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -47,6 +48,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderImpl {
private static final String TAG = "HdrImageCaptureExtender";
private static final int UNDER_STAGE_ID = 0;
@@ -128,126 +130,11 @@
@Override
public CaptureProcessorImpl getCaptureProcessor() {
- CaptureProcessorImpl captureProcessor =
- new CaptureProcessorImpl() {
- private ImageWriter mImageWriter;
-
- @Override
- public void onOutputSurface(Surface surface, int imageFormat) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- mImageWriter = ImageWriter.newInstance(surface, 1);
- }
- }
-
- @Override
- public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results) {
- Log.d(TAG, "Started HDR CaptureProcessor");
-
- // Check for availability of all requested images
- if (!results.containsKey(UNDER_STAGE_ID)) {
- Log.w(TAG,
- "Unable to process since images does not contain "
- + "underexposed image.");
- return;
- }
-
- if (!results.containsKey(NORMAL_STAGE_ID)) {
- Log.w(TAG,
- "Unable to process since images does not contain normal "
- + "exposed image.");
- return;
- }
-
- if (!results.containsKey(OVER_STAGE_ID)) {
- Log.w(TAG,
- "Unable to process since images does not contain "
- + "overexposed image.");
- return;
- }
-
- // Do processing of images, our placeholder logic just copies the first
- // Image into the output buffer.
- List<Pair<Image, TotalCaptureResult>> imageDataPairs = new ArrayList<>(
- results.values());
- if (android.os.Build.VERSION.SDK_INT
- >= android.os.Build.VERSION_CODES.M) {
- Image outputImage = mImageWriter.dequeueInputImage();
-
- // Do processing here
- // The sample here simply returns the normal image result
- Image normalImage = imageDataPairs.get(NORMAL_STAGE_ID).first;
-
- if (outputImage.getWidth() != normalImage.getWidth()
- || outputImage.getHeight() != normalImage.getHeight()) {
- throw new IllegalStateException(String.format("input image "
- + "resolution [%d, %d] not the same as the "
- + "output image[%d, %d]", normalImage.getWidth(),
- normalImage.getHeight(), outputImage.getWidth(),
- outputImage.getHeight()));
- }
-
- try {
- // copy y plane
- Image.Plane inYPlane = normalImage.getPlanes()[0];
- Image.Plane outYPlane = outputImage.getPlanes()[0];
- ByteBuffer inYBuffer = inYPlane.getBuffer();
- ByteBuffer outYBuffer = outYPlane.getBuffer();
- int inYPixelStride = inYPlane.getPixelStride();
- int inYRowStride = inYPlane.getRowStride();
- int outYPixelStride = outYPlane.getPixelStride();
- int outYRowStride = outYPlane.getRowStride();
- for (int x = 0; x < outputImage.getHeight(); x++) {
- for (int y = 0; y < outputImage.getWidth(); y++) {
- int inIndex = x * inYRowStride + y * inYPixelStride;
- int outIndex = x * outYRowStride + y * outYPixelStride;
- outYBuffer.put(outIndex, inYBuffer.get(inIndex));
- }
- }
-
- // Copy UV
- for (int i = 1; i < 3; i++) {
- Image.Plane inPlane = normalImage.getPlanes()[i];
- Image.Plane outPlane = outputImage.getPlanes()[i];
- ByteBuffer inBuffer = inPlane.getBuffer();
- ByteBuffer outBuffer = outPlane.getBuffer();
- int inPixelStride = inPlane.getPixelStride();
- int inRowStride = inPlane.getRowStride();
- int outPixelStride = outPlane.getPixelStride();
- int outRowStride = outPlane.getRowStride();
- // UV are half width compared to Y
- for (int x = 0; x < outputImage.getHeight() / 2; x++) {
- for (int y = 0; y < outputImage.getWidth() / 2; y++) {
- int inIndex = x * inRowStride + y * inPixelStride;
- int outIndex = x * outRowStride + y * outPixelStride;
- byte b = inBuffer.get(inIndex);
- outBuffer.put(outIndex, b);
- }
- }
- }
- } catch (IllegalStateException e) {
- Log.e(TAG, "Error accessing the Image: " + e);
- // Since something went wrong, don't try to queue up the image.
- // Instead let the Image writing get dropped.
- return;
- }
-
- mImageWriter.queueInputImage(outputImage);
- }
-
- Log.d(TAG, "Completed HDR CaptureProcessor");
- }
-
- @Override
- public void onResolutionUpdate(Size size) {
-
- }
-
- @Override
- public void onImageFormatUpdate(int imageFormat) {
-
- }
- };
- return captureProcessor;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ return new HdrImageCaptureExtenderCaptureProcessorImpl();
+ } else {
+ return new NoOpCaptureProcessorImpl();
+ }
}
@Override
@@ -300,4 +187,119 @@
public Range<Long> getEstimatedCaptureLatencyRange(@Nullable Size captureOutputSize) {
return new Range<>(300L, 1000L);
}
+
+ @RequiresApi(23)
+ static final class HdrImageCaptureExtenderCaptureProcessorImpl implements CaptureProcessorImpl {
+ private ImageWriter mImageWriter;
+
+ @Override
+ public void onOutputSurface(Surface surface, int imageFormat) {
+ mImageWriter = ImageWriter.newInstance(surface, 1);
+ }
+
+ @Override
+ public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results) {
+ Log.d(TAG, "Started HDR CaptureProcessor");
+
+ // Check for availability of all requested images
+ if (!results.containsKey(UNDER_STAGE_ID)) {
+ Log.w(TAG,
+ "Unable to process since images does not contain "
+ + "underexposed image.");
+ return;
+ }
+
+ if (!results.containsKey(NORMAL_STAGE_ID)) {
+ Log.w(TAG,
+ "Unable to process since images does not contain normal "
+ + "exposed image.");
+ return;
+ }
+
+ if (!results.containsKey(OVER_STAGE_ID)) {
+ Log.w(TAG,
+ "Unable to process since images does not contain "
+ + "overexposed image.");
+ return;
+ }
+
+ // Do processing of images, our placeholder logic just copies the first
+ // Image into the output buffer.
+ List<Pair<Image, TotalCaptureResult>> imageDataPairs = new ArrayList<>(
+ results.values());
+ Image outputImage = mImageWriter.dequeueInputImage();
+
+ // Do processing here
+ // The sample here simply returns the normal image result
+ Image normalImage = imageDataPairs.get(NORMAL_STAGE_ID).first;
+
+ if (outputImage.getWidth() != normalImage.getWidth()
+ || outputImage.getHeight() != normalImage.getHeight()) {
+ throw new IllegalStateException(String.format("input image "
+ + "resolution [%d, %d] not the same as the "
+ + "output image[%d, %d]", normalImage.getWidth(),
+ normalImage.getHeight(), outputImage.getWidth(),
+ outputImage.getHeight()));
+ }
+
+ try {
+ // copy y plane
+ Image.Plane inYPlane = normalImage.getPlanes()[0];
+ Image.Plane outYPlane = outputImage.getPlanes()[0];
+ ByteBuffer inYBuffer = inYPlane.getBuffer();
+ ByteBuffer outYBuffer = outYPlane.getBuffer();
+ int inYPixelStride = inYPlane.getPixelStride();
+ int inYRowStride = inYPlane.getRowStride();
+ int outYPixelStride = outYPlane.getPixelStride();
+ int outYRowStride = outYPlane.getRowStride();
+ for (int x = 0; x < outputImage.getHeight(); x++) {
+ for (int y = 0; y < outputImage.getWidth(); y++) {
+ int inIndex = x * inYRowStride + y * inYPixelStride;
+ int outIndex = x * outYRowStride + y * outYPixelStride;
+ outYBuffer.put(outIndex, inYBuffer.get(inIndex));
+ }
+ }
+
+ // Copy UV
+ for (int i = 1; i < 3; i++) {
+ Image.Plane inPlane = normalImage.getPlanes()[i];
+ Image.Plane outPlane = outputImage.getPlanes()[i];
+ ByteBuffer inBuffer = inPlane.getBuffer();
+ ByteBuffer outBuffer = outPlane.getBuffer();
+ int inPixelStride = inPlane.getPixelStride();
+ int inRowStride = inPlane.getRowStride();
+ int outPixelStride = outPlane.getPixelStride();
+ int outRowStride = outPlane.getRowStride();
+ // UV are half width compared to Y
+ for (int x = 0; x < outputImage.getHeight() / 2; x++) {
+ for (int y = 0; y < outputImage.getWidth() / 2; y++) {
+ int inIndex = x * inRowStride + y * inPixelStride;
+ int outIndex = x * outRowStride + y * outPixelStride;
+ byte b = inBuffer.get(inIndex);
+ outBuffer.put(outIndex, b);
+ }
+ }
+ }
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Error accessing the Image: " + e);
+ // Since something went wrong, don't try to queue up the image.
+ // Instead let the Image writing get dropped.
+ return;
+ }
+
+ mImageWriter.queueInputImage(outputImage);
+
+ Log.d(TAG, "Completed HDR CaptureProcessor");
+ }
+
+ @Override
+ public void onResolutionUpdate(Size size) {
+
+ }
+
+ @Override
+ public void onImageFormatUpdate(int imageFormat) {
+
+ }
+ }
}
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
index 2e44ba9..264dfd5 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
@@ -26,6 +26,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.util.List;
@@ -37,6 +38,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class HdrPreviewExtenderImpl implements PreviewExtenderImpl {
private static final int DEFAULT_STAGE_ID = 0;
@@ -79,7 +81,38 @@
return null;
}
- private PreviewImageProcessorImpl mProcessor = new PreviewImageProcessorImpl() {
+ private final PreviewImageProcessorImpl mProcessor =
+ new HdrPreviewExtenderPreviewImageProcessorImpl();
+
+ @Override
+ public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
+ Context context) {
+ mRenderer = new GLImage2SurfaceRenderer();
+ }
+
+ @Override
+ public void onDeInit() {
+ mRenderer.close();
+ mRenderer = null;
+ }
+
+ @Override
+ public CaptureStageImpl onPresetSession() {
+ return null;
+ }
+
+ @Override
+ public CaptureStageImpl onEnableSession() {
+ return null;
+ }
+
+ @Override
+ public CaptureStageImpl onDisableSession() {
+ return null;
+ }
+
+ @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+ final class HdrPreviewExtenderPreviewImageProcessorImpl implements PreviewImageProcessorImpl {
Surface mSurface;
Size mSize;
@@ -112,32 +145,5 @@
public void onImageFormatUpdate(int imageFormat) {
}
- };
-
- @Override
- public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
- Context context) {
- mRenderer = new GLImage2SurfaceRenderer();
- }
-
- @Override
- public void onDeInit() {
- mRenderer.close();
- mRenderer = null;
- }
-
- @Override
- public CaptureStageImpl onPresetSession() {
- return null;
- }
-
- @Override
- public CaptureStageImpl onEnableSession() {
- return null;
- }
-
- @Override
- public CaptureStageImpl onDisableSession() {
- return null;
}
}
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
index 884c0dd..f47a1a0 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
@@ -23,6 +23,7 @@
import android.util.Size;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.util.List;
@@ -31,6 +32,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface ImageCaptureExtenderImpl extends ExtenderStateListener {
/**
* Indicates whether the extension is supported on the device.
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/InitializerImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/InitializerImpl.java
index fc245c8..66892da 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/InitializerImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/InitializerImpl.java
@@ -20,6 +20,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
@@ -31,6 +32,7 @@
*
* @since 1.1
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public class InitializerImpl {
private InitializerImpl() {
}
@@ -116,6 +118,7 @@
/**
* Callback that gets called when the library has finished initializing and is ready for used.
*/
+ @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface OnExtensionsInitializedCallback {
/** Called if the library successfully initializes. */
void onSuccess();
@@ -135,6 +138,7 @@
* {@link #init(String, Context, OnExtensionsInitializedCallback, Executor)} can be called
* again regardless of whether or not the deinitialization has succeeded or failed.
*/
+ @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface OnExtensionsDeinitializedCallback {
/** Called if the library successfully deinitializes. */
void onSuccess();
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
index 405da8d..6d84fa0 100755
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
@@ -30,6 +30,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -44,6 +45,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class NightImageCaptureExtenderImpl implements ImageCaptureExtenderImpl {
private static final String TAG = "NightICExtender";
private static final int DEFAULT_STAGE_ID = 0;
@@ -84,59 +86,11 @@
@Override
public CaptureProcessorImpl getCaptureProcessor() {
- CaptureProcessorImpl captureProcessor =
- new CaptureProcessorImpl() {
- private ImageWriter mImageWriter;
-
- @Override
- public void onOutputSurface(Surface surface, int imageFormat) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- mImageWriter = ImageWriter.newInstance(surface, 1);
- }
- }
-
- @Override
- public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results) {
- Log.d(TAG, "Started night CaptureProcessor");
-
- Pair<Image, TotalCaptureResult> result = results.get(DEFAULT_STAGE_ID);
-
- if (result == null) {
- Log.w(TAG,
- "Unable to process since images does not contain all stages.");
- return;
- } else {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- Image image = mImageWriter.dequeueInputImage();
-
- // Do processing here
- ByteBuffer yByteBuffer = image.getPlanes()[0].getBuffer();
- ByteBuffer uByteBuffer = image.getPlanes()[2].getBuffer();
- ByteBuffer vByteBuffer = image.getPlanes()[1].getBuffer();
-
- // Sample here just simply copy/paste the capture image result
- yByteBuffer.put(result.first.getPlanes()[0].getBuffer());
- uByteBuffer.put(result.first.getPlanes()[2].getBuffer());
- vByteBuffer.put(result.first.getPlanes()[1].getBuffer());
-
- mImageWriter.queueInputImage(image);
- }
- }
-
- Log.d(TAG, "Completed night CaptureProcessor");
- }
-
- @Override
- public void onResolutionUpdate(Size size) {
-
- }
-
- @Override
- public void onImageFormatUpdate(int imageFormat) {
-
- }
- };
- return captureProcessor;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ return new NightImageCaptureExtenderCaptureProcessorImpl();
+ } else {
+ return new NoOpCaptureProcessorImpl();
+ }
}
@Override
@@ -201,4 +155,54 @@
public Range<Long> getEstimatedCaptureLatencyRange(@Nullable Size captureOutputSize) {
return new Range<>(300L, 1000L);
}
+
+ @RequiresApi(23)
+ static final class NightImageCaptureExtenderCaptureProcessorImpl implements
+ CaptureProcessorImpl {
+ private ImageWriter mImageWriter;
+
+ @Override
+ public void onOutputSurface(Surface surface, int imageFormat) {
+ mImageWriter = ImageWriter.newInstance(surface, 1);
+ }
+
+ @Override
+ public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results) {
+ Log.d(TAG, "Started night CaptureProcessor");
+
+ Pair<Image, TotalCaptureResult> result = results.get(DEFAULT_STAGE_ID);
+
+ if (result == null) {
+ Log.w(TAG,
+ "Unable to process since images does not contain all stages.");
+ return;
+ } else {
+ Image image = mImageWriter.dequeueInputImage();
+
+ // Do processing here
+ ByteBuffer yByteBuffer = image.getPlanes()[0].getBuffer();
+ ByteBuffer uByteBuffer = image.getPlanes()[2].getBuffer();
+ ByteBuffer vByteBuffer = image.getPlanes()[1].getBuffer();
+
+ // Sample here just simply copy/paste the capture image result
+ yByteBuffer.put(result.first.getPlanes()[0].getBuffer());
+ uByteBuffer.put(result.first.getPlanes()[2].getBuffer());
+ vByteBuffer.put(result.first.getPlanes()[1].getBuffer());
+
+ mImageWriter.queueInputImage(image);
+ }
+
+ Log.d(TAG, "Completed night CaptureProcessor");
+ }
+
+ @Override
+ public void onResolutionUpdate(Size size) {
+
+ }
+
+ @Override
+ public void onImageFormatUpdate(int imageFormat) {
+
+ }
+ }
}
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
index 8bb6074..2df3724 100755
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
@@ -24,6 +24,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.util.List;
@@ -35,6 +36,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class NightPreviewExtenderImpl implements PreviewExtenderImpl {
private static final int DEFAULT_STAGE_ID = 0;
private static final int SESSION_STAGE_ID = 101;
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NoOpCaptureProcessorImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NoOpCaptureProcessorImpl.java
new file mode 100644
index 0000000..9645c43
--- /dev/null
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/NoOpCaptureProcessorImpl.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2021 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.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.hardware.camera2.TotalCaptureResult;
+import android.media.Image;
+import android.util.Pair;
+import android.util.Size;
+import android.view.Surface;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+
+import java.util.Map;
+
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+final class NoOpCaptureProcessorImpl implements CaptureProcessorImpl {
+ @Override
+ public void onOutputSurface(@NonNull Surface surface, int imageFormat) {
+
+ }
+
+ @Override
+ public void process(@NonNull Map<Integer, Pair<Image, TotalCaptureResult>> results) {
+
+ }
+
+ @Override
+ public void onResolutionUpdate(@NonNull Size size) {
+
+ }
+
+ @Override
+ public void onImageFormatUpdate(int imageFormat) {
+
+ }
+}
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/PreviewExtenderImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/PreviewExtenderImpl.java
index 4324987..4613f24 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/PreviewExtenderImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/PreviewExtenderImpl.java
@@ -23,6 +23,7 @@
import android.util.Size;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import java.util.List;
@@ -31,6 +32,7 @@
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface PreviewExtenderImpl extends ExtenderStateListener {
/** The different types of the preview processing. */
enum ProcessorType {
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/PreviewImageProcessorImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/PreviewImageProcessorImpl.java
index 7caad1a..60d3f77 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/PreviewImageProcessorImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/PreviewImageProcessorImpl.java
@@ -20,12 +20,15 @@
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
+import androidx.annotation.RequiresApi;
+
/**
* Processing a single {@link Image} and {@link TotalCaptureResult} to produce an output to a
* stream.
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface PreviewImageProcessorImpl extends ProcessorImpl {
/**
* Processes the requested image capture.
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ProcessorImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ProcessorImpl.java
index 6be328b..663a16a 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ProcessorImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/ProcessorImpl.java
@@ -19,11 +19,14 @@
import android.util.Size;
import android.view.Surface;
+import androidx.annotation.RequiresApi;
+
/**
* Processes an input image stream and produces an output image stream.
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface ProcessorImpl {
/**
* Updates where the ProcessorImpl should write the output to.
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/RequestUpdateProcessorImpl.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/RequestUpdateProcessorImpl.java
index 14637d7..d42aa2a 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/RequestUpdateProcessorImpl.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/RequestUpdateProcessorImpl.java
@@ -18,11 +18,14 @@
import android.hardware.camera2.TotalCaptureResult;
+import androidx.annotation.RequiresApi;
+
/**
* Processes a {@link TotalCaptureResult} to update a CaptureStage.
*
* @since 1.0
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public interface RequestUpdateProcessorImpl extends ProcessorImpl {
/**
* Process the {@link TotalCaptureResult} to update the {@link CaptureStageImpl}
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/RequestUpdateProcessorImpls.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/RequestUpdateProcessorImpls.java
index afbad00..45ac4ab 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/RequestUpdateProcessorImpls.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/RequestUpdateProcessorImpls.java
@@ -20,6 +20,9 @@
import android.util.Size;
import android.view.Surface;
+import androidx.annotation.RequiresApi;
+
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
class RequestUpdateProcessorImpls {
private static final RequestUpdateProcessorImpl sNoUpdateProcessor =
new RequestUpdateProcessorImpl() {
diff --git a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/SettableCaptureStage.java b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/SettableCaptureStage.java
index 66d75b9..8aecf5d 100644
--- a/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/SettableCaptureStage.java
+++ b/camera/camera-testlib-extensions/src/main/java/androidx/camera/extensions/impl/SettableCaptureStage.java
@@ -19,11 +19,14 @@
import android.hardware.camera2.CaptureRequest;
import android.util.Pair;
+import androidx.annotation.RequiresApi;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
final class SettableCaptureStage implements CaptureStageImpl {
private final int mId;