Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e48fb064 authored by Igor Murashkin's avatar Igor Murashkin Committed by Android Git Automerger
Browse files

am 31771fd6: Merge "camera2: Refactor CameraMetadata.Key out into 3 key...

am 31771fd6: Merge "camera2: Refactor CameraMetadata.Key out into 3 key classes" into lmp-preview-dev

* commit '31771fd63b8d08207012c4877a08679fa9b9d539':
  camera2: Refactor CameraMetadata.Key out into 3 key classes
parents e5bf17ea db9c3aee
Loading
Loading
Loading
Loading
+207 −196

File changed.

Preview size limit exceeded, changes collapsed.

+161 −11
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@

package android.hardware.camera2;

import android.hardware.camera2.CaptureResult.Key;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.utils.TypeReference;
import android.util.Rational;

import java.util.Collections;
@@ -35,18 +37,109 @@ import java.util.List;
 * @see CameraDevice
 * @see CameraManager
 */
public final class CameraCharacteristics extends CameraMetadata {
public final class CameraCharacteristics extends CameraMetadata<CameraCharacteristics.Key<?>> {

    /**
     * A {@code Key} is used to do camera characteristics field lookups with
     * {@link CameraCharacteristics#get}.
     *
     * <p>For example, to get the stream configuration map:
     * <code><pre>
     * StreamConfigurationMap map = cameraCharacteristics.get(
     *      CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
     * </pre></code>
     * </p>
     *
     * <p>To enumerate over all possible keys for {@link CameraCharacteristics}, see
     * {@link CameraCharacteristics#getKeys()}.</p>
     *
     * @see CameraCharacteristics#get
     * @see CameraCharacteristics#getKeys()
     */
    public static final class Key<T> {
        private final CameraMetadataNative.Key<T> mKey;

        /**
         * Visible for testing and vendor extensions only.
         *
         * @hide
         */
        public Key(String name, Class<T> type) {
            mKey = new CameraMetadataNative.Key<T>(name,  type);
        }

        /**
         * Visible for testing and vendor extensions only.
         *
         * @hide
         */
        public Key(String name, TypeReference<T> typeReference) {
            mKey = new CameraMetadataNative.Key<T>(name,  typeReference);
        }

        /**
         * Return a camelCase, period separated name formatted like:
         * {@code "root.section[.subsections].name"}.
         *
         * <p>Built-in keys exposed by the Android SDK are always prefixed with {@code "android."};
         * keys that are device/platform-specific are prefixed with {@code "com."}.</p>
         *
         * <p>For example, {@code CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP} would
         * have a name of {@code "android.scaler.streamConfigurationMap"}; whereas a device
         * specific key might look like {@code "com.google.nexus.data.private"}.</p>
         *
         * @return String representation of the key name
         */
        public String getName() {
            return mKey.getName();
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public final int hashCode() {
            return mKey.hashCode();
        }

        /**
         * {@inheritDoc}
         */
        @SuppressWarnings("unchecked")
        @Override
        public final boolean equals(Object o) {
            return o instanceof Key && ((Key<T>)o).mKey.equals(mKey);
        }

        /**
         * Visible for CameraMetadataNative implementation only; do not use.
         *
         * TODO: Make this private or remove it altogether.
         *
         * @hide
         */
        public CameraMetadataNative.Key<T> getNativeKey() {
            return mKey;
        }

        @SuppressWarnings({
                "unused", "unchecked"
        })
        private Key(CameraMetadataNative.Key<?> nativeKey) {
            mKey = (CameraMetadataNative.Key<T>) nativeKey;
        }
    }

    private final CameraMetadataNative mProperties;
    private List<Key<?>> mAvailableRequestKeys;
    private List<Key<?>> mAvailableResultKeys;
    private List<CaptureRequest.Key<?>> mAvailableRequestKeys;
    private List<CaptureResult.Key<?>> mAvailableResultKeys;

    /**
     * Takes ownership of the passed-in properties object
     * @hide
     */
    public CameraCharacteristics(CameraMetadataNative properties) {
        mProperties = properties;
        mProperties = CameraMetadataNative.move(properties);
    }

    /**
@@ -57,11 +150,54 @@ public final class CameraCharacteristics extends CameraMetadata {
        return new CameraMetadataNative(mProperties);
    }

    @Override
    /**
     * Get a camera characteristics field value.
     *
     * <p>The field definitions can be
     * found in {@link CameraCharacteristics}.</p>
     *
     * <p>Querying the value for the same key more than once will return a value
     * which is equal to the previous queried value.</p>
     *
     * @throws IllegalArgumentException if the key was not valid
     *
     * @param key The characteristics field to read.
     * @return The value of that key, or {@code null} if the field is not set.
     */
    public <T> T get(Key<T> key) {
        return mProperties.get(key);
    }

    /**
     * {@inheritDoc}
     * @hide
     */
    @SuppressWarnings("unchecked")
    @Override
    protected <T> T getProtected(Key<?> key) {
        return (T) mProperties.get(key);
    }

    /**
     * {@inheritDoc}
     * @hide
     */
    @SuppressWarnings("unchecked")
    @Override
    protected Class<Key<?>> getKeyClass() {
        Object thisClass = Key.class;
        return (Class<Key<?>>)thisClass;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<Key<?>> getKeys() {
        // Force the javadoc for this function to show up on the CameraCharacteristics page
        return super.getKeys();
    }

    /**
     * Returns the list of keys supported by this {@link CameraDevice} for querying
     * with a {@link CaptureRequest}.
@@ -76,9 +212,14 @@ public final class CameraCharacteristics extends CameraMetadata {
     *
     * @return List of keys supported by this CameraDevice for CaptureRequests.
     */
    public List<Key<?>> getAvailableCaptureRequestKeys() {
    @SuppressWarnings({"unchecked"})
    public List<CaptureRequest.Key<?>> getAvailableCaptureRequestKeys() {
        if (mAvailableRequestKeys == null) {
            mAvailableRequestKeys = getAvailableKeyList(CaptureRequest.class);
            Object crKey = CaptureRequest.Key.class;
            Class<CaptureRequest.Key<?>> crKeyTyped = (Class<CaptureRequest.Key<?>>)crKey;

            mAvailableRequestKeys = Collections.unmodifiableList(
                    getAvailableKeyList(CaptureRequest.class, crKeyTyped));
        }
        return mAvailableRequestKeys;
    }
@@ -97,9 +238,14 @@ public final class CameraCharacteristics extends CameraMetadata {
     *
     * @return List of keys supported by this CameraDevice for CaptureResults.
     */
    public List<Key<?>> getAvailableCaptureResultKeys() {
    @SuppressWarnings({"unchecked"})
    public List<CaptureResult.Key<?>> getAvailableCaptureResultKeys() {
        if (mAvailableResultKeys == null) {
            mAvailableResultKeys = getAvailableKeyList(CaptureResult.class);
            Object crKey = CaptureResult.Key.class;
            Class<CaptureResult.Key<?>> crKeyTyped = (Class<CaptureResult.Key<?>>)crKey;

            mAvailableResultKeys = Collections.unmodifiableList(
                    getAvailableKeyList(CaptureResult.class, crKeyTyped));
        }
        return mAvailableResultKeys;
    }
@@ -113,12 +259,14 @@ public final class CameraCharacteristics extends CameraMetadata {
     * <p>Each key is only listed once in the list. The order of the keys is undefined.</p>
     *
     * @param metadataClass The subclass of CameraMetadata that you want to get the keys for.
     * @param keyClass The class of the metadata key, e.g. CaptureRequest.Key.class
     *
     * @return List of keys supported by this CameraDevice for metadataClass.
     *
     * @throws IllegalArgumentException if metadataClass is not a subclass of CameraMetadata
     */
    private <T extends CameraMetadata> List<Key<?>> getAvailableKeyList(Class<T> metadataClass) {
    private <TKey> List<TKey>
    getAvailableKeyList(Class<?> metadataClass, Class<TKey> keyClass) {

        if (metadataClass.equals(CameraMetadata.class)) {
            throw new AssertionError(
@@ -128,7 +276,9 @@ public final class CameraCharacteristics extends CameraMetadata {
                    "metadataClass must be a subclass of CameraMetadata");
        }

        return Collections.unmodifiableList(getKeysStatic(metadataClass, /*instance*/null));
        List<TKey> staticKeyList = CameraCharacteristics.<TKey>getKeysStatic(
                metadataClass, keyClass, /*instance*/null);
        return Collections.unmodifiableList(staticKeyList);
    }

    /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+33 −122
Original line number Diff line number Diff line
@@ -16,8 +16,7 @@

package android.hardware.camera2;

import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.utils.TypeReference;
import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -36,7 +35,7 @@ import java.util.List;
 *
 * <p>
 * All instances of CameraMetadata are immutable. The list of keys with {@link #getKeys()}
 * never changes, nor do the values returned by any key with {@link #get} throughout
 * never changes, nor do the values returned by any key with {@code #get} throughout
 * the lifetime of the object.
 * </p>
 *
@@ -44,7 +43,10 @@ import java.util.List;
 * @see CameraManager
 * @see CameraCharacteristics
 **/
public abstract class CameraMetadata {
public abstract class CameraMetadata<TKey> {

    private static final String TAG = "CameraMetadataAb";
    private static final boolean VERBOSE = false;

    /**
     * Set a camera metadata field to a value. The field definitions can be
@@ -74,8 +76,15 @@ public abstract class CameraMetadata {
     *
     * @param key The metadata field to read.
     * @return The value of that key, or {@code null} if the field is not set.
     *
     * @hide
     */
     protected abstract <T> T getProtected(TKey key);

     /**
      * @hide
      */
    public abstract <T> T get(Key<T> key);
     protected abstract Class<TKey> getKeyClass();

    /**
     * Returns a list of the keys contained in this map.
@@ -83,14 +92,16 @@ public abstract class CameraMetadata {
     * <p>The list returned is not modifiable, so any attempts to modify it will throw
     * a {@code UnsupportedOperationException}.</p>
     *
     * <p>All values retrieved by a key from this list with {@link #get} are guaranteed to be
     * <p>All values retrieved by a key from this list with {@code #get} are guaranteed to be
     * non-{@code null}. Each key is only listed once in the list. The order of the keys
     * is undefined.</p>
     *
     * @return List of the keys contained in this map.
     */
    public List<Key<?>> getKeys() {
        return Collections.unmodifiableList(getKeysStatic(this.getClass(), this));
    @SuppressWarnings("unchecked")
    public List<TKey> getKeys() {
        Class<CameraMetadata<TKey>> thisClass = (Class<CameraMetadata<TKey>>) getClass();
        return Collections.unmodifiableList(getKeysStatic(thisClass, getKeyClass(), this));
    }

    /**
@@ -101,24 +112,31 @@ public abstract class CameraMetadata {
     * Optionally, if {@code instance} is not null, then filter out any keys with null values.
     * </p>
     */
    /*package*/ static ArrayList<Key<?>> getKeysStatic(Class<? extends CameraMetadata> type,
            CameraMetadata instance) {
        ArrayList<Key<?>> keyList = new ArrayList<Key<?>>();
     /*package*/ @SuppressWarnings("unchecked")
    static <TKey> ArrayList<TKey> getKeysStatic(
             Class<?> type, Class<TKey> keyClass,
             CameraMetadata<TKey> instance) {

        if (VERBOSE) Log.v(TAG, "getKeysStatic for " + type);

        ArrayList<TKey> keyList = new ArrayList<TKey>();

        Field[] fields = type.getDeclaredFields();
        for (Field field : fields) {
            // Filter for Keys that are public
            if (field.getType().isAssignableFrom(Key.class) &&
            if (field.getType().isAssignableFrom(keyClass) &&
                    (field.getModifiers() & Modifier.PUBLIC) != 0) {
                Key<?> key;

                TKey key;
                try {
                    key = (Key<?>) field.get(instance);
                    key = (TKey) field.get(instance);
                } catch (IllegalAccessException e) {
                    throw new AssertionError("Can't get IllegalAccessException", e);
                } catch (IllegalArgumentException e) {
                    throw new AssertionError("Can't get IllegalArgumentException", e);
                }
                if (instance == null || instance.get(key) != null) {

                if (instance == null || instance.getProtected(key) != null) {
                    keyList.add(key);
                }
            }
@@ -127,113 +145,6 @@ public abstract class CameraMetadata {
        return keyList;
    }

    // TODO: make final or abstract
    public static class Key<T> {

        private boolean mHasTag;
        private int mTag;
        private final Class<T> mType;
        private final TypeReference<T> mTypeReference;
        private final String mName;

        /**
         * @hide
         */
        public Key(String name, Class<T> type) {
            if (name == null) {
                throw new NullPointerException("Key needs a valid name");
            } else if (type == null) {
                throw new NullPointerException("Type needs to be non-null");
            }
            mName = name;
            mType = type;
            mTypeReference = TypeReference.createSpecializedTypeReference(type);
        }

        /**
         * @hide
         */
        @SuppressWarnings("unchecked")
        public Key(String name, TypeReference<T> typeReference) {
            if (name == null) {
                throw new NullPointerException("Key needs a valid name");
            } else if (typeReference == null) {
                throw new NullPointerException("TypeReference needs to be non-null");
            }
            mName = name;
            mType = (Class<T>)typeReference.getRawType();
            mTypeReference = typeReference;
        }

        public final String getName() {
            return mName;
        }

        @Override
        public final int hashCode() {
            return mName.hashCode() ^ mTypeReference.hashCode();
        }

        @Override
        public final boolean equals(Object o) {
            if (this == o) {
                return true;
            }

            if (!(o instanceof Key)) {
                return false;
            }

            Key<?> lhs = (Key<?>)o;
            return mName.equals(lhs.mName) && mTypeReference.equals(lhs.mTypeReference);
        }

        /**
         * <p>
         * Get the tag corresponding to this key. This enables insertion into the
         * native metadata.
         * </p>
         *
         * <p>This value is looked up the first time, and cached subsequently.</p>
         *
         * @return The tag numeric value corresponding to the string
         *
         * @hide
         */
        public final int getTag() {
            if (!mHasTag) {
                mTag = CameraMetadataNative.getTag(mName);
                mHasTag = true;
            }
            return mTag;
        }

        /**
         * Get the raw class backing the type {@code T} for this key.
         *
         * <p>The distinction is only important if {@code T} is a generic, e.g.
         * {@code Range<Integer>} since the nested type will be erased.</p>
         *
         * @hide
         */
        public final Class<T> getType() {
            // TODO: remove this; other places should use #getTypeReference() instead
            return mType;
        }

        /**
         * Get the type reference backing the type {@code T} for this key.
         *
         * <p>The distinction is only important if {@code T} is a generic, e.g.
         * {@code Range<Integer>} since the nested type will be retained.</p>
         *
         * @hide
         */
        public final TypeReference<T> getTypeReference() {
            return mTypeReference;
        }
    }

    /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
     * The enum values below this point are generated from metadata
     * definitions in /system/media/camera/docs. Do not modify by hand or
+139 −4
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@

package android.hardware.camera2;

import android.hardware.camera2.CameraCharacteristics.Key;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.utils.TypeReference;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Rational;
@@ -25,6 +27,7 @@ import android.view.Surface;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;


@@ -58,7 +61,98 @@ import java.util.Objects;
 * @see CameraDevice#setRepeatingRequest
 * @see CameraDevice#createCaptureRequest
 */
public final class CaptureRequest extends CameraMetadata implements Parcelable {
public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
        implements Parcelable {

    /**
     * A {@code Key} is used to do capture request field lookups with
     * {@link CaptureResult#get} or to set fields with
     * {@link CaptureRequest.Builder#set(Key, Object)}.
     *
     * <p>For example, to set the crop rectangle for the next capture:
     * <code><pre>
     * Rect cropRectangle = new Rect(0, 0, 640, 480);
     * captureRequestBuilder.set(SCALER_CROP_REGION, cropRectangle);
     * </pre></code>
     * </p>
     *
     * <p>To enumerate over all possible keys for {@link CaptureResult}, see
     * {@link CameraCharacteristics#getAvailableCaptureResultKeys}.</p>
     *
     * @see CaptureResult#get
     * @see CameraCharacteristics#getAvailableCaptureResultKeys
     */
    public final static class Key<T> {
        private final CameraMetadataNative.Key<T> mKey;

        /**
         * Visible for testing and vendor extensions only.
         *
         * @hide
         */
        public Key(String name, Class<T> type) {
            mKey = new CameraMetadataNative.Key<T>(name, type);
        }

        /**
         * Visible for testing and vendor extensions only.
         *
         * @hide
         */
        public Key(String name, TypeReference<T> typeReference) {
            mKey = new CameraMetadataNative.Key<T>(name, typeReference);
        }

        /**
         * Return a camelCase, period separated name formatted like:
         * {@code "root.section[.subsections].name"}.
         *
         * <p>Built-in keys exposed by the Android SDK are always prefixed with {@code "android."};
         * keys that are device/platform-specific are prefixed with {@code "com."}.</p>
         *
         * <p>For example, {@code CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP} would
         * have a name of {@code "android.scaler.streamConfigurationMap"}; whereas a device
         * specific key might look like {@code "com.google.nexus.data.private"}.</p>
         *
         * @return String representation of the key name
         */
        public String getName() {
            return mKey.getName();
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public final int hashCode() {
            return mKey.hashCode();
        }

        /**
         * {@inheritDoc}
         */
        @SuppressWarnings("unchecked")
        @Override
        public final boolean equals(Object o) {
            return o instanceof Key && ((Key<T>)o).mKey.equals(mKey);
        }

        /**
         * Visible for CameraMetadataNative implementation only; do not use.
         *
         * TODO: Make this private or remove it altogether.
         *
         * @hide
         */
        public CameraMetadataNative.Key<T> getNativeKey() {
            return mKey;
        }

        @SuppressWarnings({ "unchecked" })
        /*package*/ Key(CameraMetadataNative.Key<?> nativeKey) {
            mKey = (CameraMetadataNative.Key<T>) nativeKey;
        }
    }

    private final HashSet<Surface> mSurfaceSet;
    private final CameraMetadataNative mSettings;
@@ -93,16 +187,57 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
     * Used by the Builder to create a mutable CaptureRequest.
     */
    private CaptureRequest(CameraMetadataNative settings) {
        mSettings = settings;
        mSettings = CameraMetadataNative.move(settings);
        mSurfaceSet = new HashSet<Surface>();
    }

    @SuppressWarnings("unchecked")
    @Override
    /**
     * Get a capture request field value.
     *
     * <p>The field definitions can be found in {@link CaptureRequest}.</p>
     *
     * <p>Querying the value for the same key more than once will return a value
     * which is equal to the previous queried value.</p>
     *
     * @throws IllegalArgumentException if the key was not valid
     *
     * @param key The result field to read.
     * @return The value of that key, or {@code null} if the field is not set.
     */
    public <T> T get(Key<T> key) {
        return mSettings.get(key);
    }

    /**
     * {@inheritDoc}
     * @hide
     */
    @SuppressWarnings("unchecked")
    @Override
    protected <T> T getProtected(Key<?> key) {
        return (T) mSettings.get(key);
    }

    /**
     * {@inheritDoc}
     * @hide
     */
    @SuppressWarnings("unchecked")
    @Override
    protected Class<Key<?>> getKeyClass() {
        Object thisClass = Key.class;
        return (Class<Key<?>>)thisClass;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<Key<?>> getKeys() {
        // Force the javadoc for this function to show up on the CaptureRequest page
        return super.getKeys();
    }

    /**
     * Retrieve the tag for this request, if any.
     *
+179 −5

File changed.

Preview size limit exceeded, changes collapsed.

Loading