Refactor camera initialization support of gralloc.

Switch to a factory model so that initialization can
fail when the gralloc module can't be found or isn't supported.

BUG: 30140438
Change-Id: I6e0a62a207797aef96c532cff7632c1a4da8818f
diff --git a/modules/camera/3_4/V4L2Camera.cpp b/modules/camera/3_4/V4L2Camera.cpp
index 25a5955..623e0a5 100644
--- a/modules/camera/3_4/V4L2Camera.cpp
+++ b/modules/camera/3_4/V4L2Camera.cpp
@@ -47,9 +47,23 @@
   return keys;
 }
 
-V4L2Camera::V4L2Camera(int id, std::string path)
+V4L2Camera* V4L2Camera::NewV4L2Camera(int id, const std::string path) {
+  HAL_LOG_ENTER();
+
+  std::unique_ptr<V4L2Gralloc> gralloc(V4L2Gralloc::NewV4L2Gralloc());
+  if (!gralloc) {
+    HAL_LOGE("Failed to initialize gralloc helper.");
+    return nullptr;
+  }
+
+  return new V4L2Camera(id, path, std::move(gralloc));
+}
+
+V4L2Camera::V4L2Camera(int id, std::string path,
+                       std::unique_ptr<V4L2Gralloc> gralloc)
     : default_camera_hal::Camera(id),
       mDevicePath(std::move(path)),
+      mGralloc(std::move(gralloc)),
       mOutStreamType(0),
       mOutStreamFormat(0),
       mOutStreamWidth(0),
@@ -753,21 +767,6 @@
   HAL_LOG_ENTER();
   int res;
 
-  // Initialize and check the gralloc module.
-  const hw_module_t* module;
-  res = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
-  if (res) {
-    HAL_LOGE("Couldn't get gralloc module.");
-    return -ENODEV;
-  }
-  const gralloc_module_t* gralloc =
-      reinterpret_cast<const gralloc_module_t*>(module);
-  mGralloc = V4L2Gralloc(gralloc);
-  if (!mGralloc.isValid()) {
-    HAL_LOGE("Invalid gralloc module.");
-    return -ENODEV;
-  }
-
   // Templates should be set up if they haven't already been.
   if (!mTemplatesInitialized) {
     res = initTemplates();
@@ -800,14 +799,14 @@
   // queue length.
   device_buffer.index = 0;
   // Lock the buffer for writing.
-  int res = mGralloc.lock(camera_buffer, mOutStreamBytesPerLine,
+  int res = mGralloc->lock(camera_buffer, mOutStreamBytesPerLine,
                           &device_buffer);
   if (res) {
     return res;
   }
   if (ioctlLocked(VIDIOC_QBUF, &device_buffer) < 0) {
     HAL_LOGE("QBUF (%d) fails: %s", 0, strerror(errno));
-    mGralloc.unlock(&device_buffer);
+    mGralloc->unlock(&device_buffer);
     return -ENODEV;
   }
 
@@ -817,7 +816,7 @@
   // turned off before another call to this function).
   res = streamOn();
   if (res) {
-    mGralloc.unlock(&device_buffer);
+    mGralloc->unlock(&device_buffer);
     return res;
   }
 
@@ -828,11 +827,11 @@
   v4l2_buffer result_buffer;
   res = dequeueBuffer(&result_buffer);
   if (res) {
-    mGralloc.unlock(&result_buffer);
+    mGralloc->unlock(&result_buffer);
     return res;
   }
   // Now that we're done painting the buffer, we can unlock it.
-  res = mGralloc.unlock(&result_buffer);
+  res = mGralloc->unlock(&result_buffer);
   if (res) {
     return res;
   }
diff --git a/modules/camera/3_4/V4L2Camera.h b/modules/camera/3_4/V4L2Camera.h
index 1fabde9..b6cd79e 100644
--- a/modules/camera/3_4/V4L2Camera.h
+++ b/modules/camera/3_4/V4L2Camera.h
@@ -38,10 +38,17 @@
 // metadata and logic about that device.
 class V4L2Camera : public default_camera_hal::Camera {
 public:
-  V4L2Camera(int id, const std::string path);
+  // Use this method to create V4L2Camera objects. Functionally equivalent
+  // to "new V4L2Camera", except that it may return nullptr in case of failure.
+  static V4L2Camera* NewV4L2Camera(int id, const std::string path);
   ~V4L2Camera();
 
 private:
+  // Constructor private to allow failing on bad input.
+  // Use NewV4L2Camera instead.
+  V4L2Camera(int id, const std::string path,
+             std::unique_ptr<V4L2Gralloc> gralloc);
+
   // default_camera_hal::Camera virtual methods.
   // Connect to the device: open dev nodes, etc.
   int connect() override;
@@ -86,7 +93,7 @@
   // The opened device fd.
   ScopedFd mDeviceFd;
   // Gralloc helper.
-  V4L2Gralloc mGralloc;
+  std::unique_ptr<V4L2Gralloc> mGralloc;
   // Lock protecting use of the device.
   android::Mutex mDeviceLock;
   // Wrapper around ioctl.
diff --git a/modules/camera/3_4/V4L2CameraHAL.cpp b/modules/camera/3_4/V4L2CameraHAL.cpp
index 6696ba5..40797e9 100644
--- a/modules/camera/3_4/V4L2CameraHAL.cpp
+++ b/modules/camera/3_4/V4L2CameraHAL.cpp
@@ -95,8 +95,12 @@
       bus = reinterpret_cast<char*>(cap.bus_info);
       if (buses.insert(bus).second) {
         HAL_LOGV("Found unique bus at %s.", node.c_str());
-        std::unique_ptr<V4L2Camera> cam(new V4L2Camera(id++, node));
-        mCameras.push_back(std::move(cam));
+        std::unique_ptr<V4L2Camera> cam(V4L2Camera::NewV4L2Camera(id++, node));
+        if (cam) {
+          mCameras.push_back(std::move(cam));
+        } else {
+          HAL_LOGE("Failed to initialize camera at %s.", node.c_str());
+        }
       }
     }
     TEMP_FAILURE_RETRY(close(fd));
diff --git a/modules/camera/3_4/V4L2Gralloc.cpp b/modules/camera/3_4/V4L2Gralloc.cpp
index 8ffd262..d46d119 100644
--- a/modules/camera/3_4/V4L2Gralloc.cpp
+++ b/modules/camera/3_4/V4L2Gralloc.cpp
@@ -46,6 +46,33 @@
   }
 }
 
+V4L2Gralloc* V4L2Gralloc::NewV4L2Gralloc() {
+  HAL_LOG_ENTER();
+
+  // Initialize and check the gralloc module.
+  const hw_module_t* module = nullptr;
+  int res = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+  if (res || !module) {
+    HAL_LOGE("Couldn't get gralloc module.");
+    return nullptr;
+  }
+  const gralloc_module_t* gralloc =
+      reinterpret_cast<const gralloc_module_t*>(module);
+
+  // This class only supports Gralloc v0, not Gralloc V1.
+  if (gralloc->common.module_api_version > GRALLOC_MODULE_API_VERSION_0_3) {
+    HAL_LOGE("Invalid gralloc version %x. Only 0.3 (%x) "
+             "and below are supported by this HAL.",
+             gralloc->common.module_api_version,
+             GRALLOC_MODULE_API_VERSION_0_3);
+    return nullptr;
+  }
+
+  return new V4L2Gralloc(gralloc);
+}
+
+// Private. As checked by above factory, module will be non-null
+// and a supported version.
 V4L2Gralloc::V4L2Gralloc(const gralloc_module_t* module)
     : mModule(module) {
   HAL_LOG_ENTER();
@@ -65,21 +92,6 @@
   }
 }
 
-bool V4L2Gralloc::isValid() {
-  HAL_LOG_ENTER();
-
-  // This helper only supports Gralloc v0, not Gralloc V1.
-  if (mModule->common.module_api_version > GRALLOC_MODULE_API_VERSION_0_3) {
-    HAL_LOGE("Invalid gralloc version %x. Only 0.3 (%x) "
-             "and below are supported by this HAL.",
-             mModule->common.module_api_version,
-             GRALLOC_MODULE_API_VERSION_0_3);
-    return false;
-  }
-
-  return true;
-}
-
 int V4L2Gralloc::lock(const camera3_stream_buffer_t* camera_buffer,
                       uint32_t bytes_per_line,
                       /*out*/ v4l2_buffer* device_buffer) {
diff --git a/modules/camera/3_4/V4L2Gralloc.h b/modules/camera/3_4/V4L2Gralloc.h
index 6e37adb..a58a84d 100644
--- a/modules/camera/3_4/V4L2Gralloc.h
+++ b/modules/camera/3_4/V4L2Gralloc.h
@@ -34,8 +34,10 @@
 // with some assistive transformations.
 class V4L2Gralloc {
 public:
-  V4L2Gralloc(const gralloc_module_t* module = nullptr);
-  ~V4L2Gralloc();
+  // Use this method to create V4L2Gralloc objects. Functionally equivalent
+  // to "new V4L2Gralloc", except that it may return nullptr in case of failure.
+  static V4L2Gralloc* NewV4L2Gralloc();
+  virtual ~V4L2Gralloc();
 
   // Lock a camera buffer. Sets device buffer user pointer and length.
   int lock(const camera3_stream_buffer_t* camera_buffer,
@@ -45,10 +47,11 @@
   // based on buffer user pointer, not the specific object).
   int unlock(const v4l2_buffer* device_buffer);
 
-  // Check that the module passed in to the constructor is supported.
-  bool isValid();
-
 private:
+  // Constructor is private to allow failing on bad input.
+  // Use NewV4L2Gralloc instead.
+  V4L2Gralloc(const gralloc_module_t* module);
+
   const gralloc_module_t* mModule;
 
   struct BufferData {