{"id":2729,"url":"https://patchwork.libcamera.org/api/patches/2729/?format=json","web_url":"https://patchwork.libcamera.org/patch/2729/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20200122205723.8865-14-laurent.pinchart@ideasonboard.com>","date":"2020-01-22T20:57:23","name":"[libcamera-devel,v2,13/13] android: Remove internal thread","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"fd50e3f47f20b8ca4a9907e4c59b324312da4816","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/?format=json","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/2729/mbox/","series":[{"id":645,"url":"https://patchwork.libcamera.org/api/series/645/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=645","date":"2020-01-22T20:57:10","name":"Initial libcamera threading model","version":2,"mbox":"https://patchwork.libcamera.org/series/645/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/2729/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/2729/checks/","tags":{},"headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 118CE6089D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 22 Jan 2020 21:57:47 +0100 (CET)","from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id AC165595\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 22 Jan 2020 21:57:46 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1579726666;\n\tbh=peFN2Ay2QuFU4xqB+UxkwIydOLtT275sffzIlsacPjc=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=T9DkJffivbCGT25Wk7j31EXVF/igvG5aJMzUUTpUq7ZmmhGhs9WITHiAGctfwkfPx\n\tkoS+Zbik/HX9r/ea7dHYdMreLZPP2+gBa1Zoyb2ZCU0Ij7Y6/4jTsyOeNMxaUeDopi\n\trwewZ+6gEggfe7l8OhKIWs9AyjofGSD0aO2pPv2Y=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Date":"Wed, 22 Jan 2020 22:57:23 +0200","Message-Id":"<20200122205723.8865-14-laurent.pinchart@ideasonboard.com>","X-Mailer":"git-send-email 2.24.1","In-Reply-To":"<20200122205723.8865-1-laurent.pinchart@ideasonboard.com>","References":"<20200122205723.8865-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH v2 13/13] android: Remove internal thread","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Wed, 22 Jan 2020 20:57:49 -0000"},"content":"Now that libcamera creates threads internally and doesn't rely on an\napplication-provided event loop, remove the thread from the Android\nCamera HAL layer. The CameraProxy class becomes meaningless, remove it\nand communicate directly from the CameraHalManager to the CameraDevice.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\nChanges since v1:\n\n- Remove unused CameraDevice::cameraDevice_\n- Include stddef.h in camera_hal_manager.h to fix compilation of\n  Android's hardware/hardware.h header\n---\n src/android/camera3_hal.cpp        |   8 +-\n src/android/camera_device.cpp      |  48 +++++---\n src/android/camera_device.h        |  16 ++-\n src/android/camera_hal_manager.cpp |  78 +++++--------\n src/android/camera_hal_manager.h   |  17 +--\n src/android/camera_ops.cpp         |  96 +++++++++++++++\n src/android/camera_ops.h           |  15 +++\n src/android/camera_proxy.cpp       | 180 -----------------------------\n src/android/camera_proxy.h         |  42 -------\n src/android/meson.build            |   2 +-\n 10 files changed, 188 insertions(+), 314 deletions(-)\n create mode 100644 src/android/camera_ops.cpp\n create mode 100644 src/android/camera_ops.h\n delete mode 100644 src/android/camera_proxy.cpp\n delete mode 100644 src/android/camera_proxy.h","diff":"diff --git a/src/android/camera3_hal.cpp b/src/android/camera3_hal.cpp\nindex 8d2629ca356c..d6fc1ecc01bf 100644\n--- a/src/android/camera3_hal.cpp\n+++ b/src/android/camera3_hal.cpp\n@@ -7,8 +7,8 @@\n \n #include <hardware/camera_common.h>\n \n+#include \"camera_device.h\"\n #include \"camera_hal_manager.h\"\n-#include \"camera_proxy.h\"\n #include \"log.h\"\n \n using namespace libcamera;\n@@ -71,14 +71,14 @@ static int hal_dev_open(const hw_module_t *module, const char *name,\n \tLOG(HAL, Debug) << \"Open camera \" << name;\n \n \tint id = atoi(name);\n-\tCameraProxy *proxy = cameraManager.open(id, module);\n-\tif (!proxy) {\n+\tCameraDevice *camera = cameraManager.open(id, module);\n+\tif (!camera) {\n \t\tLOG(HAL, Error)\n \t\t\t<< \"Failed to open camera module '\" << id << \"'\";\n \t\treturn -ENODEV;\n \t}\n \n-\t*device = &proxy->camera3Device()->common;\n+\t*device = &camera->camera3Device()->common;\n \n \treturn 0;\n }\ndiff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp\nindex 67c1d47e67ed..b460d499375b 100644\n--- a/src/android/camera_device.cpp\n+++ b/src/android/camera_device.cpp\n@@ -6,6 +6,7 @@\n  */\n \n #include \"camera_device.h\"\n+#include \"camera_ops.h\"\n \n #include \"log.h\"\n #include \"utils.h\"\n@@ -39,13 +40,13 @@ CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()\n  * \\class CameraDevice\n  *\n  * The CameraDevice class wraps a libcamera::Camera instance, and implements\n- * the camera_device_t interface by handling RPC requests received from its\n- * associated CameraProxy.\n+ * the camera3_device_t interface, bridging calls received from the Android\n+ * camera service to the CameraDevice.\n  *\n- * It translate parameters and operations from Camera HALv3 API to the libcamera\n- * ones to provide static information for a Camera, create request templates\n- * for it, process capture requests and then deliver capture results back\n- * to the framework using the designated callbacks.\n+ * The class translates parameters and operations from the Camera HALv3 API to\n+ * the libcamera API to provide static information for a Camera, create request\n+ * templates for it, process capture requests and then deliver capture results\n+ * back to the framework using the designated callbacks.\n  */\n \n CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)\n@@ -63,7 +64,7 @@ CameraDevice::~CameraDevice()\n \t\tdelete it.second;\n }\n \n-int CameraDevice::open()\n+int CameraDevice::open(const hw_module_t *hardwareModule)\n {\n \tint ret = camera_->acquire();\n \tif (ret) {\n@@ -71,6 +72,19 @@ int CameraDevice::open()\n \t\treturn ret;\n \t}\n \n+\t/* Initialize the hw_device_t in the instance camera3_module_t. */\n+\tcamera3Device_.common.tag = HARDWARE_DEVICE_TAG;\n+\tcamera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;\n+\tcamera3Device_.common.module = (hw_module_t *)hardwareModule;\n+\tcamera3Device_.common.close = hal_dev_close;\n+\n+\t/*\n+\t * The camera device operations. These actually implement\n+\t * the Android Camera HALv3 interface.\n+\t */\n+\tcamera3Device_.ops = &hal_dev_ops;\n+\tcamera3Device_.priv = this;\n+\n \treturn 0;\n }\n \n@@ -90,7 +104,7 @@ void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)\n /*\n  * Return static information for the camera.\n  */\n-camera_metadata_t *CameraDevice::getStaticMetadata()\n+const camera_metadata_t *CameraDevice::getStaticMetadata()\n {\n \tif (staticMetadata_)\n \t\treturn staticMetadata_->get();\n@@ -675,7 +689,7 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)\n \treturn 0;\n }\n \n-void CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)\n+int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)\n {\n \tStreamConfiguration *streamConfiguration = &config_->at(0);\n \tStream *stream = streamConfiguration->stream();\n@@ -683,7 +697,7 @@ void CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reque\n \tif (camera3Request->num_output_buffers != 1) {\n \t\tLOG(HAL, Error) << \"Invalid number of output buffers: \"\n \t\t\t\t<< camera3Request->num_output_buffers;\n-\t\treturn;\n+\t\treturn -EINVAL;\n \t}\n \n \t/* Start the camera if that's the first request we handle. */\n@@ -691,7 +705,7 @@ void CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reque\n \t\tint ret = camera_->start();\n \t\tif (ret) {\n \t\t\tLOG(HAL, Error) << \"Failed to start camera\";\n-\t\t\treturn;\n+\t\t\treturn ret;\n \t\t}\n \n \t\trunning_ = true;\n@@ -747,7 +761,7 @@ void CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reque\n \tif (!buffer) {\n \t\tLOG(HAL, Error) << \"Failed to create buffer\";\n \t\tdelete descriptor;\n-\t\treturn;\n+\t\treturn -ENOMEM;\n \t}\n \n \tRequest *request =\n@@ -757,14 +771,12 @@ void CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reque\n \tint ret = camera_->queueRequest(request);\n \tif (ret) {\n \t\tLOG(HAL, Error) << \"Failed to queue request\";\n-\t\tgoto error;\n+\t\tdelete request;\n+\t\tdelete descriptor;\n+\t\treturn ret;\n \t}\n \n-\treturn;\n-\n-error:\n-\tdelete request;\n-\tdelete descriptor;\n+\treturn 0;\n }\n \n void CameraDevice::requestComplete(Request *request)\ndiff --git a/src/android/camera_device.h b/src/android/camera_device.h\nindex caa617dcbfe1..55eac317e0e4 100644\n--- a/src/android/camera_device.h\n+++ b/src/android/camera_device.h\n@@ -13,7 +13,6 @@\n \n #include <libcamera/buffer.h>\n #include <libcamera/camera.h>\n-#include <libcamera/object.h>\n #include <libcamera/request.h>\n #include <libcamera/stream.h>\n \n@@ -21,19 +20,23 @@\n \n class CameraMetadata;\n \n-class CameraDevice : public libcamera::Object\n+class CameraDevice\n {\n public:\n \tCameraDevice(unsigned int id, const std::shared_ptr<libcamera::Camera> &camera);\n \t~CameraDevice();\n \n-\tint open();\n+\tint open(const hw_module_t *hardwareModule);\n \tvoid close();\n+\n+\tunsigned int id() const { return id_; }\n+\tcamera3_device_t *camera3Device() { return &camera3Device_; }\n+\n \tvoid setCallbacks(const camera3_callback_ops_t *callbacks);\n-\tcamera_metadata_t *getStaticMetadata();\n+\tconst camera_metadata_t *getStaticMetadata();\n \tconst camera_metadata_t *constructDefaultRequestSettings(int type);\n \tint configureStreams(camera3_stream_configuration_t *stream_list);\n-\tvoid processCaptureRequest(camera3_capture_request_t *request);\n+\tint processCaptureRequest(camera3_capture_request_t *request);\n \tvoid requestComplete(libcamera::Request *request);\n \n private:\n@@ -52,6 +55,9 @@ private:\n \tstd::unique_ptr<CameraMetadata> getResultMetadata(int frame_number,\n \t\t\t\t\t\t\t  int64_t timestamp);\n \n+\tunsigned int id_;\n+\tcamera3_device_t camera3Device_;\n+\n \tbool running_;\n \tstd::shared_ptr<libcamera::Camera> camera_;\n \tstd::unique_ptr<libcamera::CameraConfiguration> config_;\ndiff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp\nindex 22f0323b3ff0..5bd3bdba8a55 100644\n--- a/src/android/camera_hal_manager.cpp\n+++ b/src/android/camera_hal_manager.cpp\n@@ -12,7 +12,6 @@\n #include \"log.h\"\n \n #include \"camera_device.h\"\n-#include \"camera_proxy.h\"\n \n using namespace libcamera;\n \n@@ -28,92 +27,67 @@ LOG_DECLARE_CATEGORY(HAL);\n  * their static information and to open camera devices.\n  */\n \n-CameraHalManager::~CameraHalManager()\n+CameraHalManager::CameraHalManager()\n+\t: cameraManager_(nullptr)\n {\n-\tif (isRunning()) {\n-\t\texit(0);\n-\t\t/* \\todo Wait with a timeout, just in case. */\n-\t\twait();\n-\t}\n }\n \n-int CameraHalManager::init()\n+CameraHalManager::~CameraHalManager()\n {\n-\t/*\n-\t * Start the camera HAL manager thread and wait until its\n-\t * initialisation completes to be fully operational before\n-\t * receiving calls from the camera stack.\n-\t */\n-\tstart();\n-\n-\tMutexLocker locker(mutex_);\n-\tcv_.wait(locker);\n+\tcameras_.clear();\n \n-\treturn 0;\n+\tif (cameraManager_) {\n+\t\tcameraManager_->stop();\n+\t\tdelete cameraManager_;\n+\t\tcameraManager_ = nullptr;\n+\t}\n }\n \n-void CameraHalManager::run()\n+int CameraHalManager::init()\n {\n-\t/*\n-\t * All the libcamera components must be initialised here, in\n-\t * order to bind them to the camera HAL manager thread that\n-\t * executes the event dispatcher.\n-\t */\n \tcameraManager_ = new CameraManager();\n \n \tint ret = cameraManager_->start();\n \tif (ret) {\n \t\tLOG(HAL, Error) << \"Failed to start camera manager: \"\n \t\t\t\t<< strerror(-ret);\n-\t\treturn;\n+\t\tdelete cameraManager_;\n+\t\tcameraManager_ = nullptr;\n+\t\treturn ret;\n \t}\n \n \t/*\n-\t * For each Camera registered in the system, a CameraProxy\n-\t * gets created here to wraps a camera device.\n+\t * For each Camera registered in the system, a CameraDevice\n+\t * gets created here to wraps a libcamera Camera instance.\n \t *\n \t * \\todo Support camera hotplug.\n \t */\n \tunsigned int index = 0;\n-\tfor (auto &camera : cameraManager_->cameras()) {\n-\t\tCameraProxy *proxy = new CameraProxy(index, camera);\n-\t\tproxies_.emplace_back(proxy);\n+\tfor (auto &cam : cameraManager_->cameras()) {\n+\t\tCameraDevice *camera = new CameraDevice(index, cam);\n+\t\tcameras_.emplace_back(camera);\n \n \t\t++index;\n \t}\n \n-\t/*\n-\t * libcamera has been initialized. Unlock the init() caller\n-\t * as we're now ready to handle calls from the framework.\n-\t */\n-\tcv_.notify_one();\n-\n-\t/* Now start processing events and messages. */\n-\texec();\n-\n-\t/* Clean up the resources we have allocated. */\n-\tproxies_.clear();\n-\n-\tcameraManager_->stop();\n-\tdelete cameraManager_;\n-\tcameraManager_ = nullptr;\n+\treturn 0;\n }\n \n-CameraProxy *CameraHalManager::open(unsigned int id,\n-\t\t\t\t    const hw_module_t *hardwareModule)\n+CameraDevice *CameraHalManager::open(unsigned int id,\n+\t\t\t\t     const hw_module_t *hardwareModule)\n {\n \tif (id >= numCameras()) {\n \t\tLOG(HAL, Error) << \"Invalid camera id '\" << id << \"'\";\n \t\treturn nullptr;\n \t}\n \n-\tCameraProxy *proxy = proxies_[id].get();\n-\tif (proxy->open(hardwareModule))\n+\tCameraDevice *camera = cameras_[id].get();\n+\tif (camera->open(hardwareModule))\n \t\treturn nullptr;\n \n \tLOG(HAL, Info) << \"Open camera '\" << id << \"'\";\n \n-\treturn proxy;\n+\treturn camera;\n }\n \n unsigned int CameraHalManager::numCameras() const\n@@ -131,14 +105,14 @@ int CameraHalManager::getCameraInfo(unsigned int id, struct camera_info *info)\n \t\treturn -EINVAL;\n \t}\n \n-\tCameraProxy *proxy = proxies_[id].get();\n+\tCameraDevice *camera = cameras_[id].get();\n \n \t/* \\todo Get these info dynamically inspecting the camera module. */\n \tinfo->facing = id ? CAMERA_FACING_FRONT : CAMERA_FACING_BACK;\n \tinfo->orientation = 0;\n \tinfo->device_version = 0;\n \tinfo->resource_cost = 0;\n-\tinfo->static_camera_characteristics = proxy->getStaticMetadata();\n+\tinfo->static_camera_characteristics = camera->getStaticMetadata();\n \tinfo->conflicting_devices = nullptr;\n \tinfo->conflicting_devices_length = 0;\n \ndiff --git a/src/android/camera_hal_manager.h b/src/android/camera_hal_manager.h\nindex c23abd1c00af..94d8f005444d 100644\n--- a/src/android/camera_hal_manager.h\n+++ b/src/android/camera_hal_manager.h\n@@ -7,8 +7,7 @@\n #ifndef __ANDROID_CAMERA_MANAGER_H__\n #define __ANDROID_CAMERA_MANAGER_H__\n \n-#include <condition_variable>\n-#include <mutex>\n+#include <stddef.h>\n #include <vector>\n \n #include <hardware/hardware.h>\n@@ -16,33 +15,27 @@\n \n #include <libcamera/camera_manager.h>\n \n-#include \"thread.h\"\n-\n class CameraDevice;\n-class CameraProxy;\n \n-class CameraHalManager : public libcamera::Thread\n+class CameraHalManager\n {\n public:\n+\tCameraHalManager();\n \t~CameraHalManager();\n \n \tint init();\n \n-\tCameraProxy *open(unsigned int id, const hw_module_t *module);\n+\tCameraDevice *open(unsigned int id, const hw_module_t *module);\n \n \tunsigned int numCameras() const;\n \tint getCameraInfo(unsigned int id, struct camera_info *info);\n \n private:\n-\tvoid run() override;\n \tcamera_metadata_t *getStaticMetadata(unsigned int id);\n \n \tlibcamera::CameraManager *cameraManager_;\n \n-\tstd::mutex mutex_;\n-\tstd::condition_variable cv_;\n-\n-\tstd::vector<std::unique_ptr<CameraProxy>> proxies_;\n+\tstd::vector<std::unique_ptr<CameraDevice>> cameras_;\n };\n \n #endif /* __ANDROID_CAMERA_MANAGER_H__ */\ndiff --git a/src/android/camera_ops.cpp b/src/android/camera_ops.cpp\nnew file mode 100644\nindex 000000000000..9dfc2e655e83\n--- /dev/null\n+++ b/src/android/camera_ops.cpp\n@@ -0,0 +1,96 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * camera_ops.h - Android Camera HAL Operations\n+ */\n+\n+#include \"camera_ops.h\"\n+\n+#include <system/camera_metadata.h>\n+\n+#include \"camera_device.h\"\n+\n+using namespace libcamera;\n+\n+/*\n+ * Translatation layer between the Android Camera HAL device operations and the\n+ * CameraDevice.\n+ */\n+\n+static int hal_dev_initialize(const struct camera3_device *dev,\n+\t\t\t      const camera3_callback_ops_t *callback_ops)\n+{\n+\tif (!dev)\n+\t\treturn -EINVAL;\n+\n+\tCameraDevice *camera = reinterpret_cast<CameraDevice *>(dev->priv);\n+\tcamera->setCallbacks(callback_ops);\n+\n+\treturn 0;\n+}\n+\n+static int hal_dev_configure_streams(const struct camera3_device *dev,\n+\t\t\t\t     camera3_stream_configuration_t *stream_list)\n+{\n+\tif (!dev)\n+\t\treturn -EINVAL;\n+\n+\tCameraDevice *camera = reinterpret_cast<CameraDevice *>(dev->priv);\n+\treturn camera->configureStreams(stream_list);\n+}\n+\n+static const camera_metadata_t *\n+hal_dev_construct_default_request_settings(const struct camera3_device *dev,\n+\t\t\t\t\t   int type)\n+{\n+\tif (!dev)\n+\t\treturn nullptr;\n+\n+\tCameraDevice *camera = reinterpret_cast<CameraDevice *>(dev->priv);\n+\treturn camera->constructDefaultRequestSettings(type);\n+}\n+\n+static int hal_dev_process_capture_request(const struct camera3_device *dev,\n+\t\t\t\t\t   camera3_capture_request_t *request)\n+{\n+\tif (!dev)\n+\t\treturn -EINVAL;\n+\n+\tCameraDevice *camera = reinterpret_cast<CameraDevice *>(dev->priv);\n+\treturn camera->processCaptureRequest(request);\n+}\n+\n+static void hal_dev_dump(const struct camera3_device *dev, int fd)\n+{\n+}\n+\n+static int hal_dev_flush(const struct camera3_device *dev)\n+{\n+\treturn 0;\n+}\n+\n+int hal_dev_close(hw_device_t *hw_device)\n+{\n+\tif (!hw_device)\n+\t\treturn -EINVAL;\n+\n+\tcamera3_device_t *dev = reinterpret_cast<camera3_device_t *>(hw_device);\n+\tCameraDevice *camera = reinterpret_cast<CameraDevice *>(dev->priv);\n+\n+\tcamera->close();\n+\n+\treturn 0;\n+}\n+\n+camera3_device_ops hal_dev_ops = {\n+\t.initialize = hal_dev_initialize,\n+\t.configure_streams = hal_dev_configure_streams,\n+\t.register_stream_buffers = nullptr,\n+\t.construct_default_request_settings = hal_dev_construct_default_request_settings,\n+\t.process_capture_request = hal_dev_process_capture_request,\n+\t.get_metadata_vendor_tag_ops = nullptr,\n+\t.dump = hal_dev_dump,\n+\t.flush = hal_dev_flush,\n+\t.reserved = { nullptr },\n+};\ndiff --git a/src/android/camera_ops.h b/src/android/camera_ops.h\nnew file mode 100644\nindex 000000000000..304e7b856e81\n--- /dev/null\n+++ b/src/android/camera_ops.h\n@@ -0,0 +1,15 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * camera_ops.h - Android Camera HAL Operations\n+ */\n+#ifndef __ANDROID_CAMERA_OPS_H__\n+#define __ANDROID_CAMERA_OPS_H__\n+\n+#include <hardware/camera3.h>\n+\n+int hal_dev_close(hw_device_t *hw_device);\n+extern camera3_device_ops hal_dev_ops;\n+\n+#endif /* __ANDROID_CAMERA_OPS_H__ */\ndiff --git a/src/android/camera_proxy.cpp b/src/android/camera_proxy.cpp\ndeleted file mode 100644\nindex 3964b5665e2f..000000000000\n--- a/src/android/camera_proxy.cpp\n+++ /dev/null\n@@ -1,180 +0,0 @@\n-/* SPDX-License-Identifier: LGPL-2.1-or-later */\n-/*\n- * Copyright (C) 2019, Google Inc.\n- *\n- * camera_proxy.cpp - Proxy to camera devices\n- */\n-\n-#include \"camera_proxy.h\"\n-\n-#include <system/camera_metadata.h>\n-\n-#include <libcamera/object.h>\n-\n-#include \"log.h\"\n-#include \"message.h\"\n-#include \"utils.h\"\n-\n-#include \"camera_device.h\"\n-\n-using namespace libcamera;\n-\n-LOG_DECLARE_CATEGORY(HAL);\n-\n-/*\n- * \\class CameraProxy\n- *\n- * The CameraProxy wraps a CameraDevice and implements the camera3_device_t\n- * API, bridging calls received from the camera framework to the CameraDevice.\n- *\n- * Bridging operation calls between the framework and the CameraDevice is\n- * required as the two run in two different threads and certain operations,\n- * such as queueing a new capture request to the camera, shall be called in\n- * the thread that dispatches events. Other operations do not require any\n- * bridging and resolve to direct function calls on the CameraDevice instance\n- * instead.\n- */\n-\n-static int hal_dev_initialize(const struct camera3_device *dev,\n-\t\t\t      const camera3_callback_ops_t *callback_ops)\n-{\n-\tif (!dev)\n-\t\treturn -EINVAL;\n-\n-\tCameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);\n-\tproxy->initialize(callback_ops);\n-\n-\treturn 0;\n-}\n-\n-static int hal_dev_configure_streams(const struct camera3_device *dev,\n-\t\t\t\t     camera3_stream_configuration_t *stream_list)\n-{\n-\tif (!dev)\n-\t\treturn -EINVAL;\n-\n-\tCameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);\n-\treturn proxy->configureStreams(stream_list);\n-}\n-\n-static const camera_metadata_t *\n-hal_dev_construct_default_request_settings(const struct camera3_device *dev,\n-\t\t\t\t\t   int type)\n-{\n-\tif (!dev)\n-\t\treturn nullptr;\n-\n-\tCameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);\n-\treturn proxy->constructDefaultRequestSettings(type);\n-}\n-\n-static int hal_dev_process_capture_request(const struct camera3_device *dev,\n-\t\t\t\t\t   camera3_capture_request_t *request)\n-{\n-\tif (!dev)\n-\t\treturn -EINVAL;\n-\n-\tCameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);\n-\treturn proxy->processCaptureRequest(request);\n-}\n-\n-static void hal_dev_dump(const struct camera3_device *dev, int fd)\n-{\n-}\n-\n-static int hal_dev_flush(const struct camera3_device *dev)\n-{\n-\treturn 0;\n-}\n-\n-static int hal_dev_close(hw_device_t *hw_device)\n-{\n-\tif (!hw_device)\n-\t\treturn -EINVAL;\n-\n-\tcamera3_device_t *dev = reinterpret_cast<camera3_device_t *>(hw_device);\n-\tCameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);\n-\n-\tproxy->close();\n-\n-\treturn 0;\n-}\n-\n-static camera3_device_ops hal_dev_ops = {\n-\t.initialize = hal_dev_initialize,\n-\t.configure_streams = hal_dev_configure_streams,\n-\t.register_stream_buffers = nullptr,\n-\t.construct_default_request_settings = hal_dev_construct_default_request_settings,\n-\t.process_capture_request = hal_dev_process_capture_request,\n-\t.get_metadata_vendor_tag_ops = nullptr,\n-\t.dump = hal_dev_dump,\n-\t.flush = hal_dev_flush,\n-\t.reserved = { nullptr },\n-};\n-\n-CameraProxy::CameraProxy(unsigned int id, const std::shared_ptr<Camera> &camera)\n-\t: id_(id)\n-{\n-\tcameraDevice_ = new CameraDevice(id, camera);\n-}\n-\n-CameraProxy::~CameraProxy()\n-{\n-\tdelete cameraDevice_;\n-}\n-\n-int CameraProxy::open(const hw_module_t *hardwareModule)\n-{\n-\tint ret = cameraDevice_->open();\n-\tif (ret)\n-\t\treturn ret;\n-\n-\t/* Initialize the hw_device_t in the instance camera3_module_t. */\n-\tcamera3Device_.common.tag = HARDWARE_DEVICE_TAG;\n-\tcamera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;\n-\tcamera3Device_.common.module = (hw_module_t *)hardwareModule;\n-\tcamera3Device_.common.close = hal_dev_close;\n-\n-\t/*\n-\t * The camera device operations. These actually implement\n-\t * the Android Camera HALv3 interface.\n-\t */\n-\tcamera3Device_.ops = &hal_dev_ops;\n-\tcamera3Device_.priv = this;\n-\n-\treturn 0;\n-}\n-\n-void CameraProxy::close()\n-{\n-\tcameraDevice_->invokeMethod(&CameraDevice::close,\n-\t\t\t\t    ConnectionTypeBlocking);\n-}\n-\n-void CameraProxy::initialize(const camera3_callback_ops_t *callbacks)\n-{\n-\tcameraDevice_->setCallbacks(callbacks);\n-}\n-\n-const camera_metadata_t *CameraProxy::getStaticMetadata()\n-{\n-\treturn cameraDevice_->getStaticMetadata();\n-}\n-\n-const camera_metadata_t *CameraProxy::constructDefaultRequestSettings(int type)\n-{\n-\treturn cameraDevice_->constructDefaultRequestSettings(type);\n-}\n-\n-int CameraProxy::configureStreams(camera3_stream_configuration_t *stream_list)\n-{\n-\treturn cameraDevice_->configureStreams(stream_list);\n-}\n-\n-int CameraProxy::processCaptureRequest(camera3_capture_request_t *request)\n-{\n-\tcameraDevice_->invokeMethod(&CameraDevice::processCaptureRequest,\n-\t\t\t\t    ConnectionTypeBlocking, request);\n-\n-\treturn 0;\n-}\ndiff --git a/src/android/camera_proxy.h b/src/android/camera_proxy.h\ndeleted file mode 100644\nindex e8cfbc9dd526..000000000000\n--- a/src/android/camera_proxy.h\n+++ /dev/null\n@@ -1,42 +0,0 @@\n-/* SPDX-License-Identifier: LGPL-2.1-or-later */\n-/*\n- * Copyright (C) 2019, Google Inc.\n- *\n- * camera_proxy.h - Proxy to camera devices\n- */\n-#ifndef __ANDROID_CAMERA_PROXY_H__\n-#define __ANDROID_CAMERA_PROXY_H__\n-\n-#include <memory>\n-\n-#include <hardware/camera3.h>\n-\n-#include <libcamera/camera.h>\n-\n-class CameraDevice;\n-\n-class CameraProxy\n-{\n-public:\n-\tCameraProxy(unsigned int id, const std::shared_ptr<libcamera::Camera> &camera);\n-\t~CameraProxy();\n-\n-\tint open(const hw_module_t *hardwareModule);\n-\tvoid close();\n-\n-\tvoid initialize(const camera3_callback_ops_t *callbacks);\n-\tconst camera_metadata_t *getStaticMetadata();\n-\tconst camera_metadata_t *constructDefaultRequestSettings(int type);\n-\tint configureStreams(camera3_stream_configuration_t *stream_list);\n-\tint processCaptureRequest(camera3_capture_request_t *request);\n-\n-\tunsigned int id() const { return id_; }\n-\tcamera3_device_t *camera3Device() { return &camera3Device_; }\n-\n-private:\n-\tunsigned int id_;\n-\tCameraDevice *cameraDevice_;\n-\tcamera3_device_t camera3Device_;\n-};\n-\n-#endif /* __ANDROID_CAMERA_PROXY_H__ */\ndiff --git a/src/android/meson.build b/src/android/meson.build\nindex 70dfcc1df27a..5a5a332e6a6f 100644\n--- a/src/android/meson.build\n+++ b/src/android/meson.build\n@@ -3,7 +3,7 @@ android_hal_sources = files([\n     'camera_hal_manager.cpp',\n     'camera_device.cpp',\n     'camera_metadata.cpp',\n-    'camera_proxy.cpp',\n+    'camera_ops.cpp',\n ])\n \n android_camera_metadata_sources = files([\n","prefixes":["libcamera-devel","v2","13/13"]}