Merge "Propogate invalidations through CompositionReferences properly" into androidx-master-dev
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index c0b1b7f7..c8ccc81 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -1,7 +1,14 @@
 <component name="InspectionProjectProfileManager">
   <profile version="1.0">
     <option name="myName" value="Project Default" />
-    <inspection_tool class="AndroidLintSyntheticAccessor" enabled="true" level="WARNING" enabled_by_default="true" />
+    <inspection_tool class="AndroidLintSyntheticAccessor" enabled="true" level="WARNING" enabled_by_default="true">
+      <scope name="Compose" level="WARNING" enabled="false" />
+    </inspection_tool>
+    <inspection_tool class="FunctionName" enabled="true" level="WEAK WARNING" enabled_by_default="true">
+      <scope name="Compose" level="WEAK WARNING" enabled="true">
+        <option name="namePattern" value="[A-Za-z\d]+" />
+      </scope>
+    </inspection_tool>
     <inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
       <option name="TOP_LEVEL_CLASS_OPTIONS">
         <value>
@@ -34,5 +41,20 @@
       <option name="myAdditionalJavadocTags" value="hide" />
     </inspection_tool>
     <inspection_tool class="MissingDeprecatedAnnotation" enabled="true" level="ERROR" enabled_by_default="true" />
+    <inspection_tool class="PrivatePropertyName" enabled="true" level="WEAK WARNING" enabled_by_default="true">
+      <scope name="Compose" level="WEAK WARNING" enabled="true">
+        <option name="namePattern" value="_?[A-Za-z\d]+" />
+      </scope>
+    </inspection_tool>
+    <inspection_tool class="PropertyName" enabled="true" level="WEAK WARNING" enabled_by_default="true">
+      <scope name="Compose" level="WEAK WARNING" enabled="true">
+        <option name="namePattern" value="[A-Za-z\d]+" />
+      </scope>
+    </inspection_tool>
+    <inspection_tool class="TestFunctionName" enabled="true" level="WEAK WARNING" enabled_by_default="true">
+      <scope name="Compose" level="WEAK WARNING" enabled="true">
+        <option name="namePattern" value="[A-Za-z_\d]+" />
+      </scope>
+    </inspection_tool>
   </profile>
-</component>
\ No newline at end of file
+</component>
diff --git a/.idea/scopes/Compose.xml b/.idea/scopes/Compose.xml
new file mode 100644
index 0000000..28eb901
--- /dev/null
+++ b/.idea/scopes/Compose.xml
@@ -0,0 +1,3 @@
+<component name="DependencyValidationManager">
+  <scope name="Compose" pattern="src:*androidx.compose..*||test:*androidx.compose..*||src:*androidx.ui..*||test:*androidx.ui..*" />
+</component>
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
index e902c1b..04d8d6c 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
@@ -20,78 +20,78 @@
  * The list of maven group names of all the libraries in this project.
  */
 object LibraryGroups {
-    val ACTIVITY = LibraryGroup("androidx.activity", false)
+    val ACTIVITY = LibraryGroup("androidx.activity")
     val ANIMATION = LibraryGroup("androidx.animation", false)
-    val ANNOTATION = LibraryGroup("androidx.annotation", false)
+    val ANNOTATION = LibraryGroup("androidx.annotation")
     val APPCOMPAT = LibraryGroup("androidx.appcompat", false)
     val ARCH_CORE = LibraryGroup("androidx.arch.core", false)
-    val ASYNCLAYOUTINFLATER = LibraryGroup("androidx.asynclayoutinflater", false)
-    val AUTOFILL = LibraryGroup("androidx.autofill", false)
-    val BIOMETRIC = LibraryGroup("androidx.biometric", false)
-    val BROWSER = LibraryGroup("androidx.browser", false)
-    val BENCHMARK = LibraryGroup("androidx.benchmark", false)
+    val ASYNCLAYOUTINFLATER = LibraryGroup("androidx.asynclayoutinflater")
+    val AUTOFILL = LibraryGroup("androidx.autofill")
+    val BIOMETRIC = LibraryGroup("androidx.biometric")
+    val BROWSER = LibraryGroup("androidx.browser")
+    val BENCHMARK = LibraryGroup("androidx.benchmark")
     val CAMERA = LibraryGroup("androidx.camera", false)
     val CAR = LibraryGroup("androidx.car", false)
-    val CARDVIEW = LibraryGroup("androidx.cardview", false)
-    val COLLECTION = LibraryGroup("androidx.collection", false)
-    val CONCURRENT = LibraryGroup("androidx.concurrent", false)
-    val CONTENTPAGER = LibraryGroup("androidx.contentpager", false)
-    val COORDINATORLAYOUT = LibraryGroup("androidx.coordinatorlayout", false)
+    val CARDVIEW = LibraryGroup("androidx.cardview")
+    val COLLECTION = LibraryGroup("androidx.collection")
+    val CONCURRENT = LibraryGroup("androidx.concurrent")
+    val CONTENTPAGER = LibraryGroup("androidx.contentpager")
+    val COORDINATORLAYOUT = LibraryGroup("androidx.coordinatorlayout")
     val COMPOSE = LibraryGroup("androidx.compose", false)
-    val CORE = LibraryGroup("androidx.core", false)
-    val CURSORADAPTER = LibraryGroup("androidx.cursoradapter", false)
-    val CUSTOMVIEW = LibraryGroup("androidx.customview", false)
-    val DOCUMENTFILE = LibraryGroup("androidx.documentfile", false)
-    val DRAWERLAYOUT = LibraryGroup("androidx.drawerlayout", false)
+    val CORE = LibraryGroup("androidx.core")
+    val CURSORADAPTER = LibraryGroup("androidx.cursoradapter")
+    val CUSTOMVIEW = LibraryGroup("androidx.customview")
+    val DOCUMENTFILE = LibraryGroup("androidx.documentfile")
+    val DRAWERLAYOUT = LibraryGroup("androidx.drawerlayout")
     val DYNAMICANIMATION = LibraryGroup("androidx.dynamicanimation", false)
     val EMOJI = LibraryGroup("androidx.emoji", false)
-    val ENTERPRISE = LibraryGroup("androidx.enterprise", false)
-    val EXIFINTERFACE = LibraryGroup("androidx.exifinterface", false)
-    val FRAGMENT = LibraryGroup("androidx.fragment", false)
-    val GRIDLAYOUT = LibraryGroup("androidx.gridlayout", false)
-    val HEIFWRITER = LibraryGroup("androidx.heifwriter", false)
-    val INTERPOLATOR = LibraryGroup("androidx.interpolator", false)
+    val ENTERPRISE = LibraryGroup("androidx.enterprise")
+    val EXIFINTERFACE = LibraryGroup("androidx.exifinterface")
+    val FRAGMENT = LibraryGroup("androidx.fragment")
+    val GRIDLAYOUT = LibraryGroup("androidx.gridlayout")
+    val HEIFWRITER = LibraryGroup("androidx.heifwriter")
+    val INTERPOLATOR = LibraryGroup("androidx.interpolator")
     val JETIFIER = LibraryGroup("com.android.tools.build.jetifier", false)
     val LEANBACK = LibraryGroup("androidx.leanback", false)
     val LEGACY = LibraryGroup("androidx.legacy", false)
     val LIFECYCLE = LibraryGroup("androidx.lifecycle", false)
-    val LOADER = LibraryGroup("androidx.loader", false)
-    val LOCALBROADCASTMANAGER = LibraryGroup("androidx.localbroadcastmanager", false)
+    val LOADER = LibraryGroup("androidx.loader")
+    val LOCALBROADCASTMANAGER = LibraryGroup("androidx.localbroadcastmanager")
     val MEDIA = LibraryGroup("androidx.media", false)
     val MEDIA2 = LibraryGroup("androidx.media2", false)
-    val MEDIAROUTER = LibraryGroup("androidx.mediarouter", false)
+    val MEDIAROUTER = LibraryGroup("androidx.mediarouter")
     val NAVIGATION = LibraryGroup("androidx.navigation", false)
     val PAGING = LibraryGroup("androidx.paging", false)
-    val PALETTE = LibraryGroup("androidx.palette", false)
-    val PERCENTLAYOUT = LibraryGroup("androidx.percentlayout", false)
+    val PALETTE = LibraryGroup("androidx.palette")
+    val PERCENTLAYOUT = LibraryGroup("androidx.percentlayout")
     val PERSISTENCE = LibraryGroup("androidx.sqlite", false)
-    val PREFERENCE = LibraryGroup("androidx.preference", false)
-    val PRINT = LibraryGroup("androidx.print", false)
-    val RECOMMENDATION = LibraryGroup("androidx.recommendation", false)
+    val PREFERENCE = LibraryGroup("androidx.preference")
+    val PRINT = LibraryGroup("androidx.print")
+    val RECOMMENDATION = LibraryGroup("androidx.recommendation")
     val RECYCLERVIEW = LibraryGroup("androidx.recyclerview", false)
-    val SAVEDSTATE = LibraryGroup("androidx.savedstate", false)
-    val SECURITY = LibraryGroup("androidx.security", false)
-    val SHARETARGET = LibraryGroup("androidx.sharetarget", false)
-    val SLICE = LibraryGroup("androidx.slice", false)
-    val REMOTECALLBACK = LibraryGroup("androidx.remotecallback", false)
+    val REMOTECALLBACK = LibraryGroup("androidx.remotecallback")
     val ROOM = LibraryGroup("androidx.room", false)
-    val SLIDINGPANELAYOUT = LibraryGroup("androidx.slidingpanelayout", false)
-    val SWIPEREFRESHLAYOUT = LibraryGroup("androidx.swiperefreshlayout", false)
-    val TEXTCLASSIFIER = LibraryGroup("androidx.textclassifier", false)
-    val TRANSITION = LibraryGroup("androidx.transition", false)
-    val TVPROVIDER = LibraryGroup("androidx.tvprovider", false)
+    val SAVEDSTATE = LibraryGroup("androidx.savedstate")
+    val SECURITY = LibraryGroup("androidx.security", false)
+    val SHARETARGET = LibraryGroup("androidx.sharetarget")
+    val SLICE = LibraryGroup("androidx.slice", false)
+    val SLIDINGPANELAYOUT = LibraryGroup("androidx.slidingpanelayout")
+    val SWIPEREFRESHLAYOUT = LibraryGroup("androidx.swiperefreshlayout")
+    val TEXTCLASSIFIER = LibraryGroup("androidx.textclassifier")
+    val TRANSITION = LibraryGroup("androidx.transition")
+    val TVPROVIDER = LibraryGroup("androidx.tvprovider")
     val UI = LibraryGroup("androidx.ui", false)
     val VECTORDRAWABLE = LibraryGroup("androidx.vectordrawable", false)
     val VERSIONEDPARCELABLE = LibraryGroup("androidx.versionedparcelable", false)
-    val VIEWPAGER = LibraryGroup("androidx.viewpager", false)
-    val VIEWPAGER2 = LibraryGroup("androidx.viewpager2", false)
-    val WEAR = LibraryGroup("androidx.wear", false)
-    val WEBKIT = LibraryGroup("androidx.webkit", false)
-    val WORKMANAGER = LibraryGroup("androidx.work", false)
+    val VIEWPAGER = LibraryGroup("androidx.viewpager")
+    val VIEWPAGER2 = LibraryGroup("androidx.viewpager2")
+    val WEAR = LibraryGroup("androidx.wear")
+    val WEBKIT = LibraryGroup("androidx.webkit")
+    val WORKMANAGER = LibraryGroup("androidx.work")
 }
 
 /**
  * This object contains the library group, as well as whether libraries
  * in this group are all required to have the same development version.
  */
-data class LibraryGroup(val group: String = "unspecified", val requireSameVersion: Boolean = false)
\ No newline at end of file
+data class LibraryGroup(val group: String = "unspecified", val requireSameVersion: Boolean = true)
diff --git a/camera/core/proguard.flags b/camera/core/proguard.flags
index d5339e5..89513b1 100644
--- a/camera/core/proguard.flags
+++ b/camera/core/proguard.flags
@@ -78,8 +78,3 @@
   public <init>(...);
 }
 
-# Keep generic types for the TypeReference class
--keepattributes Signature
-
-# Keep the TypeReference class as it uses self-inspection
--keep class * extends androidx.camera.core.TypeReference
diff --git a/camera/core/src/main/java/androidx/camera/core/Config.java b/camera/core/src/main/java/androidx/camera/core/Config.java
index 1a3b47f..8c6648e 100644
--- a/camera/core/src/main/java/androidx/camera/core/Config.java
+++ b/camera/core/src/main/java/androidx/camera/core/Config.java
@@ -21,7 +21,6 @@
 import androidx.annotation.RestrictTo.Scope;
 
 import com.google.auto.value.AutoValue;
-import com.google.auto.value.extension.memoized.Memoized;
 
 import java.util.Set;
 
@@ -167,9 +166,8 @@
          * @return An {@link Option} object which can be used to store/retrieve values from a {@link
          * Config}.
          */
-        public static <T> Option<T> create(String id, Class<T> valueClass) {
-            TypeReference<T> valueType = TypeReference.createSpecializedTypeReference(valueClass);
-            return create(id, valueType, /*token=*/ null);
+        public static <T> Option<T> create(String id, Class<?> valueClass) {
+            return Option.create(id, valueClass, /*token=*/ null);
         }
 
         /**
@@ -187,22 +185,9 @@
          * @return An {@link Option} object which can be used to store/retrieve values from a {@link
          * Config}.
          */
-        public static <T> Option<T> create(String id, Class<T> valueClass, @Nullable Object token) {
-            TypeReference<T> valueType = TypeReference.createSpecializedTypeReference(valueClass);
-            return create(id, valueType, token);
-        }
-
-        /** @hide */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        public static <T> Option<T> create(String name, TypeReference<T> valueType) {
-            return create(name, valueType, /*token=*/ null);
-        }
-
-        /** @hide */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        public static <T> Option<T> create(
-                String name, TypeReference<T> valueType, @Nullable Object token) {
-            return new AutoValue_Config_Option<>(name, valueType, token);
+        @SuppressWarnings("unchecked")
+        public static <T> Option<T> create(String id, Class<?> valueClass, @Nullable Object token) {
+            return new AutoValue_Config_Option<>(id, (Class<T>) valueClass, token);
         }
 
         /**
@@ -216,7 +201,12 @@
          */
         public abstract String getId();
 
-        abstract TypeReference<T> getTypeReference();
+        /**
+         * Returns the class object associated with the value for this option.
+         *
+         * @return The class object for the value's type.
+         */
+        public abstract Class<T> getValueClass();
 
         /**
          * Returns the optional type-erased context object for this option.
@@ -227,16 +217,5 @@
          */
         @Nullable
         public abstract Object getToken();
-
-        /**
-         * Returns the class object associated with the value for this option.
-         *
-         * @return The class object for the value's type.
-         */
-        @Memoized
-        @SuppressWarnings("unchecked")
-        public Class<T> getValueClass() {
-            return (Class<T>) getTypeReference().getRawType();
-        }
     }
 }
diff --git a/camera/core/src/main/java/androidx/camera/core/TargetConfig.java b/camera/core/src/main/java/androidx/camera/core/TargetConfig.java
index 141555d..9c9a109 100644
--- a/camera/core/src/main/java/androidx/camera/core/TargetConfig.java
+++ b/camera/core/src/main/java/androidx/camera/core/TargetConfig.java
@@ -47,8 +47,7 @@
      */
     @RestrictTo(Scope.LIBRARY_GROUP)
     Option<Class<?>> OPTION_TARGET_CLASS =
-            Option.create("camerax.core.target.class", new TypeReference<Class<?>>() {
-            });
+            Option.create("camerax.core.target.class", Class.class);
 
     // *********************************************************************************************
 
diff --git a/camera/core/src/main/java/androidx/camera/core/TypeReference.java b/camera/core/src/main/java/androidx/camera/core/TypeReference.java
deleted file mode 100644
index 36cc2bf..0000000
--- a/camera/core/src/main/java/androidx/camera/core/TypeReference.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2018 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.core;
-
-import androidx.annotation.RestrictTo;
-import androidx.annotation.RestrictTo.Scope;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-
-/**
- * Super type token; allows capturing generic types at runtime by forcing them to be reified.
- *
- * <p>Usage example:
- *
- * <pre>{@code
- *      // using anonymous classes (preferred)
- *      TypeReference&lt;Integer> intToken = new TypeReference&lt;Integer>() {{ }};
- *
- *      // using named classes
- *      class IntTypeReference extends TypeReference&lt;Integer> {...}
- *      TypeReference&lt;Integer> intToken = new IntTypeReference();
- * }</p>
- * </pre>
- *
- * <p>Unlike the reference implementation, this bans nested TypeVariables; that is all dynamic types
- * must equal to the static types.
- *
- * <p>See <a href="http://gafter.blogspot.com/2007/05/limitation-of-super-type-tokens.html">
- * http://gafter.blogspot.com/2007/05/limitation-of-super-type-tokens.html</a> for more details.
- *
- * @param <T> the type to capture
- * @hide
- */
-@RestrictTo(Scope.LIBRARY_GROUP)
-public abstract class TypeReference<T> {
-    private final Type mType;
-    private final int mHash;
-
-    /**
-     * Create a new type reference for {@code T}.
-     *
-     * @throws IllegalArgumentException if {@code T}'s actual type contains a type variable
-     * @see TypeReference
-     */
-    protected TypeReference() {
-        ParameterizedType thisType = (ParameterizedType) getClass().getGenericSuperclass();
-
-        // extract the "T" from TypeReference<T>
-        mType = thisType.getActualTypeArguments()[0];
-
-        /*
-         * Prohibit type references with type variables such as
-         *
-         *    class GenericListToken<T> extends TypeReference<List<T>>
-         *
-         * Since the "T" there is not known without an instance of T, type equality would
-         * consider *all* Lists equal regardless of T. Allowing this would defeat
-         * some of the type safety of a type reference.
-         */
-        if (containsTypeVariable(mType)) {
-            throw new IllegalArgumentException(
-                    "Including a type variable in a type reference is not allowed");
-        }
-        mHash = mType.hashCode();
-    }
-
-    TypeReference(Type type) {
-        mType = type;
-        if (containsTypeVariable(mType)) {
-            throw new IllegalArgumentException(
-                    "Including a type variable in a type reference is not allowed");
-        }
-        mHash = mType.hashCode();
-    }
-
-    /**
-     * Create a specialized type reference from a dynamic class instance, bypassing the standard
-     * compile-time checks.
-     *
-     * <p>As with a regular type reference, the {@code klass} must not contain any type variables.
-     *
-     * @param klass a non-{@code null} {@link Class} instance
-     * @return a type reference which captures {@code T} at runtime
-     * @throws IllegalArgumentException if {@code T} had any type variables
-     */
-    public static <T> TypeReference<T> createSpecializedTypeReference(Class<T> klass) {
-        return new SpecializedTypeReference<T>(klass);
-    }
-
-    private static Class<?> getRawType(Type type) {
-        if (type == null) {
-            throw new NullPointerException("type must not be null");
-        }
-
-        if (type instanceof Class<?>) {
-            return (Class<?>) type;
-        } else if (type instanceof ParameterizedType) {
-            return (Class<?>) ((ParameterizedType) type).getRawType();
-        } else if (type instanceof GenericArrayType) {
-            return getArrayClass(getRawType(((GenericArrayType) type).getGenericComponentType()));
-        } else if (type instanceof WildcardType) {
-            // Should be at most 1 upper bound, but treat it like an array for simplicity
-            return getRawType(((WildcardType) type).getUpperBounds());
-        } else if (type instanceof TypeVariable) {
-            throw new AssertionError("Type variables are not allowed in type references");
-        } else {
-            // Impossible
-            throw new AssertionError("Unhandled branch to get raw type for type " + type);
-        }
-    }
-
-    private static Class<?> getRawType(Type[] types) {
-        if (types == null) {
-            return null;
-        }
-
-        for (Type type : types) {
-            Class<?> klass = getRawType(type);
-            if (klass != null) {
-                return klass;
-            }
-        }
-
-        return null;
-    }
-
-    private static Class<?> getArrayClass(Class<?> componentType) {
-        return Array.newInstance(componentType, 0).getClass();
-    }
-
-    /**
-     * Check if the {@code type} contains a {@link TypeVariable} recursively.
-     *
-     * <p>Intuitively, a type variable is a type in a type expression that refers to a generic type
-     * which is not known at the definition of the expression (commonly seen when type parameters
-     * are used, e.g. {@code class Foo<T>}).
-     *
-     * <p>See <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4">
-     * http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4</a> for a more formal
-     * definition of a type variable.
-     *
-     * @param type a type object ({@code null} is allowed)
-     * @return {@code true} if there were nested type variables; {@code false} otherwise
-     */
-    public static boolean containsTypeVariable(Type type) {
-        if (type == null) {
-            // Trivially false
-            return false;
-        } else if (type instanceof TypeVariable<?>) {
-            /*
-             * T -> trivially true
-             */
-            return true;
-        } else if (type instanceof Class<?>) {
-            /*
-             * class Foo -> no type variable
-             * class Foo<T> - has a type variable
-             *
-             * This also covers the case of class Foo<T> extends ... / implements ...
-             * since everything on the right hand side would either include a type variable T
-             * or have no type variables.
-             */
-            Class<?> klass = (Class<?>) type;
-
-            // Empty array => class is not generic
-            if (klass.getTypeParameters().length != 0) {
-                return true;
-            } else {
-                // Does the outer class(es) contain any type variables?
-
-                /*
-                 * class Outer<T> {
-                 *   class Inner {
-                 *      T field;
-                 *   }
-                 * }
-                 *
-                 * In this case 'Inner' has no type parameters itself, but it still has a type
-                 * variable as part of the type definition.
-                 */
-                return containsTypeVariable(klass.getDeclaringClass());
-            }
-        } else if (type instanceof ParameterizedType) {
-            /*
-             * This is the "Foo<T1, T2, T3, ... Tn>" in the scope of a
-             *
-             *      // no type variables here, T1-Tn are known at this definition
-             *      class X extends Foo<T1, T2, T3, ... Tn>
-             *
-             *      // T1 is a type variable, T2-Tn are known at this definition
-             *      class X<T1> extends Foo<T1, T2, T3, ... Tn>
-             */
-            ParameterizedType p = (ParameterizedType) type;
-
-            // This needs to be recursively checked
-            for (Type arg : p.getActualTypeArguments()) {
-                if (containsTypeVariable(arg)) {
-                    return true;
-                }
-            }
-
-            return false;
-        } else if (type instanceof WildcardType) {
-            WildcardType wild = (WildcardType) type;
-
-            /*
-             * This is is the "?" inside of a
-             *
-             *       Foo<?> --> unbounded; trivially no type variables
-             *       Foo<? super T> --> lower bound; does T have a type variable?
-             *       Foo<? extends T> --> upper bound; does T have a type variable?
-             */
-
-            /*
-             *  According to JLS 4.5.1
-             *  (http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.5.1):
-             *
-             *  - More than 1 lower/upper bound is illegal
-             *  - Both a lower and upper bound is illegal
-             *
-             *  However, we use this 'array OR array' approach for readability
-             */
-            return containsTypeVariable(wild.getLowerBounds())
-                    || containsTypeVariable(wild.getUpperBounds());
-        }
-
-        return false;
-    }
-
-    /**
-     * Check if any of the elements in this array contained a type variable.
-     *
-     * <p>Empty and null arrays trivially have no type variables.
-     *
-     * @param typeArray an array ({@code null} is ok) of types
-     * @return true if any elements contained a type variable; false otherwise
-     */
-    private static boolean containsTypeVariable(Type[] typeArray) {
-        if (typeArray == null) {
-            return false;
-        }
-
-        for (Type type : typeArray) {
-            if (containsTypeVariable(type)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static void toString(Type type, StringBuilder out) {
-        if (type != null) {
-            if (type instanceof TypeVariable<?>) {
-                // T
-                out.append(((TypeVariable<?>) type).getName());
-            } else if (type instanceof Class<?>) {
-                Class<?> klass = (Class<?>) type;
-
-                out.append(klass.getName());
-                toString(klass.getTypeParameters(), out);
-            } else if (type instanceof ParameterizedType) {
-                // "Foo<T1, T2, T3, ... Tn>"
-                ParameterizedType p = (ParameterizedType) type;
-
-                out.append(((Class<?>) p.getRawType()).getName());
-                toString(p.getActualTypeArguments(), out);
-            } else if (type instanceof GenericArrayType) {
-                GenericArrayType gat = (GenericArrayType) type;
-
-                toString(gat.getGenericComponentType(), out);
-                out.append("[]");
-            } else { // WildcardType, BoundedType
-                // TODO:
-                out.append(type);
-            }
-        }
-    }
-
-    private static void toString(Type[] types, StringBuilder out) {
-        if (types == null) {
-            return;
-        } else if (types.length == 0) {
-            return;
-        }
-
-        out.append("<");
-
-        for (int i = 0; i < types.length; ++i) {
-            toString(types[i], out);
-            if (i != types.length - 1) {
-                out.append(", ");
-            }
-        }
-
-        out.append(">");
-    }
-
-    /** Return the dynamic {@link Type} corresponding to the captured type {@code T}. */
-    public Type getType() {
-        return mType;
-    }
-
-    /**
-     * Returns the raw type of T.
-     *
-     * <p>
-     *
-     * <ul>
-     * <li>If T is a Class itself, T itself is returned.
-     * <li>If T is a ParameterizedType, the raw type of the parameterized type is returned.
-     * <li>If T is a GenericArrayType, the returned type is the corresponding array class. For
-     * example: {@code List<Integer>[]} => {@code List[]}.
-     * <li>If T is a type variable or a wildcard type, the raw type of the first upper bound is
-     * returned. For example: {@code <X extends Foo>} => {@code Foo}.
-     * </ul>
-     *
-     * @return the raw type of {@code T}
-     */
-    @SuppressWarnings("unchecked")
-    public final Class<? super T> getRawType() {
-        return (Class<? super T>) getRawType(mType);
-    }
-
-    /**
-     * Compare two objects for equality.
-     *
-     * <p>A TypeReference is only equal to another TypeReference if their captured type {@code T} is
-     * also equal.
-     */
-    @Override
-    public boolean equals(Object o) {
-        // Note that this comparison could inaccurately return true when comparing types
-        // with nested type variables; therefore we ban type variables in the constructor.
-        return o instanceof TypeReference<?> && mType.equals(((TypeReference<?>) o).mType);
-    }
-
-    @Override
-    public int hashCode() {
-        return mHash;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("TypeReference<");
-        toString(getType(), builder);
-        builder.append(">");
-
-        return builder.toString();
-    }
-
-    private static class SpecializedTypeReference<T> extends TypeReference<T> {
-        SpecializedTypeReference(Class<T> klass) {
-            super(klass);
-        }
-    }
-}
diff --git a/camera/core/src/test/java/androidx/camera/core/OptionTest.java b/camera/core/src/test/java/androidx/camera/core/OptionTest.java
index 55775c0..16b6a7e 100644
--- a/camera/core/src/test/java/androidx/camera/core/OptionTest.java
+++ b/camera/core/src/test/java/androidx/camera/core/OptionTest.java
@@ -29,6 +29,7 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.annotation.internal.DoNotInstrument;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -62,10 +63,15 @@
     }
 
     @Test
-    public void canCreateOption_fromTypeReference() {
-        Option<List<Integer>> option =
-                Option.create(OPTION_1_ID, new TypeReference<List<Integer>>() {
-                });
+    public void canCreateOption_fromGenericClass_andAssignFromNarrowClass() {
+        List<Integer> intList = new ArrayList<>();
+        Option<List<Integer>> option = Option.create(OPTION_1_ID, List.class);
+        assertThat(intList.getClass()).isAssignableTo(option.getValueClass());
+    }
+
+    @Test
+    public void canCreateOption_fromGenericClass() {
+        Option<List<Integer>> option = Option.create(OPTION_1_ID, List.class);
         assertThat(option).isNotNull();
     }
 
diff --git a/camera/core/src/test/java/androidx/camera/core/OptionsBundleTest.java b/camera/core/src/test/java/androidx/camera/core/OptionsBundleTest.java
index 5c924fa..c158ad4 100644
--- a/camera/core/src/test/java/androidx/camera/core/OptionsBundleTest.java
+++ b/camera/core/src/test/java/androidx/camera/core/OptionsBundleTest.java
@@ -29,6 +29,8 @@
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.internal.DoNotInstrument;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
@@ -42,14 +44,24 @@
     private static final Option<Object> OPTION_1 = Option.create("option.1", Object.class);
     private static final Option<Object> OPTION_1_A = Option.create("option.1.a", Object.class);
     private static final Option<Object> OPTION_2 = Option.create("option.2", Object.class);
+    private static final Option<List<Integer>> OPTION_INTEGER_LIST = Option.create(
+            "option.int_list", List.class);
     private static final Option<Object> OPTION_MISSING =
             Option.create("option.missing", Object.class);
 
     private static final Object VALUE_1 = new Object();
     private static final Object VALUE_1_A = new Object();
     private static final Object VALUE_2 = new Object();
+    private static final List<Integer> VALUE_INTEGER_LIST = new ArrayList<>();
     private static final Object VALUE_MISSING = new Object();
 
+    static {
+        VALUE_INTEGER_LIST.add(1);
+        VALUE_INTEGER_LIST.add(2);
+        VALUE_INTEGER_LIST.add(3);
+    }
+
+
     private OptionsBundle mAllOpts;
 
     @Before
@@ -58,6 +70,7 @@
         mutOpts.insertOption(OPTION_1, VALUE_1);
         mutOpts.insertOption(OPTION_1_A, VALUE_1_A);
         mutOpts.insertOption(OPTION_2, VALUE_2);
+        mutOpts.insertOption(OPTION_INTEGER_LIST, VALUE_INTEGER_LIST);
 
         mAllOpts = OptionsBundle.from(mutOpts);
     }
@@ -70,6 +83,12 @@
     }
 
     @Test
+    public void canRetrieveListOfIntegers() {
+        List<Integer> list = mAllOpts.retrieveOption(OPTION_INTEGER_LIST);
+        assertThat(list).isSameInstanceAs(VALUE_INTEGER_LIST);
+    }
+
+    @Test
     public void willReturnDefault_ifOptionIsMissing() {
         Object value = mAllOpts.retrieveOption(OPTION_MISSING, VALUE_MISSING);
         assertThat(value).isSameInstanceAs(VALUE_MISSING);
@@ -85,10 +104,10 @@
     public void canListOptions() {
         Set<Option<?>> list = mAllOpts.listOptions();
         for (Option<?> opt : list) {
-            assertThat(opt).isAnyOf(OPTION_1, OPTION_1_A, OPTION_2);
+            assertThat(opt).isAnyOf(OPTION_1, OPTION_1_A, OPTION_2, OPTION_INTEGER_LIST);
         }
 
-        assertThat(list).hasSize(3);
+        assertThat(list).hasSize(4);
     }
 
     @Test
diff --git a/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java b/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
new file mode 100755
index 0000000..3a3414f
--- /dev/null
+++ b/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
@@ -0,0 +1,82 @@
+/*
+ * 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 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.
+ */
+public final class AutoImageCaptureExtenderImpl implements ImageCaptureExtenderImpl {
+    public AutoImageCaptureExtenderImpl() {}
+
+    @Override
+    public boolean isExtensionAvailable(String cameraId,
+            CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void enableExtension(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.");
+    }
+}
diff --git a/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java b/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
new file mode 100755
index 0000000..37d0e4f
--- /dev/null
+++ b/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
@@ -0,0 +1,82 @@
+/*
+ * 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;
+
+/**
+ * Stub implementation for auto preview use case.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices.
+ */
+public final class AutoPreviewExtenderImpl implements PreviewExtenderImpl {
+    public AutoPreviewExtenderImpl() {
+    }
+
+    @Override
+    public boolean isExtensionAvailable(String cameraId,
+            CameraCharacteristics cameraCharacteristics) {
+        throw new RuntimeException("Stub, replace with implementation.");
+    }
+
+    @Override
+    public void enableExtension(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 RequestUpdateProcessorImpl getRequestUpdatePreviewProcessor() {
+        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.");
+    }
+}
diff --git a/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java b/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
index fcecc7c..c87898e 100755
--- a/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
+++ b/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
@@ -20,7 +20,7 @@
 import android.hardware.camera2.CameraCharacteristics;
 
 /**
- * Stub implementation for beauty view finder use case.
+ * Stub implementation for beauty preview use case.
  *
  * <p>This class should be implemented by OEM and deployed to the target devices.
  */
diff --git a/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java b/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
index 71a7747..8fbf1ad 100644
--- a/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
+++ b/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
@@ -19,7 +19,7 @@
 import android.hardware.camera2.CameraCharacteristics;
 
 /**
- * Stub implementation for bokeh view finder use case.
+ * Stub implementation for bokeh preview use case.
  *
  * <p>This class should be implemented by OEM and deployed to the target devices.
  */
diff --git a/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java b/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
index 8a50b6c..74695e4 100644
--- a/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
+++ b/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
@@ -20,7 +20,7 @@
 import android.hardware.camera2.CameraCharacteristics;
 
 /**
- * Stub implementation for HDR view finder use case.
+ * Stub implementation for HDR preview use case.
  *
  * <p>This class should be implemented by OEM and deployed to the target devices.
  */
diff --git a/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java b/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
index 2ec2392..d64c865 100755
--- a/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
+++ b/camera/extensions-stub/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
@@ -20,7 +20,7 @@
 import android.hardware.camera2.CameraCharacteristics;
 
 /**
- * Stub implementation for night view finder use case.
+ * Stub implementation for night preview use case.
  *
  * <p>This class should be implemented by OEM and deployed to the target devices.
  */
diff --git a/camera/extensions/src/main/java/androidx/camera/extensions/AutoImageCaptureExtender.java b/camera/extensions/src/main/java/androidx/camera/extensions/AutoImageCaptureExtender.java
new file mode 100644
index 0000000..8c0905e
--- /dev/null
+++ b/camera/extensions/src/main/java/androidx/camera/extensions/AutoImageCaptureExtender.java
@@ -0,0 +1,71 @@
+/*
+ * 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;
+
+import android.util.Log;
+
+import androidx.camera.core.ImageCaptureConfig;
+import androidx.camera.extensions.impl.AutoImageCaptureExtenderImpl;
+
+/**
+ * Load the OEM extension implementation for auto effect type.
+ */
+public class AutoImageCaptureExtender extends ImageCaptureExtender {
+    private static final String TAG = "AutoICExtender";
+
+    /**
+     * Create a new instance of the auto extender.
+     *
+     * @param builder Builder that will be used to create the configurations for the
+     * {@link androidx.camera.core.ImageCapture}.
+     */
+    public static AutoImageCaptureExtender create(ImageCaptureConfig.Builder builder) {
+        try {
+            return new VendorAutoImageCaptureExtender(builder);
+        } catch (NoClassDefFoundError e) {
+            Log.d(TAG, "No auto image capture extender found. Falling back to default.");
+            return new DefaultAutoImageCaptureExtender();
+        }
+    }
+
+    /** Empty implementation of auto extender which does nothing. */
+    static class DefaultAutoImageCaptureExtender extends AutoImageCaptureExtender {
+        DefaultAutoImageCaptureExtender() {
+        }
+
+        @Override
+        public boolean isExtensionAvailable() {
+            return false;
+        }
+
+        @Override
+        public void enableExtension() {
+        }
+    }
+
+    /** Auto extender that calls into the vendor provided implementation. */
+    static class VendorAutoImageCaptureExtender extends AutoImageCaptureExtender {
+        private final AutoImageCaptureExtenderImpl mImpl;
+
+        VendorAutoImageCaptureExtender(ImageCaptureConfig.Builder builder) {
+            mImpl = new AutoImageCaptureExtenderImpl();
+            init(builder, mImpl);
+        }
+    }
+
+    private AutoImageCaptureExtender() {}
+}
diff --git a/camera/extensions/src/main/java/androidx/camera/extensions/AutoPreviewExtender.java b/camera/extensions/src/main/java/androidx/camera/extensions/AutoPreviewExtender.java
new file mode 100644
index 0000000..44b0ee6
--- /dev/null
+++ b/camera/extensions/src/main/java/androidx/camera/extensions/AutoPreviewExtender.java
@@ -0,0 +1,71 @@
+/*
+ * 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;
+
+import android.util.Log;
+
+import androidx.camera.core.PreviewConfig;
+import androidx.camera.extensions.impl.AutoPreviewExtenderImpl;
+
+/**
+ * Load the OEM extension Preview implementation for auto effect type.
+ */
+public class AutoPreviewExtender extends PreviewExtender {
+    private static final String TAG = "AutoPreviewExtender";
+
+    /**
+     * Create a new instance of the auto extender.
+     *
+     * @param builder Builder that will be used to create the configurations for the
+     * {@link androidx.camera.core.Preview}.
+     */
+    public static AutoPreviewExtender create(PreviewConfig.Builder builder) {
+        try {
+            return new VendorAutoPreviewExtender(builder);
+        } catch (NoClassDefFoundError e) {
+            Log.d(TAG, "No auto preview extender found. Falling back to default.");
+            return new DefaultAutoPreviewExtender();
+        }
+    }
+
+    /** Empty implementation of auto extender which does nothing. */
+    static class DefaultAutoPreviewExtender extends AutoPreviewExtender {
+        DefaultAutoPreviewExtender() {
+        }
+
+        @Override
+        public boolean isExtensionAvailable() {
+            return false;
+        }
+
+        @Override
+        public void enableExtension() {
+        }
+    }
+
+    /** Auto extender that calls into the vendor provided implementation. */
+    static class VendorAutoPreviewExtender extends AutoPreviewExtender {
+        private final AutoPreviewExtenderImpl mImpl;
+
+        VendorAutoPreviewExtender(PreviewConfig.Builder builder) {
+            mImpl = new AutoPreviewExtenderImpl();
+            init(builder, mImpl);
+        }
+    }
+
+    private AutoPreviewExtender() {}
+}
diff --git a/camera/extensions/src/main/java/androidx/camera/extensions/BeautyPreviewExtender.java b/camera/extensions/src/main/java/androidx/camera/extensions/BeautyPreviewExtender.java
index 5f37e7d..d24b3ce 100644
--- a/camera/extensions/src/main/java/androidx/camera/extensions/BeautyPreviewExtender.java
+++ b/camera/extensions/src/main/java/androidx/camera/extensions/BeautyPreviewExtender.java
@@ -37,7 +37,7 @@
         try {
             return new VendorBeautyPreviewExtender(builder);
         } catch (NoClassDefFoundError e) {
-            Log.d(TAG, "No beauty view finder extender found. Falling back to default.");
+            Log.d(TAG, "No beauty preview extender found. Falling back to default.");
             return new DefaultBeautyPreviewExtender();
         }
     }
diff --git a/camera/extensions/src/main/java/androidx/camera/extensions/BokehPreviewExtender.java b/camera/extensions/src/main/java/androidx/camera/extensions/BokehPreviewExtender.java
index 3caee19..5a23970 100644
--- a/camera/extensions/src/main/java/androidx/camera/extensions/BokehPreviewExtender.java
+++ b/camera/extensions/src/main/java/androidx/camera/extensions/BokehPreviewExtender.java
@@ -37,7 +37,7 @@
         try {
             return new VendorBokehPreviewExtender(builder);
         } catch (NoClassDefFoundError e) {
-            Log.d(TAG, "No bokeh view finder extender found. Falling back to default.");
+            Log.d(TAG, "No bokeh preview extender found. Falling back to default.");
             return new DefaultBokehPreviewExtender();
         }
     }
diff --git a/camera/extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java b/camera/extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
index 7e7e1c3..b4e6c26 100644
--- a/camera/extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
+++ b/camera/extensions/src/main/java/androidx/camera/extensions/ExtensionsManager.java
@@ -46,7 +46,12 @@
          * Beauty mode is used for taking still capture images that incorporate facial changes
          * like skin tone, geometry, or retouching.
          */
-        BEAUTY
+        BEAUTY,
+        /**
+         * Auto mode is used for taking still capture images that automatically adjust to the
+         * surrounding scenery.
+         */
+        AUTO
     }
 
     /**
@@ -103,6 +108,9 @@
             case BEAUTY:
                 extender = BeautyImageCaptureExtender.create(builder);
                 break;
+            case AUTO:
+                extender = AutoImageCaptureExtender.create(builder);
+                break;
             case NORMAL:
                 return true;
             default:
@@ -131,6 +139,9 @@
             case BEAUTY:
                 extender = BeautyPreviewExtender.create(builder);
                 break;
+            case AUTO:
+                extender = AutoPreviewExtender.create(builder);
+                break;
             case NORMAL:
                 return true;
             default:
diff --git a/camera/extensions/src/main/java/androidx/camera/extensions/HdrPreviewExtender.java b/camera/extensions/src/main/java/androidx/camera/extensions/HdrPreviewExtender.java
index 5c48724..239cef1 100644
--- a/camera/extensions/src/main/java/androidx/camera/extensions/HdrPreviewExtender.java
+++ b/camera/extensions/src/main/java/androidx/camera/extensions/HdrPreviewExtender.java
@@ -37,7 +37,7 @@
         try {
             return new VendorHdrPreviewExtender(builder);
         } catch (NoClassDefFoundError e) {
-            Log.d(TAG, "No HDR view finder extender found. Falling back to default.");
+            Log.d(TAG, "No HDR preview extender found. Falling back to default.");
             return new DefaultHdrPreviewExtender();
         }
     }
diff --git a/camera/extensions/src/main/java/androidx/camera/extensions/NightPreviewExtender.java b/camera/extensions/src/main/java/androidx/camera/extensions/NightPreviewExtender.java
index 5d5d40e..71f0ad2 100644
--- a/camera/extensions/src/main/java/androidx/camera/extensions/NightPreviewExtender.java
+++ b/camera/extensions/src/main/java/androidx/camera/extensions/NightPreviewExtender.java
@@ -37,7 +37,7 @@
         try {
             return new VendorNightPreviewExtender(builder);
         } catch (NoClassDefFoundError e) {
-            Log.d(TAG, "No night view finder extender found. Falling back to default.");
+            Log.d(TAG, "No night preview extender found. Falling back to default.");
             return new DefaultNightPreviewExtender();
         }
     }
diff --git a/camera/extensions/src/main/java/androidx/camera/extensions/PreviewExtender.java b/camera/extensions/src/main/java/androidx/camera/extensions/PreviewExtender.java
index 343b117..142b7e7 100644
--- a/camera/extensions/src/main/java/androidx/camera/extensions/PreviewExtender.java
+++ b/camera/extensions/src/main/java/androidx/camera/extensions/PreviewExtender.java
@@ -43,7 +43,7 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
- * Class for using an OEM provided extension on view finder.
+ * Class for using an OEM provided extension on preview.
  */
 public abstract class PreviewExtender {
     private PreviewConfig.Builder mBuilder;
diff --git a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
index f937b62..4d0178d 100644
--- a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
+++ b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
@@ -219,7 +219,7 @@
                         .getLensFacing(/*valueIfMissing=*/ null);
         if (previewLensFacing != mCurrentCameraLensFacing) {
             throw new IllegalStateException(
-                    "Invalid view finder lens facing: "
+                    "Invalid preview lens facing: "
                             + previewLensFacing
                             + " Should be: "
                             + mCurrentCameraLensFacing);
diff --git a/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java b/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java
index 5921cde..5add375 100644
--- a/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java
+++ b/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/CameraExtensionsActivity.java
@@ -39,6 +39,8 @@
 import androidx.camera.core.Preview;
 import androidx.camera.core.PreviewConfig;
 import androidx.camera.core.UseCase;
+import androidx.camera.extensions.AutoImageCaptureExtender;
+import androidx.camera.extensions.AutoPreviewExtender;
 import androidx.camera.extensions.BeautyImageCaptureExtender;
 import androidx.camera.extensions.BeautyPreviewExtender;
 import androidx.camera.extensions.BokehImageCaptureExtender;
@@ -80,7 +82,7 @@
     private ImageCaptureType mCurrentImageCaptureType = ImageCaptureType.IMAGE_CAPTURE_TYPE_HDR;
 
     /**
-     * Creates a view finder use case.
+     * Creates a preview use case.
      *
      * <p>This use case observes a {@link SurfaceTexture}. The texture is connected to a {@link
      * TextureView} to display a camera preview.
@@ -100,35 +102,42 @@
                         .setLensFacing(LensFacing.BACK)
                         .setTargetName("Preview");
 
-        Log.d(TAG, "Enabling the extended view finder");
+        Log.d(TAG, "Enabling the extended preview");
         if (mCurrentImageCaptureType == ImageCaptureType.IMAGE_CAPTURE_TYPE_BOKEH) {
-            Log.d(TAG, "Enabling the extended view finder in bokeh mode.");
+            Log.d(TAG, "Enabling the extended preview in bokeh mode.");
 
             BokehPreviewExtender extender = BokehPreviewExtender.create(builder);
             if (extender.isExtensionAvailable()) {
                 extender.enableExtension();
             }
         } else if (mCurrentImageCaptureType == ImageCaptureType.IMAGE_CAPTURE_TYPE_HDR) {
-            Log.d(TAG, "Enabling the extended view finder in HDR mode.");
+            Log.d(TAG, "Enabling the extended preview in HDR mode.");
 
             HdrPreviewExtender extender = HdrPreviewExtender.create(builder);
             if (extender.isExtensionAvailable()) {
                 extender.enableExtension();
             }
         } else if (mCurrentImageCaptureType == ImageCaptureType.IMAGE_CAPTURE_TYPE_NIGHT) {
-            Log.d(TAG, "Enabling the extended view finder in night mode.");
+            Log.d(TAG, "Enabling the extended preview in night mode.");
 
             NightPreviewExtender extender = NightPreviewExtender.create(builder);
             if (extender.isExtensionAvailable()) {
                 extender.enableExtension();
             }
         } else if (mCurrentImageCaptureType == ImageCaptureType.IMAGE_CAPTURE_TYPE_BEAUTY) {
-            Log.d(TAG, "Enabling the extended view finder in beauty mode.");
+            Log.d(TAG, "Enabling the extended preview in beauty mode.");
 
             BeautyPreviewExtender extender = BeautyPreviewExtender.create(builder);
             if (extender.isExtensionAvailable()) {
                 extender.enableExtension();
             }
+        } else if (mCurrentImageCaptureType == ImageCaptureType.IMAGE_CAPTURE_TYPE_AUTO) {
+            Log.d(TAG, "Enabling the extended preview in auto mode.");
+
+            AutoPreviewExtender extender = AutoPreviewExtender.create(builder);
+            if (extender.isExtensionAvailable()) {
+                extender.enableExtension();
+            }
         }
 
         mPreview = new Preview(builder.build());
@@ -154,6 +163,7 @@
         IMAGE_CAPTURE_TYPE_BOKEH,
         IMAGE_CAPTURE_TYPE_NIGHT,
         IMAGE_CAPTURE_TYPE_BEAUTY,
+        IMAGE_CAPTURE_TYPE_AUTO,
         IMAGE_CAPTURE_TYPE_DEFAULT,
         IMAGE_CAPTURE_TYPE_NONE,
     }
@@ -186,6 +196,10 @@
                                 enablePreview();
                                 break;
                             case IMAGE_CAPTURE_TYPE_BEAUTY:
+                                enableImageCapture(ImageCaptureType.IMAGE_CAPTURE_TYPE_AUTO);
+                                enablePreview();
+                                break;
+                            case IMAGE_CAPTURE_TYPE_AUTO:
                                 enableImageCapture(ImageCaptureType.IMAGE_CAPTURE_TYPE_DEFAULT);
                                 enablePreview();
                                 break;
@@ -243,6 +257,13 @@
                     beautyImageCapture.enableExtension();
                 }
                 break;
+            case IMAGE_CAPTURE_TYPE_AUTO:
+                AutoImageCaptureExtender autoImageCapture = AutoImageCaptureExtender.create(
+                        builder);
+                if (autoImageCapture.isExtensionAvailable()) {
+                    autoImageCapture.enableExtension();
+                }
+                break;
             case IMAGE_CAPTURE_TYPE_DEFAULT:
                 break;
             case IMAGE_CAPTURE_TYPE_NONE:
diff --git a/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java b/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
new file mode 100755
index 0000000..56cbb28
--- /dev/null
+++ b/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
@@ -0,0 +1,176 @@
+/*
+ * 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.CaptureRequest;
+import android.hardware.camera2.TotalCaptureResult;
+import android.media.Image;
+import android.media.ImageWriter;
+import android.os.Build;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Size;
+import android.view.Surface;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation for auto image capture use case.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices. 3P developers
+ * don't need to implement this, unless this is used for related testing usage.
+ */
+public final class AutoImageCaptureExtenderImpl implements ImageCaptureExtenderImpl {
+    private static final String TAG = "AutoICExtender";
+    private static final int DEFAULT_STAGE_ID = 0;
+    private static final int SESSION_STAGE_ID = 101;
+
+    public AutoImageCaptureExtenderImpl() {
+    }
+
+    @Override
+    public void enableExtension(String cameraId, CameraCharacteristics cameraCharacteristics) {
+    }
+
+    @Override
+    public boolean isExtensionAvailable(String cameraId,
+            CameraCharacteristics cameraCharacteristics) {
+        // Requires API 23 for ImageWriter
+        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
+    }
+
+    @Override
+    public List<CaptureStageImpl> getCaptureStages() {
+        // Placeholder set of CaptureRequest.Key values
+        SettableCaptureStage captureStage = new SettableCaptureStage(DEFAULT_STAGE_ID);
+        captureStage.addCaptureRequestParameters(CaptureRequest.CONTROL_EFFECT_MODE,
+                CaptureRequest.CONTROL_EFFECT_MODE_SOLARIZE);
+        List<CaptureStageImpl> captureStages = new ArrayList<>();
+        captureStages.add(captureStage);
+        return captureStages;
+    }
+
+    @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;
+    }
+
+    @Override
+    public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
+            Context context) {
+
+    }
+
+    @Override
+    public void onDeInit() {
+
+    }
+
+    @Override
+    public CaptureStageImpl onPresetSession() {
+        // Set the necessary CaptureRequest parameters via CaptureStage, here we use some
+        // placeholder set of CaptureRequest.Key values
+        SettableCaptureStage captureStage = new SettableCaptureStage(SESSION_STAGE_ID);
+        captureStage.addCaptureRequestParameters(CaptureRequest.CONTROL_EFFECT_MODE,
+                CaptureRequest.CONTROL_EFFECT_MODE_SOLARIZE);
+
+        return captureStage;
+    }
+
+    @Override
+    public CaptureStageImpl onEnableSession() {
+        // Set the necessary CaptureRequest parameters via CaptureStage, here we use some
+        // placeholder set of CaptureRequest.Key values
+        SettableCaptureStage captureStage = new SettableCaptureStage(SESSION_STAGE_ID);
+        captureStage.addCaptureRequestParameters(CaptureRequest.CONTROL_EFFECT_MODE,
+                CaptureRequest.CONTROL_EFFECT_MODE_SOLARIZE);
+
+        return captureStage;
+    }
+
+    @Override
+    public CaptureStageImpl onDisableSession() {
+        // Set the necessary CaptureRequest parameters via CaptureStage, here we use some
+        // placeholder set of CaptureRequest.Key values
+        SettableCaptureStage captureStage = new SettableCaptureStage(SESSION_STAGE_ID);
+        captureStage.addCaptureRequestParameters(CaptureRequest.CONTROL_EFFECT_MODE,
+                CaptureRequest.CONTROL_EFFECT_MODE_SOLARIZE);
+
+        return captureStage;
+    }
+
+    @Override
+    public int getMaxCaptureStage() {
+        return 3;
+    }
+}
diff --git a/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java b/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
new file mode 100755
index 0000000..df8676f
--- /dev/null
+++ b/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
@@ -0,0 +1,110 @@
+/*
+ * 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.CaptureRequest;
+
+/**
+ * Implementation for auto preview use case.
+ *
+ * <p>This class should be implemented by OEM and deployed to the target devices. 3P developers
+ * don't need to implement this, unless this is used for related testing usage.
+ */
+public final class AutoPreviewExtenderImpl implements PreviewExtenderImpl {
+    private static final int DEFAULT_STAGE_ID = 0;
+    private static final int SESSION_STAGE_ID = 101;
+
+    public AutoPreviewExtenderImpl() {
+    }
+
+    @Override
+    public void enableExtension(String cameraId, CameraCharacteristics cameraCharacteristics) {
+    }
+
+    @Override
+    public boolean isExtensionAvailable(String cameraId,
+            CameraCharacteristics cameraCharacteristics) {
+        // Implement the logic to check whether the extension function is supported or not.
+        return true;
+    }
+
+    @Override
+    public CaptureStageImpl getCaptureStage() {
+        // Set the necessary CaptureRequest parameters via CaptureStage, here we use some
+        // placeholder set of CaptureRequest.Key values
+        SettableCaptureStage captureStage = new SettableCaptureStage(DEFAULT_STAGE_ID);
+        captureStage.addCaptureRequestParameters(CaptureRequest.CONTROL_EFFECT_MODE,
+                CaptureRequest.CONTROL_EFFECT_MODE_SOLARIZE);
+
+        return captureStage;
+    }
+
+    @Override
+    public ProcessorType getProcessorType() {
+        return ProcessorType.PROCESSOR_TYPE_REQUEST_UPDATE_ONLY;
+    }
+
+    @Override
+    public RequestUpdateProcessorImpl getRequestUpdatePreviewProcessor() {
+        return RequestUpdateProcessorImpls.noUpdateProcessor();
+    }
+
+    @Override
+    public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics,
+            Context context) {
+
+    }
+
+    @Override
+    public void onDeInit() {
+
+    }
+
+    @Override
+    public CaptureStageImpl onPresetSession() {
+        // Set the necessary CaptureRequest parameters via CaptureStage, here we use some
+        // placeholder set of CaptureRequest.Key values
+        SettableCaptureStage captureStage = new SettableCaptureStage(SESSION_STAGE_ID);
+        captureStage.addCaptureRequestParameters(CaptureRequest.CONTROL_EFFECT_MODE,
+                CaptureRequest.CONTROL_EFFECT_MODE_SOLARIZE);
+
+        return captureStage;
+    }
+
+    @Override
+    public CaptureStageImpl onEnableSession() {
+        // Set the necessary CaptureRequest parameters via CaptureStage, here we use some
+        // placeholder set of CaptureRequest.Key values
+        SettableCaptureStage captureStage = new SettableCaptureStage(SESSION_STAGE_ID);
+        captureStage.addCaptureRequestParameters(CaptureRequest.CONTROL_EFFECT_MODE,
+                CaptureRequest.CONTROL_EFFECT_MODE_SOLARIZE);
+
+        return captureStage;
+    }
+
+    @Override
+    public CaptureStageImpl onDisableSession() {
+        // Set the necessary CaptureRequest parameters via CaptureStage, here we use some
+        // placeholder set of CaptureRequest.Key values
+        SettableCaptureStage captureStage = new SettableCaptureStage(SESSION_STAGE_ID);
+        captureStage.addCaptureRequestParameters(CaptureRequest.CONTROL_EFFECT_MODE,
+                CaptureRequest.CONTROL_EFFECT_MODE_SOLARIZE);
+
+        return captureStage;
+    }
+}
diff --git a/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java b/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
index f3d553e..56312f4 100755
--- a/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
+++ b/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
@@ -20,7 +20,7 @@
 import android.hardware.camera2.CaptureRequest;
 
 /**
- * Implementation for beauty view finder use case.
+ * Implementation for beauty preview use case.
  *
  * <p>This class should be implemented by OEM and deployed to the target devices. 3P developers
  * don't need to implement this, unless this is used for related testing usage.
diff --git a/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java b/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
index 883fafa..7700116 100644
--- a/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
+++ b/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
@@ -21,7 +21,7 @@
 import android.hardware.camera2.TotalCaptureResult;
 
 /**
- * Implementation for bokeh view finder use case.
+ * Implementation for bokeh preview use case.
  *
  * <p>This class should be implemented by OEM and deployed to the target devices. 3P developers
  * don't need to implement this, unless this is used for related testing usage.
diff --git a/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java b/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
index f33b561..27c094c 100644
--- a/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
+++ b/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
@@ -21,7 +21,7 @@
 import android.hardware.camera2.CaptureRequest;
 
 /**
- * Implementation for HDR view finder use case.
+ * Implementation for HDR preview use case.
  *
  * <p>This class should be implemented by OEM and deployed to the target devices. 3P developers
  * don't need to implement this, unless this is used for related testing usage.
diff --git a/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java b/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
index f9925c8..a2bce02 100755
--- a/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
+++ b/camera/integration-tests/extensionstestlib/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
@@ -20,7 +20,7 @@
 import android.hardware.camera2.CaptureRequest;
 
 /**
- * Implementation for night view finder use case.
+ * Implementation for night preview use case.
  *
  * <p>This class should be implemented by OEM and deployed to the target devices. 3P developers
  * don't need to implement this, unless this is used for related testing usage.
diff --git a/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt b/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt
index c45ca96..7b0fd81 100644
--- a/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt
+++ b/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt
@@ -26,6 +26,7 @@
 import android.view.animation.AnimationUtils
 import android.view.animation.TranslateAnimation
 import androidx.annotation.AnimRes
+import androidx.annotation.LayoutRes
 import androidx.core.view.ViewCompat
 import androidx.fragment.app.test.FragmentTestActivity
 import androidx.fragment.test.R
@@ -216,6 +217,38 @@
         assertFragmentAnimation(replacement2!!, expectedAnimations, true, POP_ENTER)
     }
 
+    // Ensure child view is not removed before parent view animates out.
+    @Test
+    fun removeParentWithAnimation() {
+        waitForAnimationReady()
+        val fm = activityRule.activity.supportFragmentManager
+
+        val parent = AnimatorFragment(R.layout.simple_container)
+        fm.beginTransaction()
+            .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
+            .add(R.id.fragmentContainer, parent, "parent")
+            .commit()
+        activityRule.executePendingTransactions()
+
+        val child = AnimatorFragment()
+        parent.childFragmentManager.beginTransaction()
+            .add(R.id.fragmentContainer, child, "child")
+            .commit()
+        activityRule.executePendingTransactions(parent.childFragmentManager)
+
+        val childContainer = child.mContainer
+        val childView = child.mView
+
+        fm.beginTransaction()
+            .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
+            .replace(R.id.fragmentContainer, AnimatorFragment(), "other")
+            .commit()
+        activityRule.executePendingTransactions()
+
+        assertFragmentAnimation(parent, 2, false, EXIT)
+        assertThat(childContainer.findViewById<View>(childView.id)).isNotNull()
+    }
+
     // Ensure that adding and popping a Fragment uses the enter and popExit animators,
     // but the animators are delayed when an entering Fragment is postponed.
     @Test
@@ -577,7 +610,6 @@
         assertFragmentAnimation(fragment, 2, true, POP_ENTER)
     }
 
-    @Throws(InterruptedException::class)
     private fun assertFragmentAnimation(
         fragment: AnimatorFragment,
         numAnimators: Int,
@@ -593,7 +625,6 @@
         assertThat(fragment.nextAnim).isEqualTo(0)
     }
 
-    @Throws(InterruptedException::class)
     private fun assertPostponed(fragment: AnimatorFragment, expectedAnimators: Int) {
         assertThat(fragment.onCreateViewCalled).isTrue()
         assertThat(fragment.requireView().visibility).isEqualTo(View.VISIBLE)
@@ -623,7 +654,8 @@
         }
     }
 
-    class AnimatorFragment : StrictViewFragment() {
+    class AnimatorFragment(@LayoutRes contentLayoutId: Int = R.layout.strict_view_fragment)
+        : StrictViewFragment(contentLayoutId) {
         var numAnimators: Int = 0
         var animation: Animation? = null
         var enter: Boolean = false
diff --git a/fragment/src/main/java/androidx/fragment/app/FragmentManagerImpl.java b/fragment/src/main/java/androidx/fragment/app/FragmentManagerImpl.java
index 2afd497..bf16323 100644
--- a/fragment/src/main/java/androidx/fragment/app/FragmentManagerImpl.java
+++ b/fragment/src/main/java/androidx/fragment/app/FragmentManagerImpl.java
@@ -957,17 +957,20 @@
                             f.mContainer.endViewTransition(f.mView);
                             f.mView.clearAnimation();
                             AnimationOrAnimator anim = null;
-                            if (mCurState > Fragment.INITIALIZING && !mDestroyed
-                                    && f.mView.getVisibility() == View.VISIBLE
-                                    && f.mPostponedAlpha >= 0) {
-                                anim = loadAnimation(f, transit, false,
-                                        transitionStyle);
+                            // If parent is being removed, no need to handle child animations.
+                            if (f.getParentFragment() == null || !f.getParentFragment().mRemoving) {
+                                if (mCurState > Fragment.INITIALIZING && !mDestroyed
+                                        && f.mView.getVisibility() == View.VISIBLE
+                                        && f.mPostponedAlpha >= 0) {
+                                    anim = loadAnimation(f, transit, false,
+                                            transitionStyle);
+                                }
+                                f.mPostponedAlpha = 0;
+                                if (anim != null) {
+                                    animateRemoveFragment(f, anim, newState);
+                                }
+                                f.mContainer.removeView(f.mView);
                             }
-                            f.mPostponedAlpha = 0;
-                            if (anim != null) {
-                                animateRemoveFragment(f, anim, newState);
-                            }
-                            f.mContainer.removeView(f.mView);
                         }
                         f.mContainer = null;
                         f.mView = null;
diff --git a/room/runtime/src/main/java/androidx/room/DatabaseConfiguration.java b/room/runtime/src/main/java/androidx/room/DatabaseConfiguration.java
index c49f3d3..07e0425 100644
--- a/room/runtime/src/main/java/androidx/room/DatabaseConfiguration.java
+++ b/room/runtime/src/main/java/androidx/room/DatabaseConfiguration.java
@@ -198,6 +198,7 @@
      * @deprecated Use {@link #isMigrationRequired(int, int)} which takes
      * {@link #allowDestructiveMigrationOnDowngrade} into account.
      */
+    @Deprecated
     public boolean isMigrationRequiredFrom(int version) {
         return isMigrationRequired(version, version + 1);
     }
diff --git a/ui/.idea/inspectionProfiles/Project_Default.xml b/ui/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 084c3f2c..0000000
--- a/ui/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <profile version="1.0">
-    <option name="myName" value="Project Default" />
-    <inspection_tool class="FunctionName" enabled="true" level="WEAK WARNING" enabled_by_default="true">
-      <option name="namePattern" value="[A-Za-z\d]+" />
-    </inspection_tool>
-    <inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
-      <option name="TOP_LEVEL_CLASS_OPTIONS">
-        <value>
-          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
-          <option name="REQUIRED_TAGS" value="" />
-        </value>
-      </option>
-      <option name="INNER_CLASS_OPTIONS">
-        <value>
-          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
-          <option name="REQUIRED_TAGS" value="" />
-        </value>
-      </option>
-      <option name="METHOD_OPTIONS">
-        <value>
-          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
-          <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
-        </value>
-      </option>
-      <option name="FIELD_OPTIONS">
-        <value>
-          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
-          <option name="REQUIRED_TAGS" value="" />
-        </value>
-      </option>
-      <option name="IGNORE_DEPRECATED" value="false" />
-      <option name="IGNORE_JAVADOC_PERIOD" value="true" />
-      <option name="IGNORE_DUPLICATED_THROWS" value="false" />
-      <option name="IGNORE_POINT_TO_ITSELF" value="false" />
-      <option name="myAdditionalJavadocTags" value="hide" />
-    </inspection_tool>
-    <inspection_tool class="MissingDeprecatedAnnotation" enabled="true" level="ERROR" enabled_by_default="true" />
-    <inspection_tool class="PrivatePropertyName" enabled="true" level="WEAK WARNING" enabled_by_default="true">
-      <option name="namePattern" value="_?[A-Za-z\d]+" />
-    </inspection_tool>
-    <inspection_tool class="PropertyName" enabled="true" level="WEAK WARNING" enabled_by_default="true">
-      <option name="namePattern" value="[A-Za-z\d]+" />
-    </inspection_tool>
-    <inspection_tool class="TestFunctionName" enabled="true" level="WEAK WARNING" enabled_by_default="true">
-      <option name="namePattern" value="[A-Za-z\d]+" />
-    </inspection_tool>
-  </profile>
-</component>
\ No newline at end of file
diff --git a/ui/.idea/inspectionProfiles/Project_Default.xml b/ui/.idea/inspectionProfiles/Project_Default.xml
new file mode 120000
index 0000000..a7481f4
--- /dev/null
+++ b/ui/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1 @@
+../../../.idea/inspectionProfiles/Project_Default.xml
\ No newline at end of file
diff --git a/ui/.idea/scopes/Compose.xml b/ui/.idea/scopes/Compose.xml
new file mode 120000
index 0000000..5b0b419
--- /dev/null
+++ b/ui/.idea/scopes/Compose.xml
@@ -0,0 +1 @@
+../../../.idea/scopes/Compose.xml
\ No newline at end of file