Merge "be more explicit about 64 bits values in sensor events"
diff --git a/modules/camera/Camera.cpp b/modules/camera/Camera.cpp
index 3bafdf4..137c5f6 100644
--- a/modules/camera/Camera.cpp
+++ b/modules/camera/Camera.cpp
@@ -135,6 +135,29 @@
 {
     ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
     mCallbackOps = callback_ops;
+    // Create standard settings templates
+    // 0 is invalid as template
+    mTemplates[0] = NULL;
+    // CAMERA3_TEMPLATE_PREVIEW = 1
+    mTemplates[1] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+            ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW);
+    // CAMERA3_TEMPLATE_STILL_CAPTURE = 2
+    mTemplates[2] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+            ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
+    // CAMERA3_TEMPLATE_VIDEO_RECORD = 3
+    mTemplates[3] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+            ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
+    // CAMERA3_TEMPLATE_VIDEO_SNAPSHOT = 4
+    mTemplates[4] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+            ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
+    // CAMERA3_TEMPLATE_STILL_ZERO_SHUTTER_LAG = 5
+    mTemplates[5] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+            ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG);
+    // Pre-generate metadata structures
+    for (int i = 1; i < CAMERA3_TEMPLATE_COUNT; i++) {
+        mTemplates[i]->generate();
+    }
+    // TODO: create vendor templates
     return 0;
 }
 
@@ -303,10 +326,13 @@
     // Fill new stream array with reused streams and new streams
     for (unsigned int i = 0; i < stream_config->num_streams; i++) {
         astream = stream_config->streams[i];
-        if (astream->max_buffers > 0)
+        if (astream->max_buffers > 0) {
+            ALOGV("%s:%d: Reusing stream %d", __func__, mId, i);
             newStreams[i] = reuseStream(astream);
-        else
+        } else {
+            ALOGV("%s:%d: Creating new stream %d", __func__, mId, i);
             newStreams[i] = new Stream(mId, astream);
+        }
 
         if (newStreams[i] == NULL) {
             ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
@@ -388,6 +414,8 @@
         if (streams[i]->isOutputType())
             outputs++;
     }
+    ALOGV("%s:%d: Configuring %d output streams and %d input streams",
+            __func__, mId, outputs, inputs);
     if (outputs < 1) {
         ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
         return false;
@@ -445,8 +473,12 @@
 const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
 {
     ALOGV("%s:%d: type=%d", __func__, mId, type);
-    // TODO: return statically built default request
-    return NULL;
+
+    if (type < 1 || type >= CAMERA3_TEMPLATE_COUNT) {
+        ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
+        return NULL;
+    }
+    return mTemplates[type]->generate();
 }
 
 int Camera::processCaptureRequest(camera3_capture_request_t *request)
diff --git a/modules/camera/Camera.h b/modules/camera/Camera.h
index e97dfd0..c7ee52d 100644
--- a/modules/camera/Camera.h
+++ b/modules/camera/Camera.h
@@ -91,6 +91,8 @@
         Stream **mStreams;
         // Number of streams in mStreams
         int mNumStreams;
+        // Static array of standard camera settings templates
+        Metadata *mTemplates[CAMERA3_TEMPLATE_COUNT];
         // Most recent request settings seen, memoized to be reused
         camera_metadata_t *mSettings;
 };
diff --git a/modules/camera/Metadata.cpp b/modules/camera/Metadata.cpp
index 77f5405..362a087 100644
--- a/modules/camera/Metadata.cpp
+++ b/modules/camera/Metadata.cpp
@@ -33,7 +33,9 @@
   : mHead(NULL),
     mTail(NULL),
     mEntryCount(0),
-    mDataCount(0)
+    mDataCount(0),
+    mGenerated(NULL),
+    mDirty(true)
 {
     // NULL (default) pthread mutex attributes
     pthread_mutex_init(&mMutex, NULL);
@@ -41,6 +43,37 @@
 
 Metadata::~Metadata()
 {
+    if (mGenerated != NULL)
+        free_camera_metadata(mGenerated);
+}
+
+Metadata::Metadata(uint8_t mode, uint8_t intent)
+  : mHead(NULL),
+    mTail(NULL),
+    mEntryCount(0),
+    mDataCount(0),
+    mGenerated(NULL),
+    mDirty(true)
+{
+    pthread_mutex_init(&mMutex, NULL);
+
+    if (validate(ANDROID_CONTROL_MODE, TYPE_BYTE, 1)) {
+        int res = add(ANDROID_CONTROL_MODE, 1, &mode);
+        if (res != 0) {
+            ALOGE("%s: Unable to add mode to template!", __func__);
+        }
+    } else {
+        ALOGE("%s: Invalid mode constructing template!", __func__);
+    }
+
+    if (validate(ANDROID_CONTROL_CAPTURE_INTENT, TYPE_BYTE, 1)) {
+        int res = add(ANDROID_CONTROL_CAPTURE_INTENT, 1, &intent);
+        if (res != 0) {
+            ALOGE("%s: Unable to add capture intent to template!", __func__);
+        }
+    } else {
+        ALOGE("%s: Invalid capture intent constructing template!", __func__);
+    }
 }
 
 int Metadata::addUInt8(uint32_t tag, int count, uint8_t *data)
@@ -113,33 +146,54 @@
         return -ENOMEM;
     memcpy(data, tag_data, count * type_sz);
 
+    pthread_mutex_lock(&mMutex);
     mEntryCount++;
     mDataCount += calculate_camera_metadata_entry_data_size(tag_type, count);
     push(new Entry(tag, data, count));
+    mDirty = true;
+    pthread_mutex_unlock(&mMutex);
     return 0;
 }
 
 camera_metadata_t* Metadata::generate()
 {
-    Entry *current = mHead;
+    Entry *current;
 
     pthread_mutex_lock(&mMutex);
+    // Reuse if old generated metadata still valid
+    if (!mDirty && mGenerated != NULL) {
+        ALOGV("%s: Reusing generated metadata at %p", __func__, mGenerated);
+        goto out;
+    }
+    // Destroy old metadata
+    if (mGenerated != NULL) {
+        ALOGV("%s: Freeing generated metadata at %p", __func__, mGenerated);
+        free_camera_metadata(mGenerated);
+        mGenerated = NULL;
+    }
+    // Generate new metadata structure
+    ALOGV("%s: Generating new camera metadata structure, Entries:%d Data:%d",
+            __func__, mEntryCount, mDataCount);
+    mGenerated = allocate_camera_metadata(mEntryCount, mDataCount);
     if (mGenerated == NULL) {
-        ALOGV("Generating new camera metadata structure");
-        mGenerated = allocate_camera_metadata(mEntryCount, mDataCount);
-        if (mGenerated == NULL) {
-            ALOGE("%s: Failed to allocate metadata (%d entries %d data)",
-                    __func__, mEntryCount, mDataCount);
-        }
+        ALOGE("%s: Failed to allocate metadata (%d entries %d data)",
+                __func__, mEntryCount, mDataCount);
+        goto out;
     }
     // Walk list of entries adding each one to newly allocated metadata
-    while (current != NULL) {
-        add_camera_metadata_entry(mGenerated, current->mTag, current->mData,
-                current->mCount);
-        current = current->mNext;
+    for (current = mHead; current != NULL; current = current->mNext) {
+        int res = add_camera_metadata_entry(mGenerated, current->mTag,
+                current->mData, current->mCount);
+        if (res != 0) {
+            ALOGE("%s: Failed to add camera metadata: %d", __func__, res);
+            free_camera_metadata(mGenerated);
+            mGenerated = NULL;
+            goto out;
+        }
     }
-    pthread_mutex_unlock(&mMutex);
 
+out:
+    pthread_mutex_unlock(&mMutex);
     return mGenerated;
 }
 
diff --git a/modules/camera/Metadata.h b/modules/camera/Metadata.h
index d5aac36..22d2f22 100644
--- a/modules/camera/Metadata.h
+++ b/modules/camera/Metadata.h
@@ -28,6 +28,8 @@
     public:
         Metadata();
         ~Metadata();
+        // Constructor used for request metadata templates
+        Metadata(uint8_t mode, uint8_t intent);
 
         // Parse and add an entry
         int addUInt8(uint32_t tag, int count, uint8_t *data);
@@ -67,6 +69,8 @@
         int mDataCount;
         // Save generated metadata, invalidated on update
         camera_metadata_t *mGenerated;
+        // Flag to force metadata regeneration
+        bool mDirty;
         // Lock protecting the Metadata object for modifications
         pthread_mutex_t mMutex;
 };
diff --git a/modules/camera/Stream.cpp b/modules/camera/Stream.cpp
index 0834aee..aae7adb 100644
--- a/modules/camera/Stream.cpp
+++ b/modules/camera/Stream.cpp
@@ -61,6 +61,7 @@
     pthread_mutex_lock(&mMutex);
     if (usage != mUsage) {
         mUsage = usage;
+        mStream->usage = usage;
         unregisterBuffers_L();
     }
     pthread_mutex_unlock(&mMutex);
@@ -71,6 +72,7 @@
     pthread_mutex_lock(&mMutex);
     if (max_buffers != mMaxBuffers) {
         mMaxBuffers = max_buffers;
+        mStream->max_buffers = max_buffers;
         unregisterBuffers_L();
     }
     pthread_mutex_unlock(&mMutex);
@@ -83,12 +85,14 @@
 
 bool Stream::isInputType()
 {
-    return mType & (CAMERA3_STREAM_INPUT | CAMERA3_STREAM_BIDIRECTIONAL);
+    return mType == CAMERA3_STREAM_INPUT ||
+        mType == CAMERA3_STREAM_BIDIRECTIONAL;
 }
 
 bool Stream::isOutputType()
 {
-    return mType & (CAMERA3_STREAM_OUTPUT | CAMERA3_STREAM_BIDIRECTIONAL);
+    return mType == CAMERA3_STREAM_OUTPUT ||
+        mType == CAMERA3_STREAM_BIDIRECTIONAL;
 }
 
 bool Stream::isRegistered()
diff --git a/modules/camera/Stream.h b/modules/camera/Stream.h
index 521362e..34abd95 100644
--- a/modules/camera/Stream.h
+++ b/modules/camera/Stream.h
@@ -52,7 +52,7 @@
         // The camera device id this stream belongs to
         const int mId;
         // Handle to framework's stream, used as a cookie for buffers
-        const camera3_stream_t *mStream;
+        camera3_stream_t *mStream;
         // Stream type: CAMERA3_STREAM_* (see <hardware/camera3.h>)
         const int mType;
         // Width in pixels of the buffers in this stream
diff --git a/tests/camera2/CameraBurstTests.cpp b/tests/camera2/CameraBurstTests.cpp
index e39970c..5c4b6e7 100644
--- a/tests/camera2/CameraBurstTests.cpp
+++ b/tests/camera2/CameraBurstTests.cpp
@@ -34,7 +34,7 @@
 #define CAMERA_EXPOSURE_DOUBLE  2
 #define CAMERA_EXPOSURE_DOUBLING_THRESHOLD 1.0f
 #define CAMERA_EXPOSURE_DOUBLING_COUNT 4
-#define CAMERA_EXPOSURE_FORMAT HAL_PIXEL_FORMAT_YCrCb_420_SP
+#define CAMERA_EXPOSURE_FORMAT CAMERA_STREAM_AUTO_CPU_FORMAT
 #define CAMERA_EXPOSURE_STARTING 100000 // 1/10ms, up to 51.2ms with 10 steps
 
 #if CAMERA_BURST_DEBUGGING
@@ -86,7 +86,7 @@
         TEST_EXTENSION_FORKING_TEAR_DOWN;
     }
 
-    /* this assumes the format is YUV420sp */
+    /* this assumes the format is YUV420sp or flexible YUV */
     long long TotalBrightness(const CpuConsumer::LockedBuffer& imgBuffer,
                               int *underexposed,
                               int *overexposed) const {
@@ -170,6 +170,11 @@
         uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
         ASSERT_EQ(OK, previewRequest.update(ANDROID_CONTROL_MODE,
                                             &cmOff, 1));
+
+        int requestId = 1;
+        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_ID,
+                                            &requestId, 1));
+
         if (CAMERA_BURST_DEBUGGING) {
             int frameCount = 0;
             ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_FRAME_COUNT,
@@ -255,4 +260,3 @@
 }
 }
 }
-
diff --git a/tests/camera2/CameraFrameTests.cpp b/tests/camera2/CameraFrameTests.cpp
index 2b5b546..8445098 100644
--- a/tests/camera2/CameraFrameTests.cpp
+++ b/tests/camera2/CameraFrameTests.cpp
@@ -23,7 +23,7 @@
 #include "hardware/hardware.h"
 #include "hardware/camera2.h"
 
-#include "Camera2Device.h"
+#include "CameraDeviceBase.h"
 #include "utils/StrongPointer.h"
 
 #include <gui/CpuConsumer.h>
@@ -46,7 +46,7 @@
 namespace tests {
 
 static CameraStreamParams STREAM_PARAMETERS = {
-    /*mFormat*/     HAL_PIXEL_FORMAT_YCrCb_420_SP,
+    /*mFormat*/     CAMERA_STREAM_AUTO_CPU_FORMAT,
     /*mHeapCount*/  CAMERA_HEAP_COUNT
 };
 
@@ -139,4 +139,3 @@
 }
 }
 }
-
diff --git a/tests/camera2/CameraMetadataTests.cpp b/tests/camera2/CameraMetadataTests.cpp
index 8cae619..66c4847 100644
--- a/tests/camera2/CameraMetadataTests.cpp
+++ b/tests/camera2/CameraMetadataTests.cpp
@@ -25,7 +25,7 @@
 #include "hardware/hardware.h"
 #include "hardware/camera2.h"
 
-#include "Camera2Device.h"
+#include "CameraDeviceBase.h"
 #include "utils/StrongPointer.h"
 
 #include <gui/CpuConsumer.h>
@@ -142,13 +142,25 @@
         HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
                                        HAL_PIXEL_FORMAT_BLOB)); // JPEG
 
-    EXPECT_TRUE(
-        HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                                       HAL_PIXEL_FORMAT_YCrCb_420_SP)); // NV21
+    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_0) {
+        // HAL2 can support either flexible YUV or YV12 + NV21
+        if (!HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
+                        HAL_PIXEL_FORMAT_YCbCr_420_888)) {
 
-    EXPECT_TRUE(
-        HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                                       HAL_PIXEL_FORMAT_YV12));
+            EXPECT_TRUE(
+                HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
+                        HAL_PIXEL_FORMAT_YCrCb_420_SP)); // NV21
+
+            EXPECT_TRUE(
+                HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
+                        HAL_PIXEL_FORMAT_YV12));
+        }
+    } else {
+        // HAL3 must support flexible YUV
+        EXPECT_TRUE(HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
+                        HAL_PIXEL_FORMAT_YCbCr_420_888));
+    }
+
 }
 
 TEST_F(CameraMetadataTest, SaneResolutions) {
@@ -156,7 +168,7 @@
 
     // Iff there are listed raw resolutions, the format should be available
     int rawResolutionsCount =
-            GetEntryCountFromStaticTag(HAL_PIXEL_FORMAT_RAW_SENSOR);
+            GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_RAW_SIZES);
     EXPECT_EQ(rawResolutionsCount > 0,
         HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
                                         HAL_PIXEL_FORMAT_RAW_SENSOR));
diff --git a/tests/camera2/CameraModuleFixture.h b/tests/camera2/CameraModuleFixture.h
index 01e1ad0..ef4a9a5 100644
--- a/tests/camera2/CameraModuleFixture.h
+++ b/tests/camera2/CameraModuleFixture.h
@@ -23,6 +23,7 @@
 #include "hardware/camera2.h"
 
 #include "Camera2Device.h"
+#include "Camera3Device.h"
 #include "camera2_utils.h"
 #include "TestExtensions.h"
 
@@ -82,6 +83,42 @@
         }
     }
 
+    void CreateCamera(int cameraID, /*out*/ sp<CameraDeviceBase> *device) {
+        struct camera_info info;
+        ASSERT_EQ(OK, mModule->get_camera_info(cameraID, &info));
+
+        ASSERT_GE((int)info.device_version, CAMERA_DEVICE_API_VERSION_2_0) <<
+                "Device version too old for camera " << cameraID << ". Version: " <<
+                info.device_version;
+        switch(info.device_version) {
+            case CAMERA_DEVICE_API_VERSION_2_0:
+            case CAMERA_DEVICE_API_VERSION_2_1:
+                *device = new Camera2Device(cameraID);
+                break;
+            case CAMERA_DEVICE_API_VERSION_3_0:
+                *device = new Camera3Device(cameraID);
+                break;
+            default:
+                device->clear();
+                FAIL() << "Device version unknown for camera " << cameraID << ". Version: " <<
+                       info.device_version;
+        }
+
+    }
+
+    int getDeviceVersion() {
+        return getDeviceVersion(mCameraID);
+    }
+
+    int getDeviceVersion(int cameraId, status_t* status = NULL) {
+        camera_info info;
+        status_t res;
+        res = mModule->get_camera_info(cameraId, &info);
+        if (status != NULL) *status = res;
+
+        return info.device_version;
+    }
+
 private:
 
     void SetUpMixin() {
@@ -90,14 +127,12 @@
             EXPECT_LE(0, mCameraID);
             EXPECT_LT(mCameraID, mNumberOfCameras);
 
-            /* HALBUG (Exynos5); crashes if trying to initialize
-               before calling get_camera_info */
-            if (InfoQuirk) {
-                struct camera_info info;
-                ASSERT_EQ(OK, mModule->get_camera_info(mCameraID, &info));
-            }
+            /* HALBUG (Exynos5); crashes if we skip calling get_camera_info
+               before initializing. Need info anyway now. */
 
-            mDevice = new Camera2Device(mCameraID);
+            CreateCamera(mCameraID, &mDevice);
+
+            ASSERT_TRUE(mDevice != NULL) << "Failed to open device " << mCameraID;
             ASSERT_EQ(OK, mDevice->initialize(mModule))
                 << "Failed to initialize device " << mCameraID;
         }
@@ -110,7 +145,7 @@
 protected:
     int mNumberOfCameras;
     camera_module_t *mModule;
-    sp<Camera2Device> mDevice;
+    sp<CameraDeviceBase> mDevice;
 
 private:
     int mCameraID;
diff --git a/tests/camera2/CameraModuleTests.cpp b/tests/camera2/CameraModuleTests.cpp
index fc6fd36..44d3e3b 100644
--- a/tests/camera2/CameraModuleTests.cpp
+++ b/tests/camera2/CameraModuleTests.cpp
@@ -23,7 +23,7 @@
 #include "hardware/hardware.h"
 #include "hardware/camera2.h"
 
-#include "Camera2Device.h"
+#include "CameraDeviceBase.h"
 #include "utils/StrongPointer.h"
 #include "CameraModuleFixture.h"
 
@@ -54,13 +54,6 @@
         return stat;
     }
 
-    int getDeviceVersion(int cameraId, status_t* status) {
-        camera_info info;
-        *status = mModule->get_camera_info(cameraId, &info);
-
-        return info.device_version;
-    }
-
     bool isDeviceVersionHal2(int cameraId, status_t* status) {
         return getDeviceVersion(cameraId, status)
                >= CAMERA_DEVICE_API_VERSION_2_0;
@@ -72,8 +65,7 @@
     TEST_EXTENSION_FORKING_INIT;
 
     for (int i = 0; i < mNumberOfCameras; ++i) {
-        mDevice = new Camera2Device(i);
-
+        CreateCamera(i, &mDevice);
         ASSERT_EQ(OK, initializeDevice(i))
             << "Failed to initialize device " << i;
         mDevice.clear();
@@ -88,6 +80,8 @@
     int idx[] = { -1, mNumberOfCameras, mNumberOfCameras + 1 };
 
     for (unsigned i = 0; i < sizeof(idx)/sizeof(idx[0]); ++i) {
+        // Since the initialization should fail at device open(), it doesn't
+        // matter which version of CameraNDevice is used here
         mDevice = new Camera2Device(idx[i]);
         status_t deviceInitializeCode = initializeDevice(idx[i]);
         EXPECT_NE(OK, deviceInitializeCode);
@@ -136,4 +130,3 @@
 }
 }
 }
-
diff --git a/tests/camera2/CameraStreamFixture.h b/tests/camera2/CameraStreamFixture.h
index c5db7ef..a4dc4a8 100644
--- a/tests/camera2/CameraStreamFixture.h
+++ b/tests/camera2/CameraStreamFixture.h
@@ -24,6 +24,7 @@
 #include <gui/Surface.h>
 #include <utils/Condition.h>
 #include <utils/Mutex.h>
+#include <system/camera_metadata.h>
 
 #include "CameraModuleFixture.h"
 #include "TestExtensions.h"
@@ -32,14 +33,33 @@
 namespace camera2 {
 namespace tests {
 
+// Format specifier for picking the best format for CPU reading the given device
+// version
+#define CAMERA_STREAM_AUTO_CPU_FORMAT (-1)
+
+struct CameraStreamParams;
+
+void PrintTo(const CameraStreamParams& p, ::std::ostream* os);
+
 struct CameraStreamParams {
     int mFormat;
     int mHeapCount;
+
 };
 
+inline ::std::ostream& operator<<(::std::ostream& os, const CameraStreamParams &p) {
+    PrintTo(p, &os);
+    return os;
+}
+
 inline void PrintTo(const CameraStreamParams& p, ::std::ostream* os) {
+    char fmt[100];
+    camera_metadata_enum_snprint(
+        ANDROID_SCALER_AVAILABLE_FORMATS, p.mFormat, fmt, sizeof(fmt));
+
     *os <<  "{ ";
     *os <<  "Format: 0x"  << std::hex << p.mFormat    << ", ";
+    *os <<  "Format name: " << fmt << ", ";
     *os <<  "HeapCount: " <<             p.mHeapCount;
     *os << " }";
 }
@@ -71,7 +91,7 @@
         CameraModuleFixture::SetUp();
 
         CameraStreamParams p = mParam;
-        sp<Camera2Device> device = mDevice;
+        sp<CameraDeviceBase> device = mDevice;
 
         /* use an arbitrary w,h */
         {
@@ -136,7 +156,7 @@
     };
 
     void CreateStream() {
-        sp<Camera2Device> device = mDevice;
+        sp<CameraDeviceBase> device = mDevice;
         CameraStreamParams p = mParam;
 
         mCpuConsumer = new CpuConsumer(p.mHeapCount);
@@ -145,9 +165,11 @@
         mNativeWindow = new Surface(
             mCpuConsumer->getProducerInterface());
 
+        int format = MapAutoFormat(p.mFormat);
+
         ASSERT_EQ(OK,
             device->createStream(mNativeWindow,
-                mWidth, mHeight, p.mFormat, /*size (for jpegs)*/0,
+                mWidth, mHeight, format, /*size (for jpegs)*/0,
                 &mStreamId));
 
         ASSERT_NE(-1, mStreamId);
@@ -161,6 +183,17 @@
         ASSERT_EQ(OK, mDevice->deleteStream(mStreamId));
     }
 
+    int MapAutoFormat(int format) {
+        if (format == CAMERA_STREAM_AUTO_CPU_FORMAT) {
+            if (getDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_0) {
+                format = HAL_PIXEL_FORMAT_YCbCr_420_888;
+            } else {
+                format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
+            }
+        }
+        return format;
+    }
+
     int mWidth;
     int mHeight;
 
diff --git a/tests/camera2/CameraStreamTests.cpp b/tests/camera2/CameraStreamTests.cpp
index 5423a30..164e0e5 100644
--- a/tests/camera2/CameraStreamTests.cpp
+++ b/tests/camera2/CameraStreamTests.cpp
@@ -93,8 +93,8 @@
             std::cerr << "Skipping test "
                       << test_info->test_case_name() << "."
                       << test_info->name()
-                      << " because the format was not available: 0x"
-                      << std::hex << GetParam().mFormat << std::endl;
+                      << " because the format was not available: "
+                      << GetParam() << std::endl;
             return;
         }
     }
@@ -186,4 +186,3 @@
 }
 }
 }
-
diff --git a/tests/camera2/camera2.cpp b/tests/camera2/camera2.cpp
index 0f75070..92ef221 100644
--- a/tests/camera2/camera2.cpp
+++ b/tests/camera2/camera2.cpp
@@ -92,7 +92,8 @@
                 std::cout << "    Version: 0x" << std::hex <<
                         info.device_version  << std::endl;
             }
-            if (info.device_version >= CAMERA_DEVICE_API_VERSION_2_0) {
+            if (info.device_version >= CAMERA_DEVICE_API_VERSION_2_0 &&
+                    info.device_version < CAMERA_DEVICE_API_VERSION_3_0) {
                 sCameraSupportsHal2[i] = true;
                 ASSERT_TRUE(NULL != info.static_camera_characteristics);
                 IF_ALOGV() {
@@ -181,12 +182,15 @@
         return OK;
     }
 
-    static status_t closeCameraDevice(camera2_device_t *cam_dev) {
+    static status_t closeCameraDevice(camera2_device_t **cam_dev) {
         int res;
+        if (*cam_dev == NULL ) return OK;
+
         ALOGV("Closing camera %p", cam_dev);
 
-        hw_device_t *dev = reinterpret_cast<hw_device_t *>(cam_dev);
+        hw_device_t *dev = reinterpret_cast<hw_device_t *>(*cam_dev);
         res = dev->close(dev);
+        *cam_dev = NULL;
         return res;
     }
 
@@ -195,7 +199,7 @@
         status_t res;
 
         if (mDevice != NULL) {
-            closeCameraDevice(mDevice);
+            closeCameraDevice(&mDevice);
         }
         mDevice = openCameraDevice(id);
         ASSERT_TRUE(NULL != mDevice) << "Failed to open camera device";
@@ -324,7 +328,7 @@
             delete mStreams[i];
         }
         if (mDevice != NULL) {
-            closeCameraDevice(mDevice);
+            closeCameraDevice(&mDevice);
         }
 
         TearDownModule();
@@ -366,7 +370,7 @@
         camera2_device_t *d = openCameraDevice(id);
         ASSERT_TRUE(NULL != d) << "Failed to open camera device";
 
-        res = closeCameraDevice(d);
+        res = closeCameraDevice(&d);
         ASSERT_EQ(NO_ERROR, res) << "Failed to close camera device";
     }
 }
@@ -499,7 +503,7 @@
         ASSERT_EQ(OK, waitUntilDrained());
         ASSERT_NO_FATAL_FAILURE(disconnectStream(streamId));
 
-        res = closeCameraDevice(mDevice);
+        res = closeCameraDevice(&mDevice);
         ASSERT_EQ(NO_ERROR, res) << "Failed to close camera device";
 
     }
@@ -802,7 +806,7 @@
         ASSERT_EQ(OK, waitUntilDrained());
         ASSERT_NO_FATAL_FAILURE(disconnectStream(streamId));
 
-        res = closeCameraDevice(mDevice);
+        res = closeCameraDevice(&mDevice);
         ASSERT_EQ(NO_ERROR, res) << "Failed to close camera device";
 
     }