Initial import of camerax stub code

Change-Id: I46e9f31eb408bb9f12de4778ba2ead19ac047af5
Signed-off-by: Alexander Martinz <amartinz@shiftphones.com>
diff --git a/camerax-extensions/build.gradle b/camerax-extensions/build.gradle
new file mode 100644
index 0000000..43a030a
--- /dev/null
+++ b/camerax-extensions/build.gradle
@@ -0,0 +1,26 @@
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion 29
+
+    defaultConfig {
+        minSdkVersion 29
+        targetSdkVersion 29
+        versionCode 1
+        versionName "1.0"
+
+        consumerProguardFiles 'consumer-rules.pro'
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+
+}
+
+dependencies {
+    implementation "androidx.annotation:annotation:1.1.0"
+}
diff --git a/camerax-extensions/consumer-rules.pro b/camerax-extensions/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/camerax-extensions/consumer-rules.pro
diff --git a/camerax-extensions/proguard-rules.pro b/camerax-extensions/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/camerax-extensions/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/camerax-extensions/src/main/AndroidManifest.xml b/camerax-extensions/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..33ea49f
--- /dev/null
+++ b/camerax-extensions/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+<manifest package="androidx.camera.extensions.impl" />
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
new file mode 100644
index 0000000..112eb3e
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.camera.extensions.impl;
+
+import android.content.Context;
+import android.hardware.camera2.CameraCharacteristics;
+import android.util.Pair;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Stub implementation for auto image capture use case.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices.
+ *
+ * @since 1.0
+ */
+public final class AutoImageCaptureExtenderImpl implements ImageCaptureExtenderImpl {
+    public AutoImageCaptureExtenderImpl() {}
+
+    @Override
+    public boolean isExtensionAvailable(@NonNull String cameraId,
+            @Nullable CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void init(String cameraId, CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureProcessorImpl getCaptureProcessor() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<CaptureStageImpl> getCaptureStages() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public int getMaxCaptureStage() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
+            Context context) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onDeInit() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onPresetSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onEnableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onDisableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
new file mode 100644
index 0000000..100f665
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.content.Context;
+import android.hardware.camera2.CameraCharacteristics;
+import android.util.Pair;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Stub implementation for auto preview use case.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices.
+ *
+ * @since 1.0
+ */
+public final class AutoPreviewExtenderImpl implements PreviewExtenderImpl {
+    public AutoPreviewExtenderImpl() {
+    }
+
+    @Override
+    public boolean isExtensionAvailable(@NonNull String cameraId,
+            @Nullable CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void init(String cameraId, CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl getCaptureStage() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public ProcessorType getProcessorType() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public ProcessorImpl getProcessor() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
+            Context context) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onDeInit() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onPresetSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onEnableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onDisableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
new file mode 100644
index 0000000..79dbff6
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.camera.extensions.impl;
+
+import android.content.Context;
+import android.hardware.camera2.CameraCharacteristics;
+import android.util.Pair;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Stub implementation for beauty image capture use case.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices.
+ *
+ * @since 1.0
+ */
+public final class BeautyImageCaptureExtenderImpl implements ImageCaptureExtenderImpl {
+    public BeautyImageCaptureExtenderImpl() {}
+
+    @Override
+    public boolean isExtensionAvailable(@NonNull String cameraId,
+            @Nullable CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void init(String cameraId, CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureProcessorImpl getCaptureProcessor() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<CaptureStageImpl> getCaptureStages() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public int getMaxCaptureStage() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
+            Context context) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onDeInit() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onPresetSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onEnableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onDisableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
new file mode 100644
index 0000000..bc3e48d
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.content.Context;
+import android.hardware.camera2.CameraCharacteristics;
+import android.util.Pair;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Stub implementation for beauty preview use case.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices.
+ *
+ * @since 1.0
+ */
+public final class BeautyPreviewExtenderImpl implements PreviewExtenderImpl {
+    public BeautyPreviewExtenderImpl() {
+    }
+
+    @Override
+    public boolean isExtensionAvailable(@NonNull String cameraId,
+            @Nullable CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void init(String cameraId, CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl getCaptureStage() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public ProcessorType getProcessorType() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public ProcessorImpl getProcessor() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
+            Context context) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onDeInit() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onPresetSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onEnableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onDisableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
new file mode 100644
index 0000000..dc823c1
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.camera.extensions.impl;
+
+import android.content.Context;
+import android.hardware.camera2.CameraCharacteristics;
+import android.util.Pair;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Stub implementation for bokeh image capture use case.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices.
+ *
+ * @since 1.0
+ */
+public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtenderImpl {
+    public BokehImageCaptureExtenderImpl() {}
+
+    @Override
+    public boolean isExtensionAvailable(@NonNull String cameraId,
+            @Nullable CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void init(String cameraId, CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureProcessorImpl getCaptureProcessor() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<CaptureStageImpl> getCaptureStages() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public int getMaxCaptureStage() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
+            Context context) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onDeInit() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onPresetSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onEnableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onDisableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
new file mode 100644
index 0000000..ff58862
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.camera.extensions.impl;
+
+import android.content.Context;
+import android.hardware.camera2.CameraCharacteristics;
+import android.util.Pair;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Stub implementation for bokeh preview use case.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices.
+ *
+ * @since 1.0
+ */
+public final class BokehPreviewExtenderImpl implements PreviewExtenderImpl {
+    public BokehPreviewExtenderImpl() {}
+
+    @Override
+    public boolean isExtensionAvailable(@NonNull String cameraId,
+            @Nullable CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void init(String cameraId, CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl getCaptureStage() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public ProcessorType getProcessorType() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public ProcessorImpl getProcessor() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
+            Context context) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onDeInit() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onPresetSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onEnableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onDisableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
new file mode 100644
index 0000000..a42275e
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.hardware.camera2.TotalCaptureResult;
+import android.media.Image;
+import android.util.Pair;
+import android.view.Surface;
+
+import java.util.Map;
+
+/**
+ * The interface for processing a set of {@link Image}s that have captured.
+ *
+ * @since 1.0
+ */
+public interface CaptureProcessorImpl extends ProcessorImpl {
+    /**
+     * Process a set images captured that were requested.
+     *
+     * <p> The result of the processing step should be written to the {@link Surface} that was
+     * received by {@link #onOutputSurface(Surface, int)}.
+     *
+     * @param results The map of images and metadata to process. The {@link Image} that are
+     *                contained within the map will become invalid after this method completes,
+     *                so no references to them should be kept.
+     */
+    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results);
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/CaptureStageImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/CaptureStageImpl.java
new file mode 100644
index 0000000..c4796c2
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/CaptureStageImpl.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.hardware.camera2.CaptureRequest;
+import android.util.Pair;
+
+import java.util.List;
+
+/**
+ * The set of parameters that defines a single capture that will be sent to the camera.
+ *
+ * @since 1.0
+ */
+public interface CaptureStageImpl {
+    /** Returns the identifier for the {@link CaptureStageImpl}. */
+    int getId();
+
+    /**
+     * Returns the set of {@link CaptureRequest.Key} and the corresponding values that will be
+     * set for a single {@link CaptureRequest}.
+     */
+    List<Pair<CaptureRequest.Key, Object>> getParameters();
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/ExtenderStateListener.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/ExtenderStateListener.java
new file mode 100644
index 0000000..f1817a7
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/ExtenderStateListener.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.content.Context;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+
+/**
+ * Provides interfaces that the OEM needs to implement to handle the state change.
+ *
+ * @since 1.0
+ */
+public interface ExtenderStateListener {
+
+    /**
+     * Notify to initialize the extension. This will be called after bindToLifeCycle. This is
+     * where the use case is started and would be able to allocate resources here. After onInit() is
+     * called, the camera ID, cameraCharacteristics and context will not change until onDeInit()
+     * has been called.
+     *
+     * @param cameraId The camera2 id string of the camera.
+     * @param cameraCharacteristics The {@link CameraCharacteristics} of the camera.
+     * @param context The {@link Context} used for CameraX.
+     */
+    void onInit(String cameraId, CameraCharacteristics cameraCharacteristics, Context context);
+
+    /**
+     * Notify to de-initialize the extension. This callback will be invoked after unbind.
+     * After onDeInit() was called, it is expected that the camera ID, cameraCharacteristics will
+     * no longer hold, this should be where to clear all resources allocated for this use case.
+     */
+    void onDeInit();
+
+    /**
+     * This will be invoked before creating a
+     * {@link android.hardware.camera2.CameraCaptureSession}. The {@link CaptureRequest}
+     * parameters returned via {@link CaptureStageImpl} will be passed to the camera device as
+     * part of the capture session initialization via setSessionParameters(). The valid parameter
+     * is a subset of the available capture request parameters.
+     *
+     * @return The request information to set the session wide camera parameters.
+     */
+    CaptureStageImpl onPresetSession();
+
+    /**
+     * This will be invoked once after the {@link android.hardware.camera2.CameraCaptureSession}
+     * has been created. The {@link CaptureRequest} parameters returned via
+     * {@link CaptureStageImpl} will be used to generate a single request to the current
+     * configured {@link CameraDevice}. The generated request will be submitted to camera before
+     * processing other single requests.
+     *
+     * @return The request information to create a single capture request to camera device.
+     */
+    CaptureStageImpl onEnableSession();
+
+    /**
+     * This will be invoked before the {@link android.hardware.camera2.CameraCaptureSession} is
+     * closed. The {@link CaptureRequest} parameters returned via {@link CaptureStageImpl} will
+     * be used to generate a single request to the currently configured {@link CameraDevice}. The
+     * generated request will be submitted to camera before the CameraCaptureSession is closed.
+     *
+     * @return The request information to customize the session.
+     */
+    CaptureStageImpl onDisableSession();
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
new file mode 100644
index 0000000..7f3bbe2
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+/**
+ * Stub implementation for the extension version check.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices.
+ *
+ * @since 1.0
+ */
+public class ExtensionVersionImpl {
+    public ExtensionVersionImpl() {
+    }
+
+    /**
+     * Provide the current CameraX extension library version to vendor library and vendor would
+     * need to return the supported version for this device. If the returned version is not
+     * supported by CameraX library, the Preview and ImageCapture would not be able to enable the
+     * specific effects provided by the vendor.
+     *
+     * <p>CameraX library provides the Semantic Versioning string in a form of
+     * MAJOR.MINOR.PATCH-description
+     * We will increment the
+     * MAJOR version when make incompatible API changes,
+     * MINOR version when add functionality in a backwards-compatible manner, and
+     * PATCH version when make backwards-compatible bug fixes. And the description can be ignored.
+     *
+     * <p>Vendor library should provide MAJOR.MINOR.PATCH to CameraX. The MAJOR and MINOR
+     * version is used to map to the version of CameraX that it supports, and CameraX extension
+     * would only available when MAJOR version is matched with CameraX current version. The PATCH
+     * version does not indicate compatibility. The patch version should be incremented whenever
+     * the vendor library makes bug fixes or updates to the algorithm.
+     *
+     * @param version the version of CameraX library formatted as MAJOR.MINOR.PATCH-description.
+     * @return the version that vendor supported in this device. The MAJOR.MINOR.PATCH format
+     * should be used.
+     */
+    public String checkApiVersion(String version) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
new file mode 100644
index 0000000..a277fba
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.camera.extensions.impl;
+
+import android.content.Context;
+import android.hardware.camera2.CameraCharacteristics;
+import android.util.Pair;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Stub implementation for HDR image capture use case.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices.
+ *
+ * @since 1.0
+ */
+public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderImpl {
+    public HdrImageCaptureExtenderImpl() {}
+
+    @Override
+    public boolean isExtensionAvailable(@NonNull String cameraId,
+            @Nullable CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void init(String cameraId, CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureProcessorImpl getCaptureProcessor() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<CaptureStageImpl> getCaptureStages() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public int getMaxCaptureStage() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
+            Context context) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onDeInit() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onPresetSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onEnableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onDisableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
new file mode 100644
index 0000000..0eb4a61
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.content.Context;
+import android.hardware.camera2.CameraCharacteristics;
+import android.util.Pair;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Stub implementation for HDR preview use case.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices.
+ *
+ * @since 1.0
+ */
+public final class HdrPreviewExtenderImpl implements PreviewExtenderImpl {
+    public HdrPreviewExtenderImpl() {
+    }
+
+    @Override
+    public boolean isExtensionAvailable(@NonNull String cameraId,
+            @Nullable CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void init(String cameraId, CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl getCaptureStage() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public ProcessorType getProcessorType() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public ProcessorImpl getProcessor() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
+            Context context) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onDeInit() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onPresetSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onEnableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onDisableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
new file mode 100644
index 0000000..b95c047
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.graphics.ImageFormat;
+import android.hardware.camera2.CameraCharacteristics;
+import android.util.Pair;
+import android.util.Size;
+
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Provides abstract methods that the OEM needs to implement to enable extensions for image capture.
+ *
+ * @since 1.0
+ */
+public interface ImageCaptureExtenderImpl extends ExtenderStateListener {
+    /**
+     * Indicates whether the extension is supported on the device.
+     *
+     * @param cameraId The camera2 id string of the camera.
+     * @param cameraCharacteristics The {@link CameraCharacteristics} of the camera.
+     * @return true if the extension is supported, otherwise false
+     */
+    boolean isExtensionAvailable(String cameraId, CameraCharacteristics cameraCharacteristics);
+
+    /**
+     * Initializes the extender to be used with the specified camera.
+     *
+     * <p>This should be called before any other method on the extender. The exception is {@link
+     * #isExtensionAvailable(String, CameraCharacteristics)}.
+     *
+     * @param cameraId The camera2 id string of the camera.
+     * @param cameraCharacteristics The {@link CameraCharacteristics} of the camera.
+     */
+    void init(String cameraId, CameraCharacteristics cameraCharacteristics);
+
+    /**
+     * The processing that will be done on a set of captures to create and image with the effect.
+     */
+    CaptureProcessorImpl getCaptureProcessor();
+
+    /** The set of captures that are needed to create an image with the effect. */
+    List<CaptureStageImpl> getCaptureStages();
+
+    /**
+     * Returns the maximum size of the list returned by {@link #getCaptureStages()}.
+     * @return the maximum count.
+     */
+    int getMaxCaptureStage();
+
+    /**
+     * Returns the customized supported resolutions.
+     *
+     * <p>Pair list composed with {@link ImageFormat} and {@link Size} array will be returned.
+     *
+     * <p>The returned resolutions should be subset of the supported sizes retrieved from
+     * {@link android.hardware.camera2.params.StreamConfigurationMap} for the camera device. If the
+     * returned list is not null, it will be used to find the best resolutions combination for
+     * the bound use cases.
+     *
+     * @return the customized supported resolutions.
+     * @since 1.1
+     */
+    @Nullable
+    List<Pair<Integer, Size[]>> getSupportedResolutions();
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/InitializerImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/InitializerImpl.java
new file mode 100644
index 0000000..779a2ee
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/InitializerImpl.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Used for initializing the extensions library.
+ *
+ * @since 1.1
+ */
+public class InitializerImpl {
+    private InitializerImpl() {
+    }
+
+    /** An unknown error has occurred. */
+    public static final int ERROR_UNKNOWN = 0;
+
+    /**
+     * Error reported if the application version of extensions is incompatible with the on device
+     * library version.
+     */
+    public static final int ERROR_INITIALIZE_VERSION_INCOMPATIBLE = 1;
+
+    /**
+     * Initializes the {@link Context}.
+     *
+     * <p>Before this call has been made no calls to the extensions library should be made except
+     * for {@link ExtensionVersionImpl#checkApiVersion(String)}.
+     *
+     * @param version  The version of the extension used by the application.
+     * @param context  The {@link Context} of the calling application.
+     * @param executor The executor to run the callback on. If null then the callback will run on
+     *                 any arbitrary executor.
+     */
+    public static void init(@NonNull String version, @NonNull Context context,
+            @NonNull OnExtensionsInitializedCallback callback, @Nullable Executor executor) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    /**
+     * Deinitializes the extensions to release resources.
+     *
+     * <p>After this call has been made no calls to the extensions library should be made except
+     * for {@link ExtensionVersionImpl#checkApiVersion(String)}.
+     *
+     * @param executor The executor to run the callback on. If null then the callback will run on
+     *                 any arbitrary executor.
+     */
+    public static void deinit(@NonNull OnExtensionsDeinitializedCallback callback,
+            @Nullable Executor executor) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    /**
+     * Callback that gets called when the library has finished initializing and is ready for used.
+     */
+    public interface OnExtensionsInitializedCallback {
+        /** Called if the library successfully initializes. */
+        void onSuccess();
+
+        /**
+         * Called if the library is unable to successfully initialize.
+         *
+         * @param error The reason for failing to initialize.
+         */
+        void onFailure(int error);
+    }
+
+    /**
+     * Callback that gets called when the library has finished deinitialized.
+     *
+     * <p> Once this interface has been called then
+     * {@link #init(String, Context, OnExtensionsInitializedCallback, Executor)} can be called
+     * again regardless of whether or not the deinitialization has succeeded or failed.
+     */
+    public interface OnExtensionsDeinitializedCallback {
+        /**
+         * Called if the library successfully deinitializes.
+         */
+        void onSuccess();
+
+        /**
+         * Called if the library encountered some error during the deinitialization.
+         *
+         * <p>Even if the library fails to deinitialize it is now valid for
+         * {@link #init(String, Context, OnExtensionsInitializedCallback, Executor)} to be called
+         * again.
+         *
+         * @param error The reason for failing to deinitialize.
+         */
+        void onFailure(int error);
+    }
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
new file mode 100644
index 0000000..8570fd3
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.camera.extensions.impl;
+
+import android.content.Context;
+import android.hardware.camera2.CameraCharacteristics;
+import android.util.Pair;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Stub implementation for night image capture use case.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices.
+ *
+ * @since 1.0
+ */
+public final class NightImageCaptureExtenderImpl implements ImageCaptureExtenderImpl {
+    public NightImageCaptureExtenderImpl() {}
+
+    @Override
+    public boolean isExtensionAvailable(@NonNull String cameraId,
+            @Nullable CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void init(String cameraId, CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureProcessorImpl getCaptureProcessor() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<CaptureStageImpl> getCaptureStages() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public int getMaxCaptureStage() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
+            Context context) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onDeInit() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onPresetSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onEnableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onDisableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
new file mode 100644
index 0000000..a5809f6
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.content.Context;
+import android.hardware.camera2.CameraCharacteristics;
+import android.util.Pair;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Stub implementation for night preview use case.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices.
+ *
+ * @since 1.0
+ */
+public final class NightPreviewExtenderImpl implements PreviewExtenderImpl {
+    public NightPreviewExtenderImpl() {
+    }
+
+    @Override
+    public boolean isExtensionAvailable(@NonNull String cameraId,
+            @Nullable CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void init(String cameraId, CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl getCaptureStage() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public ProcessorType getProcessorType() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public ProcessorImpl getProcessor() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
+            Context context) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void onDeInit() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onPresetSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onEnableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public CaptureStageImpl onDisableSession() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public List<Pair<Integer, Size[]>> getSupportedResolutions() {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/PreviewExtenderImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/PreviewExtenderImpl.java
new file mode 100644
index 0000000..4324987
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/PreviewExtenderImpl.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.graphics.ImageFormat;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.TotalCaptureResult;
+import android.util.Pair;
+import android.util.Size;
+
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Provides abstract methods that the OEM needs to implement to enable extensions in the preview.
+ *
+ * @since 1.0
+ */
+public interface PreviewExtenderImpl extends ExtenderStateListener {
+    /** The different types of the preview processing. */
+    enum ProcessorType {
+        /** Processor which only updates the {@link CaptureStageImpl}. */
+        PROCESSOR_TYPE_REQUEST_UPDATE_ONLY,
+        /** Processor which updates the received {@link android.media.Image}. */
+        PROCESSOR_TYPE_IMAGE_PROCESSOR,
+        /** No processor, only a {@link CaptureStageImpl} is defined. */
+        PROCESSOR_TYPE_NONE
+    }
+
+    /**
+     * Indicates whether the extension is supported on the device.
+     *
+     * @param cameraId The camera2 id string of the camera.
+     * @param cameraCharacteristics The {@link CameraCharacteristics} of the camera.
+     * @return true if the extension is supported, otherwise false
+     */
+    boolean isExtensionAvailable(String cameraId, CameraCharacteristics cameraCharacteristics);
+
+    /**
+     * Initializes the extender to be used with the specified camera.
+     *
+     * <p>This should be called before any other method on the extender. The exception is {@link
+     * #isExtensionAvailable(String, CameraCharacteristics)}.
+     *
+     * @param cameraId The camera2 id string of the camera.
+     * @param cameraCharacteristics The {@link CameraCharacteristics} of the camera.
+     */
+    void init(String cameraId, CameraCharacteristics cameraCharacteristics);
+
+    /**
+     * The set of parameters required to produce the effect on the preview stream.
+     *
+     * <p> This will be the initial set of parameters used for the preview
+     * {@link android.hardware.camera2.CaptureRequest}. If the {@link ProcessorType} is defined as
+     * {@link ProcessorType#PROCESSOR_TYPE_REQUEST_UPDATE_ONLY} then this will be updated when
+     * the {@link RequestUpdateProcessorImpl#process(TotalCaptureResult)} from {@link
+     * #getProcessor()} has been called, this should be updated to reflect the new {@link
+     * CaptureStageImpl}. If the processing step returns a {@code null}, meaning the required
+     * parameters has not changed, then calling this will return the previous non-null value.
+     */
+    CaptureStageImpl getCaptureStage();
+
+    /** The type of preview processing to use. */
+    ProcessorType getProcessorType();
+
+    /**
+     * Returns a processor which only updates the {@link CaptureStageImpl}.
+     *
+     * <p>The type of processor is dependent on the return of {@link #getProcessorType()}. The
+     * type of ProcessorImpl returned will be according to the following table.
+     *
+     * <table>
+     * <tr><th> ProcessorType </th> <th> ProcessorImpl </th> </tr>
+     * <tr><td> PROCESSOR_TYPE_REQUEST_UPDATE_ONLY </td> <td> RequestUpdateProcessorImpl </td> </tr>
+     * <tr><td> PROCESSOR_TYPE_IMAGE_PROCESSOR </td> <td> PreviewImageProcessorImpl </td> </tr>
+     * <tr><td> PROCESSOR_TYPE_NONE </td> <td> null </td> </tr>
+     * </table>
+     */
+    ProcessorImpl getProcessor();
+
+    /**
+     * Returns the customized supported resolutions.
+     *
+     * <p>Pair list composed with {@link ImageFormat} and {@link Size} array will be returned.
+     *
+     * <p>The returned resolutions should be subset of the supported sizes retrieved from
+     * {@link android.hardware.camera2.params.StreamConfigurationMap} for the camera device. If the
+     * returned list is not null, it will be used to find the best resolutions combination for
+     * the bound use cases.
+     *
+     * @return the customized supported resolutions.
+     * @since 1.1
+     */
+    @Nullable
+    List<Pair<Integer, Size[]>> getSupportedResolutions();
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/PreviewImageProcessorImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/PreviewImageProcessorImpl.java
new file mode 100644
index 0000000..629f13c
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/PreviewImageProcessorImpl.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.hardware.camera2.TotalCaptureResult;
+import android.media.Image;
+
+/**
+ * Processes a single {@link Image} and {@link TotalCaptureResult} to produce an output to a
+ * stream.
+ *
+ * @since 1.0
+ */
+public interface PreviewImageProcessorImpl extends ProcessorImpl {
+    /**
+     * Processes the requested image capture.
+     *
+     * <p> The result of the processing step should be written to the {@link android.view.Surface}
+     * that was received by {@link ProcessorImpl#onOutputSurface(android.view.Surface, int)}.
+     *
+     * @param image The image to process. This will be invalid after the method completes so no
+     *              reference to it should be kept.
+     * @param result The metadata associated with the image to process.
+     */
+    void process(Image image, TotalCaptureResult result);
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/ProcessorImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/ProcessorImpl.java
new file mode 100644
index 0000000..6be328b
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/ProcessorImpl.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.util.Size;
+import android.view.Surface;
+
+/**
+ * Processes an input image stream and produces an output image stream.
+ *
+ * @since 1.0
+ */
+public interface ProcessorImpl {
+    /**
+     * Updates where the ProcessorImpl should write the output to.
+     *
+     * @param surface     The {@link Surface} that the ProcessorImpl should write data into.
+     * @param imageFormat The format of that the surface expects.
+     */
+    void onOutputSurface(Surface surface, int imageFormat);
+
+    /**
+     * Invoked when CameraX changes the configured output resolution.
+     *
+     * <p>After this call, {@link CaptureProcessorImpl} should expect any {@link Image} received as
+     * input to be at the specified resolution.
+     *
+     * @param size for the surface.
+     */
+    void onResolutionUpdate(Size size);
+
+    /**
+     * Invoked when CameraX changes the configured input image format.
+     *
+     * <p>After this call, {@link CaptureProcessorImpl} should expect any {@link Image} received as
+     * input to have the specified image format.
+     *
+     * @param imageFormat for the surface.
+     */
+    void onImageFormatUpdate(int imageFormat);
+}
diff --git a/camerax-extensions/src/main/java/androidx/camera/extensions/impl/RequestUpdateProcessorImpl.java b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/RequestUpdateProcessorImpl.java
new file mode 100644
index 0000000..14637d7
--- /dev/null
+++ b/camerax-extensions/src/main/java/androidx/camera/extensions/impl/RequestUpdateProcessorImpl.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl;
+
+import android.hardware.camera2.TotalCaptureResult;
+
+/**
+ * Processes a {@link TotalCaptureResult} to update a CaptureStage.
+ *
+ * @since 1.0
+ */
+public interface RequestUpdateProcessorImpl extends ProcessorImpl {
+    /**
+     * Process the {@link TotalCaptureResult} to update the {@link CaptureStageImpl}
+     *
+     * @param result The metadata associated with the image. Can be null if the image and meta have
+     *               not been synced.
+     * @return The updated parameters used for the repeating requests. If this is {@code null} then
+     * the previous parameters will be used.
+     */
+    CaptureStageImpl process(TotalCaptureResult result);
+}