/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2019, Google Inc. * * object-invoke.cpp - Cross-thread Object method invocation test */ #include #include #include #include #include #include "test.h" using namespace std; using namespace libcamera; class InvokedObject : public Object { public: enum Status { NoCall, InvalidThread, CallReceived, }; InvokedObject() : status_(NoCall) { } Status status() const { return status_; } int value() const { return value_; } void reset() { status_ = NoCall; value_ = 0; } void method(int value) { if (Thread::current() != thread()) status_ = InvalidThread; else status_ = CallReceived; value_ = value; } void methodWithReference([[maybe_unused]] const int &value) { } int methodWithReturn() { return 42; } private: Status status_; int value_; }; class ObjectInvokeTest : public Test { protected: int run() { EventDispatcher *dispatcher = Thread::current()->eventDispatcher(); /* * Test that queued method invocation in the same thread goes * through the event dispatcher. */ object_.invokeMethod(&InvokedObject::method, ConnectionTypeQueued, 42); if (object_.status() != InvokedObject::NoCall) { cerr << "Method not invoked asynchronously" << endl; return TestFail; } dispatcher->processEvents(); switch (object_.status()) { case InvokedObject::NoCall: cout << "Method not invoked for main thread" << endl; return TestFail; case InvokedObject::InvalidThread: cout << "Method invoked in incorrect thread for main thread" << endl; return TestFail; default: break; } if (object_.value() != 42) { cout << "Method invoked with incorrect value for main thread" << endl; return TestFail; } /* * Test that blocking invocation is delivered directly when the * caller and callee live in the same thread. */ object_.reset(); object_.invokeMethod(&InvokedObject::method, ConnectionTypeBlocking, 42); switch (object_.status()) { case InvokedObject::NoCall: cout << "Method not invoked for main thread (blocking)" << endl; return TestFail; case InvokedObject::InvalidThread: cout << "Method invoked in incorrect thread for main thread (blocking)" << endl; return TestFail; default: break; } /* * Move the object to a thread and verify that auto method * invocation is delivered in the correct thread. */ object_.reset(); object_.moveToThread(&thread_); thread_.start(); object_.invokeMethod(&InvokedObject::method, ConnectionTypeBlocking, 42); switch (object_.status()) { case InvokedObject::NoCall: cout << "Method not invoked for custom thread" << endl; return TestFail; case InvokedObject::InvalidThread: cout << "Method invoked in incorrect thread for custom thread" << endl; return TestFail; default: break; } if (object_.value() != 42) { cout << "Method invoked with incorrect value for custom thread" << endl; return TestFail; } /* Test that direct method invocation bypasses threads. */ object_.reset(); object_.invokeMethod(&InvokedObject::method, ConnectionTypeDirect, 42); switch (object_.status()) { case InvokedObject::NoCall: cout << "Method not invoked for custom thread" << endl; return TestFail; case InvokedObject::CallReceived: cout << "Method invoked in incorrect thread for direct call" << endl; return TestFail; default: break; } if (object_.value() != 42) { cout << "Method invoked with incorrect value for direct call" << endl; return TestFail; } /* * Test invoking a method that takes reference arguments. This * targets compilation, there's no need to check runtime * results. */ object_.invokeMethod(&InvokedObject::methodWithReference, ConnectionTypeBlocking, 42); /* Test invoking a method that returns a value. */ int ret = object_.invokeMethod(&InvokedObject::methodWithReturn, ConnectionTypeBlocking); if (ret != 42) { cout << "Method invoked return incorrect value (" << ret << ")" << endl; return TestFail; } return TestPass; } void cleanup() { thread_.exit(0); thread_.wait(); } private: Thread thread_; InvokedObject object_; }; TEST_REGISTER(ObjectInvokeTest) ='#n23'>23 24 25 26 27 28 29 30
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2019, Google Inc.
 *
 * camera_metadata.h - libcamera Android Camera Metadata Helper
 */
#ifndef __ANDROID_CAMERA_METADATA_H__
#define __ANDROID_CAMERA_METADATA_H__

#include <stdint.h>

#include <system/camera_metadata.h>

class CameraMetadata
{
public:
	CameraMetadata(size_t entryCapacity, size_t dataCapacity);
	~CameraMetadata();

	bool isValid() { return valid_; }
	bool addEntry(uint32_t tag, const void *data, size_t data_count);

	camera_metadata_t *get();

private:
	camera_metadata_t *metadata_;
	bool valid_;
};

#endif /* __ANDROID_CAMERA_METADATA_H__ */