From patchwork Wed May 6 10:33:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 3689 Return-Path: Received: from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7EB51616A3 for ; Wed, 6 May 2020 12:33:54 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="NXP4yS/c"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com; h=from:subject:in-reply-to:references:mime-version:to:cc: content-transfer-encoding:content-type; s=s1; bh=nvs/rjJ8PZxG296bnRiK0IggLde78s6PT5wz+vhKNtc=; b=NXP4yS/cWOzXxJvguvFRjddbJSp9oqKHUzreiS8zk3y3kks1jr9FwcDhA6hg5SnqrpVl lobjnDLPNWbBMIe3s/DLvGuWZzMfzV3ummqcPaGuK62Gm6AGi57dgJNCFQGoNYVxRwjxTT vLA7+hJMbIb9jdIALbAzmmjizCN0cm1RM= Received: by filter0084p3las1.sendgrid.net with SMTP id filter0084p3las1-1974-5EB2928F-DC 2020-05-06 10:33:52.129458492 +0000 UTC m=+1773124.266965506 Received: from mail.uajain.com (unknown) by ismtpd0004p1maa1.sendgrid.net (SG) with ESMTP id rc7wGKDQR6CxvN76n4JPTA for ; Wed, 06 May 2020 10:33:51.720 +0000 (UTC) From: Umang Jain Date: Wed, 06 May 2020 10:33:52 +0000 (UTC) Message-Id: <20200506103346.3433-2-email@uajain.com> In-Reply-To: <20200506103346.3433-1-email@uajain.com> References: <20200506103346.3433-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcIgOyDPOiX995eQdp4XFd3CIIppLN3xVP9fnjZAkHN9qdTnu2NWIgAXU39+5gdwjrGNoa+u8+5CJSOTjEjGwKmq5HFCWqqKeBYAIDPTUhZ47UQDjoNLx9V0JhD5RpQUMms6JvWpybQKsoQDJ5ST0GWNvXrRJiUWjHxPuvDlw/9d81eSSbGMF4p/cs/VDPzUxY To: libcamera-devel Subject: [libcamera-devel] [PATCH 1/4] libcamera: device_enumerator: Emit a signal when a new device is hotplugged X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 May 2020 10:33:55 -0000 Emit a signal whenever is a new MediaDevice is added to the DeviceEnumerator. This will allow CameraManager to get notified about the new devices that have been hot-plugged. Signed-off-by: Umang Jain --- src/libcamera/camera_manager.cpp | 27 +++++++++++++++++++++-- src/libcamera/device_enumerator.cpp | 10 +++++++++ src/libcamera/include/device_enumerator.h | 3 +++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index fddf734..c75979a 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -54,6 +54,7 @@ protected: private: int init(); void cleanup(); + void enumerateNewDevices(DeviceEnumerator *enumerator); CameraManager *cm_; @@ -144,14 +145,36 @@ int CameraManager::Private::init() } } - /* TODO: register hot-plug callback here */ + enumerator_->newDevicesFound.connect(this, &CameraManager::Private::enumerateNewDevices); return 0; } +void CameraManager::Private::enumerateNewDevices(DeviceEnumerator *enumerator) +{ + std::vector &factories = PipelineHandlerFactory::factories(); + + for (PipelineHandlerFactory *factory : factories) { + /* + * Try each pipeline handler until it exhaust + * all pipelines it can provide. + */ + while (1) { + std::shared_ptr pipe = factory->create(cm_); + if (!pipe->match(enumerator_.get())) + break; + + LOG(Camera, Debug) + << "Pipeline handler \"" << factory->name() + << "\" matched"; + pipes_.push_back(std::move(pipe)); + } + } +} + void CameraManager::Private::cleanup() { - /* TODO: unregister hot-plug callback here */ + enumerator_->newDevicesFound.disconnect(this, &CameraManager::Private::enumerateNewDevices); /* * Release all references to cameras and pipeline handlers to ensure diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp index dd17e3e..2721120 100644 --- a/src/libcamera/device_enumerator.cpp +++ b/src/libcamera/device_enumerator.cpp @@ -227,6 +227,15 @@ std::unique_ptr DeviceEnumerator::createDevice(const std::string &d return media; } +/** + * \var DeviceEnumerator::newDevicesFound + * \brief Signal emitted when a new MediaDevice is added to the DeviceEnumerator + * + * CameraManager connects to this signal to know about new MediaDevices being plugged-in, + * while it is running. CameraManager will then iterate over the DeviceEnumerator, to match + * their respective pipeline-handlers and prepare the newly plugged-in device for use. + */ + /** * \brief Add a media device to the enumerator * \param[in] media media device instance to add @@ -242,6 +251,7 @@ void DeviceEnumerator::addDevice(std::unique_ptr &&media) << "Added device " << media->deviceNode() << ": " << media->driver(); devices_.push_back(std::move(media)); + newDevicesFound.emit(this); } /** diff --git a/src/libcamera/include/device_enumerator.h b/src/libcamera/include/device_enumerator.h index 433e357..6cc6ec2 100644 --- a/src/libcamera/include/device_enumerator.h +++ b/src/libcamera/include/device_enumerator.h @@ -11,6 +11,7 @@ #include #include +#include #include namespace libcamera { @@ -43,6 +44,8 @@ public: std::shared_ptr search(const DeviceMatch &dm); + Signal newDevicesFound; + protected: std::unique_ptr createDevice(const std::string &deviceNode); void addDevice(std::unique_ptr &&media); From patchwork Wed May 6 10:33:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 3690 Return-Path: Received: from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4B32561698 for ; Wed, 6 May 2020 12:33:55 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="Rbyg+v+M"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com; h=from:subject:in-reply-to:references:mime-version:to:cc: content-transfer-encoding:content-type; s=s1; bh=B5Jbb3/CjZ/78+Unt8jaSzv4o2LgeBkW6IhXGg6FNiM=; b=Rbyg+v+MVnjP6E26/cUJGvt6VkfTJR7q7GzmTDJklpDuWM4mtit5fKQ4zig/FENUbOhR ZFg+R06jefX8OOA98cF2wpfrZOAklCkKtIhOL5qP40OpdiGdbvjVGZzb2rkceHIDuF5mzb RT2UpUmOrrUGLZkh0yt/Qgz3D22hbUUSI= Received: by filter0081p3las1.sendgrid.net with SMTP id filter0081p3las1-3357-5EB29290-F2 2020-05-06 10:33:53.206528954 +0000 UTC m=+1773122.500703768 Received: from mail.uajain.com (unknown) by ismtpd0005p1maa1.sendgrid.net (SG) with ESMTP id IxvEqa3mSwma1nYmOmTIdA for ; Wed, 06 May 2020 10:33:52.840 +0000 (UTC) From: Umang Jain Date: Wed, 06 May 2020 10:33:53 +0000 (UTC) Message-Id: <20200506103346.3433-3-email@uajain.com> In-Reply-To: <20200506103346.3433-1-email@uajain.com> References: <20200506103346.3433-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPc8Y1sFjEEckHl5AFRmKDueraXKxp573m8sSCEK90OLFw+qYpEOzFFN3Mh07YU/WWy7V3S2jEqv8pKCFA8dL0JHiS15q++nMXIZNSnz/i8DTPT2nRhPWgM/8fcYtsFJOiZ5uB19qoUfJ+cyASB2+HIXQ/0UzG+h3YPY72YC6fu+/sqIiBWEQiA/kNHLALC+j+e To: libcamera-devel Subject: [libcamera-devel] [PATCH 2/4] libcamera: camera_manager: Introduce signals when a camera is added/removed X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 May 2020 10:33:55 -0000 Emit 'cameraAdded' and 'cameraRemoved' from CameraManager to enable hotplug and hot-unplug support in appplications like QCam. Signed-off-by: Umang Jain --- include/libcamera/camera_manager.h | 4 ++++ src/libcamera/camera_manager.cpp | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/libcamera/camera_manager.h b/include/libcamera/camera_manager.h index 079f848..558bb96 100644 --- a/include/libcamera/camera_manager.h +++ b/include/libcamera/camera_manager.h @@ -13,6 +13,7 @@ #include #include +#include namespace libcamera { @@ -42,6 +43,9 @@ public: void setEventDispatcher(std::unique_ptr dispatcher); EventDispatcher *eventDispatcher(); + Signal cameraAdded; + Signal cameraRemoved; + private: static const std::string version_; static CameraManager *self_; diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index c75979a..6438f87 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -391,6 +391,23 @@ std::shared_ptr CameraManager::get(dev_t devnum) return iter->second.lock(); } +/** + * \var CameraManager::cameraAdded + * \brief Signal emitted when a new camera is added in CameraManager + * + * This signal is emitted when a new camera is added by the CameraManager + * in the list of cameras it manages. A pointer to the newly-added camera + * is passed as a parameter. + */ + +/** + * \var CameraManager::cameraRemoved + * \brief Signal emitted when a camera is removed in CameraManager + * + * This signal is emitted when a camera is removed from the CameraManager. + * A pointer to the removed camera is passed as a parameter. + */ + /** * \brief Add a camera to the camera manager * \param[in] camera The camera to be added @@ -409,7 +426,9 @@ void CameraManager::addCamera(std::shared_ptr camera, dev_t devnum) { ASSERT(Thread::current() == p_.get()); + Camera *cam = camera.get(); p_->addCamera(camera, devnum); + cameraAdded.emit(cam); } /** @@ -427,6 +446,7 @@ void CameraManager::removeCamera(Camera *camera) ASSERT(Thread::current() == p_.get()); p_->removeCamera(camera); + cameraRemoved.emit(camera); } /** From patchwork Wed May 6 10:33:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 3691 Return-Path: Received: from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E7D2A603F2 for ; Wed, 6 May 2020 12:33:56 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="jtje/80o"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com; h=from:subject:in-reply-to:references:mime-version:to:cc: content-transfer-encoding:content-type; s=s1; bh=YOzeV9I0yRCuhBhV55Ws1NbDSeCQGxCmgAVL0q5ysaE=; b=jtje/80o3Ku1vQc6g82jTIXcGCV4jRBKtvAb1W/kr2AVD6smFQGTN9fK6mE8Q2m7JMhz yha/UEaKOocQgrDRUa9FpLCPK/dRDbOn2ucIEkeGzWjbu5D77pKnHOBiYpH0zclOg/jVcL M3o4SLesMrzuCU5jRVDBU8ynidq1qSeT4= Received: by filter0135p3las1.sendgrid.net with SMTP id filter0135p3las1-28320-5EB29293-45 2020-05-06 10:33:55.453271144 +0000 UTC m=+1773090.744415389 Received: from mail.uajain.com (unknown) by ismtpd0005p1hnd1.sendgrid.net (SG) with ESMTP id oB1VGW0fSQGdyZH1_tqsxQ for ; Wed, 06 May 2020 10:33:54.946 +0000 (UTC) From: Umang Jain Date: Wed, 06 May 2020 10:33:55 +0000 (UTC) Message-Id: <20200506103346.3433-4-email@uajain.com> In-Reply-To: <20200506103346.3433-1-email@uajain.com> References: <20200506103346.3433-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcHcG1g99dnq0SJ9KzJgHEPq0KUG1dy9EmNymiHJrtKW61eXuBmqlYgdA/DCg/Df/zF8XfxjcYG4KGtvldMEXReScn5tVjNs0JYiWUAD+Zc02gAIwZ1T/lL7QDkhChpE98EahJ5S/jIUrr7fYLgfhb6BSgYCzY8axiTccO0xO7G2Vdv9mG9jwLklSjB71Hx6II To: libcamera-devel Subject: [libcamera-devel] [PATCH 3/4] qcam: main_window: Introduce hotplug support X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 May 2020 10:33:57 -0000 Signed-off-by: Umang Jain --- src/qcam/main_window.cpp | 31 +++++++++++++++++++++++++++++++ src/qcam/main_window.h | 3 +++ 2 files changed, 34 insertions(+) diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 7de0895..9db1647 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -71,6 +71,10 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) setCentralWidget(viewfinder_); adjustSize(); + /* Hotplug/unplug support */ + cm_->cameraAdded.connect(this, &MainWindow::addNewCamera); + cm_->cameraRemoved.connect(this, &MainWindow::removeCamera); + /* Open the camera and start capture. */ ret = openCamera(); if (ret < 0) { @@ -525,6 +529,33 @@ void MainWindow::stopCapture() setWindowTitle(title_); } +/* ----------------------------------------------------------------------------- + * Camera hotplugging support + */ + +void MainWindow::addNewCamera(Camera *cam) +{ + qInfo() << "Adding new camera: " << cam->name().c_str(); + cameraCombo_->addItem(QString::fromStdString(cam->name())); +} + +void MainWindow::removeCamera(Camera *cam) +{ + int camIndex = cameraCombo_->findText(QString::fromStdString(cam->name())); + + /* Check if the currently-streaming camera is removed. + * + * \todo Also analyse the edge-case where the only available + * camera is removed. */ + if (camIndex == cameraCombo_->currentIndex()) { + toggleCapture(false); + cameraCombo_->setCurrentIndex(0); + } + + qInfo() << "Removing camera: " << cam->name().c_str(); + cameraCombo_->removeItem(camIndex); +} + /* ----------------------------------------------------------------------------- * Image Save */ diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index 59fa2d9..cb2fa26 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -87,6 +87,9 @@ private: int startCapture(); void stopCapture(); + void addNewCamera(Camera *camera); + void removeCamera(Camera *camera); + void requestComplete(Request *request); void processCapture(); void processViewfinder(FrameBuffer *buffer); From patchwork Wed May 6 10:33:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 3692 Return-Path: Received: from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 03B9261698 for ; Wed, 6 May 2020 12:33:56 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="qJgcUaff"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com; h=from:subject:in-reply-to:references:mime-version:to:cc: content-transfer-encoding:content-type; s=s1; bh=cVkjUO5BjpbgYvPjS7Ub9dJ9A6WwFxXwH5SJcYlIxXA=; b=qJgcUaffKpeHNIZhg++dr/ce9Gqj+xr4TnLgu/KVEfcTVCnk3QtdV9GQKb2dZYoV1j0V Uv/JM0cZrbBCAMH9maihgBs8LDQvNqYz2run/wrx9wp32uz4HRZgv7nJo1EEphRUUmoruw O3t3WTLmSJiw5LM2LKZozj5vIVWH9Oz/M= Received: by filter0073p3las1.sendgrid.net with SMTP id filter0073p3las1-3640-5EB29293-16 2020-05-06 10:33:55.304344903 +0000 UTC m=+1773093.727196486 Received: from mail.uajain.com (unknown) by ismtpd0004p1maa1.sendgrid.net (SG) with ESMTP id P8_x8N4PRbSs4TaL1yjd6A for ; Wed, 06 May 2020 10:33:54.981 +0000 (UTC) From: Umang Jain Date: Wed, 06 May 2020 10:33:55 +0000 (UTC) Message-Id: <20200506103346.3433-5-email@uajain.com> In-Reply-To: <20200506103346.3433-1-email@uajain.com> References: <20200506103346.3433-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcYDswUgqLHty1lirORaEnteN0qcmeuvSogZGEEe3BYijD8Pro8oSDTZzlek2qF6WQhMQYR/09D8OsJUPsv5DM7FNqgTy70nLnpX1TmbNZHaeJTM1hdlL+bPmmqOUM8AxYb1XqTt4Wx0PyRnOTAEQt975chNisywfZmwWF640U9fysAUQywHFP9J8VoFnBsgz4 To: libcamera-devel Subject: [libcamera-devel] [PATCH 4/4] tests: Introduce hotplug hot-unplug unit test X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 May 2020 10:33:57 -0000 Signed-off-by: Umang Jain --- test/hotplug-cameras.cpp | 152 +++++++++++++++++++++++++++++++++++++++ test/meson.build | 1 + 2 files changed, 153 insertions(+) create mode 100644 test/hotplug-cameras.cpp diff --git a/test/hotplug-cameras.cpp b/test/hotplug-cameras.cpp new file mode 100644 index 0000000..7f1e5a5 --- /dev/null +++ b/test/hotplug-cameras.cpp @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2020, Umang Jain + * + * hotplug-cameras.cpp - Emulate cameraAdded/cameraRemoved signals in CameraManager + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "file.h" +#include "test.h" +#include "thread.h" + +using namespace std; +using namespace libcamera; + +class HotplugTest : public Test +{ +protected: + void cameraAddedHandler(Camera *cam) + { + cameraAddedPass_ = true; + } + + void cameraRemovedHandler(Camera *cam) + { + cameraRemovedPass_ = true; + } + + int init() + { + if (!File::exists("/sys/module/uvcvideo")) { + std::cout << "uvcvideo driver is not loaded, skipping" << std::endl; + return TestSkip; + } + + if (geteuid() != 0) { + std::cout << "This test requires root permissions, skipping" << std::endl; + return TestSkip; + } + + cm_ = new CameraManager(); + if (cm_->start()) { + std::cout << "Failed to start camera manager" << std::endl; + return TestFail; + } + + cameraAddedPass_ = false; + cameraRemovedPass_ = false; + + cm_->cameraAdded.connect(this, &HotplugTest::cameraAddedHandler); + cm_->cameraRemoved.connect(this, &HotplugTest::cameraRemovedHandler); + + uvc_toplevel_ = "/sys/module/uvcvideo/drivers/usb:uvcvideo/"; + + return 0; + } + + int run() + { + DIR *dir; + struct dirent *dirent, *dirent2; + std::string uvc_driver_dir; + bool uvc_driver_found = false; + + dir = opendir(uvc_toplevel_.c_str()); + /* Find a UVC device driver symlink, which we can bind/unbind */ + while ((dirent = readdir(dir)) != nullptr) { + if (dirent->d_type != DT_LNK) + continue; + + std::string child_dir = uvc_toplevel_ + dirent->d_name; + DIR *device_driver = opendir(child_dir.c_str()); + while ((dirent2 = readdir(device_driver)) != nullptr) { + if (strncmp(dirent2->d_name, "video4linux", 11) == 0) { + uvc_driver_dir = dirent->d_name; + uvc_driver_found = true; + break; + } + } + closedir(device_driver); + + if (uvc_driver_found) + break; + } + closedir(dir); + + /* If no UVC driver found, skip */ + if (!uvc_driver_found) + return TestSkip; + + /* Unbind a camera, process events */ + int fd1 = open("/sys/module/uvcvideo/drivers/usb:uvcvideo/unbind", O_WRONLY); + write(fd1, uvc_driver_dir.c_str(), uvc_driver_dir.size()); + close(fd1); + Timer timer; + timer.start(1000); + while (timer.isRunning()) + Thread::current()->eventDispatcher()->processEvents(); + + /* \todo: Fix this workaround of stopping and starting the camera-manager. + * We need to do this, so that cm_ release all references to the uvc media symlinks. + */ + cm_->stop(); + if (cm_->start()) { + std::cout << "Failed to restart camera-manager" << std::endl; + return TestFail; + } + + /* Bind the camera again, process events */ + int fd2 = open("/sys/module/uvcvideo/drivers/usb:uvcvideo/bind", O_WRONLY); + write(fd2, uvc_driver_dir.c_str(), uvc_driver_dir.size()); + close(fd2); + + timer.start(1000); + while (timer.isRunning()) + Thread::current()->eventDispatcher()->processEvents(); + + if (cameraAddedPass_ && cameraRemovedPass_) + return TestPass; + else + return TestFail; + } + + void cleanup() + { + cm_->stop(); + delete cm_; + } + +private: + CameraManager *cm_; + std::string uvc_toplevel_; + bool cameraRemovedPass_; + bool cameraAddedPass_; +}; + +TEST_REGISTER(HotplugTest) + diff --git a/test/meson.build b/test/meson.build index 5a45a85..383a7ea 100644 --- a/test/meson.build +++ b/test/meson.build @@ -29,6 +29,7 @@ internal_tests = [ ['file', 'file.cpp'], ['file-descriptor', 'file-descriptor.cpp'], ['message', 'message.cpp'], + ['hotplug-cameras', 'hotplug-cameras.cpp'], ['object', 'object.cpp'], ['object-invoke', 'object-invoke.cpp'], ['signal-threads', 'signal-threads.cpp'],