[libcamera-devel,5/5] android: hal: Add Camera3 HAL

Message ID 20190801155420.24694-6-jacopo@jmondi.org
State Superseded
Headers show
Series
  • android: Add initial Camera HAL implementation
Related show

Commit Message

Jacopo Mondi Aug. 1, 2019, 3:54 p.m. UTC
Add Libcamera Android Camerav3 HAL implementation.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 src/android/camera3_hal.cpp        | 130 +++++
 src/android/camera_hal_manager.cpp | 173 +++++++
 src/android/camera_hal_manager.h   |  56 ++
 src/android/camera_module.cpp      | 795 +++++++++++++++++++++++++++++
 src/android/camera_module.h        |  69 +++
 src/android/camera_proxy.cpp       | 181 +++++++
 src/android/camera_proxy.h         |  41 ++
 src/android/meson.build            |   8 +
 src/android/tags                   | 424 +++++++++++++++
 src/android/thread_rpc.cpp         |  41 ++
 src/android/thread_rpc.h           |  56 ++
 src/libcamera/meson.build          |  22 +-
 src/meson.build                    |   4 +
 13 files changed, 1995 insertions(+), 5 deletions(-)
 create mode 100644 src/android/camera3_hal.cpp
 create mode 100644 src/android/camera_hal_manager.cpp
 create mode 100644 src/android/camera_hal_manager.h
 create mode 100644 src/android/camera_module.cpp
 create mode 100644 src/android/camera_module.h
 create mode 100644 src/android/camera_proxy.cpp
 create mode 100644 src/android/camera_proxy.h
 create mode 100644 src/android/tags
 create mode 100644 src/android/thread_rpc.cpp
 create mode 100644 src/android/thread_rpc.h

Comments

Laurent Pinchart Aug. 5, 2019, 11:53 a.m. UTC | #1
Hi Jacopo,

Thank you for the patch.

On Thu, Aug 01, 2019 at 05:54:20PM +0200, Jacopo Mondi wrote:
> Add Libcamera Android Camerav3 HAL implementation.

s/Libcamera/libcamera/
s/Camerav3/Camera HAL v3/

> 
> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> ---
>  src/android/camera3_hal.cpp        | 130 +++++
>  src/android/camera_hal_manager.cpp | 173 +++++++
>  src/android/camera_hal_manager.h   |  56 ++
>  src/android/camera_module.cpp      | 795 +++++++++++++++++++++++++++++
>  src/android/camera_module.h        |  69 +++
>  src/android/camera_proxy.cpp       | 181 +++++++
>  src/android/camera_proxy.h         |  41 ++
>  src/android/meson.build            |   8 +
>  src/android/tags                   | 424 +++++++++++++++

Could you send a v2 without this file ? :-)

>  src/android/thread_rpc.cpp         |  41 ++
>  src/android/thread_rpc.h           |  56 ++
>  src/libcamera/meson.build          |  22 +-
>  src/meson.build                    |   4 +
>  13 files changed, 1995 insertions(+), 5 deletions(-)
>  create mode 100644 src/android/camera3_hal.cpp
>  create mode 100644 src/android/camera_hal_manager.cpp
>  create mode 100644 src/android/camera_hal_manager.h
>  create mode 100644 src/android/camera_module.cpp
>  create mode 100644 src/android/camera_module.h
>  create mode 100644 src/android/camera_proxy.cpp
>  create mode 100644 src/android/camera_proxy.h
>  create mode 100644 src/android/tags
>  create mode 100644 src/android/thread_rpc.cpp
>  create mode 100644 src/android/thread_rpc.h

[snip]

> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
> index a09b23d60022..9b6e4b769760 100644
> --- a/src/libcamera/meson.build
> +++ b/src/libcamera/meson.build
> @@ -103,11 +103,23 @@ libcamera_deps = [
>      dependency('threads'),
>  ]
>  
> -libcamera = shared_library('camera',
> -                           libcamera_sources,
> -                           install : true,
> -                           include_directories : includes,
> -                           dependencies : libcamera_deps)
> +if get_option('android')
> +    libcamera_sources += android_hal_sources
> +    includes += android_includes
> +
> +    libcamera = shared_library('camera',
> +                               libcamera_sources,
> +                               install : true,
> +                               link_with : android_camera_metadata,
> +                               include_directories : includes,
> +                               dependencies : libcamera_deps)
> +else
> +    libcamera = shared_library('camera',
> +                               libcamera_sources,
> +                               install : true,
> +                               include_directories : includes,
> +                               dependencies : libcamera_deps)
> +endif

Would it be possible to keep a single shared_library statement, with a
variable for link_with that is declared initially empty, and is updated
when the android option is set ?

>  
>  libcamera_dep = declare_dependency(sources : [libcamera_api, libcamera_h],
>                                     include_directories : libcamera_includes,
> diff --git a/src/meson.build b/src/meson.build
> index 628e7a7f23f2..67ad20aab86b 100644
> --- a/src/meson.build
> +++ b/src/meson.build
> @@ -1,3 +1,7 @@
> +if get_option('android')
> +    subdir('android')
> +endif
> +
>  subdir('libcamera')
>  subdir('ipa')
>  subdir('cam')
Jacopo Mondi Aug. 6, 2019, 9:34 a.m. UTC | #2
Hi Laurent,

On Mon, Aug 05, 2019 at 02:53:55PM +0300, Laurent Pinchart wrote:
> Hi Jacopo,
>
> Thank you for the patch.
>
> On Thu, Aug 01, 2019 at 05:54:20PM +0200, Jacopo Mondi wrote:
> > Add Libcamera Android Camerav3 HAL implementation.
>
> s/Libcamera/libcamera/
> s/Camerav3/Camera HAL v3/
>
> >
> > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> > ---
> >  src/android/camera3_hal.cpp        | 130 +++++
> >  src/android/camera_hal_manager.cpp | 173 +++++++
> >  src/android/camera_hal_manager.h   |  56 ++
> >  src/android/camera_module.cpp      | 795 +++++++++++++++++++++++++++++
> >  src/android/camera_module.h        |  69 +++
> >  src/android/camera_proxy.cpp       | 181 +++++++
> >  src/android/camera_proxy.h         |  41 ++
> >  src/android/meson.build            |   8 +
> >  src/android/tags                   | 424 +++++++++++++++
>
> Could you send a v2 without this file ? :-)
>

Just wanted to save you all some CPU time to generate tags. I'm sorry
you don't appreciate that :)

sorry about this, I added them by mistake, I'll drop..

> >  src/android/thread_rpc.cpp         |  41 ++
> >  src/android/thread_rpc.h           |  56 ++
> >  src/libcamera/meson.build          |  22 +-
> >  src/meson.build                    |   4 +
> >  13 files changed, 1995 insertions(+), 5 deletions(-)
> >  create mode 100644 src/android/camera3_hal.cpp
> >  create mode 100644 src/android/camera_hal_manager.cpp
> >  create mode 100644 src/android/camera_hal_manager.h
> >  create mode 100644 src/android/camera_module.cpp
> >  create mode 100644 src/android/camera_module.h
> >  create mode 100644 src/android/camera_proxy.cpp
> >  create mode 100644 src/android/camera_proxy.h
> >  create mode 100644 src/android/tags
> >  create mode 100644 src/android/thread_rpc.cpp
> >  create mode 100644 src/android/thread_rpc.h
>
> [snip]
>
> > diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
> > index a09b23d60022..9b6e4b769760 100644
> > --- a/src/libcamera/meson.build
> > +++ b/src/libcamera/meson.build
> > @@ -103,11 +103,23 @@ libcamera_deps = [
> >      dependency('threads'),
> >  ]
> >
> > -libcamera = shared_library('camera',
> > -                           libcamera_sources,
> > -                           install : true,
> > -                           include_directories : includes,
> > -                           dependencies : libcamera_deps)
> > +if get_option('android')
> > +    libcamera_sources += android_hal_sources
> > +    includes += android_includes
> > +
> > +    libcamera = shared_library('camera',
> > +                               libcamera_sources,
> > +                               install : true,
> > +                               link_with : android_camera_metadata,
> > +                               include_directories : includes,
> > +                               dependencies : libcamera_deps)
> > +else
> > +    libcamera = shared_library('camera',
> > +                               libcamera_sources,
> > +                               install : true,
> > +                               include_directories : includes,
> > +                               dependencies : libcamera_deps)
> > +endif
>
> Would it be possible to keep a single shared_library statement, with a
> variable for link_with that is declared initially empty, and is updated
> when the android option is set ?

I'll look into improving this!

Thanks
  j
>
> >
> >  libcamera_dep = declare_dependency(sources : [libcamera_api, libcamera_h],
> >                                     include_directories : libcamera_includes,
> > diff --git a/src/meson.build b/src/meson.build
> > index 628e7a7f23f2..67ad20aab86b 100644
> > --- a/src/meson.build
> > +++ b/src/meson.build
> > @@ -1,3 +1,7 @@
> > +if get_option('android')
> > +    subdir('android')
> > +endif
> > +
> >  subdir('libcamera')
> >  subdir('ipa')
> >  subdir('cam')
>
> --
> Regards,
>
> Laurent Pinchart

Patch

diff --git a/src/android/camera3_hal.cpp b/src/android/camera3_hal.cpp
new file mode 100644
index 000000000000..0a97a9333d20
--- /dev/null
+++ b/src/android/camera3_hal.cpp
@@ -0,0 +1,130 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * camera3_hal.cpp - Android Camera3 HAL module
+ */
+
+#include <iostream>
+#include <memory>
+#include <vector>
+
+#include <hardware/hardware.h>
+#include <system/camera_metadata.h>
+
+#include <libcamera/libcamera.h>
+
+#include "log.h"
+
+#include "camera_hal_manager.h"
+#include "camera_module.h"
+#include "camera_proxy.h"
+
+using namespace libcamera;
+
+LOG_DEFINE_CATEGORY(HAL)
+
+static CameraHalManager cameraManager;
+
+/*------------------------------------------------------------------------------
+ * Android Camera HAL callbacks
+ */
+
+static int hal_get_number_of_cameras(void)
+{
+	return cameraManager.numCameras();
+}
+
+static int hal_get_camera_info(int id, struct camera_info *info)
+{
+	return cameraManager.getCameraInfo(id, info);
+}
+
+static int hal_set_callbacks(const camera_module_callbacks_t *callbacks)
+{
+	return 0;
+}
+
+static int hal_open_legacy(const struct hw_module_t *module, const char *id,
+			   uint32_t halVersion, struct hw_device_t **device)
+{
+	return -ENOSYS;
+}
+
+static int hal_set_torch_mode(const char *camera_id, bool enabled)
+{
+	return -ENOSYS;
+}
+
+/*
+ * First entry point of the camera HAL module.
+ *
+ * Initialize the HAL but does not open any camera device yet (see hal_dev_open)
+ */
+static int hal_init()
+{
+	LOG(HAL, Info) << "Initialising Android camera HAL";
+
+	cameraManager.initialize();
+
+	return 0;
+}
+
+/*------------------------------------------------------------------------------
+ * Android Camera Device
+ */
+
+static int hal_dev_close(hw_device_t *hw_device)
+{
+	if (!hw_device)
+		return -EINVAL;
+
+	camera3_device_t *dev = reinterpret_cast<camera3_device_t *>(hw_device);
+	CameraProxy *cameraModule = reinterpret_cast<CameraProxy *>(dev->priv);
+
+	return cameraManager.close(cameraModule);
+}
+
+static int hal_dev_open(const hw_module_t* module, const char* name,
+			hw_device_t** device)
+{
+	LOG(HAL, Debug) << "Open camera: " << name;
+
+	int id = atoi(name);
+	CameraProxy *proxy = cameraManager.open(id, module);
+	if (!proxy) {
+		LOG(HAL, Error) << "Failed to open camera module " << id;
+		return -ENODEV;
+	}
+	proxy->device()->common.close = hal_dev_close;
+	*device = &proxy->device()->common;
+
+	return 0;
+}
+
+static struct hw_module_methods_t hal_module_methods = {
+	.open = hal_dev_open,
+};
+
+camera_module_t HAL_MODULE_INFO_SYM = {
+	.common = {
+		.tag = HARDWARE_MODULE_TAG,
+		.module_api_version = CAMERA_MODULE_API_VERSION_2_4,
+		.hal_api_version = HARDWARE_HAL_API_VERSION,
+		.id = CAMERA_HARDWARE_MODULE_ID,
+		.name = "Libcamera Camera3HAL Module",
+		.author = "libcamera",
+		.methods = &hal_module_methods,
+		.dso = nullptr,
+		.reserved = {},
+	},
+
+	.get_number_of_cameras = hal_get_number_of_cameras,
+	.get_camera_info = hal_get_camera_info,
+	.set_callbacks = hal_set_callbacks,
+	.get_vendor_tag_ops = nullptr,
+	.open_legacy = hal_open_legacy,
+	.set_torch_mode = hal_set_torch_mode,
+	.init = hal_init,
+	.reserved = {},
+};
diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp
new file mode 100644
index 000000000000..734b5eebd9a5
--- /dev/null
+++ b/src/android/camera_hal_manager.cpp
@@ -0,0 +1,173 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * camera_hal_manager.cpp - Libcamera Android Camera Manager
+ */
+
+#include "camera_hal_manager.h"
+
+#include <map>
+
+#include <hardware/hardware.h>
+#include <system/camera_metadata.h>
+
+#include <libcamera/libcamera.h>
+#include <libcamera/camera.h>
+
+#include "log.h"
+
+#include "camera_module.h"
+#include "camera_proxy.h"
+
+using namespace libcamera;
+LOG_DECLARE_CATEGORY(HAL);
+
+CameraHalManager::~CameraHalManager()
+{
+	for (auto metadata : staticMetadataMap_)
+		free_camera_metadata(metadata.second);
+}
+
+int CameraHalManager::initialize()
+{
+	/*
+	 * Thread::start() will create a std::thread which will execute
+	 * CameraHalManager::run()
+	 */
+	start();
+
+	/*
+	 * Wait for run() to notify us before returning to the caller to
+	 * make sure libcamera is fully initialized before we start handling
+	 * calls from the camera stack.
+	 */
+	MutexLocker locker(mutex_);
+	cv_.wait(locker);
+
+	return 0;
+}
+
+void CameraHalManager::run()
+{
+	/*
+	 * The run() operation is scheduled in its own thread;
+	 * It exec() to run the even dispatcher loop and initialize libcamera.
+	 *
+	 * All the libcamera components initialized from here will be tied to
+	 * the same thread as the here below run event dispatcher.
+	 */
+	libcameraManager_ = libcamera::CameraManager::instance();
+
+	int ret = libcameraManager_->start();
+	if (ret) {
+		LOG(HAL, Error) << "Failed to start camera manager: "
+				<< strerror(-ret);
+		return;
+	}
+
+	/*
+	 * For each Camera registered in the system, a CameraModule
+	 * get created here with an associated Camera and a proxy.
+	 *
+	 * \todo Support camera hotplug.
+	 */
+	unsigned int cameraIndex = 0;
+	for (auto camera : libcameraManager_->cameras()) {
+		cameras_.push_back(camera);
+
+		CameraModule *module = new CameraModule(cameraIndex,
+							camera.get());
+		modules_.emplace_back(module);
+
+		CameraProxy *proxy = new CameraProxy(cameraIndex,
+						     module);
+		proxies_.emplace_back(proxy);
+
+		++cameraIndex;
+	}
+
+	/*
+	 * libcamera has been initialized! Unlock the initialize() caller
+	 * as we're now ready to handle calls from the framework.
+	 */
+	cv_.notify_one();
+
+	/* Now start processing events and messages! */
+	exec();
+}
+
+CameraProxy *CameraHalManager::open(unsigned int id,
+				    const hw_module_t *hardwareModule)
+{
+	if (id < 0 || id >= numCameras()) {
+		LOG(HAL, Error) << "Invalid camera id '" << id << "'";
+		return nullptr;
+	}
+
+	CameraProxy *proxy = proxies_[id].get();
+	if (proxy->open(hardwareModule))
+		return proxy;
+
+	LOG(HAL, Info) << "Camera: '" << id << "' opened";
+
+	return proxy;
+}
+
+int CameraHalManager::close(CameraProxy *proxy)
+{
+	proxy->close();
+	LOG(HAL, Info) << "Close camera: " << proxy->id();
+
+	return 0;
+}
+
+unsigned int CameraHalManager::numCameras() const
+{
+	return libcameraManager_->cameras().size();
+}
+
+/*
+ * Before the camera framework even tries to open a camera device with
+ * hal_dev_open() it requires the camera HAL to report a list of static
+ * informations on the camera device with id \a id in the hal_get_camera_info()
+ * method.
+ *
+ * The static metadata should be then generated probably from a
+ * platform-specific module, as we cannot operate on the camera at this time as
+ * it has not yet been open by the framework.
+ *
+ * This is what the Intel XML file is used for, it is parsed and the data there
+ * combined with informations from the PSL service (which I -think- it's what
+ * our IPA is) to generate a list of static metadata per-camera device.
+ */
+int CameraHalManager::getCameraInfo(int id, struct camera_info *info)
+{
+	int cameras = numCameras();
+	if (id >= cameras || id < 0 || !info) {
+		LOG(HAL, Error) << "Invalid camera id: " << id;
+		return -EINVAL;
+	}
+
+	camera_metadata_t *staticMetadata;
+	auto it = staticMetadataMap_.find(id);
+	if (it != staticMetadataMap_.end()) {
+		staticMetadata = it->second;
+	} else {
+		CameraModule *cameraModule = modules_[id].get();
+
+		staticMetadata = cameraModule->getStaticMetadata();
+		staticMetadataMap_[id] = staticMetadata;
+	}
+
+	/* \todo: Get these info dynamically inspecting the camera module. */
+	info->facing = id ? CAMERA_FACING_FRONT : CAMERA_FACING_BACK;
+	info->orientation = 0;
+	info->device_version = 0;
+	info->resource_cost = 0;
+	info->static_camera_characteristics = staticMetadata;
+	info->conflicting_devices = nullptr;
+	info->conflicting_devices_length = 0;
+
+	return 0;
+}
diff --git a/src/android/camera_hal_manager.h b/src/android/camera_hal_manager.h
new file mode 100644
index 000000000000..65d6fa3150ef
--- /dev/null
+++ b/src/android/camera_hal_manager.h
@@ -0,0 +1,56 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * camera_hal_manager.h - Libcamera Android Camera Manager
+ */
+#ifndef __ANDROID_CAMERA_MANAGER_H__
+#define __ANDROID_CAMERA_MANAGER_H__
+
+#include <condition_variable>
+#include <cstddef>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <hardware/hardware.h>
+#include <system/camera_metadata.h>
+
+#include <libcamera/libcamera.h>
+
+#include "thread.h"
+#include "thread_rpc.h"
+
+class CameraModule;
+class CameraProxy;
+
+class CameraHalManager : public libcamera::Thread
+{
+public:
+	~CameraHalManager();
+
+	int initialize();
+
+	CameraProxy *open(unsigned int id, const hw_module_t *module);
+	int close(CameraProxy *proxy);
+
+	unsigned int numCameras() const;
+	int getCameraInfo(int id, struct camera_info *info);
+
+private:
+	void run() override;
+	camera_metadata_t *getStaticMetadata(unsigned int id);
+
+	libcamera::CameraManager *libcameraManager_;
+
+	std::mutex mutex_;
+	std::condition_variable cv_;
+
+	std::vector<std::shared_ptr<libcamera::Camera>> cameras_;
+	std::vector<std::unique_ptr<CameraModule>> modules_;
+	std::vector<std::unique_ptr<CameraProxy>> proxies_;
+
+	std::map<unsigned int, camera_metadata_t *> staticMetadataMap_;
+};
+
+#endif /* __ANDROID_CAMERA_MANAGER_H__ */
diff --git a/src/android/camera_module.cpp b/src/android/camera_module.cpp
new file mode 100644
index 000000000000..1d7e007f62c0
--- /dev/null
+++ b/src/android/camera_module.cpp
@@ -0,0 +1,795 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * camera_module.cpp - Libcamera Android Camera Module
+ */
+
+#include "camera_module.h"
+
+#include <iostream>
+#include <memory>
+
+#include <system/camera_metadata.h>
+
+#include <hardware/camera3.h>
+#include <libcamera/libcamera.h>
+
+#include "message.h"
+
+#include "log.h"
+
+using namespace libcamera;
+
+LOG_DECLARE_CATEGORY(HAL);
+
+CameraModule::CameraModule(unsigned int id, libcamera::Camera *camera)
+	: id_(id), camera_(camera), requestTemplate_(nullptr)
+{
+	camera_->requestCompleted.connect(this,
+					  &CameraModule::requestComplete);
+}
+
+CameraModule::~CameraModule()
+{
+	if (requestTemplate_)
+		free_camera_metadata(requestTemplate_);
+	requestTemplate_ = nullptr;
+}
+
+void CameraModule::message(Message *message)
+{
+	ThreadRpcMessage *rpcMessage = static_cast<ThreadRpcMessage *>
+				       (message);
+
+	if (rpcMessage->type() != ThreadRpcMessage::type())
+		return Object::message(message);
+
+	ThreadRpc *rpc = rpcMessage->rpc;
+
+	switch (rpc->tag) {
+	case ThreadRpc::ProcessCaptureRequest:
+		processCaptureRequest(rpc->request);
+		break;
+	case ThreadRpc::Close:
+		close();
+		break;
+	default:
+		LOG(HAL, Error) << "Unknown RPC operation: " << rpc->tag;
+	}
+
+	rpc->notifyReception();
+}
+
+int CameraModule::open()
+{
+	int ret = camera_->acquire();
+	if (ret) {
+		LOG(HAL, Error) << "Failed to acquire the camera";
+		return ret;
+	}
+
+	return 0;
+}
+
+void CameraModule::close()
+{
+	if (camera_->state() >= CameraRunning)
+		camera_->stop();
+
+	camera_->freeBuffers();
+	camera_->release();
+}
+
+void CameraModule::setCallbacks(const struct camera3_device *camera3Device,
+				const camera3_callback_ops_t *callbacks)
+{
+	camera3Device_ = camera3Device;
+	callbacks_ = callbacks;
+}
+
+camera_metadata_t *CameraModule::getStaticMetadata()
+{
+	int ret;
+
+	/*
+	 * The below metadata has been added by inspecting the Intel XML
+	 * file and it's associated parsing routines in the Intel IPU3 HAL.
+	 *
+	 * The here below metadata are enough to satisfy the camera3-test
+	 * provided by ChromeOS, but a real camera implementation might require
+	 * more.
+	 *
+	 * See CameraConf::AiqConf class implementation in the Intel HAL
+	 * to get a list of the static metadata registered by parsing the
+	 * XML config file in AiqConf::fillStaticMetadataFromCMC
+	 */
+
+	/*
+	 * FIXME: this sizes come from the Intel IPU3 HAL, and are way too large for
+	 * this intial HAL version.
+	 */
+	#define STATIC_ENTRY_CAP 256
+	#define STATIC_DATA_CAP 6688
+	camera_metadata_t *staticMetadata =
+		allocate_camera_metadata(STATIC_ENTRY_CAP, STATIC_DATA_CAP);
+
+	/* Sensor static metadata. */
+	int32_t pixelArraySize[] = {
+		2592, 1944,
+	};
+	ret = add_camera_metadata_entry(staticMetadata,
+				ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
+				&pixelArraySize, 2);
+	METADATA_ASSERT(ret);
+
+	int32_t sensorSizes[] = {
+		0, 0, 2560, 1920,
+	};
+	ret = add_camera_metadata_entry(staticMetadata,
+				ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
+				&sensorSizes, 4);
+	METADATA_ASSERT(ret);
+
+	int32_t sensitivityRange[] = {
+		32, 2400,
+	};
+	ret = add_camera_metadata_entry(staticMetadata,
+				ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
+				&sensitivityRange, 2);
+	METADATA_ASSERT(ret);
+
+	uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;
+	ret = add_camera_metadata_entry(staticMetadata,
+				ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
+				&filterArr, 1);
+	METADATA_ASSERT(ret);
+
+	int64_t exposureTimeRange[] = {
+		100000, 200000000,
+	};
+	ret = add_camera_metadata_entry(staticMetadata,
+				ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
+				&exposureTimeRange, 2);
+	METADATA_ASSERT(ret);
+
+	int32_t orientation = 0;
+	ret = add_camera_metadata_entry(staticMetadata,
+				ANDROID_SENSOR_ORIENTATION,
+				&orientation, 1);
+	METADATA_ASSERT(ret);
+
+	/* Flash static metadata. */
+	char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
+	ret = add_camera_metadata_entry(staticMetadata,
+			ANDROID_FLASH_INFO_AVAILABLE,
+			&flashAvailable, 1);
+	METADATA_ASSERT(ret);
+
+	/* Lens static metadata. */
+	float fn = 2.53 / 100;
+	ret = add_camera_metadata_entry(staticMetadata,
+				ANDROID_LENS_INFO_AVAILABLE_APERTURES, &fn, 1);
+	METADATA_ASSERT(ret);
+
+	/* Control metadata. */
+	char controlMetadata = ANDROID_CONTROL_MODE_AUTO;
+	ret = add_camera_metadata_entry(staticMetadata,
+			ANDROID_CONTROL_AVAILABLE_MODES,
+			&controlMetadata, 1);
+	METADATA_ASSERT(ret);
+
+	char availableAntiBandingModes[] = {
+		ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
+		ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
+		ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
+		ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
+	};
+	ret = add_camera_metadata_entry(staticMetadata,
+			ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
+			availableAntiBandingModes, 4);
+	METADATA_ASSERT(ret);
+
+	char aeAvailableModes[] = {
+		ANDROID_CONTROL_AE_MODE_ON,
+		ANDROID_CONTROL_AE_MODE_OFF,
+	};
+	ret = add_camera_metadata_entry(staticMetadata,
+			ANDROID_CONTROL_AE_AVAILABLE_MODES,
+			aeAvailableModes, 2);
+	METADATA_ASSERT(ret);
+
+	controlMetadata = ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE;
+	ret = add_camera_metadata_entry(staticMetadata,
+			ANDROID_CONTROL_AE_LOCK_AVAILABLE,
+			&controlMetadata, 1);
+	METADATA_ASSERT(ret);
+
+	uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
+	ret = add_camera_metadata_entry(staticMetadata,
+			ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
+			&awbLockAvailable, 1);
+
+	/* Scaler static metadata. */
+	std::vector<uint32_t> availableStreamFormats = {
+		ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
+		ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
+		ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
+	};
+	ret = add_camera_metadata_entry(staticMetadata,
+			ANDROID_SCALER_AVAILABLE_FORMATS,
+			availableStreamFormats.data(),
+			availableStreamFormats.size());
+	METADATA_ASSERT(ret);
+
+	std::vector<uint32_t> availableStreamConfigurations = {
+		ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920,
+		ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+		ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888, 2560, 1920,
+		ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+		ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED, 2560, 1920,
+		ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+	};
+	ret = add_camera_metadata_entry(staticMetadata,
+			ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+			availableStreamConfigurations.data(),
+			availableStreamConfigurations.size());
+	METADATA_ASSERT(ret);
+
+	std::vector<int64_t> availableStallDurations = {
+		ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
+	};
+	ret = add_camera_metadata_entry(staticMetadata,
+			ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
+			availableStallDurations.data(),
+			availableStallDurations.size());
+	METADATA_ASSERT(ret);
+
+	std::vector<int64_t> minFrameDurations = {
+		ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
+		ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED, 2560, 1920, 33333333,
+		ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888, 2560, 1920, 33333333,
+	};
+	ret = add_camera_metadata_entry(staticMetadata,
+			ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
+			minFrameDurations.data(), minFrameDurations.size());
+	METADATA_ASSERT(ret);
+
+	/* Info static metadata. */
+	uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
+	ret = add_camera_metadata_entry(staticMetadata,
+			ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
+			&supportedHWLevel, 1);
+
+	return staticMetadata;
+}
+
+const camera_metadata_t *CameraModule::constructDefaultRequestMetadata(int type)
+{
+	int ret;
+
+	/*
+	 * TODO: inspect type and pick the right metadata pack.
+	 * As of now just use a single one for all templates
+	 */
+	uint8_t captureIntent;
+	switch (type) {
+	case CAMERA3_TEMPLATE_PREVIEW:
+		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
+		break;
+	case CAMERA3_TEMPLATE_STILL_CAPTURE:
+		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
+		break;
+	case CAMERA3_TEMPLATE_VIDEO_RECORD:
+		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
+		break;
+	case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
+		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
+		break;
+	case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
+		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
+		break;
+	case CAMERA3_TEMPLATE_MANUAL:
+		captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
+		break;
+	default:
+		LOG(HAL, Error) << "Invalid template request type: " << type;
+		return nullptr;
+	}
+
+	if (requestTemplate_)
+		return requestTemplate_;
+
+	/* FIXME: this sizes are quite arbitrary ones */
+	#define REQUEST_TEMPLATE_ENTRIES	  30
+	#define REQUEST_TEMPLATE_DATA		2048
+	requestTemplate_ = allocate_camera_metadata(REQUEST_TEMPLATE_ENTRIES,
+						    REQUEST_TEMPLATE_DATA);
+	if (!requestTemplate_) {
+		LOG(HAL, Error) << "Failed to allocate template metadata";
+		return nullptr;
+	}
+
+	/*
+	 * Fill in the required Request metadata.
+	 *
+	 * Part (most?) of this entries comes from inspecting the Intel's IPU3
+	 * HAL xml configuration file.
+	 */
+
+	/* Set to 0 the number of 'processed and stalling' streams (ie JPEG). */
+	int32_t maxOutStream[] = { 0, 2, 0 };
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
+			maxOutStream, 3);
+	METADATA_ASSERT(ret);
+
+	uint8_t maxPipelineDepth = 5;
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
+			&maxPipelineDepth, 1);
+	METADATA_ASSERT(ret);
+
+	int32_t inputStreams = 0;
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
+			&inputStreams, 1);
+	METADATA_ASSERT(ret);
+
+	int32_t partialResultCount = 1;
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
+			&partialResultCount, 1);
+	METADATA_ASSERT(ret);
+
+	uint8_t availableCapabilities[] = {
+		ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
+	};
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
+			availableCapabilities, 1);
+	METADATA_ASSERT(ret);
+
+	uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_CONTROL_AE_MODE,
+			&aeMode, 1);
+	METADATA_ASSERT(ret);
+
+	int32_t aeExposureCompensation = 0;
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+			&aeExposureCompensation, 1);
+	METADATA_ASSERT(ret);
+
+	uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
+			&aePrecaptureTrigger, 1);
+	METADATA_ASSERT(ret);
+
+	uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_CONTROL_AE_LOCK,
+			&aeLock, 1);
+	METADATA_ASSERT(ret);
+
+	uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_CONTROL_AF_TRIGGER,
+			&afTrigger, 1);
+	METADATA_ASSERT(ret);
+
+	uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_CONTROL_AWB_MODE,
+			&awbMode, 1);
+	METADATA_ASSERT(ret);
+
+	uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_CONTROL_AWB_LOCK,
+			&awbLock, 1);
+	METADATA_ASSERT(ret);
+
+	uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
+			&awbLockAvailable, 1);
+	METADATA_ASSERT(ret);
+
+	uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_FLASH_MODE,
+			&flashMode, 1);
+	METADATA_ASSERT(ret);
+
+	uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_STATISTICS_FACE_DETECT_MODE,
+			&faceDetectMode, 1);
+	METADATA_ASSERT(ret);
+
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_CONTROL_CAPTURE_INTENT,
+			&captureIntent, 1);
+	METADATA_ASSERT(ret);
+
+	/*
+	 * This is quite hard to list at the moment wihtout knowing what
+	 * we could control.
+	 *
+	 * For now, just list in the available Request keys and in the available
+	 * result keys the control and reporting of the AE algorithm.
+	 */
+	std::vector<int32_t> availableRequestKeys = {
+		ANDROID_CONTROL_AE_MODE,
+		ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+		ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
+		ANDROID_CONTROL_AE_LOCK,
+		ANDROID_CONTROL_AF_TRIGGER,
+		ANDROID_CONTROL_AWB_MODE,
+		ANDROID_CONTROL_AWB_LOCK,
+		ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
+		ANDROID_CONTROL_CAPTURE_INTENT,
+		ANDROID_FLASH_MODE,
+		ANDROID_STATISTICS_FACE_DETECT_MODE,
+	};
+
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
+			availableRequestKeys.data(),
+			availableRequestKeys.size());
+	METADATA_ASSERT(ret);
+
+	std::vector<int32_t> availableResultKeys = {
+		ANDROID_CONTROL_AE_MODE,
+		ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+		ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
+		ANDROID_CONTROL_AE_LOCK,
+		ANDROID_CONTROL_AF_TRIGGER,
+		ANDROID_CONTROL_AWB_MODE,
+		ANDROID_CONTROL_AWB_LOCK,
+		ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
+		ANDROID_CONTROL_CAPTURE_INTENT,
+		ANDROID_FLASH_MODE,
+		ANDROID_STATISTICS_FACE_DETECT_MODE,
+	};
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
+			availableResultKeys.data(),
+			availableResultKeys.size());
+	METADATA_ASSERT(ret);
+
+	/*
+	 * The available characteristics should be the tags reported
+	 * as part of the static metadata reported at hal_get_camera_info()
+	 * time. The xml file sets those to 0 though.
+	 */
+	std::vector<int32_t> availableCharacteristicsKeys = {};
+	ret = add_camera_metadata_entry(requestTemplate_,
+			ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
+			availableCharacteristicsKeys.data(),
+			availableCharacteristicsKeys.size());
+	METADATA_ASSERT(ret);
+
+	return requestTemplate_;
+}
+
+/**
+ * Inspect the stream_list to produce a list of StreamConfiguration to
+ * be use to configure the Camera.
+ */
+int CameraModule::configureStreams(camera3_stream_configuration_t *stream_list)
+{
+
+	for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
+		camera3_stream_t *stream = stream_list->streams[i];
+
+		LOG(HAL, Info) << "Stream #" << i
+			       << ": direction: " << stream->stream_type
+			       << " - width: " << stream->width
+			       << " - height: " << stream->height
+			       << " - format: " << std::hex << stream->format;
+	}
+
+	/* Hardcode viewfinder role, collecting sizes from the stream config. */
+	if (stream_list->num_streams != 1) {
+		LOG(HAL, Error) << "Only one stream supported";
+		return -EINVAL;
+	}
+
+	StreamRoles roles = {};
+	roles.push_back(StreamRole::StillCapture);
+
+	config_ = camera_->generateConfiguration(roles);
+	if (!config_ || config_->empty()) {
+		LOG(HAL, Error) << "Failed to generate camera configuration";
+		return -EINVAL;
+	}
+
+	/* Only one stream is supported. */
+	camera3_stream_t *camera3Stream = stream_list->streams[0];
+	StreamConfiguration *streamConfiguration = &config_->at(0);
+	streamConfiguration->size.width = camera3Stream->width;
+	streamConfiguration->size.height = camera3Stream->height;
+	streamConfiguration->memoryType = ExternalMemory;
+
+	/*
+	 * FIXME: do not change the pixel format from the one returned
+	 * from the Camera::generateConfiguration();
+	 *
+	 * We'll need to translate from Android defined pixel format codes
+	 * to whatever libcamera will use.
+	 */
+
+	switch (config_->validate()) {
+	case CameraConfiguration::Valid:
+		break;
+	case CameraConfiguration::Adjusted:
+		LOG(HAL, Info) << "Camera configuration adjusted";
+		return -EINVAL;
+	case CameraConfiguration::Invalid:
+		LOG(HAL, Info) << "Camera configuration invalid";
+		config_.reset();
+		return -EINVAL;
+	}
+
+	camera3Stream->max_buffers = streamConfiguration->bufferCount;
+
+	/*
+	 * Once the CameraConfiguration has been adjusted/validated
+	 * it can be applied to the camera.
+	 */
+	int ret = camera_->configure(config_.get());
+	if (ret) {
+		LOG(HAL, Error) << "Failed to configure camera '"
+				<< camera_->name() << "'";
+		return ret;
+	}
+
+	return 0;
+}
+
+int CameraModule::processCaptureRequest(camera3_capture_request_t *camera3Request)
+{
+	StreamConfiguration *streamConfiguration = &config_->at(0);
+	Stream *stream = streamConfiguration->stream();
+
+	if (camera3Request->num_output_buffers != 1) {
+		LOG(HAL, Error) << "Invalid number of output buffers: "
+				<< camera3Request->num_output_buffers;
+		return -EINVAL;
+	}
+
+	/* Start the camera if that's the first request we handle. */
+	if (camera_->state() < CameraRunning) {
+		int ret = camera_->allocateBuffers();
+		if (ret) {
+			LOG(HAL, Error) << "Failed to allocate buffers";
+			return ret;
+		}
+
+		ret = camera_->start();
+		if (ret) {
+			LOG(HAL, Error) << "Failed to start camera";
+			camera_->freeBuffers();
+			return ret;
+		}
+	}
+
+	/*
+	 * Queue a request for the Camera with the provided dmabuf file
+	 * descriptors.
+	 */
+	const camera3_stream_buffer_t *camera3Buffer =
+					&camera3Request->output_buffers[0];
+	const buffer_handle_t camera3Handle = *camera3Buffer->buffer;
+
+	std::array<int, 3> fds = {
+		camera3Handle->data[0],
+		camera3Handle->data[1],
+		camera3Handle->data[2],
+	};
+	std::unique_ptr<Buffer> buffer = stream->createBuffer(fds);
+	if (!buffer) {
+		LOG(HAL, Error) << "Failed to create buffer";
+		return -EINVAL;
+	}
+
+	Request *request = camera_->createRequest();
+	request->addBuffer(std::move(buffer));
+	int ret = camera_->queueRequest(request);
+	if (ret) {
+		LOG(HAL, Error) << "Failed to queue request";
+		return ret;
+	}
+
+	/* Save the request descriptors for use at completion time. */
+	Camera3RequestDescriptor descriptor = {};
+	descriptor.frameNumber = camera3Request->frame_number,
+	descriptor.numBuffers = camera3Request->num_output_buffers,
+	descriptor.buffers = new camera3_stream_buffer_t[descriptor.numBuffers];
+	for (unsigned int i = 0; i < descriptor.numBuffers; ++i) {
+		camera3_stream_buffer_t &buffer = descriptor.buffers[i];
+		buffer = camera3Request->output_buffers[i];
+	}
+
+	requestMap_[request] = descriptor;
+
+	return 0;
+}
+
+void CameraModule::requestComplete(Request *request,
+				   const std::map<Stream *, Buffer *> &buffers)
+{
+	Buffer *libcameraBuffer = buffers.begin()->second;
+	camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
+	camera_metadata_t *resultMetadata = nullptr;
+
+	if (request->status() != Request::RequestComplete) {
+		LOG(HAL, Error) << "Request not succesfully completed: "
+				<< request->status();
+		status = CAMERA3_BUFFER_STATUS_ERROR;
+	}
+
+	/* Prepare to call back the Android camera stack. */
+	Camera3RequestDescriptor &descriptor = requestMap_[request];
+
+	camera3_capture_result_t captureResult = {};
+	captureResult.frame_number = descriptor.frameNumber;
+	captureResult.num_output_buffers = descriptor.numBuffers;
+
+	camera3_stream_buffer_t *resultBuffers =
+		new camera3_stream_buffer_t[descriptor.numBuffers];
+	for (unsigned int i = 0; i < descriptor.numBuffers; ++i) {
+		camera3_stream_buffer_t resultBuffer;
+
+		resultBuffer = descriptor.buffers[i];
+		resultBuffer.acquire_fence = -1;
+		resultBuffer.release_fence = -1;
+		resultBuffer.status = status;
+
+		resultBuffers[i] = resultBuffer;
+	}
+	captureResult.output_buffers =
+		const_cast<const camera3_stream_buffer_t *>(resultBuffers);
+
+	if (status == CAMERA3_BUFFER_STATUS_ERROR) {
+		/* \todo Improve error handling. */
+		notifyError(descriptor.frameNumber, resultBuffers->stream);
+	} else {
+		notifyShutter(descriptor.frameNumber, libcameraBuffer->timestamp());
+
+		captureResult.partial_result = 1;
+		resultMetadata = getResultMetadata(descriptor.frameNumber,
+						   libcameraBuffer->timestamp());
+		captureResult.result = resultMetadata;
+	}
+
+	callbacks_->process_capture_result(callbacks_, &captureResult);
+
+	if (resultMetadata)
+		free_camera_metadata(resultMetadata);
+
+	delete[] resultBuffers;
+	delete[] descriptor.buffers;
+	requestMap_.erase(request);
+
+	return;
+}
+
+void CameraModule::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
+{
+	camera3_notify_msg_t notify = {};
+
+	notify.type = CAMERA3_MSG_SHUTTER;
+	notify.message.shutter.frame_number = frameNumber;
+	notify.message.shutter.timestamp = timestamp;
+
+	callbacks_->notify(callbacks_, &notify);
+}
+
+void CameraModule::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
+{
+	camera3_notify_msg_t notify = {};
+
+	notify.type = CAMERA3_MSG_ERROR;
+	notify.message.error.error_stream = stream;
+	notify.message.error.frame_number = frameNumber;
+	notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
+
+	callbacks_->notify(callbacks_, &notify);
+}
+
+/*
+ * Fixed result metadata, mostly imported from the UVC camera HAL, which
+ * does not produces metadata and thus needs to generate a fixed set.
+ */
+camera_metadata_t *CameraModule::getResultMetadata(int frame_number,
+						   int64_t timestamp)
+{
+	int ret;
+
+	/* FIXME: random "big enough" values. */
+	#define RESULT_ENTRY_CAP 256
+	#define RESULT_DATA_CAP 6688
+	camera_metadata_t *resultMetadata =
+		allocate_camera_metadata(STATIC_ENTRY_CAP, STATIC_DATA_CAP);
+
+	const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
+	ret = add_camera_metadata_entry(resultMetadata, ANDROID_CONTROL_AE_STATE,
+					&ae_state, 1);
+	METADATA_ASSERT(ret);
+
+	const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
+	ret = add_camera_metadata_entry(resultMetadata, ANDROID_CONTROL_AE_LOCK,
+					&ae_lock, 1);
+	METADATA_ASSERT(ret);
+
+	uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
+	ret = add_camera_metadata_entry(resultMetadata, ANDROID_CONTROL_AF_STATE,
+					&af_state, 1);
+	METADATA_ASSERT(ret);
+
+	const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
+	ret = add_camera_metadata_entry(resultMetadata,
+					ANDROID_CONTROL_AWB_STATE,
+					&awb_state, 1);
+	METADATA_ASSERT(ret);
+
+	const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
+	ret = add_camera_metadata_entry(resultMetadata,
+					ANDROID_CONTROL_AWB_LOCK,
+					&awb_lock, 1);
+	METADATA_ASSERT(ret);
+
+	const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
+	ret = add_camera_metadata_entry(resultMetadata,
+					ANDROID_LENS_STATE,
+					&lens_state, 1);
+	METADATA_ASSERT(ret);
+
+	int32_t sensorSizes[] = {
+		0, 0, 2560, 1920,
+	};
+	ret = add_camera_metadata_entry(resultMetadata,
+					ANDROID_SCALER_CROP_REGION,
+					sensorSizes, 4);
+	METADATA_ASSERT(ret);
+
+	ret = add_camera_metadata_entry(resultMetadata,
+					ANDROID_SENSOR_TIMESTAMP,
+					&timestamp, 1);
+
+	METADATA_ASSERT(ret);
+
+	/* 33.3 msec */
+	const int64_t rolling_shutter_skew = 33300000;
+	ret = add_camera_metadata_entry(resultMetadata,
+					ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
+					&rolling_shutter_skew, 1);
+	METADATA_ASSERT(ret);
+
+	/* 16.6 msec */
+	const int64_t exposure_time = 16600000;
+	ret = add_camera_metadata_entry(resultMetadata,
+					ANDROID_SENSOR_EXPOSURE_TIME,
+					&exposure_time, 1);
+	METADATA_ASSERT(ret);
+
+	const uint8_t lens_shading_map_mode =
+				ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
+	ret = add_camera_metadata_entry(resultMetadata,
+					ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
+					&lens_shading_map_mode, 1);
+	METADATA_ASSERT(ret);
+
+	const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
+	ret = add_camera_metadata_entry(resultMetadata,
+					ANDROID_STATISTICS_SCENE_FLICKER,
+					&scene_flicker, 1);
+	METADATA_ASSERT(ret);
+
+	return resultMetadata;
+}
diff --git a/src/android/camera_module.h b/src/android/camera_module.h
new file mode 100644
index 000000000000..c33fde590cdc
--- /dev/null
+++ b/src/android/camera_module.h
@@ -0,0 +1,69 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * camera_module.h - Libcamera Android Camera Module
+ */
+#ifndef __ANDROID_CAMERA_MODULE_H__
+#define __ANDROID_CAMERA_MODULE_H__
+
+#include <memory>
+
+#include <hardware/camera3.h>
+#include <libcamera/libcamera.h>
+
+#include "message.h"
+
+#include "camera_hal_manager.h"
+
+#define METADATA_ASSERT(_r)		\
+	do {				\
+		if (!(_r)) break;	\
+		LOG(HAL, Error) << "Error: " << __func__ << ":" << __LINE__; \
+		return nullptr;		\
+	} while(0);
+
+class CameraModule : public libcamera::Object
+{
+public:
+	CameraModule(unsigned int id, libcamera::Camera *camera);
+	~CameraModule();
+
+	void message(libcamera::Message *message);
+
+	int open();
+	void close();
+	void setCallbacks(const struct camera3_device *cameraDevice,
+			  const camera3_callback_ops_t *callbacks);
+	camera_metadata_t *getStaticMetadata();
+	const camera_metadata_t *constructDefaultRequestMetadata(int type);
+	int configureStreams(camera3_stream_configuration_t *stream_list);
+	int processCaptureRequest(camera3_capture_request_t *request);
+	void requestComplete(libcamera::Request *request,
+			     const std::map<libcamera::Stream *, libcamera::Buffer *> &buffers);
+
+	unsigned int id() const { return id_; }
+
+private:
+	struct Camera3RequestDescriptor {
+		uint32_t frameNumber;
+		uint32_t numBuffers;
+		camera3_stream_buffer_t *buffers;
+	};
+
+	void notifyShutter(uint32_t frameNumber, uint64_t timestamp);
+	void notifyError(uint32_t frameNumber, camera3_stream_t *stream);
+	camera_metadata_t *getResultMetadata(int frame_number, int64_t timestamp);
+
+	unsigned int id_;
+	libcamera::Camera *camera_;
+	std::unique_ptr<libcamera::CameraConfiguration> config_;
+
+	camera_metadata_t *requestTemplate_;
+	const camera3_callback_ops_t *callbacks_;
+	const struct camera3_device *camera3Device_;
+
+	std::map<libcamera::Request *, Camera3RequestDescriptor> requestMap_;
+};
+
+#endif /* __ANDROID_CAMERA_MODULE_H__ */
diff --git a/src/android/camera_proxy.cpp b/src/android/camera_proxy.cpp
new file mode 100644
index 000000000000..af7817f29137
--- /dev/null
+++ b/src/android/camera_proxy.cpp
@@ -0,0 +1,181 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * camera_proxy.cpp - Proxy to camera module instances
+ */
+
+#include "camera_proxy.h"
+
+#include <hardware/camera3.h>
+#include <libcamera/libcamera.h>
+#include <system/camera_metadata.h>
+
+#include <memory>
+
+#include "log.h"
+#include "message.h"
+#include "thread_rpc.h"
+#include "utils.h"
+
+using namespace libcamera;
+
+LOG_DECLARE_CATEGORY(HAL);
+
+#define LIBCAMERA_HAL_FUNC_DBG	\
+	LOG(HAL, Debug);
+
+static int hal_dev_initialize(const struct camera3_device *dev,
+			      const camera3_callback_ops_t *callback_ops)
+{
+	LIBCAMERA_HAL_FUNC_DBG
+
+	if (!dev)
+		return -EINVAL;
+
+	CameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);
+	proxy->setCallbacks(callback_ops);
+
+	return 0;
+}
+
+static int hal_dev_configure_streams(const struct camera3_device *dev,
+				     camera3_stream_configuration_t *stream_list)
+{
+	LIBCAMERA_HAL_FUNC_DBG
+
+	if (!dev)
+		return -EINVAL;
+
+	CameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);
+	proxy->configureStreams(stream_list);
+
+	return 0;
+}
+
+static const camera_metadata_t *
+hal_dev_construct_default_request_settings(const struct camera3_device *dev,
+					   int type)
+{
+	LIBCAMERA_HAL_FUNC_DBG
+
+	if (!dev)
+		return nullptr;
+
+	CameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);
+	return proxy->constructDefaultRequest(type);
+}
+
+static int hal_dev_process_capture_request(const struct camera3_device *dev,
+					   camera3_capture_request_t *request)
+{
+	LIBCAMERA_HAL_FUNC_DBG
+
+	if (!dev)
+		return -EINVAL;
+
+	CameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);
+	return proxy->processCaptureRequest(request);
+}
+
+static void hal_dev_dump(const struct camera3_device *dev, int fd)
+{
+	LIBCAMERA_HAL_FUNC_DBG
+}
+
+static int hal_dev_flush(const struct camera3_device *dev)
+{
+	LIBCAMERA_HAL_FUNC_DBG
+
+	return 0;
+}
+
+static camera3_device_ops hal_dev_ops = {
+	.initialize = hal_dev_initialize,
+	.configure_streams = hal_dev_configure_streams,
+	.register_stream_buffers = nullptr,
+	.construct_default_request_settings = hal_dev_construct_default_request_settings,
+	.process_capture_request = hal_dev_process_capture_request,
+	.get_metadata_vendor_tag_ops = nullptr,
+	.dump = hal_dev_dump,
+	.flush = hal_dev_flush,
+	.reserved = { 0 },
+};
+
+CameraProxy::CameraProxy(unsigned int id, CameraModule *cameraModule)
+	: open_(false), id_(id), cameraModule_(cameraModule)
+{
+}
+
+int CameraProxy::open(const hw_module_t *hardwareModule)
+{
+	int ret = cameraModule_->open();
+	if (ret)
+		return ret;
+
+	/* Initialize the hw_device_t in the instance camera3_module_t. */
+	cameraDevice_.common.tag = HARDWARE_DEVICE_TAG;
+	cameraDevice_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
+	cameraDevice_.common.module = (hw_module_t *)hardwareModule;
+
+	/*
+	 * The camera device operations. These actually implement
+	 * the Android Camera HALv3 interface.
+	 */
+	cameraDevice_.ops = &hal_dev_ops;
+	cameraDevice_.priv = this;
+
+	open_ = true;
+
+	return 0;
+}
+
+void CameraProxy::close()
+{
+	LIBCAMERA_HAL_FUNC_DBG
+
+	ThreadRpc rpcRequest;
+	rpcRequest.tag = ThreadRpc::Close;
+
+	threadRpcCall(rpcRequest);
+
+	open_ = false;
+}
+
+void CameraProxy::setCallbacks(const camera3_callback_ops_t *callbacks)
+{
+	LIBCAMERA_HAL_FUNC_DBG
+
+	cameraModule_->setCallbacks(&cameraDevice_, callbacks);
+}
+
+const camera_metadata_t *CameraProxy::constructDefaultRequest(int type)
+{
+	return cameraModule_->constructDefaultRequestMetadata(type);
+}
+
+int CameraProxy::configureStreams(camera3_stream_configuration_t *stream_list)
+{
+	return cameraModule_->configureStreams(stream_list);
+}
+
+int CameraProxy::processCaptureRequest(camera3_capture_request_t *request)
+{
+	ThreadRpc rpcRequest;
+	rpcRequest.tag = ThreadRpc::ProcessCaptureRequest;
+	rpcRequest.request = request;
+
+	threadRpcCall(rpcRequest);
+
+	return 0;
+}
+
+void CameraProxy::threadRpcCall(ThreadRpc &rpcRequest)
+{
+	std::unique_ptr<ThreadRpcMessage> message =
+				utils::make_unique<ThreadRpcMessage>();
+	message->rpc = &rpcRequest;
+
+	cameraModule_->postMessage(std::move(message));
+	rpcRequest.waitDelivery();
+}
diff --git a/src/android/camera_proxy.h b/src/android/camera_proxy.h
new file mode 100644
index 000000000000..69e6878c4352
--- /dev/null
+++ b/src/android/camera_proxy.h
@@ -0,0 +1,41 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * camera_proxy.h - Proxy to camera module instances
+ */
+#ifndef __ANDROID_CAMERA_PROXY_H__
+#define __ANDROID_CAMERA_PROXY_H__
+
+#include <hardware/camera3.h>
+#include <libcamera/libcamera.h>
+
+#include "camera_module.h"
+
+class CameraProxy
+{
+public:
+	CameraProxy(unsigned int id, CameraModule *cameraModule);
+
+	int open(const hw_module_t *hardwareModule);
+	void close();
+
+	void setCallbacks(const camera3_callback_ops_t *callbacks);
+	const camera_metadata_t *constructDefaultRequest(int type);
+	int configureStreams(camera3_stream_configuration_t *stream_list);
+	int processCaptureRequest(camera3_capture_request_t *request);
+
+	bool isOpen() const { return open_; }
+	unsigned int id() const { return id_; }
+	camera3_device_t *device() { return &cameraDevice_; }
+
+private:
+	void threadRpcCall(ThreadRpc &rpcRequest);
+
+	bool open_;
+	unsigned int id_;
+	CameraModule *cameraModule_;
+	camera3_device_t cameraDevice_;
+};
+
+#endif /* __ANDROID_CAMERA_PROXY_H__ */
diff --git a/src/android/meson.build b/src/android/meson.build
index e988dfa9ee63..eb0b6fce39da 100644
--- a/src/android/meson.build
+++ b/src/android/meson.build
@@ -1,3 +1,11 @@ 
+android_hal_sources = files([
+    'camera3_hal.cpp',
+    'camera_hal_manager.cpp',
+    'camera_module.cpp',
+    'camera_proxy.cpp',
+    'thread_rpc.cpp'
+])
+
 android_camera_metadata_sources = files([
     'metadata/camera_metadata.c',
 ])
diff --git a/src/android/tags b/src/android/tags
new file mode 100644
index 000000000000..0ef3ad649604
--- /dev/null
+++ b/src/android/tags
@@ -0,0 +1,424 @@ 
+!_TAG_FILE_FORMAT	2	/extended format; --format=1 will not append ;" to lines/
+!_TAG_FILE_SORTED	1	/0=unsorted, 1=sorted, 2=foldcase/
+!_TAG_OUTPUT_MODE	u-ctags	/u-ctags or e-ctags/
+!_TAG_PROGRAM_AUTHOR	Universal Ctags Team	//
+!_TAG_PROGRAM_NAME	Universal Ctags	/Derived from Exuberant Ctags/
+!_TAG_PROGRAM_URL	https://ctags.io/	/official site/
+!_TAG_PROGRAM_VERSION	0.0.0	/3fdf28bc/
+ALIGN_TO	metadata/camera_metadata.c	/^#define ALIGN_TO(/;"	d	file:	signature:(val,alignment)
+ALOGE	metadata/camera_metadata.c	/^#define ALOGE(/;"	d	file:	signature:(...)
+CAMERA_METADATA_ENUM_STRING_MAX_SIZE	metadata/camera_metadata_tag_info.c	/^#define CAMERA_METADATA_ENUM_STRING_MAX_SIZE /;"	d	file:
+CURRENT_METADATA_VERSION	metadata/camera_metadata.c	/^#define CURRENT_METADATA_VERSION /;"	d	file:
+CameraModule	camera_module.cpp	/^CameraModule::CameraModule(unsigned int id, const hw_module_t *module,$/;"	f	class:CameraModule	signature:(unsigned int id,const hw_module_t * module,CameraManager * cameraManager)
+CameraModule	camera_module.h	/^	CameraModule(unsigned int id, const hw_module_t *module,$/;"	p	class:CameraModule	access:public	signature:(unsigned int id,const hw_module_t * module,libcamera::CameraManager * cameraManager)
+CameraModule	camera_module.h	/^class CameraModule : public libcamera::Thread$/;"	c	inherits:libcamera::Thread
+CameraModule::CameraModule	camera_module.cpp	/^CameraModule::CameraModule(unsigned int id, const hw_module_t *module,$/;"	f	class:CameraModule	signature:(unsigned int id,const hw_module_t * module,CameraManager * cameraManager)
+CameraModule::CameraModule	camera_module.h	/^	CameraModule(unsigned int id, const hw_module_t *module,$/;"	p	class:CameraModule	access:public	signature:(unsigned int id,const hw_module_t * module,libcamera::CameraManager * cameraManager)
+CameraModule::callbacks_	camera_module.h	/^	const camera3_callback_ops_t *callbacks_;$/;"	m	class:CameraModule	typeref:typename:const camera3_callback_ops_t *	access:private
+CameraModule::cameraDevice	camera_module.h	/^	camera3_device_t *cameraDevice() { return &cameraDevice_; }$/;"	f	class:CameraModule	typeref:typename:camera3_device_t *	access:public	signature:()
+CameraModule::cameraDevice_	camera_module.h	/^	camera3_device_t cameraDevice_;$/;"	m	class:CameraModule	typeref:typename:camera3_device_t	access:private
+CameraModule::cameraManager_	camera_module.h	/^	libcamera::CameraManager *cameraManager_;$/;"	m	class:CameraModule	typeref:typename:libcamera::CameraManager *	access:private
+CameraModule::camera_	camera_module.h	/^	std::shared_ptr<libcamera::Camera> camera_;$/;"	m	class:CameraModule	typeref:typename:std::shared_ptr<libcamera::Camera>	access:private
+CameraModule::close	camera_module.cpp	/^void CameraModule::close()$/;"	f	class:CameraModule	typeref:typename:void	signature:()
+CameraModule::close	camera_module.h	/^	void close();$/;"	p	class:CameraModule	typeref:typename:void	access:public	signature:()
+CameraModule::config_	camera_module.h	/^	std::unique_ptr<libcamera::CameraConfiguration> config_;$/;"	m	class:CameraModule	typeref:typename:std::unique_ptr<libcamera::CameraConfiguration>	access:private
+CameraModule::configureStreams	camera_module.cpp	/^int CameraModule::configureStreams(camera3_stream_configuration_t *stream_list)$/;"	f	class:CameraModule	typeref:typename:int	signature:(camera3_stream_configuration_t * stream_list)
+CameraModule::configureStreams	camera_module.h	/^	int configureStreams(camera3_stream_configuration_t *stream_list);$/;"	p	class:CameraModule	typeref:typename:int	access:public	signature:(camera3_stream_configuration_t * stream_list)
+CameraModule::generateDefaultRequestMetadata	camera_module.cpp	/^const camera_metadata_t *CameraModule::generateDefaultRequestMetadata(int type)$/;"	f	class:CameraModule	typeref:typename:const camera_metadata_t *	signature:(int type)
+CameraModule::generateDefaultRequestMetadata	camera_module.h	/^	const camera_metadata_t *generateDefaultRequestMetadata(int type);$/;"	p	class:CameraModule	typeref:typename:const camera_metadata_t *	access:public	signature:(int type)
+CameraModule::id	camera_module.h	/^	unsigned int id() const { return id_; }$/;"	f	class:CameraModule	typeref:typename:unsigned int	access:public	signature:() const
+CameraModule::id_	camera_module.h	/^	unsigned int id_;$/;"	m	class:CameraModule	typeref:typename:unsigned int	access:private
+CameraModule::init	camera_module.cpp	/^int CameraModule::init()$/;"	f	class:CameraModule	typeref:typename:int	signature:()
+CameraModule::init	camera_module.h	/^	int init();$/;"	p	class:CameraModule	typeref:typename:int	access:public	signature:()
+CameraModule::module_	camera_module.h	/^	const hw_module_t *module_;$/;"	m	class:CameraModule	typeref:typename:const hw_module_t *	access:private
+CameraModule::processCaptureRequest	camera_module.cpp	/^int CameraModule::processCaptureRequest(camera3_capture_request_t *camera3Request)$/;"	f	class:CameraModule	typeref:typename:int	signature:(camera3_capture_request_t * camera3Request)
+CameraModule::processCaptureRequest	camera_module.h	/^	int processCaptureRequest(camera3_capture_request_t *request);$/;"	p	class:CameraModule	typeref:typename:int	access:public	signature:(camera3_capture_request_t * request)
+CameraModule::requestComplete	camera_module.cpp	/^void CameraModule::requestComplete(Request *request,$/;"	f	class:CameraModule	typeref:typename:void	signature:(Request * request,const std::map<Stream *,Buffer * > & buffers)
+CameraModule::requestComplete	camera_module.h	/^	void requestComplete(libcamera::Request *request,$/;"	p	class:CameraModule	typeref:typename:void	access:public	signature:(libcamera::Request * request,const std::map<libcamera::Stream *,libcamera::Buffer * > & buffers)
+CameraModule::requestTemplate_	camera_module.h	/^	camera_metadata_t *requestTemplate_;$/;"	m	class:CameraModule	typeref:typename:camera_metadata_t *	access:private
+CameraModule::run	camera_module.cpp	/^void CameraModule::run()$/;"	f	class:CameraModule	typeref:typename:void	signature:()
+CameraModule::run	camera_module.h	/^	void run();$/;"	p	class:CameraModule	typeref:typename:void	access:public	signature:()
+CameraModule::setCallbacks	camera_module.h	/^	void setCallbacks(const camera3_callback_ops_t *callbacks)$/;"	f	class:CameraModule	typeref:typename:void	access:public	signature:(const camera3_callback_ops_t * callbacks)
+DATA_ALIGNMENT	metadata/camera_metadata.c	/^#define DATA_ALIGNMENT /;"	d	file:
+ENTRY_ALIGNMENT	metadata/camera_metadata.c	/^#define ENTRY_ALIGNMENT /;"	d	file:
+ERROR	metadata/camera_metadata.c	/^#define ERROR /;"	d	file:
+FLAG_SORTED	metadata/camera_metadata.c	/^#define FLAG_SORTED /;"	d	file:
+HAL_MODULE_INFO_SYM	camera3_hal.cpp	/^camera_module_t HAL_MODULE_INFO_SYM = {$/;"	v	typeref:typename:camera_module_t
+LIBCAMERA_HAL_FUNC_DBG	camera_module.h	/^#define LIBCAMERA_HAL_FUNC_DBG	/;"	d
+LOG	camera3_hal.cpp	/^	LOG(HAL, Debug) << "Open camera: " << name;$/;"	l	function:hal_dev_open	typeref:typename:LIBCAMERA_HAL_FUNC_DBG	file:
+LOG_DECLARE_CATEGORY	camera_module.cpp	/^LOG_DECLARE_CATEGORY(HAL);$/;"	p	file:	signature:(HAL)
+LOG_DEFINE_CATEGORY	camera3_hal.cpp	/^LOG_DEFINE_CATEGORY(HAL);$/;"	p	file:	signature:(HAL)
+LOG_TAG	metadata/camera_metadata.c	/^#define LOG_TAG /;"	d	file:
+MAX_ALIGNMENT	metadata/camera_metadata.c	/^#define MAX_ALIGNMENT(/;"	d	file:	signature:(A,B)
+METADATA_ALIGNMENT	metadata/camera_metadata.c	/^#define METADATA_ALIGNMENT /;"	d	file:
+METADATA_ASSERT	camera_module.h	/^#define METADATA_ASSERT(/;"	d	signature:(_r)
+METADATA_PACKET_ALIGNMENT	metadata/camera_metadata.c	/^#define METADATA_PACKET_ALIGNMENT /;"	d	file:
+NOT_FOUND	metadata/camera_metadata.c	/^#define NOT_FOUND /;"	d	file:
+OK	metadata/camera_metadata.c	/^#define OK /;"	d	file:
+REQUEST_TEMPLATE_DATA	camera_module.h	/^#define REQUEST_TEMPLATE_DATA	/;"	d
+REQUEST_TEMPLATE_ENTRIES	camera_module.h	/^#define REQUEST_TEMPLATE_ENTRIES	/;"	d
+SN_EVENT_LOG_ID	metadata/camera_metadata.c	/^#define SN_EVENT_LOG_ID /;"	d	file:
+STATIC_DATA_CAP	camera3_hal.cpp	/^#define STATIC_DATA_CAP /;"	d	file:
+STATIC_ENTRY_CAP	camera3_hal.cpp	/^#define STATIC_ENTRY_CAP /;"	d	file:
+__ANDROID_LIBCAMERA_HAL_H__	camera_module.h	/^#define __ANDROID_LIBCAMERA_HAL_H__$/;"	d
+__anon2a3e460f010a	metadata/camera_metadata.c	/^    union {$/;"	u	struct:camera_metadata_buffer_entry	file:	access:public
+__anon2a3e460f0208	metadata/camera_metadata.c	/^        static const struct {$/;"	s	function:validate_camera_metadata_structure	file:
+add_camera_metadata_entry	metadata/camera_metadata.c	/^int add_camera_metadata_entry(camera_metadata_t *dst,$/;"	f	typeref:typename:int	signature:(camera_metadata_t * dst,uint32_t tag,const void * data,size_t data_count)
+add_camera_metadata_entry_raw	metadata/camera_metadata.c	/^static int add_camera_metadata_entry_raw(camera_metadata_t *dst,$/;"	f	typeref:typename:int	file:	signature:(camera_metadata_t * dst,uint32_t tag,uint8_t type,const void * data,size_t data_count)
+aeAvailableModes	camera3_hal.cpp	/^	char aeAvailableModes[] = {$/;"	l	function:getStaticMetadata	typeref:typename:char[]	file:
+aeExposureCompensation	camera_module.cpp	/^	int32_t aeExposureCompensation = 0;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:int32_t	file:
+aeLock	camera_module.cpp	/^	uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:uint8_t	file:
+aeMode	camera_module.cpp	/^	uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:uint8_t	file:
+aePrecaptureTrigger	camera_module.cpp	/^	uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:uint8_t	file:
+afTrigger	camera_module.cpp	/^	uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:uint8_t	file:
+aligned_ptr	metadata/camera_metadata.c	/^            uintptr_t aligned_ptr = ALIGN_TO((uintptr_t) metadata + alignmentOffset,$/;"	l	function:validate_camera_metadata_structure	typeref:typename:uintptr_t	file:
+aligned_ptr	metadata/camera_metadata.c	/^    uintptr_t aligned_ptr = ALIGN_TO(metadata, METADATA_PACKET_ALIGNMENT);$/;"	l	function:validate_camera_metadata_structure	typeref:typename:uintptr_t	file:
+alignment	metadata/camera_metadata.c	/^            size_t alignment;$/;"	m	struct:validate_camera_metadata_structure::__anon2a3e460f0208	typeref:typename:size_t	file:	access:public
+alignmentOffset	metadata/camera_metadata.c	/^    const uintptr_t alignmentOffset = aligned_ptr - (uintptr_t) metadata;$/;"	l	function:validate_camera_metadata_structure	typeref:typename:const uintptr_t	file:
+alignments	metadata/camera_metadata.c	/^        } alignments[] = {$/;"	l	function:validate_camera_metadata_structure	typeref:typename:const struct validate_camera_metadata_structure::__anon2a3e460f0208[]	file:
+allocate_camera_metadata	metadata/camera_metadata.c	/^camera_metadata_t *allocate_camera_metadata(size_t entry_capacity,$/;"	f	typeref:typename:camera_metadata_t *	signature:(size_t entry_capacity,size_t data_capacity)
+allocate_copy_camera_metadata_checked	metadata/camera_metadata.c	/^camera_metadata_t *allocate_copy_camera_metadata_checked($/;"	f	typeref:typename:camera_metadata_t *	signature:(const camera_metadata_t * src,size_t src_size)
+android_black_level	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_black_level[ANDROID_BLACK_LEVEL_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_color_correction	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_color_correction[ANDROID_COLOR_CORRECTION_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_control	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_control[ANDROID_CONTROL_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_demosaic	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_demosaic[ANDROID_DEMOSAIC_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_depth	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_depth[ANDROID_DEPTH_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_distortion_correction	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_distortion_correction[ANDROID_DISTORTION_CORRECTION_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_edge	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_edge[ANDROID_EDGE_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_flash	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_flash[ANDROID_FLASH_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_flash_info	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_flash_info[ANDROID_FLASH_INFO_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_hot_pixel	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_hot_pixel[ANDROID_HOT_PIXEL_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_info	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_info[ANDROID_INFO_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_jpeg	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_jpeg[ANDROID_JPEG_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_led	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_led[ANDROID_LED_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_lens	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_lens[ANDROID_LENS_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_lens_info	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_lens_info[ANDROID_LENS_INFO_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_logical_multi_camera	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_logical_multi_camera[ANDROID_LOGICAL_MULTI_CAMERA_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_noise_reduction	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_noise_reduction[ANDROID_NOISE_REDUCTION_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_quirks	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_quirks[ANDROID_QUIRKS_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_reprocess	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_reprocess[ANDROID_REPROCESS_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_request	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_request[ANDROID_REQUEST_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_scaler	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_scaler[ANDROID_SCALER_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_sensor	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_sensor[ANDROID_SENSOR_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_sensor_info	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_sensor_info[ANDROID_SENSOR_INFO_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_shading	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_shading[ANDROID_SHADING_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_statistics	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_statistics[ANDROID_STATISTICS_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_statistics_info	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_statistics_info[ANDROID_STATISTICS_INFO_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_sync	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_sync[ANDROID_SYNC_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+android_tonemap	metadata/camera_metadata_tag_info.c	/^static tag_info_t android_tonemap[ANDROID_TONEMAP_END -$/;"	v	typeref:typename:tag_info_t[]	file:
+append_camera_metadata	metadata/camera_metadata.c	/^int append_camera_metadata(camera_metadata_t *dst,$/;"	f	typeref:typename:int	signature:(camera_metadata_t * dst,const camera_metadata_t * src)
+availableAntiBandingModes	camera3_hal.cpp	/^	char availableAntiBandingModes[] = {$/;"	l	function:getStaticMetadata	typeref:typename:char[]	file:
+availableCapabilities	camera_module.cpp	/^	uint8_t availableCapabilities[] = {$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:uint8_t[]	file:
+availableCharacteristicsKeys	camera_module.cpp	/^	std::vector<int32_t> availableCharacteristicsKeys = {$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:std::vector<int32_t>	file:
+availableRequestKeys	camera_module.cpp	/^	std::vector<int32_t> availableRequestKeys = {$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:std::vector<int32_t>	file:
+availableResultKeys	camera_module.cpp	/^	std::vector<int32_t> availableResultKeys = {$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:std::vector<int32_t>	file:
+availableStallDurations	camera3_hal.cpp	/^	std::vector<int64_t> availableStallDurations = {$/;"	l	function:getStaticMetadata	typeref:typename:std::vector<int64_t>	file:
+availableStreamConfigurations	camera3_hal.cpp	/^	std::vector<uint32_t> availableStreamConfigurations = {$/;"	l	function:getStaticMetadata	typeref:typename:std::vector<uint32_t>	file:
+availableStreamFormats	camera3_hal.cpp	/^	std::vector<uint32_t> availableStreamFormats = {$/;"	l	function:getStaticMetadata	typeref:typename:std::vector<uint32_t>	file:
+awbLock	camera_module.cpp	/^	uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:uint8_t	file:
+awbLockAvailable	camera3_hal.cpp	/^	uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;$/;"	l	function:getStaticMetadata	typeref:typename:uint8_t	file:
+awbLockAvailable	camera_module.cpp	/^	uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:uint8_t	file:
+awbMode	camera_module.cpp	/^	uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:uint8_t	file:
+buffer	metadata/camera_metadata.c	/^    void *buffer = malloc(memory_needed);$/;"	l	function:allocate_camera_metadata	typeref:typename:void *	file:
+buffer	metadata/camera_metadata.c	/^    void *buffer = malloc(src_size);$/;"	l	function:allocate_copy_camera_metadata_checked	typeref:typename:void *	file:
+buffer_entry	metadata/camera_metadata.c	/^    camera_metadata_buffer_entry_t *buffer_entry = get_entries(src) + index;$/;"	l	function:get_camera_metadata_entry	typeref:typename:camera_metadata_buffer_entry_t *	file:
+calculate_camera_metadata_entry_data_size	metadata/camera_metadata.c	/^size_t calculate_camera_metadata_entry_data_size(uint8_t type,$/;"	f	typeref:typename:size_t	signature:(uint8_t type,size_t data_count)
+calculate_camera_metadata_size	metadata/camera_metadata.c	/^size_t calculate_camera_metadata_size(size_t entry_count,$/;"	f	typeref:typename:size_t	signature:(size_t entry_count,size_t data_count)
+callbacks_	camera_module.h	/^	const camera3_callback_ops_t *callbacks_;$/;"	m	class:CameraModule	typeref:typename:const camera3_callback_ops_t *	access:private
+camera	camera3_hal.cpp	/^	std::shared_ptr<libcamera::Camera> camera = cameraManager->cameras()[id];$/;"	l	function:hal_get_camera_info	typeref:typename:std::shared_ptr<libcamera::Camera>	file:
+camera3Stream	camera_module.cpp	/^	camera3_stream_t *camera3Stream = stream_list->streams[0];$/;"	l	function:CameraModule::configureStreams	typeref:typename:camera3_stream_t *	file:
+cameraDevice	camera_module.h	/^	camera3_device_t *cameraDevice() { return &cameraDevice_; }$/;"	f	class:CameraModule	typeref:typename:camera3_device_t *	access:public	signature:()
+cameraDevice_	camera_module.h	/^	camera3_device_t cameraDevice_;$/;"	m	class:CameraModule	typeref:typename:camera3_device_t	access:private
+cameraManager	camera3_hal.cpp	/^static libcamera::CameraManager *cameraManager;$/;"	v	typeref:typename:libcamera::CameraManager *	file:
+cameraManager_	camera_module.h	/^	libcamera::CameraManager *cameraManager_;$/;"	m	class:CameraModule	typeref:typename:libcamera::CameraManager *	access:private
+cameraMap	camera3_hal.cpp	/^static std::map<unsigned int, CameraModule *> cameraMap;$/;"	v	typeref:typename:std::map<unsigned int,CameraModule * >	file:
+cameraModule	camera3_hal.cpp	/^	CameraModule *cameraModule = new CameraHal(id, module, cameraManager);$/;"	l	function:hal_dev_open	typeref:typename:CameraModule *	file:
+cameraModule	camera3_hal.cpp	/^	CameraModule *cameraModule = reinterpret_cast<CameraModule *>(dev->priv);$/;"	l	function:hal_dev_close	typeref:typename:CameraModule *	file:
+camera_	camera_module.h	/^	std::shared_ptr<libcamera::Camera> camera_;$/;"	m	class:CameraModule	typeref:typename:std::shared_ptr<libcamera::Camera>	access:private
+camera_metadata	metadata/camera_metadata.c	/^struct camera_metadata {$/;"	s	file:
+camera_metadata::data_capacity	metadata/camera_metadata.c	/^    metadata_size_t          data_capacity;$/;"	m	struct:camera_metadata	typeref:typename:metadata_size_t	file:	access:public
+camera_metadata::data_count	metadata/camera_metadata.c	/^    metadata_size_t          data_count;$/;"	m	struct:camera_metadata	typeref:typename:metadata_size_t	file:	access:public
+camera_metadata::data_start	metadata/camera_metadata.c	/^    metadata_uptrdiff_t      data_start; \/\/ Offset from camera_metadata$/;"	m	struct:camera_metadata	typeref:typename:metadata_uptrdiff_t	file:	access:public
+camera_metadata::entries_start	metadata/camera_metadata.c	/^    metadata_uptrdiff_t      entries_start; \/\/ Offset from camera_metadata$/;"	m	struct:camera_metadata	typeref:typename:metadata_uptrdiff_t	file:	access:public
+camera_metadata::entry_capacity	metadata/camera_metadata.c	/^    metadata_size_t          entry_capacity;$/;"	m	struct:camera_metadata	typeref:typename:metadata_size_t	file:	access:public
+camera_metadata::entry_count	metadata/camera_metadata.c	/^    metadata_size_t          entry_count;$/;"	m	struct:camera_metadata	typeref:typename:metadata_size_t	file:	access:public
+camera_metadata::flags	metadata/camera_metadata.c	/^    uint32_t                 flags;$/;"	m	struct:camera_metadata	typeref:typename:uint32_t	file:	access:public
+camera_metadata::padding	metadata/camera_metadata.c	/^    uint32_t                 padding;    \/\/ padding to 8 bytes boundary$/;"	m	struct:camera_metadata	typeref:typename:uint32_t	file:	access:public
+camera_metadata::size	metadata/camera_metadata.c	/^    metadata_size_t          size;$/;"	m	struct:camera_metadata	typeref:typename:metadata_size_t	file:	access:public
+camera_metadata::vendor_id	metadata/camera_metadata.c	/^    metadata_vendor_id_t     vendor_id;$/;"	m	struct:camera_metadata	typeref:typename:metadata_vendor_id_t	file:	access:public
+camera_metadata::version	metadata/camera_metadata.c	/^    uint32_t                 version;$/;"	m	struct:camera_metadata	typeref:typename:uint32_t	file:	access:public
+camera_metadata_buffer_entry	metadata/camera_metadata.c	/^typedef struct camera_metadata_buffer_entry {$/;"	s	file:
+camera_metadata_buffer_entry::__anon2a3e460f010a	metadata/camera_metadata.c	/^    union {$/;"	u	struct:camera_metadata_buffer_entry	file:	access:public
+camera_metadata_buffer_entry::__anon2a3e460f010a::offset	metadata/camera_metadata.c	/^        uint32_t offset;$/;"	m	union:camera_metadata_buffer_entry::__anon2a3e460f010a	typeref:typename:uint32_t	file:	access:public
+camera_metadata_buffer_entry::__anon2a3e460f010a::value	metadata/camera_metadata.c	/^        uint8_t  value[4];$/;"	m	union:camera_metadata_buffer_entry::__anon2a3e460f010a	typeref:typename:uint8_t[4]	file:	access:public
+camera_metadata_buffer_entry::count	metadata/camera_metadata.c	/^    uint32_t count;$/;"	m	struct:camera_metadata_buffer_entry	typeref:typename:uint32_t	file:	access:public
+camera_metadata_buffer_entry::data	metadata/camera_metadata.c	/^    } data;$/;"	m	struct:camera_metadata_buffer_entry	typeref:union:camera_metadata_buffer_entry::__anon2a3e460f010a	file:	access:public
+camera_metadata_buffer_entry::reserved	metadata/camera_metadata.c	/^    uint8_t  reserved[3];$/;"	m	struct:camera_metadata_buffer_entry	typeref:typename:uint8_t[3]	file:	access:public
+camera_metadata_buffer_entry::tag	metadata/camera_metadata.c	/^    uint32_t tag;$/;"	m	struct:camera_metadata_buffer_entry	typeref:typename:uint32_t	file:	access:public
+camera_metadata_buffer_entry::type	metadata/camera_metadata.c	/^    uint8_t  type;$/;"	m	struct:camera_metadata_buffer_entry	typeref:typename:uint8_t	file:	access:public
+camera_metadata_buffer_entry_t	metadata/camera_metadata.c	/^} camera_metadata_buffer_entry_t;$/;"	t	typeref:struct:camera_metadata_buffer_entry	file:
+camera_metadata_data	metadata/camera_metadata.c	/^typedef union camera_metadata_data {$/;"	u	file:
+camera_metadata_data::d	metadata/camera_metadata.c	/^    double  d;$/;"	m	union:camera_metadata_data	typeref:typename:double	file:	access:public
+camera_metadata_data::f	metadata/camera_metadata.c	/^    float   f;$/;"	m	union:camera_metadata_data	typeref:typename:float	file:	access:public
+camera_metadata_data::i32	metadata/camera_metadata.c	/^    int32_t i32;$/;"	m	union:camera_metadata_data	typeref:typename:int32_t	file:	access:public
+camera_metadata_data::i64	metadata/camera_metadata.c	/^    int64_t i64;$/;"	m	union:camera_metadata_data	typeref:typename:int64_t	file:	access:public
+camera_metadata_data::r	metadata/camera_metadata.c	/^    camera_metadata_rational_t r;$/;"	m	union:camera_metadata_data	typeref:typename:camera_metadata_rational_t	file:	access:public
+camera_metadata_data::u8	metadata/camera_metadata.c	/^    uint8_t u8;$/;"	m	union:camera_metadata_data	typeref:typename:uint8_t	file:	access:public
+camera_metadata_data_t	metadata/camera_metadata.c	/^} camera_metadata_data_t;$/;"	t	typeref:union:camera_metadata_data	file:
+camera_metadata_enum_snprint	metadata/camera_metadata_tag_info.c	/^int camera_metadata_enum_snprint(uint32_t tag,$/;"	f	typeref:typename:int	signature:(uint32_t tag,uint32_t value,char * dst,size_t size)
+camera_metadata_section_bounds	metadata/camera_metadata_tag_info.c	/^unsigned int camera_metadata_section_bounds[ANDROID_SECTION_COUNT][2] = {$/;"	v	typeref:typename:unsigned int[][2]
+camera_metadata_section_names	metadata/camera_metadata_tag_info.c	/^const char *camera_metadata_section_names[ANDROID_SECTION_COUNT] = {$/;"	v	typeref:typename:const char * []
+camera_metadata_type_names	metadata/camera_metadata.c	/^const char *camera_metadata_type_names[NUM_TYPES] = {$/;"	v	typeref:typename:const char * []
+camera_metadata_type_size	metadata/camera_metadata.c	/^const size_t camera_metadata_type_size[NUM_TYPES] = {$/;"	v	typeref:typename:const size_t[]
+captureIntent	camera_module.cpp	/^	uint8_t captureIntent;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:uint8_t	file:
+clone	metadata/camera_metadata.c	/^    camera_metadata_t *clone = allocate_camera_metadata($/;"	l	function:clone_camera_metadata	typeref:typename:camera_metadata_t *	file:
+clone_camera_metadata	metadata/camera_metadata.c	/^camera_metadata_t *clone_camera_metadata(const camera_metadata_t *src) {$/;"	f	typeref:typename:camera_metadata_t *	signature:(const camera_metadata_t * src)
+close	camera_module.cpp	/^void CameraModule::close()$/;"	f	class:CameraModule	typeref:typename:void	signature:()
+close	camera_module.h	/^	void close();$/;"	p	class:CameraModule	typeref:typename:void	access:public	signature:()
+compare_entry_tags	metadata/camera_metadata.c	/^static int compare_entry_tags(const void *p1, const void *p2) {$/;"	f	typeref:typename:int	file:	signature:(const void * p1,const void * p2)
+config_	camera_module.h	/^	std::unique_ptr<libcamera::CameraConfiguration> config_;$/;"	m	class:CameraModule	typeref:typename:std::unique_ptr<libcamera::CameraConfiguration>	access:private
+configureStreams	camera_module.cpp	/^int CameraModule::configureStreams(camera3_stream_configuration_t *stream_list)$/;"	f	class:CameraModule	typeref:typename:int	signature:(camera3_stream_configuration_t * stream_list)
+configureStreams	camera_module.h	/^	int configureStreams(camera3_stream_configuration_t *stream_list);$/;"	p	class:CameraModule	typeref:typename:int	access:public	signature:(camera3_stream_configuration_t * stream_list)
+controlMetadata	camera3_hal.cpp	/^	char controlMetadata = ANDROID_CONTROL_MODE_AUTO;$/;"	l	function:getStaticMetadata	typeref:typename:char	file:
+copy_camera_metadata	metadata/camera_metadata.c	/^camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,$/;"	f	typeref:typename:camera_metadata_t *	signature:(void * dst,size_t dst_size,const camera_metadata_t * src)
+count	metadata/camera_metadata.c	/^        int count = entry->count;$/;"	l	function:dump_indented_camera_metadata	typeref:typename:int	file:
+count	metadata/camera_metadata.c	/^    uint32_t count;$/;"	m	struct:camera_metadata_buffer_entry	typeref:typename:uint32_t	file:	access:public
+d	metadata/camera_metadata.c	/^    double  d;$/;"	m	union:camera_metadata_data	typeref:typename:double	file:	access:public
+data	metadata/camera_metadata.c	/^            camera_metadata_data_t *data =$/;"	l	function:validate_camera_metadata_structure	typeref:typename:camera_metadata_data_t *	file:
+data	metadata/camera_metadata.c	/^    } data;$/;"	m	struct:camera_metadata_buffer_entry	typeref:union:camera_metadata_buffer_entry::__anon2a3e460f010a	file:	access:public
+data_bytes	metadata/camera_metadata.c	/^    size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type,$/;"	l	function:delete_camera_metadata_entry	typeref:typename:size_t	file:
+data_bytes	metadata/camera_metadata.c	/^    size_t data_bytes = data_count * camera_metadata_type_size[type];$/;"	l	function:validate_and_calculate_camera_metadata_entry_data_size	typeref:typename:size_t	file:
+data_bytes	metadata/camera_metadata.c	/^    size_t data_bytes = data_count *$/;"	l	function:calculate_camera_metadata_entry_data_size	typeref:typename:size_t	file:
+data_bytes	metadata/camera_metadata.c	/^    size_t data_bytes =$/;"	l	function:add_camera_metadata_entry_raw	typeref:typename:size_t	file:
+data_bytes	metadata/camera_metadata.c	/^    size_t data_bytes =$/;"	l	function:update_camera_metadata_entry	typeref:typename:size_t	file:
+data_capacity	metadata/camera_metadata.c	/^    metadata_size_t          data_capacity;$/;"	m	struct:camera_metadata	typeref:typename:metadata_size_t	file:	access:public
+data_count	metadata/camera_metadata.c	/^    metadata_size_t          data_count;$/;"	m	struct:camera_metadata	typeref:typename:metadata_size_t	file:	access:public
+data_end	metadata/camera_metadata.c	/^    const metadata_uptrdiff_t data_end =$/;"	l	function:validate_camera_metadata_structure	typeref:typename:const metadata_uptrdiff_t	file:
+data_entry_end	metadata/camera_metadata.c	/^            size_t data_entry_end = entry.data.offset + data_size;$/;"	l	function:validate_camera_metadata_structure	typeref:typename:size_t	file:
+data_payload_bytes	metadata/camera_metadata.c	/^    size_t data_payload_bytes =$/;"	l	function:add_camera_metadata_entry_raw	typeref:typename:size_t	file:
+data_payload_bytes	metadata/camera_metadata.c	/^    size_t data_payload_bytes =$/;"	l	function:update_camera_metadata_entry	typeref:typename:size_t	file:
+data_ptr	metadata/camera_metadata.c	/^        uint8_t *data_ptr;$/;"	l	function:dump_indented_camera_metadata	typeref:typename:uint8_t *	file:
+data_size	metadata/camera_metadata.c	/^        size_t data_size;$/;"	l	function:validate_camera_metadata_structure	typeref:typename:size_t	file:
+data_start	metadata/camera_metadata.c	/^    metadata_uptrdiff_t      data_start; \/\/ Offset from camera_metadata$/;"	m	struct:camera_metadata	typeref:typename:metadata_uptrdiff_t	file:	access:public
+data_unaligned	metadata/camera_metadata.c	/^    size_t data_unaligned = (uint8_t*)(get_entries(metadata) +$/;"	l	function:place_camera_metadata	typeref:typename:size_t	file:
+delete_camera_metadata_entry	metadata/camera_metadata.c	/^int delete_camera_metadata_entry(camera_metadata_t *dst,$/;"	f	typeref:typename:int	signature:(camera_metadata_t * dst,size_t index)
+denominator	metadata/camera_metadata.c	/^                    int32_t denominator = *(int32_t*)(data_ptr + index + 4);$/;"	l	function:print_data	typeref:typename:int32_t	file:
+dev	camera3_hal.cpp	/^	camera3_device_t *dev = reinterpret_cast<camera3_device_t *>(hw_device);$/;"	l	function:hal_dev_close	typeref:typename:camera3_device_t *	file:
+dispatcher	camera_module.cpp	/^	EventDispatcher *dispatcher = cameraManager_->eventDispatcher();$/;"	l	function:CameraModule::run	typeref:typename:EventDispatcher *	file:
+dump_camera_metadata	metadata/camera_metadata.c	/^void dump_camera_metadata(const camera_metadata_t *metadata,$/;"	f	typeref:typename:void	signature:(const camera_metadata_t * metadata,int fd,int verbosity)
+dump_indented_camera_metadata	metadata/camera_metadata.c	/^void dump_indented_camera_metadata(const camera_metadata_t *metadata,$/;"	f	typeref:typename:void	signature:(const camera_metadata_t * metadata,int fd,int verbosity,int indentation)
+e	metadata/camera_metadata.c	/^            camera_metadata_buffer_entry_t *e = get_entries(dst);$/;"	l	function:update_camera_metadata_entry	typeref:typename:camera_metadata_buffer_entry_t *	file:
+e	metadata/camera_metadata.c	/^        camera_metadata_buffer_entry_t *e = get_entries(dst);$/;"	l	function:delete_camera_metadata_entry	typeref:typename:camera_metadata_buffer_entry_t *	file:
+end	metadata/camera_metadata.c	/^            uint8_t *end = start + entry_bytes;$/;"	l	function:update_camera_metadata_entry	typeref:typename:uint8_t *	file:
+end	metadata/camera_metadata.c	/^        uint8_t *end = start + data_bytes;$/;"	l	function:delete_camera_metadata_entry	typeref:typename:uint8_t *	file:
+entries	metadata/camera_metadata.c	/^    camera_metadata_buffer_entry_t *entries = get_entries(metadata);$/;"	l	function:validate_camera_metadata_structure	typeref:typename:camera_metadata_buffer_entry_t *	file:
+entries_end	metadata/camera_metadata.c	/^    const metadata_uptrdiff_t entries_end =$/;"	l	function:validate_camera_metadata_structure	typeref:typename:const metadata_uptrdiff_t	file:
+entries_start	metadata/camera_metadata.c	/^    metadata_uptrdiff_t      entries_start; \/\/ Offset from camera_metadata$/;"	m	struct:camera_metadata	typeref:typename:metadata_uptrdiff_t	file:	access:public
+entry	metadata/camera_metadata.c	/^        camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count;$/;"	l	function:append_camera_metadata	typeref:typename:camera_metadata_buffer_entry_t *	file:
+entry	metadata/camera_metadata.c	/^        camera_metadata_buffer_entry_t entry = entries[i];$/;"	l	function:validate_camera_metadata_structure	typeref:typename:camera_metadata_buffer_entry_t	file:
+entry	metadata/camera_metadata.c	/^    camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count;$/;"	l	function:add_camera_metadata_entry_raw	typeref:typename:camera_metadata_buffer_entry_t *	file:
+entry	metadata/camera_metadata.c	/^    camera_metadata_buffer_entry_t *entry = get_entries(dst) + index;$/;"	l	function:delete_camera_metadata_entry	typeref:typename:camera_metadata_buffer_entry_t *	file:
+entry	metadata/camera_metadata.c	/^    camera_metadata_buffer_entry_t *entry = get_entries(dst) + index;$/;"	l	function:update_camera_metadata_entry	typeref:typename:camera_metadata_buffer_entry_t *	file:
+entry	metadata/camera_metadata.c	/^    camera_metadata_buffer_entry_t *entry = get_entries(metadata);$/;"	l	function:dump_indented_camera_metadata	typeref:typename:camera_metadata_buffer_entry_t *	file:
+entry_bytes	metadata/camera_metadata.c	/^    size_t entry_bytes =$/;"	l	function:update_camera_metadata_entry	typeref:typename:size_t	file:
+entry_capacity	metadata/camera_metadata.c	/^    metadata_size_t          entry_capacity;$/;"	m	struct:camera_metadata	typeref:typename:metadata_size_t	file:	access:public
+entry_count	metadata/camera_metadata.c	/^    const metadata_size_t entry_count = metadata->entry_count;$/;"	l	function:validate_camera_metadata_structure	typeref:typename:const metadata_size_t	file:
+entry_count	metadata/camera_metadata.c	/^    metadata_size_t          entry_count;$/;"	m	struct:camera_metadata	typeref:typename:metadata_size_t	file:	access:public
+exposureTimeRange	camera3_hal.cpp	/^	int64_t exposureTimeRange[] = {$/;"	l	function:getStaticMetadata	typeref:typename:int64_t[]	file:
+f	metadata/camera_metadata.c	/^    float   f;$/;"	m	union:camera_metadata_data	typeref:typename:float	file:	access:public
+faceDetectMode	camera_module.cpp	/^	uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:uint8_t	file:
+filterArr	camera3_hal.cpp	/^	uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;$/;"	l	function:getStaticMetadata	typeref:typename:uint16_t	file:
+find_camera_metadata_entry	metadata/camera_metadata.c	/^int find_camera_metadata_entry(camera_metadata_t *src,$/;"	f	typeref:typename:int	signature:(camera_metadata_t * src,uint32_t tag,camera_metadata_entry_t * entry)
+find_camera_metadata_ro_entry	metadata/camera_metadata.c	/^int find_camera_metadata_ro_entry(const camera_metadata_t *src,$/;"	f	typeref:typename:int	signature:(const camera_metadata_t * src,uint32_t tag,camera_metadata_ro_entry_t * entry)
+flags	metadata/camera_metadata.c	/^    uint32_t                 flags;$/;"	m	struct:camera_metadata	typeref:typename:uint32_t	file:	access:public
+flashAvailable	camera3_hal.cpp	/^	char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;$/;"	l	function:getStaticMetadata	typeref:typename:char	file:
+flashMode	camera_module.cpp	/^	uint8_t flashMode = ANDROID_FLASH_MODE_OFF;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:uint8_t	file:
+fn	camera3_hal.cpp	/^	float fn = 2.53 \/ 100;$/;"	l	function:getStaticMetadata	typeref:typename:float	file:
+free_camera_metadata	metadata/camera_metadata.c	/^void free_camera_metadata(camera_metadata_t *metadata) {$/;"	f	typeref:typename:void	signature:(camera_metadata_t * metadata)
+generateDefaultRequestMetadata	camera_module.cpp	/^const camera_metadata_t *CameraModule::generateDefaultRequestMetadata(int type)$/;"	f	class:CameraModule	typeref:typename:const camera_metadata_t *	signature:(int type)
+generateDefaultRequestMetadata	camera_module.h	/^	const camera_metadata_t *generateDefaultRequestMetadata(int type);$/;"	p	class:CameraModule	typeref:typename:const camera_metadata_t *	access:public	signature:(int type)
+getStaticMetadata	camera3_hal.cpp	/^static camera_metadata_t *getStaticMetadata(unsigned int id)$/;"	f	typeref:typename:camera_metadata_t *	file:	signature:(unsigned int id)
+get_camera_metadata_alignment	metadata/camera_metadata.c	/^size_t get_camera_metadata_alignment() {$/;"	f	typeref:typename:size_t	signature:()
+get_camera_metadata_compact_size	metadata/camera_metadata.c	/^size_t get_camera_metadata_compact_size(const camera_metadata_t *metadata) {$/;"	f	typeref:typename:size_t	signature:(const camera_metadata_t * metadata)
+get_camera_metadata_data_capacity	metadata/camera_metadata.c	/^size_t get_camera_metadata_data_capacity(const camera_metadata_t *metadata) {$/;"	f	typeref:typename:size_t	signature:(const camera_metadata_t * metadata)
+get_camera_metadata_data_count	metadata/camera_metadata.c	/^size_t get_camera_metadata_data_count(const camera_metadata_t *metadata) {$/;"	f	typeref:typename:size_t	signature:(const camera_metadata_t * metadata)
+get_camera_metadata_entry	metadata/camera_metadata.c	/^int get_camera_metadata_entry(camera_metadata_t *src,$/;"	f	typeref:typename:int	signature:(camera_metadata_t * src,size_t index,camera_metadata_entry_t * entry)
+get_camera_metadata_entry_capacity	metadata/camera_metadata.c	/^size_t get_camera_metadata_entry_capacity(const camera_metadata_t *metadata) {$/;"	f	typeref:typename:size_t	signature:(const camera_metadata_t * metadata)
+get_camera_metadata_entry_count	metadata/camera_metadata.c	/^size_t get_camera_metadata_entry_count(const camera_metadata_t *metadata) {$/;"	f	typeref:typename:size_t	signature:(const camera_metadata_t * metadata)
+get_camera_metadata_ro_entry	metadata/camera_metadata.c	/^int get_camera_metadata_ro_entry(const camera_metadata_t *src,$/;"	f	typeref:typename:int	signature:(const camera_metadata_t * src,size_t index,camera_metadata_ro_entry_t * entry)
+get_camera_metadata_section_name	metadata/camera_metadata.c	/^const char *get_camera_metadata_section_name(uint32_t tag) {$/;"	f	typeref:typename:const char *	signature:(uint32_t tag)
+get_camera_metadata_size	metadata/camera_metadata.c	/^size_t get_camera_metadata_size(const camera_metadata_t *metadata) {$/;"	f	typeref:typename:size_t	signature:(const camera_metadata_t * metadata)
+get_camera_metadata_tag_name	metadata/camera_metadata.c	/^const char *get_camera_metadata_tag_name(uint32_t tag) {$/;"	f	typeref:typename:const char *	signature:(uint32_t tag)
+get_camera_metadata_tag_type	metadata/camera_metadata.c	/^int get_camera_metadata_tag_type(uint32_t tag) {$/;"	f	typeref:typename:int	signature:(uint32_t tag)
+get_camera_metadata_vendor_id	metadata/camera_metadata.c	/^metadata_vendor_id_t get_camera_metadata_vendor_id($/;"	f	typeref:typename:metadata_vendor_id_t	signature:(const camera_metadata_t * meta)
+get_data	metadata/camera_metadata.c	/^static uint8_t *get_data(const camera_metadata_t *metadata) {$/;"	f	typeref:typename:uint8_t *	file:	signature:(const camera_metadata_t * metadata)
+get_entries	metadata/camera_metadata.c	/^static camera_metadata_buffer_entry_t *get_entries($/;"	f	typeref:typename:camera_metadata_buffer_entry_t *	file:	signature:(const camera_metadata_t * metadata)
+get_local_camera_metadata_section_name	metadata/camera_metadata.c	/^const char *get_local_camera_metadata_section_name(uint32_t tag,$/;"	f	typeref:typename:const char *	signature:(uint32_t tag,const camera_metadata_t * meta)
+get_local_camera_metadata_section_name_vendor_id	metadata/camera_metadata.c	/^const char *get_local_camera_metadata_section_name_vendor_id(uint32_t tag,$/;"	f	typeref:typename:const char *	signature:(uint32_t tag,metadata_vendor_id_t id)
+get_local_camera_metadata_tag_name	metadata/camera_metadata.c	/^const char *get_local_camera_metadata_tag_name(uint32_t tag,$/;"	f	typeref:typename:const char *	signature:(uint32_t tag,const camera_metadata_t * meta)
+get_local_camera_metadata_tag_name_vendor_id	metadata/camera_metadata.c	/^const char *get_local_camera_metadata_tag_name_vendor_id(uint32_t tag,$/;"	f	typeref:typename:const char *	signature:(uint32_t tag,metadata_vendor_id_t id)
+get_local_camera_metadata_tag_type	metadata/camera_metadata.c	/^int get_local_camera_metadata_tag_type(uint32_t tag,$/;"	f	typeref:typename:int	signature:(uint32_t tag,const camera_metadata_t * meta)
+get_local_camera_metadata_tag_type_vendor_id	metadata/camera_metadata.c	/^int get_local_camera_metadata_tag_type_vendor_id(uint32_t tag,$/;"	f	typeref:typename:int	signature:(uint32_t tag,metadata_vendor_id_t id)
+hal_dev_close	camera3_hal.cpp	/^static int hal_dev_close(hw_device_t *hw_device)$/;"	f	typeref:typename:int	file:	signature:(hw_device_t * hw_device)
+hal_dev_configure_streams	camera_module.cpp	/^static int hal_dev_configure_streams(const struct camera3_device *dev,$/;"	f	typeref:typename:int	file:	signature:(const struct camera3_device * dev,camera3_stream_configuration_t * stream_list)
+hal_dev_construct_default_request_settings	camera_module.cpp	/^hal_dev_construct_default_request_settings(const struct camera3_device *dev,$/;"	f	typeref:typename:const camera_metadata_t *	file:	signature:(const struct camera3_device * dev,int type)
+hal_dev_dump	camera_module.cpp	/^static void hal_dev_dump(const struct camera3_device *dev, int fd)$/;"	f	typeref:typename:void	file:	signature:(const struct camera3_device * dev,int fd)
+hal_dev_flush	camera_module.cpp	/^static int hal_dev_flush(const struct camera3_device *dev)$/;"	f	typeref:typename:int	file:	signature:(const struct camera3_device * dev)
+hal_dev_initialize	camera_module.cpp	/^static int hal_dev_initialize(const struct camera3_device *dev,$/;"	f	typeref:typename:int	file:	signature:(const struct camera3_device * dev,const camera3_callback_ops_t * callback_ops)
+hal_dev_open	camera3_hal.cpp	/^static int hal_dev_open(const hw_module_t* module, const char* name,$/;"	f	typeref:typename:int	file:	signature:(const hw_module_t * module,const char * name,hw_device_t ** device)
+hal_dev_ops	camera_module.cpp	/^static camera3_device_ops hal_dev_ops = {$/;"	v	typeref:typename:camera3_device_ops	file:
+hal_dev_process_capture_request	camera_module.cpp	/^static int hal_dev_process_capture_request(const struct camera3_device *dev,$/;"	f	typeref:typename:int	file:	signature:(const struct camera3_device * dev,camera3_capture_request_t * request)
+hal_get_camera_info	camera3_hal.cpp	/^static int hal_get_camera_info(int id, struct camera_info *info)$/;"	f	typeref:typename:int	file:	signature:(int id,struct camera_info * info)
+hal_get_number_of_cameras	camera3_hal.cpp	/^static int hal_get_number_of_cameras(void)$/;"	f	typeref:typename:int	file:	signature:(void)
+hal_init	camera3_hal.cpp	/^static int hal_init()$/;"	f	typeref:typename:int	file:	signature:()
+hal_module_methods	camera3_hal.cpp	/^static struct hw_module_methods_t hal_module_methods = {$/;"	v	typeref:struct:hw_module_methods_t	file:
+hal_open_legacy	camera3_hal.cpp	/^static int hal_open_legacy(const struct hw_module_t* module, const char* id,$/;"	f	typeref:typename:int	file:	signature:(const struct hw_module_t * module,const char * id,uint32_t halVersion,struct hw_device_t ** device)
+hal_set_callbacks	camera3_hal.cpp	/^static int hal_set_callbacks(const camera_module_callbacks_t *callbacks)$/;"	f	typeref:typename:int	file:	signature:(const camera_module_callbacks_t * callbacks)
+hal_set_torch_mode	camera3_hal.cpp	/^static int hal_set_torch_mode(const char* camera_id, bool enabled)$/;"	f	typeref:typename:int	file:	signature:(const char * camera_id,bool enabled)
+i	camera_module.cpp	/^	for (unsigned int i = 0; i < stream_list->num_streams; ++i) {$/;"	l	function:hal_dev_configure_streams	typeref:typename:unsigned int	file:
+i	metadata/camera_metadata.c	/^            size_t i;$/;"	l	function:update_camera_metadata_entry	typeref:typename:size_t	file:
+i	metadata/camera_metadata.c	/^        for (size_t i = 0; i < sizeof(alignments)\/sizeof(alignments[0]); ++i) {$/;"	l	function:validate_camera_metadata_structure	typeref:typename:size_t	file:
+i	metadata/camera_metadata.c	/^        for (size_t i = 0; i < src->entry_count; i++, entry++) {$/;"	l	function:append_camera_metadata	typeref:typename:size_t	file:
+i	metadata/camera_metadata.c	/^        size_t i;$/;"	l	function:delete_camera_metadata_entry	typeref:typename:size_t	file:
+i	metadata/camera_metadata.c	/^    for (size_t i = 0; i < entry_count; ++i) {$/;"	l	function:validate_camera_metadata_structure	typeref:typename:size_t	file:
+i	metadata/camera_metadata.c	/^    unsigned int i;$/;"	l	function:dump_indented_camera_metadata	typeref:typename:unsigned int	file:
+i32	metadata/camera_metadata.c	/^    int32_t i32;$/;"	m	union:camera_metadata_data	typeref:typename:int32_t	file:	access:public
+i64	metadata/camera_metadata.c	/^    int64_t i64;$/;"	m	union:camera_metadata_data	typeref:typename:int64_t	file:	access:public
+id	camera3_hal.cpp	/^	int id = atoi(name);$/;"	l	function:hal_dev_open	typeref:typename:int	file:
+id	camera3_hal.cpp	/^	unsigned int id = cameraModule->id();$/;"	l	function:hal_dev_close	typeref:typename:unsigned int	file:
+id	camera_module.h	/^	unsigned int id() const { return id_; }$/;"	f	class:CameraModule	typeref:typename:unsigned int	access:public	signature:() const
+id	metadata/camera_metadata.c	/^    metadata_vendor_id_t id = (NULL == meta) ? CAMERA_METADATA_INVALID_VENDOR_ID :$/;"	l	function:get_local_camera_metadata_section_name	typeref:typename:metadata_vendor_id_t	file:
+id	metadata/camera_metadata.c	/^    metadata_vendor_id_t id = (NULL == meta) ? CAMERA_METADATA_INVALID_VENDOR_ID :$/;"	l	function:get_local_camera_metadata_tag_name	typeref:typename:metadata_vendor_id_t	file:
+id	metadata/camera_metadata.c	/^    metadata_vendor_id_t id = (NULL == meta) ? CAMERA_METADATA_INVALID_VENDOR_ID :$/;"	l	function:get_local_camera_metadata_tag_type	typeref:typename:metadata_vendor_id_t	file:
+id_	camera_module.h	/^	unsigned int id_;$/;"	m	class:CameraModule	typeref:typename:unsigned int	access:private
+index	metadata/camera_metadata.c	/^    int index = 0;$/;"	l	function:print_data	typeref:typename:int	file:
+index	metadata/camera_metadata.c	/^    uint32_t index;$/;"	l	function:find_camera_metadata_entry	typeref:typename:uint32_t	file:
+init	camera_module.cpp	/^int CameraModule::init()$/;"	f	class:CameraModule	typeref:typename:int	signature:()
+init	camera_module.h	/^	int init();$/;"	p	class:CameraModule	typeref:typename:int	access:public	signature:()
+inputStreams	camera_module.cpp	/^	int32_t inputStreams = 0;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:int32_t	file:
+it	camera_module.cpp	/^	for (const auto &it : buffers)$/;"	l	function:CameraModule::requestComplete	typeref:typename:const auto &	file:
+j	metadata/camera_metadata.c	/^    int j, k;$/;"	l	function:print_data	typeref:typename:int	file:
+k	metadata/camera_metadata.c	/^    int j, k;$/;"	l	function:print_data	typeref:typename:int	file:
+key	metadata/camera_metadata.c	/^        camera_metadata_buffer_entry_t key;$/;"	l	function:find_camera_metadata_entry	typeref:typename:camera_metadata_buffer_entry_t	file:
+length	metadata/camera_metadata.c	/^            size_t length = dst->data_count - entry->data.offset - entry_bytes;$/;"	l	function:update_camera_metadata_entry	typeref:typename:size_t	file:
+length	metadata/camera_metadata.c	/^        size_t length = dst->data_count - entry->data.offset - data_bytes;$/;"	l	function:delete_camera_metadata_entry	typeref:typename:size_t	file:
+libcameraHal	camera_module.cpp	/^	CameraModule *libcameraHal = reinterpret_cast<CameraModule *>(dev->priv);$/;"	l	function:hal_dev_configure_streams	typeref:typename:CameraModule *	file:
+libcameraHal	camera_module.cpp	/^	CameraModule *libcameraHal = reinterpret_cast<CameraModule *>(dev->priv);$/;"	l	function:hal_dev_construct_default_request_settings	typeref:typename:CameraModule *	file:
+libcameraHal	camera_module.cpp	/^	CameraModule *libcameraHal = reinterpret_cast<CameraModule *>(dev->priv);$/;"	l	function:hal_dev_initialize	typeref:typename:CameraModule *	file:
+libcameraHal	camera_module.cpp	/^	CameraModule *libcameraHal = reinterpret_cast<CameraModule *>(dev->priv);$/;"	l	function:hal_dev_process_capture_request	typeref:typename:CameraModule *	file:
+lines	metadata/camera_metadata.c	/^    int lines = count \/ values_per_line[type];$/;"	l	function:print_data	typeref:typename:int	file:
+maxOutStream	camera_module.cpp	/^	int32_t maxOutStream[] = { 0, 2, 0};$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:int32_t[]	file:
+maxPipelineDepth	camera_module.cpp	/^	uint8_t maxPipelineDepth = 5;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:uint8_t	file:
+memory_needed	metadata/camera_metadata.c	/^    size_t memory_needed = calculate_camera_metadata_size(entry_capacity,$/;"	l	function:allocate_camera_metadata	typeref:typename:size_t	file:
+memory_needed	metadata/camera_metadata.c	/^    size_t memory_needed = calculate_camera_metadata_size(entry_capacity,$/;"	l	function:place_camera_metadata	typeref:typename:size_t	file:
+memory_needed	metadata/camera_metadata.c	/^    size_t memory_needed = get_camera_metadata_compact_size(src);$/;"	l	function:copy_camera_metadata	typeref:typename:size_t	file:
+memory_needed	metadata/camera_metadata.c	/^    size_t memory_needed = sizeof(camera_metadata_t);$/;"	l	function:calculate_camera_metadata_size	typeref:typename:size_t	file:
+metadata	metadata/camera_metadata.c	/^    camera_metadata_t *metadata = (camera_metadata_t*) buffer;$/;"	l	function:allocate_copy_camera_metadata_checked	typeref:typename:camera_metadata_t *	file:
+metadata	metadata/camera_metadata.c	/^    camera_metadata_t *metadata = (camera_metadata_t*)dst;$/;"	l	function:place_camera_metadata	typeref:typename:camera_metadata_t *	file:
+metadata	metadata/camera_metadata.c	/^    camera_metadata_t *metadata = place_camera_metadata($/;"	l	function:allocate_camera_metadata	typeref:typename:camera_metadata_t *	file:
+metadata	metadata/camera_metadata.c	/^    camera_metadata_t *metadata =$/;"	l	function:copy_camera_metadata	typeref:typename:camera_metadata_t *	file:
+metadataMap	camera3_hal.cpp	/^static std::map<unsigned int, camera_metadata_t *> metadataMap;$/;"	v	typeref:typename:std::map<unsigned int,camera_metadata_t * >	file:
+metadata_size_t	metadata/camera_metadata.c	/^typedef uint32_t metadata_size_t;$/;"	t	typeref:typename:uint32_t	file:
+metadata_uptrdiff_t	metadata/camera_metadata.c	/^typedef uint32_t metadata_uptrdiff_t;$/;"	t	typeref:typename:uint32_t	file:
+minFrameDurations	camera3_hal.cpp	/^	std::vector<int64_t> minFrameDurations = {$/;"	l	function:getStaticMetadata	typeref:typename:std::vector<int64_t>	file:
+module_	camera_module.h	/^	const hw_module_t *module_;$/;"	m	class:CameraModule	typeref:typename:const hw_module_t *	access:private
+msg	metadata/camera_metadata_tag_info.c	/^    const char *msg = "error: not an enum";$/;"	l	function:camera_metadata_enum_snprint	typeref:typename:const char *	file:
+name	metadata/camera_metadata.c	/^            const char *name;$/;"	m	struct:validate_camera_metadata_structure::__anon2a3e460f0208	typeref:typename:const char *	file:	access:public
+numCameras	camera3_hal.cpp	/^	int numCameras = cameraManager->cameras().size();$/;"	l	function:hal_get_camera_info	typeref:typename:LIBCAMERA_HAL_FUNC_DBG int	file:
+numerator	metadata/camera_metadata.c	/^                    int32_t numerator = *(int32_t*)(data_ptr + index);$/;"	l	function:print_data	typeref:typename:int32_t	file:
+offset	metadata/camera_metadata.c	/^        uint32_t offset;$/;"	m	union:camera_metadata_buffer_entry::__anon2a3e460f010a	typeref:typename:uint32_t	file:	access:public
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_buffer_entry_t, count) == 4,$/;"	p	typeref:typename:_Static_assert (==4,"Offset of count must be 4")	file:	signature:(camera_metadata_buffer_entry_t,count)
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_buffer_entry_t, data) == 8,$/;"	p	typeref:typename:_Static_assert (==8,"Offset of data must be 8")	file:	signature:(camera_metadata_buffer_entry_t,data)
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_buffer_entry_t, tag) == 0,$/;"	p	typeref:typename:_Static_assert (==0,"Offset of tag must be 0")	file:	signature:(camera_metadata_buffer_entry_t,tag)
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_buffer_entry_t, type) == 12,$/;"	p	typeref:typename:_Static_assert (==12,"Offset of type must be 12")	file:	signature:(camera_metadata_buffer_entry_t,type)
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_t, data_capacity) == 28,$/;"	p	typeref:typename:_Static_assert (==28,"Offset of data_capacity must be 28")	file:	signature:(camera_metadata_t,data_capacity)
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_t, data_count) == 24,$/;"	p	typeref:typename:_Static_assert (==24,"Offset of data_count must be 24")	file:	signature:(camera_metadata_t,data_count)
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_t, data_start) == 32,$/;"	p	typeref:typename:_Static_assert (==32,"Offset of data_start must be 32")	file:	signature:(camera_metadata_t,data_start)
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_t, entries_start) == 20,$/;"	p	typeref:typename:_Static_assert (==20,"Offset of entries_start must be 20")	file:	signature:(camera_metadata_t,entries_start)
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_t, entry_capacity) == 16,$/;"	p	typeref:typename:_Static_assert (==16,"Offset of entry_capacity must be 16")	file:	signature:(camera_metadata_t,entry_capacity)
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_t, entry_count) == 12,$/;"	p	typeref:typename:_Static_assert (==12,"Offset of entry_count must be 12")	file:	signature:(camera_metadata_t,entry_count)
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_t, flags) == 8,$/;"	p	typeref:typename:_Static_assert (==8,"Offset of flags must be 8")	file:	signature:(camera_metadata_t,flags)
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_t, size) == 0,$/;"	p	typeref:typename:_Static_assert (==0,"Offset of size must be 0")	file:	signature:(camera_metadata_t,size)
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_t, vendor_id) == 40,$/;"	p	typeref:typename:_Static_assert (==40,"Offset of vendor_id must be 40")	file:	signature:(camera_metadata_t,vendor_id)
+offsetof	metadata/camera_metadata.c	/^_Static_assert(offsetof(camera_metadata_t, version) == 4,$/;"	p	typeref:typename:_Static_assert (==4,"Offset of version must be 4")	file:	signature:(camera_metadata_t,version)
+orientation	camera3_hal.cpp	/^	int32_t orientation = 0;$/;"	l	function:getStaticMetadata	typeref:typename:int32_t	file:
+padding	metadata/camera_metadata.c	/^    uint32_t                 padding;    \/\/ padding to 8 bytes boundary$/;"	m	struct:camera_metadata	typeref:typename:uint32_t	file:	access:public
+partialResultCount	camera_module.cpp	/^	int32_t partialResultCount = 1;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:int32_t	file:
+pixelArraySize	camera3_hal.cpp	/^	int32_t pixelArraySize[] = {$/;"	l	function:getStaticMetadata	typeref:typename:int32_t[]	file:
+place_camera_metadata	metadata/camera_metadata.c	/^camera_metadata_t *place_camera_metadata(void *dst,$/;"	f	typeref:typename:camera_metadata_t *	signature:(void * dst,size_t dst_size,size_t entry_capacity,size_t data_capacity)
+print_data	metadata/camera_metadata.c	/^static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag, int type,$/;"	p	typeref:typename:void	file:	signature:(int fd,const uint8_t * data_ptr,uint32_t tag,int type,int count,int indentation)
+print_data	metadata/camera_metadata.c	/^static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag,$/;"	f	typeref:typename:void	file:	signature:(int fd,const uint8_t * data_ptr,uint32_t tag,int type,int count,int indentation)
+processCaptureRequest	camera_module.cpp	/^int CameraModule::processCaptureRequest(camera3_capture_request_t *camera3Request)$/;"	f	class:CameraModule	typeref:typename:int	signature:(camera3_capture_request_t * camera3Request)
+processCaptureRequest	camera_module.h	/^	int processCaptureRequest(camera3_capture_request_t *request);$/;"	p	class:CameraModule	typeref:typename:int	access:public	signature:(camera3_capture_request_t * request)
+r	metadata/camera_metadata.c	/^    camera_metadata_rational_t r;$/;"	m	union:camera_metadata_data	typeref:typename:camera_metadata_rational_t	file:	access:public
+requestComplete	camera_module.cpp	/^void CameraModule::requestComplete(Request *request,$/;"	f	class:CameraModule	typeref:typename:void	signature:(Request * request,const std::map<Stream *,Buffer * > & buffers)
+requestComplete	camera_module.h	/^	void requestComplete(libcamera::Request *request,$/;"	p	class:CameraModule	typeref:typename:void	access:public	signature:(libcamera::Request * request,const std::map<libcamera::Stream *,libcamera::Buffer * > & buffers)
+requestTemplate_	camera_module.h	/^	camera_metadata_t *requestTemplate_;$/;"	m	class:CameraModule	typeref:typename:camera_metadata_t *	access:private
+res	metadata/camera_metadata.c	/^    int res;$/;"	l	function:clone_camera_metadata	typeref:typename:int	file:
+reserved	metadata/camera_metadata.c	/^    uint8_t  reserved[3];$/;"	m	struct:camera_metadata_buffer_entry	typeref:typename:uint8_t[3]	file:	access:public
+ret	camera3_hal.cpp	/^	int ret = cameraManager->start();$/;"	l	function:hal_init	typeref:typename:int	file:
+ret	camera3_hal.cpp	/^	int ret;$/;"	l	function:getStaticMetadata	typeref:typename:int	file:
+ret	camera_module.cpp	/^		int ret = camera_->allocateBuffers();$/;"	l	function:CameraModule::processCaptureRequest	typeref:typename:int	file:
+ret	camera_module.cpp	/^	int ret = camera_->configure(config_.get());$/;"	l	function:CameraModule::configureStreams	typeref:typename:int	file:
+ret	camera_module.cpp	/^	int ret;$/;"	l	function:CameraModule::generateDefaultRequestMetadata	typeref:typename:int	file:
+ret	metadata/camera_metadata.c	/^    metadata_vendor_id_t ret = CAMERA_METADATA_INVALID_VENDOR_ID;$/;"	l	function:get_camera_metadata_vendor_id	typeref:typename:metadata_vendor_id_t	file:
+ret	metadata/camera_metadata_tag_info.c	/^    int ret = -1;$/;"	l	function:camera_metadata_enum_snprint	typeref:typename:int	file:
+roles	camera_module.cpp	/^	StreamRoles roles = {};$/;"	l	function:CameraModule::configureStreams	typeref:typename:StreamRoles	file:
+run	camera_module.cpp	/^void CameraModule::run()$/;"	f	class:CameraModule	typeref:typename:void	signature:()
+run	camera_module.h	/^	void run();$/;"	p	class:CameraModule	typeref:typename:void	access:public	signature:()
+search_entry	metadata/camera_metadata.c	/^        camera_metadata_buffer_entry_t *search_entry = NULL;$/;"	l	function:find_camera_metadata_entry	typeref:typename:camera_metadata_buffer_entry_t *	file:
+search_entry	metadata/camera_metadata.c	/^        camera_metadata_buffer_entry_t *search_entry = get_entries(src);$/;"	l	function:find_camera_metadata_entry	typeref:typename:camera_metadata_buffer_entry_t *	file:
+sensitivityRange	camera3_hal.cpp	/^	int32_t sensitivityRange[] = {$/;"	l	function:getStaticMetadata	typeref:typename:int32_t[]	file:
+sensorSizes	camera3_hal.cpp	/^	int32_t sensorSizes[] = {$/;"	l	function:getStaticMetadata	typeref:typename:int32_t[]	file:
+setCallbacks	camera_module.h	/^	void setCallbacks(const camera3_callback_ops_t *callbacks)$/;"	f	class:CameraModule	typeref:typename:void	access:public	signature:(const camera3_callback_ops_t * callbacks)
+set_camera_metadata_vendor_cache_ops	metadata/camera_metadata.c	/^int set_camera_metadata_vendor_cache_ops($/;"	f	typeref:typename:int	signature:(const struct vendor_tag_cache_ops * query_cache_ops)
+set_camera_metadata_vendor_id	metadata/camera_metadata.c	/^void set_camera_metadata_vendor_id(camera_metadata_t *meta,$/;"	f	typeref:typename:void	signature:(camera_metadata_t * meta,metadata_vendor_id_t id)
+set_camera_metadata_vendor_ops	metadata/camera_metadata.c	/^int set_camera_metadata_vendor_ops(const vendor_tag_ops_t* ops) {$/;"	f	typeref:typename:int	signature:(const vendor_tag_ops_t * ops)
+set_camera_metadata_vendor_tag_ops	metadata/camera_metadata.c	/^int set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t* ops) {$/;"	f	typeref:typename:int	signature:(const vendor_tag_query_ops_t * ops)
+size	metadata/camera_metadata.c	/^    metadata_size_t          size;$/;"	m	struct:camera_metadata	typeref:typename:metadata_size_t	file:	access:public
+sort_camera_metadata	metadata/camera_metadata.c	/^int sort_camera_metadata(camera_metadata_t *dst) {$/;"	f	typeref:typename:int	signature:(camera_metadata_t * dst)
+start	metadata/camera_metadata.c	/^            uint8_t *start = get_data(dst) + entry->data.offset;$/;"	l	function:update_camera_metadata_entry	typeref:typename:uint8_t *	file:
+start	metadata/camera_metadata.c	/^        uint8_t *start = get_data(dst) + entry->data.offset;$/;"	l	function:delete_camera_metadata_entry	typeref:typename:uint8_t *	file:
+staticMetadata	camera3_hal.cpp	/^	camera_metadata_t *staticMetadata = allocate_camera_metadata(STATIC_ENTRY_CAP,$/;"	l	function:getStaticMetadata	typeref:typename:camera_metadata_t *	file:
+staticMetadata	camera3_hal.cpp	/^	camera_metadata_t *staticMetadata = getStaticMetadata(id);$/;"	l	function:hal_get_camera_info	typeref:typename:camera_metadata_t *	file:
+stream	camera_module.cpp	/^		camera3_stream_t *stream = stream_list->streams[i];$/;"	l	function:hal_dev_configure_streams	typeref:typename:camera3_stream_t *	file:
+streamConfiguration	camera_module.cpp	/^	StreamConfiguration *streamConfiguration = &config_->at(0);$/;"	l	function:CameraModule::configureStreams	typeref:typename:StreamConfiguration *	file:
+supportedHWLevel	camera3_hal.cpp	/^	uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;$/;"	l	function:getStaticMetadata	typeref:typename:uint8_t	file:
+tag	metadata/camera_metadata.c	/^    uint32_t tag;$/;"	m	struct:camera_metadata_buffer_entry	typeref:typename:uint32_t	file:	access:public
+tag1	metadata/camera_metadata.c	/^    uint32_t tag1 = ((camera_metadata_buffer_entry_t*)p1)->tag;$/;"	l	function:compare_entry_tags	typeref:typename:uint32_t	file:
+tag2	metadata/camera_metadata.c	/^    uint32_t tag2 = ((camera_metadata_buffer_entry_t*)p2)->tag;$/;"	l	function:compare_entry_tags	typeref:typename:uint32_t	file:
+tag_index	metadata/camera_metadata.c	/^    uint32_t tag_index = tag & 0xFFFF;$/;"	l	function:get_local_camera_metadata_tag_name_vendor_id	typeref:typename:uint32_t	file:
+tag_index	metadata/camera_metadata.c	/^    uint32_t tag_index = tag & 0xFFFF;$/;"	l	function:get_local_camera_metadata_tag_type_vendor_id	typeref:typename:uint32_t	file:
+tag_info	metadata/camera_metadata.c	/^typedef struct tag_info {$/;"	s	file:
+tag_info	metadata/camera_metadata_tag_info.c	/^tag_info_t *tag_info[ANDROID_SECTION_COUNT] = {$/;"	v	typeref:typename:tag_info_t * []
+tag_info::tag_name	metadata/camera_metadata.c	/^    const char *tag_name;$/;"	m	struct:tag_info	typeref:typename:const char *	file:	access:public
+tag_info::tag_type	metadata/camera_metadata.c	/^    uint8_t     tag_type;$/;"	m	struct:tag_info	typeref:typename:uint8_t	file:	access:public
+tag_info_t	metadata/camera_metadata.c	/^} tag_info_t;$/;"	t	typeref:struct:tag_info	file:
+tag_name	metadata/camera_metadata.c	/^        const char *tag_name, *tag_section;$/;"	l	function:dump_indented_camera_metadata	typeref:typename:const char *	file:
+tag_name	metadata/camera_metadata.c	/^    const char *tag_name;$/;"	m	struct:tag_info	typeref:typename:const char *	file:	access:public
+tag_section	metadata/camera_metadata.c	/^        const char *tag_name, *tag_section;$/;"	l	function:dump_indented_camera_metadata	typeref:typename:const char **	file:
+tag_section	metadata/camera_metadata.c	/^        uint32_t tag_section = entry.tag >> 16;$/;"	l	function:validate_camera_metadata_structure	typeref:typename:uint32_t	file:
+tag_section	metadata/camera_metadata.c	/^    uint32_t tag_section = tag >> 16;$/;"	l	function:get_local_camera_metadata_section_name_vendor_id	typeref:typename:uint32_t	file:
+tag_section	metadata/camera_metadata.c	/^    uint32_t tag_section = tag >> 16;$/;"	l	function:get_local_camera_metadata_tag_name_vendor_id	typeref:typename:uint32_t	file:
+tag_section	metadata/camera_metadata.c	/^    uint32_t tag_section = tag >> 16;$/;"	l	function:get_local_camera_metadata_tag_type_vendor_id	typeref:typename:uint32_t	file:
+tag_type	metadata/camera_metadata.c	/^        int tag_type = get_local_camera_metadata_tag_type(entry.tag, metadata);$/;"	l	function:validate_camera_metadata_structure	typeref:typename:int	file:
+tag_type	metadata/camera_metadata.c	/^    uint8_t     tag_type;$/;"	m	struct:tag_info	typeref:typename:uint8_t	file:	access:public
+type	metadata/camera_metadata.c	/^    int type = get_local_camera_metadata_tag_type(tag, dst);$/;"	l	function:add_camera_metadata_entry	typeref:typename:int	file:
+type	metadata/camera_metadata.c	/^    uint8_t  type;$/;"	m	struct:camera_metadata_buffer_entry	typeref:typename:uint8_t	file:	access:public
+type_name	metadata/camera_metadata.c	/^        const char *type_name;$/;"	l	function:dump_indented_camera_metadata	typeref:typename:const char *	file:
+type_size	metadata/camera_metadata.c	/^        size_t type_size = camera_metadata_type_size[entry->type];$/;"	l	function:dump_indented_camera_metadata	typeref:typename:size_t	file:
+type_size	metadata/camera_metadata.c	/^    size_t type_size = camera_metadata_type_size[type];$/;"	l	function:print_data	typeref:typename:size_t	file:
+u8	metadata/camera_metadata.c	/^    uint8_t u8;$/;"	m	union:camera_metadata_data	typeref:typename:uint8_t	file:	access:public
+update_camera_metadata_entry	metadata/camera_metadata.c	/^int update_camera_metadata_entry(camera_metadata_t *dst,$/;"	f	typeref:typename:int	signature:(camera_metadata_t * dst,size_t index,const void * data,size_t data_count,camera_metadata_entry_t * updated_entry)
+validate_and_calculate_camera_metadata_entry_data_size	metadata/camera_metadata.c	/^static int validate_and_calculate_camera_metadata_entry_data_size(size_t *data_size, uint8_t typ/;"	f	typeref:typename:int	file:	signature:(size_t * data_size,uint8_t type,size_t data_count)
+validate_camera_metadata_structure	metadata/camera_metadata.c	/^int validate_camera_metadata_structure(const camera_metadata_t *metadata,$/;"	f	typeref:typename:int	signature:(const camera_metadata_t * metadata,const size_t * expected_size)
+validate_camera_metadata_structure::__anon2a3e460f0208::alignment	metadata/camera_metadata.c	/^            size_t alignment;$/;"	m	struct:validate_camera_metadata_structure::__anon2a3e460f0208	typeref:typename:size_t	file:	access:public
+validate_camera_metadata_structure::__anon2a3e460f0208::name	metadata/camera_metadata.c	/^            const char *name;$/;"	m	struct:validate_camera_metadata_structure::__anon2a3e460f0208	typeref:typename:const char *	file:	access:public
+value	metadata/camera_metadata.c	/^        uint8_t  value[4];$/;"	m	union:camera_metadata_buffer_entry::__anon2a3e460f010a	typeref:typename:uint8_t[4]	file:	access:public
+value	metadata/camera_metadata.c	/^    uint32_t value;$/;"	l	function:print_data	typeref:typename:uint32_t	file:
+value_string_tmp	metadata/camera_metadata.c	/^    char value_string_tmp[CAMERA_METADATA_ENUM_STRING_MAX_SIZE];$/;"	l	function:print_data	typeref:typename:char[]	file:
+values_per_line	metadata/camera_metadata.c	/^    static int values_per_line[NUM_TYPES] = {$/;"	l	function:print_data	typeref:typename:int[]	file:
+vendor_cache_ops	metadata/camera_metadata.c	/^static const struct vendor_tag_cache_ops *vendor_cache_ops = NULL;$/;"	v	typeref:typename:const struct vendor_tag_cache_ops *	file:
+vendor_id	metadata/camera_metadata.c	/^    metadata_vendor_id_t     vendor_id;$/;"	m	struct:camera_metadata	typeref:typename:metadata_vendor_id_t	file:	access:public
+vendor_tag_ops	metadata/camera_metadata.c	/^static const vendor_tag_ops_t *vendor_tag_ops = NULL;$/;"	v	typeref:typename:const vendor_tag_ops_t *	file:
+version	metadata/camera_metadata.c	/^    uint32_t                 version;$/;"	m	struct:camera_metadata	typeref:typename:uint32_t	file:	access:public
diff --git a/src/android/thread_rpc.cpp b/src/android/thread_rpc.cpp
new file mode 100644
index 000000000000..f13db59d0d75
--- /dev/null
+++ b/src/android/thread_rpc.cpp
@@ -0,0 +1,41 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * thread_call.cpp - Inter-thread procedure call
+ */
+
+#include "message.h"
+#include "thread_rpc.h"
+
+using namespace libcamera;
+
+libcamera::Message::Type ThreadRpcMessage::rpcType_ = Message::Type::None;
+
+ThreadRpcMessage::ThreadRpcMessage()
+	: Message(type())
+{
+}
+
+void ThreadRpc::notifyReception()
+{
+	{
+		libcamera::MutexLocker locker(mutex_);
+		delivered_ = true;
+	}
+	cv_.notify_one();
+}
+
+void ThreadRpc::waitDelivery()
+{
+	libcamera::MutexLocker locker(mutex_);
+	cv_.wait(locker, [&]{ return delivered_; });
+}
+
+Message::Type ThreadRpcMessage::type()
+{
+	if (ThreadRpcMessage::rpcType_ == Message::Type::None)
+		rpcType_ = Message::registerMessageType();
+
+	return rpcType_;
+}
diff --git a/src/android/thread_rpc.h b/src/android/thread_rpc.h
new file mode 100644
index 000000000000..173caba1a515
--- /dev/null
+++ b/src/android/thread_rpc.h
@@ -0,0 +1,56 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * thread_call.h - Inter-thread procedure call
+ */
+#ifndef __ANDROID_THREAD_CALL_H__
+#define __ANDROID_THREAD_CALL_H__
+
+#include <condition_variable>
+#include <string>
+
+#include <hardware/camera3.h>
+#include <libcamera/libcamera.h>
+
+#include "message.h"
+#include "thread.h"
+
+class ThreadRpc
+{
+public:
+	enum RpcTag {
+		ProcessCaptureRequest,
+		Close,
+	};
+
+	ThreadRpc()
+		: delivered_(false) {}
+
+	void notifyReception();
+	void waitDelivery();
+
+	RpcTag tag;
+
+	camera3_capture_request_t *request;
+
+private:
+	bool delivered_;
+	std::mutex mutex_;
+	std::condition_variable cv_;
+};
+
+class ThreadRpcMessage : public libcamera::Message
+{
+public:
+	ThreadRpcMessage();
+	ThreadRpc *rpc;
+
+	static Message::Type type();
+
+private:
+	static libcamera::Message::Type rpcType_;
+};
+
+#endif /* __ANDROID_THREAD_CALL_H__ */
+
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index a09b23d60022..9b6e4b769760 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -103,11 +103,23 @@  libcamera_deps = [
     dependency('threads'),
 ]
 
-libcamera = shared_library('camera',
-                           libcamera_sources,
-                           install : true,
-                           include_directories : includes,
-                           dependencies : libcamera_deps)
+if get_option('android')
+    libcamera_sources += android_hal_sources
+    includes += android_includes
+
+    libcamera = shared_library('camera',
+                               libcamera_sources,
+                               install : true,
+                               link_with : android_camera_metadata,
+                               include_directories : includes,
+                               dependencies : libcamera_deps)
+else
+    libcamera = shared_library('camera',
+                               libcamera_sources,
+                               install : true,
+                               include_directories : includes,
+                               dependencies : libcamera_deps)
+endif
 
 libcamera_dep = declare_dependency(sources : [libcamera_api, libcamera_h],
                                    include_directories : libcamera_includes,
diff --git a/src/meson.build b/src/meson.build
index 628e7a7f23f2..67ad20aab86b 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,3 +1,7 @@ 
+if get_option('android')
+    subdir('android')
+endif
+
 subdir('libcamera')
 subdir('ipa')
 subdir('cam')