Camera3: Add support for test pattern

Bug: 12958370
Bug: 12957744
Bug: 13077164
Change-Id: I6edf9bcc50ff864709cae82a0b35df24574f01e1
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index 368c08d..9155ae5 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -153,6 +153,14 @@
                                              512, 288,
                                              512, 384};
 
+const QCamera3HardwareInterface::QCameraMap QCamera3HardwareInterface::TEST_PATTERN_MAP[] = {
+    { ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,          CAM_TEST_PATTERN_OFF   },
+    { ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR,  CAM_TEST_PATTERN_SOLID_COLOR },
+    { ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS,   CAM_TEST_PATTERN_COLOR_BARS },
+    { ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY, CAM_TEST_PATTERN_COLOR_BARS_FADE_TO_GRAY },
+    { ANDROID_SENSOR_TEST_PATTERN_MODE_PN9,          CAM_TEST_PATTERN_PN9 },
+};
+
 camera3_device_ops_t QCamera3HardwareInterface::mCameraOps = {
     initialize:                         QCamera3HardwareInterface::initialize,
     configure_streams:                  QCamera3HardwareInterface::configure_streams,
@@ -2189,7 +2197,7 @@
           case CAM_INTF_META_STATS_FACEDETECT_MODE: {
              uint8_t  *faceDetectMode =
                 (uint8_t *)POINTER_OF(CAM_INTF_META_STATS_FACEDETECT_MODE, metadata);
-             uint8_t fwk_faceDetectMode = lookupFwkName(FACEDETECT_MODES_MAP,
+             uint8_t fwk_faceDetectMode = (uint8_t)lookupFwkName(FACEDETECT_MODES_MAP,
                                                         sizeof(FACEDETECT_MODES_MAP)/sizeof(FACEDETECT_MODES_MAP[0]),
                                                         *faceDetectMode);
              camMetadata.update(ANDROID_STATISTICS_FACE_DETECT_MODE, &fwk_faceDetectMode, 1);
@@ -2297,12 +2305,22 @@
           case CAM_INTF_PARM_EFFECT: {
              uint8_t *effectMode = (uint8_t*)
                   POINTER_OF(CAM_INTF_PARM_EFFECT, metadata);
-             uint8_t fwk_effectMode = lookupFwkName(EFFECT_MODES_MAP,
+             uint8_t fwk_effectMode = (uint8_t)lookupFwkName(EFFECT_MODES_MAP,
                                                     sizeof(EFFECT_MODES_MAP),
                                                     *effectMode);
              camMetadata.update(ANDROID_CONTROL_EFFECT_MODE, &fwk_effectMode, 1);
              break;
           }
+          case CAM_INTF_META_TEST_PATTERN_DATA: {
+             cam_test_pattern_data_t *testPatternData = (cam_test_pattern_data_t *)
+                 POINTER_OF(CAM_INTF_META_TEST_PATTERN_DATA, metadata);
+             int32_t fwk_testPatternMode = lookupFwkName(TEST_PATTERN_MAP,
+                     sizeof(TEST_PATTERN_MAP)/sizeof(TEST_PATTERN_MAP[0]),
+                     testPatternData->mode);
+             camMetadata.update(ANDROID_SENSOR_TEST_PATTERN_MODE,
+                     &fwk_testPatternMode, 1);
+             break;
+          }
           default:
              ALOGV("%s: This is not a valid metadata type to report to fwk, %d",
                    __func__, curr_entry);
@@ -2371,7 +2389,7 @@
         case CAM_INTF_PARM_FOCUS_MODE:{
             uint8_t  *focusMode =
                 (uint8_t *)POINTER_OF(CAM_INTF_PARM_FOCUS_MODE, metadata);
-            uint8_t fwkAfMode = lookupFwkName(FOCUS_MODES_MAP,
+            uint8_t fwkAfMode = (uint8_t)lookupFwkName(FOCUS_MODES_MAP,
                sizeof(FOCUS_MODES_MAP)/sizeof(FOCUS_MODES_MAP[0]), *focusMode);
             camMetadata.update(ANDROID_CONTROL_AF_MODE, &fwkAfMode, 1);
             ALOGV("%s: urgent Metadata : ANDROID_CONTROL_AF_MODE", __func__);
@@ -2405,7 +2423,7 @@
            uint8_t  *whiteBalance =
                 (uint8_t *)POINTER_OF(CAM_INTF_PARM_WHITE_BALANCE, metadata);
              uint8_t fwkWhiteBalanceMode =
-                    lookupFwkName(WHITE_BALANCE_MODES_MAP,
+                    (uint8_t)lookupFwkName(WHITE_BALANCE_MODES_MAP,
                     sizeof(WHITE_BALANCE_MODES_MAP)/
                     sizeof(WHITE_BALANCE_MODES_MAP[0]), *whiteBalance);
              camMetadata.update(ANDROID_CONTROL_AWB_MODE,
@@ -2962,9 +2980,9 @@
                       &max_jpeg_size, 1);
 
     uint8_t avail_effects[CAM_EFFECT_MODE_MAX];
-    int32_t size = 0;
+    size_t size = 0;
     for (int i = 0; i < gCamCapability[cameraId]->supported_effects_cnt; i++) {
-        int val = lookupFwkName(EFFECT_MODES_MAP,
+        int32_t val = lookupFwkName(EFFECT_MODES_MAP,
                                    sizeof(EFFECT_MODES_MAP)/sizeof(EFFECT_MODES_MAP[0]),
                                    gCamCapability[cameraId]->supported_effects[i]);
         if (val != NAME_NOT_FOUND) {
@@ -2980,7 +2998,7 @@
     uint8_t supported_indexes[CAM_SCENE_MODE_MAX];
     int32_t supported_scene_modes_cnt = 0;
     for (int i = 0; i < gCamCapability[cameraId]->supported_scene_modes_cnt; i++) {
-        int val = lookupFwkName(SCENE_MODES_MAP,
+        int32_t val = lookupFwkName(SCENE_MODES_MAP,
                                 sizeof(SCENE_MODES_MAP)/sizeof(SCENE_MODES_MAP[0]),
                                 gCamCapability[cameraId]->supported_scene_modes[i]);
         if (val != NAME_NOT_FOUND) {
@@ -3007,7 +3025,7 @@
     uint8_t avail_antibanding_modes[CAM_ANTIBANDING_MODE_MAX];
     size = 0;
     for (int i = 0; i < gCamCapability[cameraId]->supported_antibandings_cnt; i++) {
-        int val = lookupFwkName(ANTIBANDING_MODES_MAP,
+        int32_t val = lookupFwkName(ANTIBANDING_MODES_MAP,
                                  sizeof(ANTIBANDING_MODES_MAP)/sizeof(ANTIBANDING_MODES_MAP[0]),
                                  gCamCapability[cameraId]->supported_antibandings[i]);
         if (val != NAME_NOT_FOUND) {
@@ -3023,7 +3041,7 @@
     uint8_t avail_af_modes[CAM_FOCUS_MODE_MAX];
     size = 0;
     for (int i = 0; i < gCamCapability[cameraId]->supported_focus_modes_cnt; i++) {
-        int val = lookupFwkName(FOCUS_MODES_MAP,
+        int32_t val = lookupFwkName(FOCUS_MODES_MAP,
                                 sizeof(FOCUS_MODES_MAP)/sizeof(FOCUS_MODES_MAP[0]),
                                 gCamCapability[cameraId]->supported_focus_modes[i]);
         if (val != NAME_NOT_FOUND) {
@@ -3038,7 +3056,7 @@
     uint8_t avail_awb_modes[CAM_WB_MODE_MAX];
     size = 0;
     for (int i = 0; i < gCamCapability[cameraId]->supported_white_balances_cnt; i++) {
-        int8_t val = lookupFwkName(WHITE_BALANCE_MODES_MAP,
+        int32_t val = lookupFwkName(WHITE_BALANCE_MODES_MAP,
                                     sizeof(WHITE_BALANCE_MODES_MAP)/sizeof(WHITE_BALANCE_MODES_MAP[0]),
                                     gCamCapability[cameraId]->supported_white_balances[i]);
         if (val != NAME_NOT_FOUND) {
@@ -3110,14 +3128,32 @@
     staticInfo.update(ANDROID_LED_AVAILABLE_LEDS,
                       &avail_leds, 0);
 
-    int8_t val = lookupFwkName(FOCUS_CALIBRATION_MAP,
+    uint8_t focus_dist_calibrated;
+    int32_t val = lookupFwkName(FOCUS_CALIBRATION_MAP,
             sizeof(FOCUS_CALIBRATION_MAP)/sizeof(FOCUS_CALIBRATION_MAP[0]),
             gCamCapability[cameraId]->focus_dist_calibrated);
     if (val != NAME_NOT_FOUND) {
+        focus_dist_calibrated = (uint8_t)val;
         staticInfo.update(ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
-                     &gCamCapability[cameraId]->focus_dist_calibrated, 1);
+                     &focus_dist_calibrated, 1);
     }
 
+    int32_t avail_testpattern_modes[MAX_TEST_PATTERN_CNT];
+    size = 0;
+    for (int i = 0; i < gCamCapability[cameraId]->supported_test_pattern_modes_cnt;
+            i++) {
+        int32_t val = lookupFwkName(TEST_PATTERN_MAP,
+                                    sizeof(TEST_PATTERN_MAP)/sizeof(TEST_PATTERN_MAP[0]),
+                                    gCamCapability[cameraId]->supported_test_pattern_modes[i]);
+        if (val != NAME_NOT_FOUND) {
+            avail_testpattern_modes[size] = val;
+            size++;
+        }
+    }
+    staticInfo.update(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
+                      avail_testpattern_modes,
+                      size);
+
     uint8_t max_pipeline_depth = kMaxInFlight;
     staticInfo.update(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
                       &max_pipeline_depth,
@@ -3541,7 +3577,7 @@
  *              fwk_name  -- success
  *              none-zero failure code
  *==========================================================================*/
-int8_t QCamera3HardwareInterface::lookupFwkName(const QCameraMap arr[],
+int32_t QCamera3HardwareInterface::lookupFwkName(const QCameraMap arr[],
                                              int len, int hal_name)
 {
 
@@ -3573,7 +3609,7 @@
  *              none-zero failure code
  *==========================================================================*/
 int8_t QCamera3HardwareInterface::lookupHalName(const QCameraMap arr[],
-                                             int len, int fwk_name)
+                                             int len, unsigned int fwk_name)
 {
     for (int i = 0; i < len; i++) {
        if (arr[i].fwk_name == fwk_name)
@@ -4482,6 +4518,41 @@
                     sizeof(roi), &roi);
         }
     }
+
+    if (frame_settings.exists(ANDROID_SENSOR_TEST_PATTERN_MODE)) {
+        cam_test_pattern_data_t testPatternData;
+        uint32_t fwk_testPatternMode = frame_settings.find(ANDROID_SENSOR_TEST_PATTERN_MODE).data.i32[0];
+        uint8_t testPatternMode = lookupHalName(TEST_PATTERN_MAP,
+               sizeof(TEST_PATTERN_MAP), fwk_testPatternMode);
+
+        memset(&testPatternData, 0, sizeof(testPatternData));
+        testPatternData.mode = (cam_test_pattern_mode_t)testPatternMode;
+        if (testPatternMode == CAM_TEST_PATTERN_SOLID_COLOR &&
+                frame_settings.exists(ANDROID_SENSOR_TEST_PATTERN_DATA)) {
+            int32_t* fwk_testPatternData = frame_settings.find(
+                    ANDROID_SENSOR_TEST_PATTERN_DATA).data.i32;
+            testPatternData.r = fwk_testPatternData[0];
+            testPatternData.b = fwk_testPatternData[3];
+            switch (gCamCapability[mCameraId]->color_arrangement) {
+            case CAM_FILTER_ARRANGEMENT_RGGB:
+            case CAM_FILTER_ARRANGEMENT_GRBG:
+                testPatternData.gr = fwk_testPatternData[1];
+                testPatternData.gb = fwk_testPatternData[2];
+                break;
+            case CAM_FILTER_ARRANGEMENT_GBRG:
+            case CAM_FILTER_ARRANGEMENT_BGGR:
+                testPatternData.gr = fwk_testPatternData[2];
+                testPatternData.gb = fwk_testPatternData[1];
+                break;
+            default:
+                ALOGE("%s: color arrangement %d is not supported", __func__,
+                    gCamCapability[mCameraId]->color_arrangement);
+                break;
+            }
+        }
+        rc = AddSetParmEntryToBatch(mParameters, CAM_INTF_META_TEST_PATTERN_DATA,
+            sizeof(testPatternData), &testPatternData);
+    }
     return rc;
 }
 
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.h b/camera/QCamera2/HAL3/QCamera3HWI.h
index b1bece1..2b94121 100755
--- a/camera/QCamera2/HAL3/QCamera3HWI.h
+++ b/camera/QCamera2/HAL3/QCamera3HWI.h
@@ -145,7 +145,7 @@
                 camera3_stream_buffer_t *buffer, uint32_t frame_number);
 
     typedef struct {
-        uint8_t fwk_name;
+        uint32_t fwk_name;
         uint8_t hal_name;
     } QCameraMap;
 
@@ -158,8 +158,8 @@
                                uint32_t paramLength,
                                void *paramValue);
     static int8_t lookupHalName(const QCameraMap arr[],
-                      int len, int fwk_name);
-    static int8_t lookupFwkName(const QCameraMap arr[],
+                      int len, unsigned int fwk_name);
+    static int32_t lookupFwkName(const QCameraMap arr[],
                       int len, int hal_name);
 
     int validateCaptureRequest(camera3_capture_request_t *request);
@@ -278,6 +278,7 @@
     static const QCameraMap FLASH_MODES_MAP[];
     static const QCameraMap FACEDETECT_MODES_MAP[];
     static const QCameraMap FOCUS_CALIBRATION_MAP[];
+    static const QCameraMap TEST_PATTERN_MAP[];
 
     static pthread_mutex_t mCameraSessionLock;
     static unsigned int mCameraSessionActive;
diff --git a/camera/QCamera2/stack/common/cam_intf.h b/camera/QCamera2/stack/common/cam_intf.h
index 7ee6097..c6962c4 100755
--- a/camera/QCamera2/stack/common/cam_intf.h
+++ b/camera/QCamera2/stack/common/cam_intf.h
@@ -294,6 +294,9 @@
     cam_rational_type_t base_gain_factor;    /* sensor base gain factor */
 
     uint8_t focus_dist_calibrated;
+
+    uint8_t supported_test_pattern_modes_cnt;
+    cam_test_pattern_mode_t supported_test_pattern_modes[MAX_TEST_PATTERN_CNT];
 } cam_capability_t;
 
 typedef enum {
@@ -480,6 +483,7 @@
     INCLUDE(CAM_INTF_META_TONEMAP_MODE,             uint8_t,                     1);
     INCLUDE(CAM_INTF_META_FLASH_MODE,               uint8_t,                     1);
     INCLUDE(CAM_INTF_META_STREAM_ID,                cam_stream_ID_t,             1);
+    INCLUDE(CAM_INTF_META_TEST_PATTERN_DATA,        cam_test_pattern_data_t,     1);
 } parm_type_t;
 
 
@@ -548,6 +552,7 @@
     INCLUDE(CAM_INTF_META_STATS_SHARPNESS_MAP,          cam_sharpness_map_t,         3);
     INCLUDE(CAM_INTF_META_LENS_SHADING_MAP,             cam_lens_shading_map_t,      1);
     INCLUDE(CAM_INTF_META_AEC_INFO,                     cam_3a_params_t,             1);
+    INCLUDE(CAM_INTF_META_TEST_PATTERN_DATA,            cam_test_pattern_data_t,     1);
     INCLUDE(CAM_INTF_META_PRIVATE_DATA,                 char,                        MAX_METADATA_PAYLOAD_SIZE);
 } metadata_type_t;
 
diff --git a/camera/QCamera2/stack/common/cam_types.h b/camera/QCamera2/stack/common/cam_types.h
index 5957a16..8636f65 100644
--- a/camera/QCamera2/stack/common/cam_types.h
+++ b/camera/QCamera2/stack/common/cam_types.h
@@ -49,6 +49,7 @@
 #define MAX_ROI 5
 #define MAX_STREAM_NUM_IN_BUNDLE 4
 #define MAX_NUM_STREAMS          8
+#define MAX_TEST_PATTERN_CNT     8
 
 typedef enum {
     CAM_HAL_V1 = 1,
@@ -1046,6 +1047,7 @@
     CAM_INTF_META_PRIVATE_DATA,
     /* Indicates streams ID of all the requested buffers */
     CAM_INTF_META_STREAM_ID,
+    CAM_INTF_META_TEST_PATTERN_DATA,
     /*AEC info for Exif*/
     CAM_INTF_META_AEC_INFO,
     CAM_INTF_PARM_MAX
@@ -1318,4 +1320,20 @@
     CAM_FOCUS_CALIBRATED
 } cam_focus_calibration_t;
 
+typedef enum {
+    CAM_TEST_PATTERN_OFF,
+    CAM_TEST_PATTERN_SOLID_COLOR,
+    CAM_TEST_PATTERN_COLOR_BARS,
+    CAM_TEST_PATTERN_COLOR_BARS_FADE_TO_GRAY,
+    CAM_TEST_PATTERN_PN9,
+} cam_test_pattern_mode_t;
+
+typedef struct {
+    cam_test_pattern_mode_t mode;
+    int32_t r;
+    int32_t gr;
+    int32_t gb;
+    int32_t b;
+} cam_test_pattern_data_t;
+
 #endif /* __QCAMERA_TYPES_H__ */