Home | History | Annotate | Download | only in unit
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.mediaframeworktest.unit;
     18 
     19 import android.os.Parcel;
     20 import android.test.suitebuilder.annotation.SmallTest;
     21 import android.graphics.Point;
     22 import android.graphics.Rect;
     23 import android.hardware.camera2.CameraCharacteristics;
     24 import android.hardware.camera2.CaptureResult;
     25 import android.hardware.camera2.Face;
     26 import android.hardware.camera2.Rational;
     27 import android.hardware.camera2.Size;
     28 import android.hardware.camera2.impl.CameraMetadataNative;
     29 
     30 import static android.hardware.camera2.impl.CameraMetadataNative.*;
     31 
     32 import java.lang.reflect.Array;
     33 import java.nio.ByteBuffer;
     34 import java.nio.ByteOrder;
     35 
     36 /**
     37  * <pre>
     38  * adb shell am instrument \
     39  *      -e class 'com.android.mediaframeworktest.unit.CameraMetadataTest' \
     40  *      -w com.android.mediaframeworktest/.MediaFrameworkUnitTestRunner
     41  * </pre>
     42  */
     43 public class CameraMetadataTest extends junit.framework.TestCase {
     44 
     45     CameraMetadataNative mMetadata;
     46     Parcel mParcel;
     47 
     48     // Sections
     49     static final int ANDROID_COLOR_CORRECTION = 0;
     50     static final int ANDROID_CONTROL = 1;
     51 
     52     // Section starts
     53     static final int ANDROID_COLOR_CORRECTION_START = ANDROID_COLOR_CORRECTION << 16;
     54     static final int ANDROID_CONTROL_START = ANDROID_CONTROL << 16;
     55 
     56     // Tags
     57     static final int ANDROID_COLOR_CORRECTION_MODE = ANDROID_COLOR_CORRECTION_START;
     58     static final int ANDROID_COLOR_CORRECTION_TRANSFORM = ANDROID_COLOR_CORRECTION_START + 1;
     59     static final int ANDROID_COLOR_CORRECTION_GAINS = ANDROID_COLOR_CORRECTION_START + 2;
     60 
     61     static final int ANDROID_CONTROL_AE_ANTIBANDING_MODE = ANDROID_CONTROL_START;
     62     static final int ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION = ANDROID_CONTROL_START + 1;
     63 
     64     @Override
     65     public void setUp() {
     66         mMetadata = new CameraMetadataNative();
     67         mParcel = Parcel.obtain();
     68     }
     69 
     70     @Override
     71     public void tearDown() throws Exception {
     72         mMetadata = null;
     73 
     74         mParcel.recycle();
     75         mParcel = null;
     76     }
     77 
     78     @SmallTest
     79     public void testNew() {
     80         assertEquals(0, mMetadata.getEntryCount());
     81         assertTrue(mMetadata.isEmpty());
     82     }
     83 
     84     @SmallTest
     85     public void testGetTagFromKey() {
     86 
     87         // Test success
     88 
     89         assertEquals(ANDROID_COLOR_CORRECTION_MODE,
     90                 CameraMetadataNative.getTag("android.colorCorrection.mode"));
     91         assertEquals(ANDROID_COLOR_CORRECTION_TRANSFORM,
     92                 CameraMetadataNative.getTag("android.colorCorrection.transform"));
     93         assertEquals(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
     94                 CameraMetadataNative.getTag("android.control.aeAntibandingMode"));
     95         assertEquals(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
     96                 CameraMetadataNative.getTag("android.control.aeExposureCompensation"));
     97 
     98         // Test failures
     99 
    100         try {
    101             CameraMetadataNative.getTag(null);
    102             fail("A null key should throw NPE");
    103         } catch(NullPointerException e) {
    104         }
    105 
    106         try {
    107             CameraMetadataNative.getTag("android.control");
    108             fail("A section name only should not be a valid key");
    109         } catch(IllegalArgumentException e) {
    110         }
    111 
    112         try {
    113             CameraMetadataNative.getTag("android.control.thisTagNameIsFakeAndDoesNotExist");
    114             fail("A valid section with an invalid tag name should not be a valid key");
    115         } catch(IllegalArgumentException e) {
    116         }
    117 
    118         try {
    119             CameraMetadataNative.getTag("android");
    120             fail("A namespace name only should not be a valid key");
    121         } catch(IllegalArgumentException e) {
    122         }
    123 
    124         try {
    125             CameraMetadataNative.getTag("this.key.is.definitely.invalid");
    126             fail("A completely fake key name should not be valid");
    127         } catch(IllegalArgumentException e) {
    128         }
    129     }
    130 
    131     @SmallTest
    132     public void testGetTypeFromTag() {
    133         assertEquals(TYPE_BYTE, CameraMetadataNative.getNativeType(ANDROID_COLOR_CORRECTION_MODE));
    134         assertEquals(TYPE_RATIONAL, CameraMetadataNative.getNativeType(ANDROID_COLOR_CORRECTION_TRANSFORM));
    135         assertEquals(TYPE_FLOAT, CameraMetadataNative.getNativeType(ANDROID_COLOR_CORRECTION_GAINS));
    136         assertEquals(TYPE_BYTE, CameraMetadataNative.getNativeType(ANDROID_CONTROL_AE_ANTIBANDING_MODE));
    137         assertEquals(TYPE_INT32,
    138                 CameraMetadataNative.getNativeType(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION));
    139 
    140         try {
    141             CameraMetadataNative.getNativeType(0xDEADF00D);
    142             fail("No type should exist for invalid tag 0xDEADF00D");
    143         } catch(IllegalArgumentException e) {
    144         }
    145     }
    146 
    147     @SmallTest
    148     public void testReadWriteValues() {
    149         final byte ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY = 2;
    150         byte[] valueResult;
    151 
    152         assertEquals(0, mMetadata.getEntryCount());
    153         assertEquals(true, mMetadata.isEmpty());
    154 
    155         //
    156         // android.colorCorrection.mode (single enum byte)
    157         //
    158 
    159         assertEquals(null, mMetadata.readValues(ANDROID_COLOR_CORRECTION_MODE));
    160 
    161         // Write/read null values
    162         mMetadata.writeValues(ANDROID_COLOR_CORRECTION_MODE, null);
    163         assertEquals(null, mMetadata.readValues(ANDROID_COLOR_CORRECTION_MODE));
    164 
    165         // Write 0 values
    166         mMetadata.writeValues(ANDROID_COLOR_CORRECTION_MODE, new byte[] {});
    167 
    168         // Read 0 values
    169         valueResult = mMetadata.readValues(ANDROID_COLOR_CORRECTION_MODE);
    170         assertNotNull(valueResult);
    171         assertEquals(0, valueResult.length);
    172 
    173         assertEquals(1, mMetadata.getEntryCount());
    174         assertEquals(false, mMetadata.isEmpty());
    175 
    176         // Write 1 value
    177         mMetadata.writeValues(ANDROID_COLOR_CORRECTION_MODE, new byte[] {
    178             ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY
    179         });
    180 
    181         // Read 1 value
    182         valueResult = mMetadata.readValues(ANDROID_COLOR_CORRECTION_MODE);
    183         assertNotNull(valueResult);
    184         assertEquals(1, valueResult.length);
    185         assertEquals(ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY, valueResult[0]);
    186 
    187         assertEquals(1, mMetadata.getEntryCount());
    188         assertEquals(false, mMetadata.isEmpty());
    189 
    190         //
    191         // android.colorCorrection.colorCorrectionGains (float x 4 array)
    192         //
    193 
    194         final float[] colorCorrectionGains = new float[] { 1.0f, 2.0f, 3.0f, 4.0f};
    195         byte[] colorCorrectionGainsAsByteArray = new byte[colorCorrectionGains.length * 4];
    196         ByteBuffer colorCorrectionGainsByteBuffer =
    197                 ByteBuffer.wrap(colorCorrectionGainsAsByteArray).order(ByteOrder.nativeOrder());
    198         for (float f : colorCorrectionGains)
    199             colorCorrectionGainsByteBuffer.putFloat(f);
    200 
    201         // Read
    202         assertNull(mMetadata.readValues(ANDROID_COLOR_CORRECTION_GAINS));
    203         mMetadata.writeValues(ANDROID_COLOR_CORRECTION_GAINS, colorCorrectionGainsAsByteArray);
    204 
    205         // Write
    206         assertArrayEquals(colorCorrectionGainsAsByteArray,
    207                 mMetadata.readValues(ANDROID_COLOR_CORRECTION_GAINS));
    208 
    209         assertEquals(2, mMetadata.getEntryCount());
    210         assertEquals(false, mMetadata.isEmpty());
    211 
    212         // Erase
    213         mMetadata.writeValues(ANDROID_COLOR_CORRECTION_GAINS, null);
    214         assertNull(mMetadata.readValues(ANDROID_COLOR_CORRECTION_GAINS));
    215         assertEquals(1, mMetadata.getEntryCount());
    216     }
    217 
    218     private static <T> void assertArrayEquals(T expected, T actual) {
    219         assertEquals(Array.getLength(expected), Array.getLength(actual));
    220 
    221         int len = Array.getLength(expected);
    222         for (int i = 0; i < len; ++i) {
    223             assertEquals(Array.get(expected, i), Array.get(actual, i));
    224         }
    225     }
    226 
    227     private <T> void checkKeyGetAndSet(String keyStr, Class<T> type, T value) {
    228         assertFalse("Use checkKeyGetAndSetArray to compare array Keys", type.isArray());
    229 
    230         Key<T> key = new Key<T>(keyStr, type);
    231         assertNull(mMetadata.get(key));
    232         mMetadata.set(key, null);
    233         assertNull(mMetadata.get(key));
    234         mMetadata.set(key, value);
    235 
    236         T actual = mMetadata.get(key);
    237         assertEquals(value, actual);
    238     }
    239 
    240     private <T> void checkKeyGetAndSetArray(String keyStr, Class<T> type, T value) {
    241         assertTrue(type.isArray());
    242 
    243         Key<T> key = new Key<T>(keyStr, type);
    244         assertNull(mMetadata.get(key));
    245         mMetadata.set(key, value);
    246         assertArrayEquals(value, mMetadata.get(key));
    247     }
    248 
    249     @SmallTest
    250     public void testReadWritePrimitive() {
    251         // int32 (single)
    252         checkKeyGetAndSet("android.control.aeExposureCompensation", Integer.TYPE, 0xC0FFEE);
    253 
    254         // byte (single)
    255         checkKeyGetAndSet("android.flash.maxEnergy", Byte.TYPE, (byte)6);
    256 
    257         // int64 (single)
    258         checkKeyGetAndSet("android.flash.firingTime", Long.TYPE, 0xABCD12345678FFFFL);
    259 
    260         // float (single)
    261         checkKeyGetAndSet("android.lens.aperture", Float.TYPE, Float.MAX_VALUE);
    262 
    263         // double (single) -- technically double x 3, but we fake it
    264         checkKeyGetAndSet("android.jpeg.gpsCoordinates", Double.TYPE, Double.MAX_VALUE);
    265 
    266         // rational (single)
    267         checkKeyGetAndSet("android.sensor.baseGainFactor", Rational.class, new Rational(1, 2));
    268 
    269         /**
    270          * Weirder cases, that don't map 1:1 with the native types
    271          */
    272 
    273         // bool (single) -- with TYPE_BYTE
    274         checkKeyGetAndSet("android.control.aeLock", Boolean.TYPE, true);
    275 
    276         // integer (single) -- with TYPE_BYTE
    277         checkKeyGetAndSet("android.control.aePrecaptureTrigger", Integer.TYPE, 6);
    278     }
    279 
    280     @SmallTest
    281     public void testReadWritePrimitiveArray() {
    282         // int32 (n)
    283         checkKeyGetAndSetArray("android.sensor.info.sensitivityRange", int[].class,
    284                 new int[] {
    285                         0xC0FFEE, 0xDEADF00D
    286                 });
    287 
    288         // byte (n)
    289         checkKeyGetAndSetArray("android.statistics.faceScores", byte[].class, new byte[] {
    290                 1, 2, 3, 4
    291         });
    292 
    293         // int64 (n)
    294         checkKeyGetAndSetArray("android.scaler.availableProcessedMinDurations", long[].class,
    295                 new long[] {
    296                         0xABCD12345678FFFFL, 0x1234ABCD5678FFFFL, 0xFFFF12345678ABCDL
    297                 });
    298 
    299         // float (n)
    300         checkKeyGetAndSetArray("android.lens.info.availableApertures", float[].class,
    301                 new float[] {
    302                         Float.MAX_VALUE, Float.MIN_NORMAL, Float.MIN_VALUE
    303                 });
    304 
    305         // double (n) -- in particular double x 3
    306         checkKeyGetAndSetArray("android.jpeg.gpsCoordinates", double[].class,
    307                 new double[] {
    308                         Double.MAX_VALUE, Double.MIN_NORMAL, Double.MIN_VALUE
    309                 });
    310 
    311         // rational (n) -- in particular rational x 9
    312         checkKeyGetAndSetArray("android.sensor.calibrationTransform1", Rational[].class,
    313                 new Rational[] {
    314                         new Rational(1, 2), new Rational(3, 4), new Rational(5, 6),
    315                         new Rational(7, 8), new Rational(9, 10), new Rational(10, 11),
    316                         new Rational(12, 13), new Rational(14, 15), new Rational(15, 16)
    317                 });
    318 
    319         /**
    320          * Weirder cases, that don't map 1:1 with the native types
    321          */
    322 
    323         // bool (n) -- with TYPE_BYTE
    324         checkKeyGetAndSetArray("android.control.aeLock", boolean[].class, new boolean[] {
    325                 true, false, true
    326         });
    327 
    328 
    329         // integer (n) -- with TYPE_BYTE
    330         checkKeyGetAndSetArray("android.control.aeAvailableModes", int[].class, new int[] {
    331             1, 2, 3, 4
    332         });
    333     }
    334 
    335     private enum ColorCorrectionMode {
    336         TRANSFORM_MATRIX,
    337         FAST,
    338         HIGH_QUALITY
    339     }
    340 
    341     private enum AeAntibandingMode {
    342         OFF,
    343         _50HZ,
    344         _60HZ,
    345         AUTO
    346     }
    347 
    348     // TODO: special values for the enum.
    349     private enum AvailableFormat {
    350         RAW_SENSOR,
    351         YV12,
    352         YCrCb_420_SP,
    353         IMPLEMENTATION_DEFINED,
    354         YCbCr_420_888,
    355         BLOB
    356     }
    357 
    358     @SmallTest
    359     public void testReadWriteEnum() {
    360         // byte (single)
    361         checkKeyGetAndSet("android.colorCorrection.mode", ColorCorrectionMode.class,
    362                 ColorCorrectionMode.HIGH_QUALITY);
    363 
    364         // byte (single)
    365         checkKeyGetAndSet("android.control.aeAntibandingMode", AeAntibandingMode.class,
    366                 AeAntibandingMode.AUTO);
    367 
    368         // byte (n)
    369         checkKeyGetAndSetArray("android.control.aeAvailableAntibandingModes",
    370                 AeAntibandingMode[].class, new AeAntibandingMode[] {
    371                         AeAntibandingMode.OFF, AeAntibandingMode._50HZ, AeAntibandingMode._60HZ,
    372                         AeAntibandingMode.AUTO
    373                 });
    374 
    375         /**
    376          * Stranger cases that don't use byte enums
    377          */
    378         // int (n)
    379         checkKeyGetAndSetArray("android.scaler.availableFormats", AvailableFormat[].class,
    380                 new AvailableFormat[] {
    381                         AvailableFormat.RAW_SENSOR,
    382                         AvailableFormat.YV12,
    383                         AvailableFormat.IMPLEMENTATION_DEFINED,
    384                         AvailableFormat.YCbCr_420_888,
    385                         AvailableFormat.BLOB
    386                 });
    387 
    388     }
    389 
    390     @SmallTest
    391     public void testReadWriteEnumWithCustomValues() {
    392         CameraMetadataNative.registerEnumValues(AeAntibandingMode.class, new int[] {
    393             0,
    394             10,
    395             20,
    396             30
    397         });
    398 
    399         // byte (single)
    400         checkKeyGetAndSet("android.control.aeAntibandingMode", AeAntibandingMode.class,
    401                 AeAntibandingMode.AUTO);
    402 
    403         // byte (n)
    404         checkKeyGetAndSetArray("android.control.aeAvailableAntibandingModes",
    405                 AeAntibandingMode[].class, new AeAntibandingMode[] {
    406                         AeAntibandingMode.OFF, AeAntibandingMode._50HZ, AeAntibandingMode._60HZ,
    407                         AeAntibandingMode.AUTO
    408                 });
    409 
    410         Key<AeAntibandingMode[]> aeAntibandingModeKey =
    411                 new Key<AeAntibandingMode[]>("android.control.aeAvailableAntibandingModes",
    412                         AeAntibandingMode[].class);
    413         byte[] aeAntibandingModeValues = mMetadata.readValues(CameraMetadataNative
    414                 .getTag("android.control.aeAvailableAntibandingModes"));
    415         byte[] expectedValues = new byte[] { 0, 10, 20, 30 };
    416         assertArrayEquals(expectedValues, aeAntibandingModeValues);
    417 
    418 
    419         /**
    420          * Stranger cases that don't use byte enums
    421          */
    422         // int (n)
    423         CameraMetadataNative.registerEnumValues(AvailableFormat.class, new int[] {
    424             0x20,
    425             0x32315659,
    426             0x11,
    427             0x22,
    428             0x23,
    429             0x21,
    430         });
    431 
    432         checkKeyGetAndSetArray("android.scaler.availableFormats", AvailableFormat[].class,
    433                 new AvailableFormat[] {
    434                         AvailableFormat.RAW_SENSOR,
    435                         AvailableFormat.YV12,
    436                         AvailableFormat.IMPLEMENTATION_DEFINED,
    437                         AvailableFormat.YCbCr_420_888,
    438                         AvailableFormat.BLOB
    439                 });
    440 
    441         Key<AvailableFormat[]> availableFormatsKey =
    442                 new Key<AvailableFormat[]>("android.scaler.availableFormats",
    443                         AvailableFormat[].class);
    444         byte[] availableFormatValues = mMetadata.readValues(CameraMetadataNative
    445                 .getTag(availableFormatsKey.getName()));
    446 
    447         int[] expectedIntValues = new int[] {
    448                 0x20,
    449                 0x32315659,
    450                 0x22,
    451                 0x23,
    452                 0x21
    453         };
    454 
    455         ByteBuffer bf = ByteBuffer.wrap(availableFormatValues).order(ByteOrder.nativeOrder());
    456 
    457         assertEquals(expectedIntValues.length * 4, availableFormatValues.length);
    458         for (int i = 0; i < expectedIntValues.length; ++i) {
    459             assertEquals(expectedIntValues[i], bf.getInt());
    460         }
    461     }
    462 
    463     @SmallTest
    464     public void testReadWriteSize() {
    465         // int32 x n
    466         checkKeyGetAndSet("android.jpeg.thumbnailSize", Size.class, new Size(123, 456));
    467 
    468         // int32 x 2 x n
    469         checkKeyGetAndSetArray("android.scaler.availableJpegSizes", Size[].class, new Size[] {
    470             new Size(123, 456),
    471             new Size(0xDEAD, 0xF00D),
    472             new Size(0xF00, 0xB00)
    473         });
    474     }
    475 
    476     @SmallTest
    477     public void testReadWriteRectangle() {
    478         // int32 x n
    479         checkKeyGetAndSet("android.scaler.cropRegion", Rect.class, new Rect(10, 11, 1280, 1024));
    480 
    481         // int32 x 2 x n
    482         checkKeyGetAndSetArray("android.statistics.faceRectangles", Rect[].class, new Rect[] {
    483             new Rect(110, 111, 11280, 11024),
    484             new Rect(210, 111, 21280, 21024),
    485             new Rect(310, 111, 31280, 31024)
    486         });
    487     }
    488 
    489     @SmallTest
    490     public void testReadWriteString() {
    491         // (byte) string
    492         Key<String> gpsProcessingMethodKey =
    493                 new Key<String>("android.jpeg.gpsProcessingMethod", String.class);
    494 
    495         String helloWorld = new String("HelloWorld");
    496         byte[] helloWorldBytes = new byte[] {
    497                 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd', '\0' };
    498 
    499         mMetadata.set(gpsProcessingMethodKey, helloWorld);
    500 
    501         String actual = mMetadata.get(gpsProcessingMethodKey);
    502         assertEquals(helloWorld, actual);
    503 
    504         byte[] actualBytes = mMetadata.readValues(getTag(gpsProcessingMethodKey.getName()));
    505         assertArrayEquals(helloWorldBytes, actualBytes);
    506 
    507         // Does not yet test as a string[] since we don't support that in native code.
    508 
    509         // (byte) string
    510         Key<String[]> gpsProcessingMethodKeyArray =
    511                 new Key<String[]>("android.jpeg.gpsProcessingMethod", String[].class);
    512 
    513         String[] gpsStrings = new String[] { "HelloWorld", "FooBar", "Shazbot" };
    514         byte[] gpsBytes = new byte[] {
    515                 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd', '\0',
    516                 'F', 'o', 'o', 'B', 'a', 'r', '\0',
    517                 'S', 'h', 'a', 'z', 'b', 'o', 't', '\0'};
    518 
    519         mMetadata.set(gpsProcessingMethodKeyArray, gpsStrings);
    520 
    521         String[] actualArray = mMetadata.get(gpsProcessingMethodKeyArray);
    522         assertArrayEquals(gpsStrings, actualArray);
    523 
    524         byte[] actualBytes2 = mMetadata.readValues(getTag(gpsProcessingMethodKeyArray.getName()));
    525         assertArrayEquals(gpsBytes, actualBytes2);
    526     }
    527 
    528     <T> void compareGeneric(T expected, T actual) {
    529         assertEquals(expected, actual);
    530     }
    531 
    532     @SmallTest
    533     public void testReadWriteOverride() {
    534         //
    535         // android.scaler.availableFormats (int x n array)
    536         //
    537         int[] availableFormats = new int[] {
    538                 0x20,       // RAW_SENSOR
    539                 0x32315659, // YV12
    540                 0x11,       // YCrCb_420_SP
    541                 0x100,      // ImageFormat.JPEG
    542                 0x22,       // IMPLEMENTATION_DEFINED
    543                 0x23,       // YCbCr_420_888
    544         };
    545         int[] expectedIntValues = new int[] {
    546                 0x20,       // RAW_SENSOR
    547                 0x32315659, // YV12
    548                 0x11,       // YCrCb_420_SP
    549                 0x21,       // BLOB
    550                 0x22,       // IMPLEMENTATION_DEFINED
    551                 0x23,       // YCbCr_420_888
    552         };
    553         int availableFormatTag = CameraMetadataNative.getTag("android.scaler.availableFormats");
    554 
    555         // Write
    556         mMetadata.set(CameraCharacteristics.SCALER_AVAILABLE_FORMATS, availableFormats);
    557 
    558         byte[] availableFormatValues = mMetadata.readValues(availableFormatTag);
    559 
    560         ByteBuffer bf = ByteBuffer.wrap(availableFormatValues).order(ByteOrder.nativeOrder());
    561 
    562         assertEquals(expectedIntValues.length * 4, availableFormatValues.length);
    563         for (int i = 0; i < expectedIntValues.length; ++i) {
    564             assertEquals(expectedIntValues[i], bf.getInt());
    565         }
    566         // Read
    567         byte[] availableFormatsAsByteArray = new byte[expectedIntValues.length * 4];
    568         ByteBuffer availableFormatsByteBuffer =
    569                 ByteBuffer.wrap(availableFormatsAsByteArray).order(ByteOrder.nativeOrder());
    570         for (int value : expectedIntValues) {
    571             availableFormatsByteBuffer.putInt(value);
    572         }
    573         mMetadata.writeValues(availableFormatTag, availableFormatsAsByteArray);
    574 
    575         int[] resultFormats = mMetadata.get(CameraCharacteristics.SCALER_AVAILABLE_FORMATS);
    576         assertNotNull("result available formats shouldn't be null", resultFormats);
    577         assertArrayEquals(availableFormats, resultFormats);
    578 
    579         //
    580         // android.statistics.faces (Face x n array)
    581         //
    582         int[] expectedFaceIds = new int[] {1, 2, 3, 4, 5};
    583         byte[] expectedFaceScores = new byte[] {10, 20, 30, 40, 50};
    584         int numFaces = expectedFaceIds.length;
    585         Rect[] expectedRects = new Rect[numFaces];
    586         for (int i = 0; i < numFaces; i++) {
    587             expectedRects[i] = new Rect(i*4 + 1, i * 4 + 2, i * 4 + 3, i * 4 + 4);
    588         }
    589         int[] expectedFaceLM = new int[] {
    590                 1, 2, 3, 4, 5, 6,
    591                 7, 8, 9, 10, 11, 12,
    592                 13, 14, 15, 16, 17, 18,
    593                 19, 20, 21, 22, 23, 24,
    594                 25, 26, 27, 28, 29, 30,
    595         };
    596         Point[] expectedFaceLMPoints = new Point[numFaces * 3];
    597         for (int i = 0; i < numFaces; i++) {
    598             expectedFaceLMPoints[i*3] = new Point(expectedFaceLM[i*6], expectedFaceLM[i*6+1]);
    599             expectedFaceLMPoints[i*3+1] = new Point(expectedFaceLM[i*6+2], expectedFaceLM[i*6+3]);
    600             expectedFaceLMPoints[i*3+2] = new Point(expectedFaceLM[i*6+4], expectedFaceLM[i*6+5]);
    601         }
    602 
    603         /**
    604          * Read - FACE_DETECT_MODE == FULL
    605          */
    606         mMetadata.set(CaptureResult.STATISTICS_FACE_DETECT_MODE,
    607                 CaptureResult.STATISTICS_FACE_DETECT_MODE_FULL);
    608         mMetadata.set(CaptureResult.STATISTICS_FACE_IDS, expectedFaceIds);
    609         mMetadata.set(CaptureResult.STATISTICS_FACE_SCORES, expectedFaceScores);
    610         mMetadata.set(CaptureResult.STATISTICS_FACE_RECTANGLES, expectedRects);
    611         mMetadata.set(CaptureResult.STATISTICS_FACE_LANDMARKS, expectedFaceLM);
    612         Face[] resultFaces = mMetadata.get(CaptureResult.STATISTICS_FACES);
    613         assertEquals(numFaces, resultFaces.length);
    614         for (int i = 0; i < numFaces; i++) {
    615             assertEquals(expectedFaceIds[i], resultFaces[i].getId());
    616             assertEquals(expectedFaceScores[i], resultFaces[i].getScore());
    617             assertEquals(expectedRects[i], resultFaces[i].getBounds());
    618             assertEquals(expectedFaceLMPoints[i*3], resultFaces[i].getLeftEyePosition());
    619             assertEquals(expectedFaceLMPoints[i*3+1], resultFaces[i].getRightEyePosition());
    620             assertEquals(expectedFaceLMPoints[i*3+2], resultFaces[i].getMouthPosition());
    621         }
    622 
    623         /**
    624          * Read - FACE_DETECT_MODE == SIMPLE
    625          */
    626         mMetadata.set(CaptureResult.STATISTICS_FACE_DETECT_MODE,
    627                 CaptureResult.STATISTICS_FACE_DETECT_MODE_SIMPLE);
    628         mMetadata.set(CaptureResult.STATISTICS_FACE_SCORES, expectedFaceScores);
    629         mMetadata.set(CaptureResult.STATISTICS_FACE_RECTANGLES, expectedRects);
    630         Face[] resultSimpleFaces = mMetadata.get(CaptureResult.STATISTICS_FACES);
    631         assertEquals(numFaces, resultSimpleFaces.length);
    632         for (int i = 0; i < numFaces; i++) {
    633             assertEquals(Face.ID_UNSUPPORTED, resultSimpleFaces[i].getId());
    634             assertEquals(expectedFaceScores[i], resultSimpleFaces[i].getScore());
    635             assertEquals(expectedRects[i], resultSimpleFaces[i].getBounds());
    636             assertNull(resultSimpleFaces[i].getLeftEyePosition());
    637             assertNull(resultSimpleFaces[i].getRightEyePosition());
    638             assertNull(resultSimpleFaces[i].getMouthPosition());
    639         }
    640 
    641     }
    642 }
    643