Enable native HAL tests to work for camera3 devices

Change-Id: Ie11270cc8cf301ec94795b595f0517ee3bad2817
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";
 
     }