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 {