blob: 696e804368211f251c6db99bf4426225eadf8e30 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2019, Google Inc.
*
* camera_ops.h - Android Camera HAL Operations
*/
#include "camera_ops.h"
#include <system/camera_metadata.h>
#include "camera_device.h"
using namespace libcamera;
/*
* Translation layer between the Android Camera HAL device operations and the
* CameraDevice.
*/
static int hal_dev_initialize(const struct camera3_device *dev,
const camera3_callback_ops_t *callback_ops)
{
if (!dev)
return -EINVAL;
CameraDevice *camera = reinterpret_cast<CameraDevice *>(dev->priv);
camera->setCallbacks(callback_ops);
return 0;
}
static int hal_dev_configure_streams(const struct camera3_device *dev,
camera3_stream_configuration_t *stream_list)
{
if (!dev)
return -EINVAL;
CameraDevice *camera = reinterpret_cast<CameraDevice *>(dev->priv);
return camera->configureStreams(stream_list);
}
static const camera_metadata_t *
hal_dev_construct_default_request_settings(const struct camera3_device *dev,
int type)
{
if (!dev)
return nullptr;
CameraDevice *camera = reinterpret_cast<CameraDevice *>(dev->priv);
return camera->constructDefaultRequestSettings(type);
}
static int hal_dev_process_capture_request(const struct camera3_device *dev,
camera3_capture_request_t *request)
{
if (!dev)
return -EINVAL;
CameraDevice *camera = reinterpret_cast<CameraDevice *>(dev->priv);
return camera->processCaptureRequest(request);
}
static void hal_dev_dump([[maybe_unused]] const struct camera3_device *dev,
[[maybe_unused]] int fd)
{
}
static int hal_dev_flush([[maybe_unused]] const struct camera3_device *dev)
{
return 0;
}
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);
CameraDevice *camera = reinterpret_cast<CameraDevice *>(dev->priv);
camera->close();
return 0;
}
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 = { nullptr },
};
|
='#n309'>309
310
311
312
313
314
315
316
317
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2019, Google Inc.
*
* signal.cpp - Signal test
*/
#include <iostream>
#include <string.h>
#include <libcamera/object.h>
#include <libcamera/signal.h>
#include "test.h"
using namespace std;
using namespace libcamera;
static int valueStatic_ = 0;
static void slotStatic(int value)
{
valueStatic_ = value;
}
static int slotStaticReturn()
{
return 0;
}
class SlotObject : public Object
{
public:
void slot()
{
valueStatic_ = 1;
}
};
class BaseClass
{
public:
/*
* A virtual method is required in the base class, otherwise the compiler
* will always store Object before BaseClass in memory.
*/
virtual ~BaseClass()
{
}
unsigned int data_[32];
};
class SlotMulti : public BaseClass, public Object
{
public:
void slot()
{
valueStatic_ = 1;
}
};
class SignalTest : public Test
{
protected:
void slotVoid()
{
called_ = true;
}
void slotDisconnect()
{
called_ = true;
signalVoid_.disconnect(this, &SignalTest::slotDisconnect);
}
void slotInteger1(int value)
{
values_[0] = value;
}
void slotInteger2(int value)
{
values_[1] = value;
}
void slotMultiArgs(int value, const std::string &name)
{
values_[2] = value;
name_ = name;
}
int slotReturn()
{
return 0;
}
int init()
{
return 0;
}
int run()
{
/* ----------------- Signal -> !Object tests ---------------- */
/* Test signal emission and reception. */
called_ = false;
signalVoid_.connect(this, &SignalTest::slotVoid);
signalVoid_.emit();
if (!called_) {
cout << "Signal emission test failed" << endl;
return TestFail;
}
/* Test signal with parameters. */
values_[2] = 0;
name_.clear();
signalMultiArgs_.connect(this, &SignalTest::slotMultiArgs);
signalMultiArgs_.emit(42, "H2G2");
if (values_[2] != 42 || name_ != "H2G2") {
cout << "Signal parameters test failed" << endl;
return TestFail;
}
/* Test signal connected to multiple slots. */
memset(values_, 0, sizeof(values_));
valueStatic_ = 0;
signalInt_.connect(this, &SignalTest::slotInteger1);
signalInt_.connect(this, &SignalTest::slotInteger2);
signalInt_.connect(&slotStatic);
signalInt_.emit(42);
if (values_[0] != 42 || values_[1] != 42 || values_[2] != 0 ||
valueStatic_ != 42) {
cout << "Signal multi slot test failed" << endl;
return TestFail;
}
/* Test disconnection of a single slot. */
memset(values_, 0, sizeof(values_));
signalInt_.disconnect(this, &SignalTest::slotInteger2);
signalInt_.emit(42);
if (values_[0] != 42 || values_[1] != 0 || values_[2] != 0) {
cout << "Signal slot disconnection test failed" << endl;
return TestFail;
}
/* Test disconnection of a whole object. */
memset(values_, 0, sizeof(values_));
signalInt_.disconnect(this);
signalInt_.emit(42);
if (values_[0] != 0 || values_[1] != 0 || values_[2] != 0) {
cout << "Signal object disconnection test failed" << endl;
return TestFail;
}
/* Test disconnection of a whole signal. */
memset(values_, 0, sizeof(values_));
signalInt_.connect(this, &SignalTest::slotInteger1);
signalInt_.connect(this, &SignalTest::slotInteger2);
signalInt_.disconnect();
signalInt_.emit(42);
if (values_[0] != 0 || values_[1] != 0 || values_[2] != 0) {
cout << "Signal object disconnection test failed" << endl;
return TestFail;
}
/* Test disconnection from slot. */
signalVoid_.disconnect();
signalVoid_.connect(this, &SignalTest::slotDisconnect);
signalVoid_.emit();
called_ = false;
signalVoid_.emit();
if (called_) {
cout << "Signal disconnection from slot test failed" << endl;
return TestFail;
}
/*
* Test connecting to slots that return a value. This targets
* compilation, there's no need to check runtime results.
*/
signalVoid_.connect(slotStaticReturn);
signalVoid_.connect(this, &SignalTest::slotReturn);
/* ----------------- Signal -> Object tests ----------------- */
/*
* Test automatic disconnection on object deletion. Connect the
* slot twice to ensure all instances are disconnected.
*/
signalVoid_.disconnect();
SlotObject *slotObject = new SlotObject();
signalVoid_.connect(slotObject, &SlotObject::slot);
signalVoid_.connect(slotObject, &SlotObject::slot);
delete slotObject;
valueStatic_ = 0;
signalVoid_.emit();
if (valueStatic_ != 0) {
cout << "Signal disconnection on object deletion test failed" << endl;
return TestFail;
}
/*
* Test that signal deletion disconnects objects. This shall
* not generate any valgrind warning.
*/
Signal<> *dynamicSignal = new Signal<>();
slotObject = new SlotObject();
dynamicSignal->connect(slotObject, &SlotObject::slot);
delete dynamicSignal;
delete slotObject;
/*
* Test that signal manual disconnection from Object removes
* the signal for the object. This shall not generate any
* valgrind warning.
*/
dynamicSignal = new Signal<>();
slotObject = new SlotObject();
dynamicSignal->connect(slotObject, &SlotObject::slot);
dynamicSignal->disconnect(slotObject);
delete dynamicSignal;
delete slotObject;
/*
* Test that signal manual disconnection from all slots removes
* the signal for the object. This shall not generate any
* valgrind warning.
*/
dynamicSignal = new Signal<>();
slotObject = new SlotObject();
dynamicSignal->connect(slotObject, &SlotObject::slot);
dynamicSignal->disconnect();
delete dynamicSignal;
delete slotObject;
/* Exercise the Object slot code paths. */
slotObject = new SlotObject();
signalVoid_.connect(slotObject, &SlotObject::slot);
valueStatic_ = 0;
signalVoid_.emit();
if (valueStatic_ == 0) {
cout << "Signal delivery for Object test failed" << endl;
return TestFail;
}
delete slotObject;
/* --------- Signal -> Object (multiple inheritance) -------- */
/*
* Test automatic disconnection on object deletion. Connect the
* slot twice to ensure all instances are disconnected.
*/
signalVoid_.disconnect();
SlotMulti *slotMulti = new SlotMulti();
signalVoid_.connect(slotMulti, &SlotMulti::slot);
signalVoid_.connect(slotMulti, &SlotMulti::slot);
delete slotMulti;
valueStatic_ = 0;
signalVoid_.emit();
if (valueStatic_ != 0) {
cout << "Signal disconnection on object deletion test failed" << endl;
return TestFail;
}
/*
* Test that signal deletion disconnects objects. This shall
* not generate any valgrind warning.
*/
dynamicSignal = new Signal<>();
slotMulti = new SlotMulti();
dynamicSignal->connect(slotMulti, &SlotMulti::slot);
delete dynamicSignal;
delete slotMulti;
/* Exercise the Object slot code paths. */
slotMulti = new SlotMulti();
signalVoid_.connect(slotMulti, &SlotMulti::slot);
valueStatic_ = 0;
signalVoid_.emit();
if (valueStatic_ == 0) {
cout << "Signal delivery for Object test failed" << endl;
return TestFail;
}
delete slotMulti;
return TestPass;
}
void cleanup()
{
}
private:
Signal<> signalVoid_;
Signal<int> signalInt_;
Signal<int, const std::string &> signalMultiArgs_;
bool called_;
int values_[3];
std::string name_;
};
TEST_REGISTER(SignalTest)