blob: f3517ae6c71ab7bc7d35e40c8d26656eaea516ff [file] [log] [blame]
/*
* Copyright 2018 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef CAMERA_INCLUDE_CROS_CAMERA_UDEV_WATCHER_H_
#define CAMERA_INCLUDE_CROS_CAMERA_UDEV_WATCHER_H_
#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: http://www.signal11.us/oss/udev/
// > 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 {
public:
class Observer {
public:
virtual ~Observer();
virtual void OnDeviceAdded(ScopedUdevDevicePtr device);
virtual void OnDeviceRemoved(ScopedUdevDevicePtr device);
};
// The observer must outlive this wathcer.
UdevWatcher(Observer* observer, std::string subsystem);
~UdevWatcher();
// Disallow copy constructor and assign operator.
UdevWatcher(const UdevWatcher&) = delete;
UdevWatcher& operator=(const UdevWatcher&) = delete;
// Start monitoring. This shuold 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();
private:
void OnReadable();
void StartOnThread(int fd, base::Callback<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
#endif // CAMERA_INCLUDE_CROS_CAMERA_UDEV_WATCHER_H_