170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala/*
270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala * Copyright (C) 2013 The Android Open Source Project
370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala *
470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala * you may not use this file except in compliance with the License.
670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala * You may obtain a copy of the License at
770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala *
870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala *
1070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
1170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
1270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala * See the License for the specific language governing permissions and
1470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala * limitations under the License.
1570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala */
1670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
1770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvalapackage android.hardware.camera2.impl;
1870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
19b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun Heimport android.graphics.ImageFormat;
20b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun Heimport android.graphics.Point;
21b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun Heimport android.graphics.Rect;
22b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun Heimport android.hardware.camera2.CameraCharacteristics;
23d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkinimport android.hardware.camera2.CaptureRequest;
24b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun Heimport android.hardware.camera2.CaptureResult;
253c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.Marshaler;
263c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.MarshalQueryable;
273c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.MarshalRegistry;
283c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableArray;
293c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableBoolean;
3052842e7a6f0e922185db04ae8b91c776a234acf1Ruben Brunkimport android.hardware.camera2.marshal.impl.MarshalQueryableBlackLevelPattern;
313c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableColorSpaceTransform;
323c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableEnum;
3312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yehimport android.hardware.camera2.marshal.impl.MarshalQueryableHighSpeedVideoConfiguration;
343c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableMeteringRectangle;
353c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableNativeByteToInteger;
365743868e15c88d2886915163652a1571a218bf39Igor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryablePair;
373c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableParcelable;
383c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryablePrimitive;
393c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableRange;
403c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableRect;
413c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableReprocessFormatsMap;
423c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableRggbChannelVector;
433c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableSize;
443c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableSizeF;
453c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfiguration;
463c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfigurationDuration;
473c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.impl.MarshalQueryableString;
4872f9f0a96e4476ef231d5001cb30521ad4ce5b1eIgor Murashkinimport android.hardware.camera2.params.Face;
4912da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yehimport android.hardware.camera2.params.HighSpeedVideoConfiguration;
50574936894d3044445a272b39f2d925af40ece5d8Ruben Brunkimport android.hardware.camera2.params.LensShadingMap;
519c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport android.hardware.camera2.params.StreamConfiguration;
529c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport android.hardware.camera2.params.StreamConfigurationDuration;
539c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport android.hardware.camera2.params.StreamConfigurationMap;
548490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yehimport android.hardware.camera2.params.TonemapCurve;
55d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkinimport android.hardware.camera2.utils.TypeReference;
56574936894d3044445a272b39f2d925af40ece5d8Ruben Brunkimport android.location.Location;
57574936894d3044445a272b39f2d925af40ece5d8Ruben Brunkimport android.location.LocationManager;
5870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvalaimport android.os.Parcelable;
5970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvalaimport android.os.Parcel;
6070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvalaimport android.util.Log;
61574936894d3044445a272b39f2d925af40ece5d8Ruben Brunkimport android.util.Size;
6270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
63d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkinimport com.android.internal.util.Preconditions;
64d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
65d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkinimport java.io.IOException;
6670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvalaimport java.nio.ByteBuffer;
6770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvalaimport java.nio.ByteOrder;
6870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvalaimport java.util.ArrayList;
69574936894d3044445a272b39f2d925af40ece5d8Ruben Brunkimport java.util.HashMap;
7070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
7170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala/**
7270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala * Implementation of camera metadata marshal/unmarshal across Binder to
7370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala * the camera service
7470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala */
75d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkinpublic class CameraMetadataNative implements Parcelable {
76d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
77d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    public static class Key<T> {
78d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        private boolean mHasTag;
79d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        private int mTag;
80d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        private final Class<T> mType;
81d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        private final TypeReference<T> mTypeReference;
82d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        private final String mName;
83d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        private final int mHash;
84d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        /**
85d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * Visible for testing only.
86d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         *
87d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * <p>Use the CameraCharacteristics.Key, CaptureResult.Key, or CaptureRequest.Key
88d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * for application code or vendor-extended keys.</p>
89d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         */
90d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        public Key(String name, Class<T> type) {
91d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            if (name == null) {
92d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin                throw new NullPointerException("Key needs a valid name");
93d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            } else if (type == null) {
94d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin                throw new NullPointerException("Type needs to be non-null");
95d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            }
96d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            mName = name;
97d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            mType = type;
98d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            mTypeReference = TypeReference.createSpecializedTypeReference(type);
99d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            mHash = mName.hashCode() ^ mTypeReference.hashCode();
100d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        }
101d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
102d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        /**
103d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * Visible for testing only.
104d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         *
105d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * <p>Use the CameraCharacteristics.Key, CaptureResult.Key, or CaptureRequest.Key
106d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * for application code or vendor-extended keys.</p>
107d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         */
108d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        @SuppressWarnings("unchecked")
109d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        public Key(String name, TypeReference<T> typeReference) {
110d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            if (name == null) {
111d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin                throw new NullPointerException("Key needs a valid name");
112d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            } else if (typeReference == null) {
113d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin                throw new NullPointerException("TypeReference needs to be non-null");
114d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            }
115d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            mName = name;
116d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            mType = (Class<T>)typeReference.getRawType();
117d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            mTypeReference = typeReference;
118d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            mHash = mName.hashCode() ^ mTypeReference.hashCode();
119d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        }
120d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
121d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        /**
122d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * Return a camelCase, period separated name formatted like:
123d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * {@code "root.section[.subsections].name"}.
124d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         *
125d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * <p>Built-in keys exposed by the Android SDK are always prefixed with {@code "android."};
126d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * keys that are device/platform-specific are prefixed with {@code "com."}.</p>
127d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         *
128d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * <p>For example, {@code CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP} would
129d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * have a name of {@code "android.scaler.streamConfigurationMap"}; whereas a device
130d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * specific key might look like {@code "com.google.nexus.data.private"}.</p>
131d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         *
132d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * @return String representation of the key name
133d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         */
134d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        public final String getName() {
135d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            return mName;
136d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        }
137d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
138d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        /**
139d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * {@inheritDoc}
140d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         */
141d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        @Override
142d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        public final int hashCode() {
143d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            return mHash;
144d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        }
145d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
146d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        /**
147d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * Compare this key against other native keys, request keys, result keys, and
148d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * characteristics keys.
149d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         *
150d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * <p>Two keys are considered equal if their name and type reference are equal.</p>
151d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         *
152d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * <p>Note that the equality against non-native keys is one-way. A native key may be equal
153d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * to a result key; but that same result key will not be equal to a native key.</p>
154d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         */
155d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        @SuppressWarnings("rawtypes")
156d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        @Override
157d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        public final boolean equals(Object o) {
158d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            if (this == o) {
159d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin                return true;
160d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            }
161d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
162d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            if (o == null || this.hashCode() != o.hashCode()) {
163d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                return false;
164d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            }
165d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk
166d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            Key<?> lhs;
167d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
168d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            if (o instanceof CaptureResult.Key) {
169d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin                lhs = ((CaptureResult.Key)o).getNativeKey();
170d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            } else if (o instanceof CaptureRequest.Key) {
171d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin                lhs = ((CaptureRequest.Key)o).getNativeKey();
172d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            } else if (o instanceof CameraCharacteristics.Key) {
173d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin                lhs = ((CameraCharacteristics.Key)o).getNativeKey();
174d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            } else if ((o instanceof Key)) {
175d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin                lhs = (Key<?>)o;
176d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            } else {
177d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin                return false;
178d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            }
179d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
180d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            return mName.equals(lhs.mName) && mTypeReference.equals(lhs.mTypeReference);
181d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        }
182d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
183d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        /**
184d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * <p>
185d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * Get the tag corresponding to this key. This enables insertion into the
186d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * native metadata.
187d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * </p>
188d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         *
189d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * <p>This value is looked up the first time, and cached subsequently.</p>
190d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         *
191d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * @return The tag numeric value corresponding to the string
192d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         */
193d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        public final int getTag() {
194d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            if (!mHasTag) {
195d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin                mTag = CameraMetadataNative.getTag(mName);
196d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin                mHasTag = true;
197d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            }
198d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            return mTag;
199d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        }
200d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
201d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        /**
202d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * Get the raw class backing the type {@code T} for this key.
203d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         *
204d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * <p>The distinction is only important if {@code T} is a generic, e.g.
205d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * {@code Range<Integer>} since the nested type will be erased.</p>
206d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         */
207d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        public final Class<T> getType() {
208d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            // TODO: remove this; other places should use #getTypeReference() instead
209d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            return mType;
210d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        }
211d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
212d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        /**
213d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * Get the type reference backing the type {@code T} for this key.
214d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         *
215d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * <p>The distinction is only important if {@code T} is a generic, e.g.
216d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         * {@code Range<Integer>} since the nested type will be retained.</p>
217d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin         */
218d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        public final TypeReference<T> getTypeReference() {
219d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            return mTypeReference;
220d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        }
221d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
22270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
22370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private static final String TAG = "CameraMetadataJV";
224227c09f998a79ea4baf1fe178297ef6347e05e0aEino-Ville Talvala    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
225b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He    // this should be in sync with HAL_PIXEL_FORMAT_BLOB defined in graphics.h
226feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public static final int NATIVE_JPEG_FORMAT = 0x21;
22770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
228574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk    private static final String CELLID_PROCESS = "CELLID";
229574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk    private static final String GPS_PROCESS = "GPS";
2300a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin    private static final int FACE_LANDMARK_SIZE = 6;
231574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk
232574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk    private static String translateLocationProviderToProcess(final String provider) {
233574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        if (provider == null) {
234574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            return null;
235574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        }
236574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        switch(provider) {
237574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            case LocationManager.GPS_PROVIDER:
238574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk                return GPS_PROCESS;
239574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            case LocationManager.NETWORK_PROVIDER:
240574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk                return CELLID_PROCESS;
241574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            default:
242574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk                return null;
243574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        }
244574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk    }
245574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk
246574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk    private static String translateProcessToLocationProvider(final String process) {
247574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        if (process == null) {
248574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            return null;
249574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        }
250574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        switch(process) {
251574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            case GPS_PROCESS:
252574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk                return LocationManager.GPS_PROVIDER;
253574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            case CELLID_PROCESS:
254574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk                return LocationManager.NETWORK_PROVIDER;
255574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            default:
256574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk                return null;
257574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        }
258574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk    }
259574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk
26070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public CameraMetadataNative() {
26170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        super();
26270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        mMetadataPtr = nativeAllocate();
26370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        if (mMetadataPtr == 0) {
26470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            throw new OutOfMemoryError("Failed to allocate native CameraMetadata");
26570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        }
26670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
26770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
26870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
26970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * Copy constructor - clone metadata
27070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
27170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public CameraMetadataNative(CameraMetadataNative other) {
27270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        super();
27370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        mMetadataPtr = nativeAllocateCopy(other);
27470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        if (mMetadataPtr == 0) {
27570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            throw new OutOfMemoryError("Failed to allocate native CameraMetadata");
27670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        }
27770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
27870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
279d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    /**
280d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * Move the contents from {@code other} into a new camera metadata instance.</p>
281d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     *
282d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * <p>After this call, {@code other} will become empty.</p>
283d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     *
284d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * @param other the previous metadata instance which will get pilfered
285d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * @return a new metadata instance with the values from {@code other} moved into it
286d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     */
287d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    public static CameraMetadataNative move(CameraMetadataNative other) {
288d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        CameraMetadataNative newObject = new CameraMetadataNative();
289d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        newObject.swap(other);
290d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        return newObject;
291d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
292d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
29370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public static final Parcelable.Creator<CameraMetadataNative> CREATOR =
29470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            new Parcelable.Creator<CameraMetadataNative>() {
29570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        @Override
29670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        public CameraMetadataNative createFromParcel(Parcel in) {
29770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            CameraMetadataNative metadata = new CameraMetadataNative();
29870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            metadata.readFromParcel(in);
29970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            return metadata;
30070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        }
30170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
30270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        @Override
30370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        public CameraMetadataNative[] newArray(int size) {
30470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            return new CameraMetadataNative[size];
30570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        }
30670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    };
30770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
30870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    @Override
30970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public int describeContents() {
31070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        return 0;
31170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
31270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
31370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    @Override
31470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public void writeToParcel(Parcel dest, int flags) {
31570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        nativeWriteToParcel(dest);
31670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
31770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
318d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    /**
319d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * @hide
320d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     */
321d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    public <T> T get(CameraCharacteristics.Key<T> key) {
322d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        return get(key.getNativeKey());
323d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
324d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
325d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    /**
326d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * @hide
327d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     */
328d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    public <T> T get(CaptureResult.Key<T> key) {
329d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        return get(key.getNativeKey());
330d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
331d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
332d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    /**
333d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * @hide
334d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     */
335d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    public <T> T get(CaptureRequest.Key<T> key) {
336d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        return get(key.getNativeKey());
337d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
338d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
339d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    /**
340d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * Look-up a metadata field value by its key.
341d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     *
342d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * @param key a non-{@code null} key instance
343d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * @return the field corresponding to the {@code key}, or {@code null} if no value was set
344d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     */
34570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public <T> T get(Key<T> key) {
346d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        Preconditions.checkNotNull(key, "key must not be null");
347d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
348d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        // Check if key has been overridden to use a wrapper class on the java side.
349d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        GetCommand g = sGetCommandMap.get(key);
350d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        if (g != null) {
3510a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            return g.getValue(this, key);
35270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        }
353b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        return getBase(key);
35470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
35570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
35670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public void readFromParcel(Parcel in) {
35770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        nativeReadFromParcel(in);
35870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
35970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
36070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
36185c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk     * Set the global client-side vendor tag descriptor to allow use of vendor
36285c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk     * tags in camera applications.
36385c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk     *
36485c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk     * @return int A native status_t value corresponding to one of the
36585c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk     * {@link CameraBinderDecorator} integer constants.
36685c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk     * @see CameraBinderDecorator#throwOnError
36785c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk     *
36885c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk     * @hide
36985c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk     */
37085c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk    public static native int nativeSetupGlobalVendorTagDescriptor();
37185c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk
37285c4388de1fea3d45783f07895c2b113c4cc1ba5Ruben Brunk    /**
37370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * Set a camera metadata field to a value. The field definitions can be
37468f40066c914aefc1f88819dd46dd1135fb9f5bcIgor Murashkin     * found in {@link CameraCharacteristics}, {@link CaptureResult}, and
37570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * {@link CaptureRequest}.
37670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
37770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @param key The metadata field to write.
37870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @param value The value to set the field to, which must be of a matching
37970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * type to the key.
38070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
38170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public <T> void set(Key<T> key, T value) {
382d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        SetCommand s = sSetCommandMap.get(key);
383d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        if (s != null) {
384d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            s.setValue(this, value);
38570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            return;
38670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        }
38770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
388b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        setBase(key, value);
38970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
39070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
391d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    public <T> void set(CaptureRequest.Key<T> key, T value) {
392d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        set(key.getNativeKey(), value);
393d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
394d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
395d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    public <T> void set(CaptureResult.Key<T> key, T value) {
396d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        set(key.getNativeKey(), value);
397d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
398d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
399d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    public <T> void set(CameraCharacteristics.Key<T> key, T value) {
400d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        set(key.getNativeKey(), value);
401d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
402d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
40370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    // Keep up-to-date with camera_metadata.h
40470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
40570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
40670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
40770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public static final int TYPE_BYTE = 0;
40870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
40970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
41070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
41170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public static final int TYPE_INT32 = 1;
41270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
41370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
41470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
41570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public static final int TYPE_FLOAT = 2;
41670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
41770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
41870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
41970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public static final int TYPE_INT64 = 3;
42070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
42170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
42270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
42370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public static final int TYPE_DOUBLE = 4;
42470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
42570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
42670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
42770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public static final int TYPE_RATIONAL = 5;
42870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
42970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
43070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
43170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public static final int NUM_TYPES = 6;
43270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
43370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private void close() {
43470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        // this sets mMetadataPtr to 0
43570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        nativeClose();
43670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        mMetadataPtr = 0; // set it to 0 again to prevent eclipse from making this field final
43770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
43870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
439d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    private <T> T getBase(CameraCharacteristics.Key<T> key) {
440d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        return getBase(key.getNativeKey());
441d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
442d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
443d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    private <T> T getBase(CaptureResult.Key<T> key) {
444d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        return getBase(key.getNativeKey());
445d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
446d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
447d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    private <T> T getBase(CaptureRequest.Key<T> key) {
448d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        return getBase(key.getNativeKey());
449d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
450d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
451b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He    private <T> T getBase(Key<T> key) {
452b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        int tag = key.getTag();
453b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        byte[] values = readValues(tag);
454b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        if (values == null) {
455b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            return null;
456b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        }
457b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
4583c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        Marshaler<T> marshaler = getMarshalerForKey(key);
459b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        ByteBuffer buffer = ByteBuffer.wrap(values).order(ByteOrder.nativeOrder());
4603c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        return marshaler.unmarshal(buffer);
461b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He    }
462b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
463d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk    // Use Command pattern here to avoid lots of expensive if/equals checks in get for overridden
464d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk    // metadata.
465d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk    private static final HashMap<Key<?>, GetCommand> sGetCommandMap =
466d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            new HashMap<Key<?>, GetCommand>();
467d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk    static {
468d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sGetCommandMap.put(
469d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                CameraCharacteristics.SCALER_AVAILABLE_FORMATS.getNativeKey(), new GetCommand() {
470d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @Override
471d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @SuppressWarnings("unchecked")
472d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
473d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        return (T) metadata.getAvailableFormats();
474d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    }
475d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                });
476d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sGetCommandMap.put(
477d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                CaptureResult.STATISTICS_FACES.getNativeKey(), new GetCommand() {
478d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @Override
479d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @SuppressWarnings("unchecked")
480d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
48140001f5dac10c8b71af5ef051dc1a95d58bea743Ruben Brunk                        return (T) metadata.getFaces();
482d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    }
483d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                });
484d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sGetCommandMap.put(
485d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                CaptureResult.STATISTICS_FACE_RECTANGLES.getNativeKey(), new GetCommand() {
486d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @Override
487d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @SuppressWarnings("unchecked")
488d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
48940001f5dac10c8b71af5ef051dc1a95d58bea743Ruben Brunk                        return (T) metadata.getFaceRectangles();
490d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    }
491d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                });
492d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sGetCommandMap.put(
493d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP.getNativeKey(),
494d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        new GetCommand() {
495d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @Override
496d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @SuppressWarnings("unchecked")
497d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
498d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        return (T) metadata.getStreamConfigurationMap();
499d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    }
500d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                });
501d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sGetCommandMap.put(
502d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                CameraCharacteristics.CONTROL_MAX_REGIONS_AE.getNativeKey(), new GetCommand() {
503d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @Override
504d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @SuppressWarnings("unchecked")
505d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
506d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        return (T) metadata.getMaxRegions(key);
507d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    }
508d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                });
509d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sGetCommandMap.put(
510d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                CameraCharacteristics.CONTROL_MAX_REGIONS_AWB.getNativeKey(), new GetCommand() {
511d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @Override
512d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @SuppressWarnings("unchecked")
513d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
514d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        return (T) metadata.getMaxRegions(key);
515d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    }
516d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                });
517d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sGetCommandMap.put(
518d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                CameraCharacteristics.CONTROL_MAX_REGIONS_AF.getNativeKey(), new GetCommand() {
519d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @Override
520d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @SuppressWarnings("unchecked")
521d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
522d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        return (T) metadata.getMaxRegions(key);
523d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    }
524d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                });
525d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sGetCommandMap.put(
526d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW.getNativeKey(), new GetCommand() {
527d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @Override
528d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @SuppressWarnings("unchecked")
529d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
530d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        return (T) metadata.getMaxNumOutputs(key);
531d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    }
532d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                });
533d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sGetCommandMap.put(
534d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC.getNativeKey(), new GetCommand() {
535d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @Override
536d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @SuppressWarnings("unchecked")
537d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
538d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        return (T) metadata.getMaxNumOutputs(key);
539d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    }
540d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                });
541d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sGetCommandMap.put(
542d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING.getNativeKey(),
543d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        new GetCommand() {
544d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @Override
545d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @SuppressWarnings("unchecked")
546d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
547d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        return (T) metadata.getMaxNumOutputs(key);
548d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    }
549d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                });
550d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sGetCommandMap.put(
551d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                CaptureRequest.TONEMAP_CURVE.getNativeKey(), new GetCommand() {
552d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @Override
553d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @SuppressWarnings("unchecked")
554d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
555d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        return (T) metadata.getTonemapCurve();
556d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    }
557d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                });
558d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sGetCommandMap.put(
559d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                CaptureResult.JPEG_GPS_LOCATION.getNativeKey(), new GetCommand() {
560d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @Override
561d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @SuppressWarnings("unchecked")
562d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
563d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        return (T) metadata.getGpsLocation();
564d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    }
565d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                });
566d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sGetCommandMap.put(
567d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP.getNativeKey(),
568d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        new GetCommand() {
569d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @Override
570d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    @SuppressWarnings("unchecked")
571d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
572d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                        return (T) metadata.getLensShadingMap();
573d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                    }
574d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                });
575b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He    }
576b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
577b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He    private int[] getAvailableFormats() {
578b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        int[] availableFormats = getBase(CameraCharacteristics.SCALER_AVAILABLE_FORMATS);
5792f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He        if (availableFormats != null) {
5802f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He            for (int i = 0; i < availableFormats.length; i++) {
5812f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He                // JPEG has different value between native and managed side, need override.
5822f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He                if (availableFormats[i] == NATIVE_JPEG_FORMAT) {
5832f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He                    availableFormats[i] = ImageFormat.JPEG;
5842f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He                }
585b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            }
586b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        }
5872f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He
588b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        return availableFormats;
589b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He    }
590b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
5910a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin    private boolean setFaces(Face[] faces) {
5920a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        if (faces == null) {
5930a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            return false;
5940a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        }
5950a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin
5960a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        int numFaces = faces.length;
5970a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin
5980a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        // Detect if all faces are SIMPLE or not; count # of valid faces
5990a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        boolean fullMode = true;
6000a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        for (Face face : faces) {
6010a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            if (face == null) {
6020a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                numFaces--;
6030a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                Log.w(TAG, "setFaces - null face detected, skipping");
6040a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                continue;
6050a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            }
6060a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin
6070a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            if (face.getId() == Face.ID_UNSUPPORTED) {
6080a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                fullMode = false;
6090a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            }
6100a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        }
6110a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin
6120a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        Rect[] faceRectangles = new Rect[numFaces];
6130a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        byte[] faceScores = new byte[numFaces];
6140a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        int[] faceIds = null;
6150a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        int[] faceLandmarks = null;
6160a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin
6170a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        if (fullMode) {
6180a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            faceIds = new int[numFaces];
6190a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            faceLandmarks = new int[numFaces * FACE_LANDMARK_SIZE];
6200a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        }
6210a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin
6220a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        int i = 0;
6230a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        for (Face face : faces) {
6240a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            if (face == null) {
6250a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                continue;
6260a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            }
6270a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin
6280a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            faceRectangles[i] = face.getBounds();
6290a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            faceScores[i] = (byte)face.getScore();
6300a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin
6310a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            if (fullMode) {
6320a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                faceIds[i] = face.getId();
633b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
6340a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                int j = 0;
6350a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin
6360a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                faceLandmarks[i * FACE_LANDMARK_SIZE + j++] = face.getLeftEyePosition().x;
6370a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                faceLandmarks[i * FACE_LANDMARK_SIZE + j++] = face.getLeftEyePosition().y;
6380a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                faceLandmarks[i * FACE_LANDMARK_SIZE + j++] = face.getRightEyePosition().x;
6390a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                faceLandmarks[i * FACE_LANDMARK_SIZE + j++] = face.getRightEyePosition().y;
6400a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                faceLandmarks[i * FACE_LANDMARK_SIZE + j++] = face.getMouthPosition().x;
6410a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                faceLandmarks[i * FACE_LANDMARK_SIZE + j++] = face.getMouthPosition().y;
6420a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            }
6430a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin
6440a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            i++;
6450a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        }
6460a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin
6470a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        set(CaptureResult.STATISTICS_FACE_RECTANGLES, faceRectangles);
6480a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        set(CaptureResult.STATISTICS_FACE_IDS, faceIds);
6490a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        set(CaptureResult.STATISTICS_FACE_LANDMARKS, faceLandmarks);
6500a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        set(CaptureResult.STATISTICS_FACE_SCORES, faceScores);
6510a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin
6520a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        return true;
6530a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin    }
6540a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin
6550a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin    private Face[] getFaces() {
65658216c2650c9536f93467d6ab347ca3f7720deddZhijun He        Integer faceDetectMode = get(CaptureResult.STATISTICS_FACE_DETECT_MODE);
657d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        byte[] faceScores = get(CaptureResult.STATISTICS_FACE_SCORES);
658d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        Rect[] faceRectangles = get(CaptureResult.STATISTICS_FACE_RECTANGLES);
659d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        int[] faceIds = get(CaptureResult.STATISTICS_FACE_IDS);
660d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        int[] faceLandmarks = get(CaptureResult.STATISTICS_FACE_LANDMARKS);
661d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh
662d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        if (areValuesAllNull(faceDetectMode, faceScores, faceRectangles, faceIds, faceLandmarks)) {
663d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh            return null;
664d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        }
665d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh
666b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        if (faceDetectMode == null) {
66758216c2650c9536f93467d6ab347ca3f7720deddZhijun He            Log.w(TAG, "Face detect mode metadata is null, assuming the mode is SIMPLE");
66858216c2650c9536f93467d6ab347ca3f7720deddZhijun He            faceDetectMode = CaptureResult.STATISTICS_FACE_DETECT_MODE_SIMPLE;
66958216c2650c9536f93467d6ab347ca3f7720deddZhijun He        } else {
67058216c2650c9536f93467d6ab347ca3f7720deddZhijun He            if (faceDetectMode == CaptureResult.STATISTICS_FACE_DETECT_MODE_OFF) {
67158216c2650c9536f93467d6ab347ca3f7720deddZhijun He                return new Face[0];
67258216c2650c9536f93467d6ab347ca3f7720deddZhijun He            }
67358216c2650c9536f93467d6ab347ca3f7720deddZhijun He            if (faceDetectMode != CaptureResult.STATISTICS_FACE_DETECT_MODE_SIMPLE &&
67458216c2650c9536f93467d6ab347ca3f7720deddZhijun He                    faceDetectMode != CaptureResult.STATISTICS_FACE_DETECT_MODE_FULL) {
67558216c2650c9536f93467d6ab347ca3f7720deddZhijun He                Log.w(TAG, "Unknown face detect mode: " + faceDetectMode);
67658216c2650c9536f93467d6ab347ca3f7720deddZhijun He                return new Face[0];
67758216c2650c9536f93467d6ab347ca3f7720deddZhijun He            }
678b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        }
679b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
680b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        // Face scores and rectangles are required by SIMPLE and FULL mode.
681b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        if (faceScores == null || faceRectangles == null) {
68258216c2650c9536f93467d6ab347ca3f7720deddZhijun He            Log.w(TAG, "Expect face scores and rectangles to be non-null");
68358216c2650c9536f93467d6ab347ca3f7720deddZhijun He            return new Face[0];
684b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        } else if (faceScores.length != faceRectangles.length) {
68558216c2650c9536f93467d6ab347ca3f7720deddZhijun He            Log.w(TAG, String.format("Face score size(%d) doesn match face rectangle size(%d)!",
68658216c2650c9536f93467d6ab347ca3f7720deddZhijun He                    faceScores.length, faceRectangles.length));
687b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        }
688b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
68958216c2650c9536f93467d6ab347ca3f7720deddZhijun He        // To be safe, make number of faces is the minimal of all face info metadata length.
69058216c2650c9536f93467d6ab347ca3f7720deddZhijun He        int numFaces = Math.min(faceScores.length, faceRectangles.length);
691b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        // Face id and landmarks are only required by FULL mode.
692b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        if (faceDetectMode == CaptureResult.STATISTICS_FACE_DETECT_MODE_FULL) {
693b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            if (faceIds == null || faceLandmarks == null) {
69458216c2650c9536f93467d6ab347ca3f7720deddZhijun He                Log.w(TAG, "Expect face ids and landmarks to be non-null for FULL mode," +
69558216c2650c9536f93467d6ab347ca3f7720deddZhijun He                        "fallback to SIMPLE mode");
69658216c2650c9536f93467d6ab347ca3f7720deddZhijun He                faceDetectMode = CaptureResult.STATISTICS_FACE_DETECT_MODE_SIMPLE;
69758216c2650c9536f93467d6ab347ca3f7720deddZhijun He            } else {
69858216c2650c9536f93467d6ab347ca3f7720deddZhijun He                if (faceIds.length != numFaces ||
69958216c2650c9536f93467d6ab347ca3f7720deddZhijun He                        faceLandmarks.length != numFaces * FACE_LANDMARK_SIZE) {
70058216c2650c9536f93467d6ab347ca3f7720deddZhijun He                    Log.w(TAG, String.format("Face id size(%d), or face landmark size(%d) don't" +
70158216c2650c9536f93467d6ab347ca3f7720deddZhijun He                            "match face number(%d)!",
70258216c2650c9536f93467d6ab347ca3f7720deddZhijun He                            faceIds.length, faceLandmarks.length * FACE_LANDMARK_SIZE, numFaces));
70358216c2650c9536f93467d6ab347ca3f7720deddZhijun He                }
70458216c2650c9536f93467d6ab347ca3f7720deddZhijun He                // To be safe, make number of faces is the minimal of all face info metadata length.
70558216c2650c9536f93467d6ab347ca3f7720deddZhijun He                numFaces = Math.min(numFaces, faceIds.length);
70658216c2650c9536f93467d6ab347ca3f7720deddZhijun He                numFaces = Math.min(numFaces, faceLandmarks.length / FACE_LANDMARK_SIZE);
707b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            }
708b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        }
709b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
710844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He        ArrayList<Face> faceList = new ArrayList<Face>();
711b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        if (faceDetectMode == CaptureResult.STATISTICS_FACE_DETECT_MODE_SIMPLE) {
712b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            for (int i = 0; i < numFaces; i++) {
713844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He                if (faceScores[i] <= Face.SCORE_MAX &&
714844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He                        faceScores[i] >= Face.SCORE_MIN) {
715844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He                    faceList.add(new Face(faceRectangles[i], faceScores[i]));
716844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He                }
717b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            }
718b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        } else {
719b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            // CaptureResult.STATISTICS_FACE_DETECT_MODE_FULL
720b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            for (int i = 0; i < numFaces; i++) {
721844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He                if (faceScores[i] <= Face.SCORE_MAX &&
722844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He                        faceScores[i] >= Face.SCORE_MIN &&
723844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He                        faceIds[i] >= 0) {
7240a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                    Point leftEye = new Point(faceLandmarks[i*FACE_LANDMARK_SIZE],
7250a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                            faceLandmarks[i*FACE_LANDMARK_SIZE+1]);
7260a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                    Point rightEye = new Point(faceLandmarks[i*FACE_LANDMARK_SIZE+2],
7270a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                            faceLandmarks[i*FACE_LANDMARK_SIZE+3]);
7280a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                    Point mouth = new Point(faceLandmarks[i*FACE_LANDMARK_SIZE+4],
7290a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                            faceLandmarks[i*FACE_LANDMARK_SIZE+5]);
730844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He                    Face face = new Face(faceRectangles[i], faceScores[i], faceIds[i],
731844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He                            leftEye, rightEye, mouth);
732844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He                    faceList.add(face);
733844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He                }
734b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            }
735b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        }
736844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He        Face[] faces = new Face[faceList.size()];
737844b3520cc31dbca40f282e5a0e3e6d442d4c686Zhijun He        faceList.toArray(faces);
738b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        return faces;
739b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He    }
740b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
741615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala    // Face rectangles are defined as (left, top, right, bottom) instead of
742615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala    // (left, top, width, height) at the native level, so the normal Rect
743615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala    // conversion that does (l, t, w, h) -> (l, t, r, b) is unnecessary. Undo
744615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala    // that conversion here for just the faces.
7452f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He    private Rect[] getFaceRectangles() {
746615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala        Rect[] faceRectangles = getBase(CaptureResult.STATISTICS_FACE_RECTANGLES);
747615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala        if (faceRectangles == null) return null;
748615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala
749615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala        Rect[] fixedFaceRectangles = new Rect[faceRectangles.length];
750615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala        for (int i = 0; i < faceRectangles.length; i++) {
751615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala            fixedFaceRectangles[i] = new Rect(
752615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala                    faceRectangles[i].left,
753615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala                    faceRectangles[i].top,
754615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala                    faceRectangles[i].right - faceRectangles[i].left,
755615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala                    faceRectangles[i].bottom - faceRectangles[i].top);
756615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala        }
757615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala        return fixedFaceRectangles;
758615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala    }
759615b75f3351065845f95f6a2339461813f530ae9Eino-Ville Talvala
760574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk    private LensShadingMap getLensShadingMap() {
761574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        float[] lsmArray = getBase(CaptureResult.STATISTICS_LENS_SHADING_MAP);
762d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        Size s = get(CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE);
763d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh
764d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        // Do not warn if lsmArray is null while s is not. This is valid.
765574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        if (lsmArray == null) {
766574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            return null;
767574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        }
768d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh
769d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        if (s == null) {
770d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh            Log.w(TAG, "getLensShadingMap - Lens shading map size was null.");
771d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh            return null;
772d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        }
773d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh
774574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        LensShadingMap map = new LensShadingMap(lsmArray, s.getHeight(), s.getWidth());
775574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        return map;
776574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk    }
777574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk
778574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk    private Location getGpsLocation() {
779574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        String processingMethod = get(CaptureResult.JPEG_GPS_PROCESSING_METHOD);
780574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        double[] coords = get(CaptureResult.JPEG_GPS_COORDINATES);
781574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        Long timeStamp = get(CaptureResult.JPEG_GPS_TIMESTAMP);
782574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk
783d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        if (areValuesAllNull(processingMethod, coords, timeStamp)) {
784d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh            return null;
785d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        }
786d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh
787d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        Location l = new Location(translateProcessToLocationProvider(processingMethod));
788574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        if (timeStamp != null) {
789574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            l.setTime(timeStamp);
790574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        } else {
791574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            Log.w(TAG, "getGpsLocation - No timestamp for GPS location.");
792574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        }
793574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk
794574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        if (coords != null) {
795574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            l.setLatitude(coords[0]);
796574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            l.setLongitude(coords[1]);
797574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            l.setAltitude(coords[2]);
798574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        } else {
799574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            Log.w(TAG, "getGpsLocation - No coordinates for GPS location");
800574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        }
801574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk
802574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        return l;
803574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk    }
804574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk
805574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk    private boolean setGpsLocation(Location l) {
806574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        if (l == null) {
807574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            return false;
808574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        }
809574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk
810574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        double[] coords = { l.getLatitude(), l.getLongitude(), l.getAltitude() };
811574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        String processMethod = translateLocationProviderToProcess(l.getProvider());
812574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        long timestamp = l.getTime();
813574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk
814574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        set(CaptureRequest.JPEG_GPS_TIMESTAMP, timestamp);
815574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        set(CaptureRequest.JPEG_GPS_COORDINATES, coords);
816574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk
817574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        if (processMethod == null) {
818574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            Log.w(TAG, "setGpsLocation - No process method, Location is not from a GPS or NETWORK" +
819574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk                    "provider");
820574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        } else {
821574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk            setBase(CaptureRequest.JPEG_GPS_PROCESSING_METHOD, processMethod);
822574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        }
823574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk        return true;
824574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk    }
825574936894d3044445a272b39f2d925af40ece5d8Ruben Brunk
8269c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin    private StreamConfigurationMap getStreamConfigurationMap() {
8279c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin        StreamConfiguration[] configurations = getBase(
8289c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin                CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
8299c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin        StreamConfigurationDuration[] minFrameDurations = getBase(
8309c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin                CameraCharacteristics.SCALER_AVAILABLE_MIN_FRAME_DURATIONS);
8319c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin        StreamConfigurationDuration[] stallDurations = getBase(
8329c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin                CameraCharacteristics.SCALER_AVAILABLE_STALL_DURATIONS);
83312da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh        HighSpeedVideoConfiguration[] highSpeedVideoConfigurations = getBase(
83412da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh                CameraCharacteristics.CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS);
8359c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin
83612da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh        return new StreamConfigurationMap(
83712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh                configurations, minFrameDurations, stallDurations, highSpeedVideoConfigurations);
8389c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin    }
8399c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin
84078712a8bd7275542013ba099f33536eead0167fbIgor Murashkin    private <T> Integer getMaxRegions(Key<T> key) {
84178712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        final int AE = 0;
84278712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        final int AWB = 1;
84378712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        final int AF = 2;
84478712a8bd7275542013ba099f33536eead0167fbIgor Murashkin
84578712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        // The order of the elements is: (AE, AWB, AF)
84678712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        int[] maxRegions = getBase(CameraCharacteristics.CONTROL_MAX_REGIONS);
84778712a8bd7275542013ba099f33536eead0167fbIgor Murashkin
84878712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        if (maxRegions == null) {
84978712a8bd7275542013ba099f33536eead0167fbIgor Murashkin            return null;
85078712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        }
85178712a8bd7275542013ba099f33536eead0167fbIgor Murashkin
85278712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        if (key.equals(CameraCharacteristics.CONTROL_MAX_REGIONS_AE)) {
85378712a8bd7275542013ba099f33536eead0167fbIgor Murashkin            return maxRegions[AE];
85478712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        } else if (key.equals(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB)) {
85578712a8bd7275542013ba099f33536eead0167fbIgor Murashkin            return maxRegions[AWB];
85678712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        } else if (key.equals(CameraCharacteristics.CONTROL_MAX_REGIONS_AF)) {
85778712a8bd7275542013ba099f33536eead0167fbIgor Murashkin            return maxRegions[AF];
85878712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        } else {
85978712a8bd7275542013ba099f33536eead0167fbIgor Murashkin            throw new AssertionError("Invalid key " + key);
86078712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        }
86178712a8bd7275542013ba099f33536eead0167fbIgor Murashkin    }
86278712a8bd7275542013ba099f33536eead0167fbIgor Murashkin
86378712a8bd7275542013ba099f33536eead0167fbIgor Murashkin    private <T> Integer getMaxNumOutputs(Key<T> key) {
86478712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        final int RAW = 0;
86578712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        final int PROC = 1;
86678712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        final int PROC_STALLING = 2;
86778712a8bd7275542013ba099f33536eead0167fbIgor Murashkin
86878712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        // The order of the elements is: (raw, proc+nonstalling, proc+stalling)
86978712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        int[] maxNumOutputs = getBase(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_STREAMS);
87078712a8bd7275542013ba099f33536eead0167fbIgor Murashkin
87178712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        if (maxNumOutputs == null) {
87278712a8bd7275542013ba099f33536eead0167fbIgor Murashkin            return null;
87378712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        }
87478712a8bd7275542013ba099f33536eead0167fbIgor Murashkin
87578712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        if (key.equals(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW)) {
87678712a8bd7275542013ba099f33536eead0167fbIgor Murashkin            return maxNumOutputs[RAW];
87778712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        } else if (key.equals(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC)) {
87878712a8bd7275542013ba099f33536eead0167fbIgor Murashkin            return maxNumOutputs[PROC];
87978712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        } else if (key.equals(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING)) {
88078712a8bd7275542013ba099f33536eead0167fbIgor Murashkin            return maxNumOutputs[PROC_STALLING];
88178712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        } else {
88278712a8bd7275542013ba099f33536eead0167fbIgor Murashkin            throw new AssertionError("Invalid key " + key);
88378712a8bd7275542013ba099f33536eead0167fbIgor Murashkin        }
88478712a8bd7275542013ba099f33536eead0167fbIgor Murashkin    }
88578712a8bd7275542013ba099f33536eead0167fbIgor Murashkin
8868490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh    private <T> TonemapCurve getTonemapCurve() {
8878490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        float[] red = getBase(CaptureRequest.TONEMAP_CURVE_RED);
8888490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        float[] green = getBase(CaptureRequest.TONEMAP_CURVE_GREEN);
8898490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        float[] blue = getBase(CaptureRequest.TONEMAP_CURVE_BLUE);
890d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh
891d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        if (areValuesAllNull(red, green, blue)) {
892d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh            return null;
893d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        }
894d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh
8958490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        if (red == null || green == null || blue == null) {
896d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh            Log.w(TAG, "getTonemapCurve - missing tone curve components");
8978490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh            return null;
8988490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        }
8998490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        TonemapCurve tc = new TonemapCurve(red, green, blue);
9008490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        return tc;
9018490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh    }
9028490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh
903d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    private <T> void setBase(CameraCharacteristics.Key<T> key, T value) {
904d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        setBase(key.getNativeKey(), value);
905d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
906d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
907d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    private <T> void setBase(CaptureResult.Key<T> key, T value) {
908d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        setBase(key.getNativeKey(), value);
909d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
910d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
911d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    private <T> void setBase(CaptureRequest.Key<T> key, T value) {
912d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        setBase(key.getNativeKey(), value);
913d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
914d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
915b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He    private <T> void setBase(Key<T> key, T value) {
916b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        int tag = key.getTag();
917b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
918b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        if (value == null) {
9193c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            // Erase the entry
9203c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            writeValues(tag, /*src*/null);
921b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            return;
9223c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        } // else update the entry to a new value
923b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
9243c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        Marshaler<T> marshaler = getMarshalerForKey(key);
9253c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        int size = marshaler.calculateMarshalSize(value);
926b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
927b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        // TODO: Optimization. Cache the byte[] and reuse if the size is big enough.
928b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        byte[] values = new byte[size];
929b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
930b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        ByteBuffer buffer = ByteBuffer.wrap(values).order(ByteOrder.nativeOrder());
9313c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        marshaler.marshal(value, buffer);
932b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
933b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        writeValues(tag, values);
934b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He    }
935b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
936d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk    // Use Command pattern here to avoid lots of expensive if/equals checks in get for overridden
937d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk    // metadata.
938d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk    private static final HashMap<Key<?>, SetCommand> sSetCommandMap =
939d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            new HashMap<Key<?>, SetCommand>();
940d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk    static {
941d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sSetCommandMap.put(CameraCharacteristics.SCALER_AVAILABLE_FORMATS.getNativeKey(),
942d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                new SetCommand() {
943d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            @Override
944d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            public <T> void setValue(CameraMetadataNative metadata, T value) {
945d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                metadata.setAvailableFormats((int[]) value);
946d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            }
947d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        });
948d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sSetCommandMap.put(CaptureResult.STATISTICS_FACE_RECTANGLES.getNativeKey(),
949d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                new SetCommand() {
950d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            @Override
951d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            public <T> void setValue(CameraMetadataNative metadata, T value) {
952d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                metadata.setFaceRectangles((Rect[]) value);
953d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            }
954d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        });
9550a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        sSetCommandMap.put(CaptureResult.STATISTICS_FACES.getNativeKey(),
9560a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                new SetCommand() {
9570a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            @Override
9580a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            public <T> void setValue(CameraMetadataNative metadata, T value) {
9590a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin                metadata.setFaces((Face[])value);
9600a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin            }
9610a1ef4dbf39aa3dfae1a91daf972ae3457ce27feIgor Murashkin        });
962d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sSetCommandMap.put(CaptureRequest.TONEMAP_CURVE.getNativeKey(), new SetCommand() {
963d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            @Override
964d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            public <T> void setValue(CameraMetadataNative metadata, T value) {
965d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                metadata.setTonemapCurve((TonemapCurve) value);
966d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            }
967d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        });
968d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        sSetCommandMap.put(CaptureResult.JPEG_GPS_LOCATION.getNativeKey(), new SetCommand() {
969d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            @Override
970d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            public <T> void setValue(CameraMetadataNative metadata, T value) {
971d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk                metadata.setGpsLocation((Location) value);
972d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk            }
973d1f113d0f0ce5099f8efba40a88398f7945bb5e0Ruben Brunk        });
974b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He    }
975b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
976b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He    private boolean setAvailableFormats(int[] value) {
977b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        int[] availableFormat = value;
978b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        if (value == null) {
979b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            // Let setBase() to handle the null value case.
980b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            return false;
981b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        }
982b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
983b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        int[] newValues = new int[availableFormat.length];
984b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        for (int i = 0; i < availableFormat.length; i++) {
985b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            newValues[i] = availableFormat[i];
986b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            if (availableFormat[i] == ImageFormat.JPEG) {
987b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He                newValues[i] = NATIVE_JPEG_FORMAT;
988b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He            }
989b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        }
990b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
991b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        setBase(CameraCharacteristics.SCALER_AVAILABLE_FORMATS, newValues);
992b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        return true;
993b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He    }
994b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He
9952f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He    /**
9962f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He     * Convert Face Rectangles from managed side to native side as they have different definitions.
9972f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He     * <p>
9982f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He     * Managed side face rectangles are defined as: left, top, width, height.
9992f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He     * Native side face rectangles are defined as: left, top, right, bottom.
10002f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He     * The input face rectangle need to be converted to native side definition when set is called.
10012f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He     * </p>
10022f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He     *
10032f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He     * @param faceRects Input face rectangles.
10042f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He     * @return true if face rectangles can be set successfully. Otherwise, Let the caller
10052f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He     *             (setBase) to handle it appropriately.
10062f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He     */
10072f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He    private boolean setFaceRectangles(Rect[] faceRects) {
10082f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He        if (faceRects == null) {
10092f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He            return false;
10102f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He        }
10112f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He
10122f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He        Rect[] newFaceRects = new Rect[faceRects.length];
10132f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He        for (int i = 0; i < newFaceRects.length; i++) {
10142f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He            newFaceRects[i] = new Rect(
10152f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He                    faceRects[i].left,
10162f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He                    faceRects[i].top,
10172f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He                    faceRects[i].right + faceRects[i].left,
10182f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He                    faceRects[i].bottom + faceRects[i].top);
10192f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He        }
10202f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He
10212f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He        setBase(CaptureResult.STATISTICS_FACE_RECTANGLES, newFaceRects);
10222f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He        return true;
10232f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He    }
10242f1680be3d5963dc1026c8e5bcda491b77d71734Zhijun He
10258490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh    private <T> boolean setTonemapCurve(TonemapCurve tc) {
10268490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        if (tc == null) {
10278490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh            return false;
10288490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        }
10298490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh
10308490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        float[][] curve = new float[3][];
10318490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        for (int i = TonemapCurve.CHANNEL_RED; i <= TonemapCurve.CHANNEL_BLUE; i++) {
10328490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh            int pointCount = tc.getPointCount(i);
10338490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh            curve[i] = new float[pointCount * TonemapCurve.POINT_SIZE];
10348490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh            tc.copyColorCurve(i, curve[i], 0);
10358490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        }
10368490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        setBase(CaptureRequest.TONEMAP_CURVE_RED, curve[0]);
10378490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        setBase(CaptureRequest.TONEMAP_CURVE_GREEN, curve[1]);
10388490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        setBase(CaptureRequest.TONEMAP_CURVE_BLUE, curve[2]);
10398490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh
10408490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh        return true;
10418490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh    }
10428490ace76fd350e53de9554c11fca715c5a37aafYin-Chia Yeh
104370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private long mMetadataPtr; // native CameraMetadata*
104470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
104570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private native long nativeAllocate();
104670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private native long nativeAllocateCopy(CameraMetadataNative other)
104770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            throws NullPointerException;
104870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
104970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private native synchronized void nativeWriteToParcel(Parcel dest);
105070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private native synchronized void nativeReadFromParcel(Parcel source);
105170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private native synchronized void nativeSwap(CameraMetadataNative other)
105270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            throws NullPointerException;
105370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private native synchronized void nativeClose();
105470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private native synchronized boolean nativeIsEmpty();
105570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private native synchronized int nativeGetEntryCount();
105670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
105770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private native synchronized byte[] nativeReadValues(int tag);
105870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private native synchronized void nativeWriteValues(int tag, byte[] src);
1059d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    private native synchronized void nativeDump() throws IOException; // dump to ALOGD
106070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
106170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private static native int nativeGetTagFromKey(String keyName)
106270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            throws IllegalArgumentException;
106370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private static native int nativeGetTypeFromTag(int tag)
106470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            throws IllegalArgumentException;
106570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    private static native void nativeClassInit();
106670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
106770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
106870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * <p>Perform a 0-copy swap of the internal metadata with another object.</p>
106970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
107070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * <p>Useful to convert a CameraMetadata into e.g. a CaptureRequest.</p>
107170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
107270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @param other Metadata to swap with
107370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @throws NullPointerException if other was null
107470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
107570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
107670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public void swap(CameraMetadataNative other) {
107770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        nativeSwap(other);
107870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
107970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
108070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
108170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
108270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
108370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public int getEntryCount() {
108470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        return nativeGetEntryCount();
108570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
108670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
108770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
108870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * Does this metadata contain at least 1 entry?
108970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
109070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
109170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
109270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public boolean isEmpty() {
109370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        return nativeIsEmpty();
109470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
109570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
109670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
109770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * Convert a key string into the equivalent native tag.
109870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
109970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @throws IllegalArgumentException if the key was not recognized
110070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @throws NullPointerException if the key was null
110170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
110270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
110370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
110470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public static int getTag(String key) {
110570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        return nativeGetTagFromKey(key);
110670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
110770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
110870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
110970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * Get the underlying native type for a tag.
111070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
111170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @param tag An integer tag, see e.g. {@link #getTag}
111270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @return An int enum for the metadata type, see e.g. {@link #TYPE_BYTE}
111370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
111470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
111570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
111670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public static int getNativeType(int tag) {
111770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        return nativeGetTypeFromTag(tag);
111870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
111970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
112070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
112170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * <p>Updates the existing entry for tag with the new bytes pointed by src, erasing
112270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * the entry if src was null.</p>
112370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
112470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * <p>An empty array can be passed in to update the entry to 0 elements.</p>
112570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
112670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @param tag An integer tag, see e.g. {@link #getTag}
112770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @param src An array of bytes, or null to erase the entry
112870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
112970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
113070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
113170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public void writeValues(int tag, byte[] src) {
113270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        nativeWriteValues(tag, src);
113370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
113470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
113570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
113670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * <p>Returns a byte[] of data corresponding to this tag. Use a wrapped bytebuffer to unserialize
113770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * the data properly.</p>
113870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
113970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * <p>An empty array can be returned to denote an existing entry with 0 elements.</p>
114070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
114170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @param tag An integer tag, see e.g. {@link #getTag}
114270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
114370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @return {@code null} if there were 0 entries for this tag, a byte[] otherwise.
114470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     * @hide
114570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
114670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    public byte[] readValues(int tag) {
1147b7bfdc7cf7f45805e8e7ebea77a15051b8ad3e8dZhijun He        // TODO: Optimization. Native code returns a ByteBuffer instead.
114870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        return nativeReadValues(tag);
114970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
115070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
1151d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    /**
1152d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * Dumps the native metadata contents to logcat.
1153d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     *
1154d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * <p>Visibility for testing/debugging only. The results will not
1155d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * include any synthesized keys, as they are invisible to the native layer.</p>
1156d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     *
1157d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     * @hide
1158d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin     */
1159d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    public void dumpToLog() {
1160d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        try {
1161d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            nativeDump();
1162d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        } catch (IOException e) {
1163d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin            Log.wtf(TAG, "Dump logging failed", e);
1164d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin        }
1165d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin    }
1166d6d65154e55612b489aae95b60f3145f3b81f3b4Igor Murashkin
116770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    @Override
116870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    protected void finalize() throws Throwable {
116970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        try {
117070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            close();
117170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        } finally {
117270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala            super.finalize();
117370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        }
117470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
117570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
117670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    /**
11773c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin     * Get the marshaler compatible with the {@code key} and type {@code T}.
117870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     *
11793c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin     * @throws UnsupportedOperationException
11803c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin     *          if the native/managed type combination for {@code key} is not supported
118170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala     */
11823c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin    private static <T> Marshaler<T> getMarshalerForKey(Key<T> key) {
11833c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        return MarshalRegistry.getMarshaler(key.getTypeReference(),
11843c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                getNativeType(key.getTag()));
118570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
118670c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
11873c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin    @SuppressWarnings({ "unchecked", "rawtypes" })
11883c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin    private static void registerAllMarshalers() {
11893c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        if (VERBOSE) {
11903c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            Log.v(TAG, "Shall register metadata marshalers");
119170c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        }
119270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
11933c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        MarshalQueryable[] queryList = new MarshalQueryable[] {
11943c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                // marshalers for standard types
11953c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryablePrimitive(),
11963c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableEnum(),
11973c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableArray(),
11983c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
11993c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                // pseudo standard types, that expand/narrow the native type into a managed type
12003c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableBoolean(),
12013c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableNativeByteToInteger(),
12023c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
12033c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                // marshalers for custom types
12043c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableRect(),
12053c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableSize(),
12063c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableSizeF(),
12073c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableString(),
12083c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableReprocessFormatsMap(),
12093c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableRange(),
12105743868e15c88d2886915163652a1571a218bf39Igor Murashkin                new MarshalQueryablePair(),
12113c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableMeteringRectangle(),
12123c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableColorSpaceTransform(),
12133c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableStreamConfiguration(),
12143c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableStreamConfigurationDuration(),
12153c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableRggbChannelVector(),
121652842e7a6f0e922185db04ae8b91c776a234acf1Ruben Brunk                new MarshalQueryableBlackLevelPattern(),
121712da140082323d9aa048b3e928505a0a2adfdda7Yin-Chia Yeh                new MarshalQueryableHighSpeedVideoConfiguration(),
12183c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
12193c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                // generic parcelable marshaler (MUST BE LAST since it has lowest priority)
12203c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                new MarshalQueryableParcelable(),
12213c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        };
12223c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
12233c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        for (MarshalQueryable query : queryList) {
12243c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            MarshalRegistry.registerMarshalQueryable(query);
122570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        }
12263c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        if (VERBOSE) {
12273c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            Log.v(TAG, "Registered metadata marshalers");
122870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        }
122970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
123070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala
1231d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh    /** Check if input arguments are all {@code null}.
1232d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh     *
1233d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh     * @param objs Input arguments for null check
1234d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh     * @return {@code true} if input arguments are all {@code null}, otherwise {@code false}
1235d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh     */
1236d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh    private static boolean areValuesAllNull(Object... objs) {
1237d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        for (Object o : objs) {
1238d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh            if (o != null) return false;
1239d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        }
1240d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh        return true;
1241d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh    }
1242d47699a47a77781c8883f31c48ffae88ba878cf8Yin-Chia Yeh
124370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    static {
12443c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        /*
12453c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin         * We use a class initializer to allow the native code to cache some field offsets
12463c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin         */
124770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala        nativeClassInit();
12483c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        registerAllMarshalers();
124970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala    }
125070c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala}
1251