QCamera2: Validate dimensions set from framework

Currently there is no logic in the frameworks to validate against
rogue values set for stream dimensions, adding logic in HAL to
check if width, height is one of those reported in static metadata

Bug: 16030677
Change-Id: I38f5fe02674893b1d1fad616e35b99e2cc6f1a1a
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index 8f95668..2564998 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -484,6 +484,111 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : validateStreamDimensions
+ *
+ * DESCRIPTION: Check if the configuration requested are those advertised
+ *
+ * PARAMETERS :
+ *   @stream_list : streams to be configured
+ *
+ * RETURN     :
+ *
+ *==========================================================================*/
+int QCamera3HardwareInterface::validateStreamDimensions(
+        camera3_stream_configuration_t *streamList)
+{
+    int rc = NO_ERROR;
+    int32_t available_processed_sizes[MAX_SIZES_CNT * 2];
+
+    /*
+    * Loop through all streams requested in configuration
+    * Check if unsupported sizes have been requested on any of them
+    */
+    for (size_t j = 0; j < streamList->num_streams; j++){
+        bool sizeFound = false;
+        camera3_stream_t *newStream = streamList->streams[j];
+
+        /*
+        * Sizes are different for each type of stream format check against
+        * appropriate table.
+        */
+        switch (newStream->format) {
+            case ANDROID_SCALER_AVAILABLE_FORMATS_RAW16:
+            case ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE:
+            case HAL_PIXEL_FORMAT_RAW10:
+                for (int i = 0;
+                      i < gCamCapability[mCameraId]->supported_raw_dim_cnt; i++){
+                    if (gCamCapability[mCameraId]->raw_dim[i].width
+                            == (int32_t) newStream->width
+                        && gCamCapability[mCameraId]->raw_dim[i].height
+                            == (int32_t) newStream->height) {
+                        sizeFound = true;
+                    }
+                }
+                break;
+            case HAL_PIXEL_FORMAT_BLOB:
+                for (int i = 0;
+                  i < gCamCapability[mCameraId]->picture_sizes_tbl_cnt;i++){
+                    if ((int32_t)(newStream->width) ==
+                        gCamCapability[mCameraId]
+                            ->picture_sizes_tbl[i].width
+                    && (int32_t)(newStream->height) ==
+                        gCamCapability[mCameraId]
+                            ->picture_sizes_tbl[i].height){
+                    sizeFound = true;
+                    break;
+                    }
+                }
+                break;
+
+            case HAL_PIXEL_FORMAT_YCbCr_420_888:
+            case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+            default:
+                /* ZSL stream will be full active array size validate that*/
+                if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL) {
+                    if ((int32_t)(newStream->width) ==
+                        gCamCapability[mCameraId]->active_array_size.width
+                        && (int32_t)(newStream->height)  ==
+                        gCamCapability[mCameraId]->active_array_size.height) {
+                        sizeFound = true;
+                    }
+                    /* We could potentially break here to enforce ZSL stream
+                     * set from frameworks always has full active array size
+                     * but it is not clear from spec if framework will always
+                     * follow that, also we have logic to override to full array
+                     * size, so keeping this logic lenient at the moment.
+                     */
+                }
+
+                /* Non ZSL stream still need to conform to advertised sizes*/
+                for (int i = 0;
+                  i < gCamCapability[mCameraId]->picture_sizes_tbl_cnt;i++){
+                    if ((int32_t)(newStream->width) ==
+                        gCamCapability[mCameraId]
+                            ->picture_sizes_tbl[i].width
+                    && (int32_t)(newStream->height) ==
+                        gCamCapability[mCameraId]
+                            ->picture_sizes_tbl[i].height){
+                    sizeFound = true;
+                    break;
+                    }
+                }
+                break;
+        } /* End of switch(newStream->format) */
+
+        /* We error out even if a single stream has unsupported size set */
+        if (!sizeFound) {
+            ALOGE("%s: Error: Unsupported size of  %d x %d requested for stream"
+                  "type:%d", __func__, newStream->width, newStream->height,
+                  newStream->format);
+            rc = -EINVAL;
+            break;
+        }
+    } /* End of for each stream */
+    return rc;
+}
+
+/*===========================================================================
  * FUNCTION   : configureStreams
  *
  * DESCRIPTION: Reset HAL camera device processing pipeline and set up new input
@@ -516,6 +621,12 @@
         return BAD_VALUE;
     }
 
+    rc = validateStreamDimensions(streamList);
+    if (rc != NO_ERROR) {
+        ALOGE("%s: Invalid stream configuration requested!", __func__);
+        return rc;
+    }
+
     /* first invalidate all the steams in the mStreamList
      * if they appear again, they will be validated */
     for (List<stream_info_t*>::iterator it = mStreamInfo.begin();
@@ -3357,7 +3468,7 @@
                       scalar_formats,
                       scalar_formats_count);
 
-    int32_t available_processed_sizes[CAM_FORMAT_MAX * 2];
+    int32_t available_processed_sizes[MAX_SIZES_CNT * 2];
     makeTable(gCamCapability[cameraId]->picture_sizes_tbl,
               gCamCapability[cameraId]->picture_sizes_tbl_cnt,
               available_processed_sizes);
@@ -3365,7 +3476,7 @@
                 available_processed_sizes,
                 (gCamCapability[cameraId]->picture_sizes_tbl_cnt) * 2);
 
-    int32_t available_raw_sizes[CAM_FORMAT_MAX * 2];
+    int32_t available_raw_sizes[MAX_SIZES_CNT * 2];
     makeTable(gCamCapability[cameraId]->raw_dim,
               gCamCapability[cameraId]->supported_raw_dim_cnt,
               available_raw_sizes);
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.h b/camera/QCamera2/HAL3/QCamera3HWI.h
index 0cd359a..fb7e5be 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.h
+++ b/camera/QCamera2/HAL3/QCamera3HWI.h
@@ -175,7 +175,7 @@
                       int len, int hal_name);
 
     int validateCaptureRequest(camera3_capture_request_t *request);
-
+    int validateStreamDimensions(camera3_stream_configuration_t *streamList);
     void deriveMinFrameDuration();
     int64_t getMinFrameDuration(const camera3_capture_request_t *request);