libcamera: Add checking of preview sizes on setting parameters

bug fix: If it try to set invalid preview sizes,
         driver will be stuck in an unrecoverable state.
         Thus, It is fixed to return error when setting parameters

bug:3429909

Change-Id: If51b47439c140410fa03e3a0b66492633f194e53
Signed-off-by: Jeong-Seok Yang <jseok.yang@samsung.com>
diff --git a/libcamera/SecCameraHWInterface.cpp b/libcamera/SecCameraHWInterface.cpp
index 50d43a0..137653a 100644
--- a/libcamera/SecCameraHWInterface.cpp
+++ b/libcamera/SecCameraHWInterface.cpp
@@ -170,6 +170,8 @@
               "640x480");
     }
 
+    p.getSupportedPreviewSizes(mSupportedPreviewSizes);
+
     // If these fail, then we are using an invalid cameraId and we'll leave the
     // sizes at zero to catch the error.
     if (mSecCamera->getPreviewMaxSize(&preview_max_width,
@@ -1401,6 +1403,20 @@
     return NO_ERROR;
 }
 
+bool CameraHardwareSec::isSupportedPreviewSize(const int width,
+                                               const int height) const
+{
+    unsigned int i;
+
+    for (i = 0; i < mSupportedPreviewSizes.size(); i++) {
+        if (mSupportedPreviewSizes[i].width == width &&
+                mSupportedPreviewSizes[i].height == height)
+            return true;
+    }
+
+    return false;
+}
+
 status_t CameraHardwareSec::setParameters(const CameraParameters& params)
 {
     LOGV("%s :", __func__);
@@ -1427,7 +1443,9 @@
     LOGV("%s : new_preview_width x new_preview_height = %dx%d, format = %s",
          __func__, new_preview_width, new_preview_height, new_str_preview_format);
 
-    if (0 < new_preview_width && 0 < new_preview_height && new_str_preview_format != NULL) {
+    if (0 < new_preview_width && 0 < new_preview_height &&
+            new_str_preview_format != NULL &&
+            isSupportedPreviewSize(new_preview_width, new_preview_height)) {
         int new_preview_format = 0;
 
         if (!strcmp(new_str_preview_format,
@@ -1463,6 +1481,11 @@
             }
         }
 #endif
+    } else {
+        LOGE("%s: Invalid preview size(%dx%d)",
+                __func__, new_preview_width, new_preview_height);
+
+        ret = INVALID_OPERATION;
     }
 
     int new_picture_width  = 0;
diff --git a/libcamera/SecCameraHWInterface.h b/libcamera/SecCameraHWInterface.h
index 75526c6..0a948db 100644
--- a/libcamera/SecCameraHWInterface.h
+++ b/libcamera/SecCameraHWInterface.h
@@ -156,6 +156,8 @@
                                    int *pdwJPEGSize, void *pVideo,
                                    int *pdwVideoSize);
             void        setSkipFrame(int frame);
+            bool        isSupportedPreviewSize(const int width,
+                                               const int height) const;
     /* used by auto focus thread to block until it's told to run */
     mutable Mutex       mFocusLock;
     mutable Condition   mFocusCondition;
@@ -205,6 +207,8 @@
             int         mPostViewWidth;
             int         mPostViewHeight;
             int         mPostViewSize;
+
+            Vector<Size> mSupportedPreviewSizes;
 };
 
 }; // namespace android