#ifndef SERVICES_DEVICE_HID_HID_SERVICE_H_
#define SERVICES_DEVICE_HID_HID_SERVICE_H_
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/check.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/sequence_checker.h"
#include "base/task/task_traits.h"
#include "services/device/hid/hid_device_info.h"
#include "services/device/public/mojom/hid.mojom.h"
namespace device {
class HidConnection;
class HidService {
public:
class Observer {
public:
virtual void OnDeviceAdded(mojom::HidDeviceInfoPtr info);
virtual void OnDeviceRemoved(mojom::HidDeviceInfoPtr info);
virtual void OnDeviceChanged(mojom::HidDeviceInfoPtr info);
};
using GetDevicesCallback =
base::OnceCallback<void(std::vector<mojom::HidDeviceInfoPtr>)>;
using ConnectCallback =
base::OnceCallback<void(scoped_refptr<HidConnection> connection)>;
static constexpr base::TaskTraits kBlockingTaskTraits = {
base::MayBlock(), base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN};
static std::unique_ptr<HidService> Create();
HidService(const HidService&) = delete;
HidService& operator=(const HidService&) = delete;
virtual ~HidService();
void GetDevices(GetDevicesCallback callback);
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
virtual void Connect(const std::string& device_guid,
bool allow_protected_reports,
bool allow_fido_reports,
ConnectCallback callback) = 0;
protected:
friend class HidConnectionTest;
typedef std::map<std::string, scoped_refptr<HidDeviceInfo>> DeviceMap;
HidService();
virtual base::WeakPtr<HidService> GetWeakPtr() = 0;
void AddDevice(scoped_refptr<HidDeviceInfo> info);
void RemoveDevice(const HidPlatformDeviceId& platform_device_id);
void FirstEnumerationComplete();
const DeviceMap& devices() const { return devices_; }
SEQUENCE_CHECKER(sequence_checker_);
private:
void RunPendingEnumerations();
std::optional<std::string> FindDeviceGuidInDeviceMap(
const HidPlatformDeviceId& platform_device_id);
scoped_refptr<HidDeviceInfo> FindSiblingDevice(
const HidDeviceInfo& device_info) const;
DeviceMap devices_;
bool enumeration_ready_ = false;
std::vector<GetDevicesCallback> pending_enumerations_;
base::ObserverList<Observer>::Unchecked observer_list_;
};
}
#endif