blob: e22662f2020c1c2c0b0f9e1ffd43171500181a0a [file] [log] [blame]
* Copyright 2018 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
#include <memory>
#include <string>
#include <libudev.h>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/threading/thread.h>
#include "cros-camera/common.h"
#include "cros-camera/export.h"
#include "cros-camera/scoped_udev.h"
namespace cros {
// ref:
// > It's important to note that when using monitoring and enumeration together,
// > that monitoring should be enabled before enumeration. This way, any events
// > (for example devices being attached to the system) which happen during
// > enumeration will not be lost. If enumeration is done before monitoring is
// > enabled, any device attached between the time the enumeration happens and
// > when monitoring starts will be missed. The algorithm should be:
// > 1. Set up monitoring.
// > 2. Enumerate devices (optionally opening desired devices).
// > 3. Begin checking the monitoring interface for events.
// TODO(shik): There are some other packages in CrOS use libudev in the wrong
// way. We should fix them as well.
class CROS_CAMERA_EXPORT UdevWatcher {
class Observer {
virtual ~Observer();
virtual void OnDeviceAdded(ScopedUdevDevicePtr device);
virtual void OnDeviceRemoved(ScopedUdevDevicePtr device);
// The observer must outlive this watcher.
UdevWatcher(Observer* observer, std::string subsystem);
// Disallow copy constructor and assign operator.
UdevWatcher(const UdevWatcher&) = delete;
UdevWatcher& operator=(const UdevWatcher&) = delete;
// Start monitoring. This should be called before EnumerateExistingDevices().
// All callbacks will be run on |task_runner|.
bool Start(scoped_refptr<base::SingleThreadTaskRunner> task_runner);
// Synchronously enumerates the all devices known to udev, and calling
// |observer_->OnDeviceAdded()| for each device.
bool EnumerateExistingDevices();
void OnReadable();
void StartOnThread(int fd, base::OnceCallback<void(bool)> callback);
void StopOnThread();
Observer* observer_;
std::string subsystem_;
base::Thread thread_;
std::unique_ptr<base::FileDescriptorWatcher::Controller> watcher_;
ScopedUdevPtr udev_;
ScopedUdevMonitorPtr mon_;
scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner_;
} // namespace cros