[Storage] Blob Storage Refactoring pt 1:
[chromium-blink-merge.git] / device / hid / hid_service.cc
blobc0b176ea0f719d84beb525abff071b8e21e2bcb0
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "device/hid/hid_service.h"
7 #include "base/at_exit.h"
8 #include "base/bind.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/stl_util.h"
13 #if defined(OS_LINUX) && defined(USE_UDEV)
14 #include "device/hid/hid_service_linux.h"
15 #elif defined(OS_MACOSX)
16 #include "device/hid/hid_service_mac.h"
17 #else
18 #include "device/hid/hid_service_win.h"
19 #endif
21 namespace device {
23 namespace {
25 HidService* g_service;
28 void HidService::Observer::OnDeviceAdded(
29 scoped_refptr<HidDeviceInfo> device_info) {
32 void HidService::Observer::OnDeviceRemoved(
33 scoped_refptr<HidDeviceInfo> device_info) {
36 HidService* HidService::GetInstance(
37 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) {
38 if (g_service == NULL) {
39 #if defined(OS_LINUX) && defined(USE_UDEV)
40 g_service = new HidServiceLinux(file_task_runner);
41 #elif defined(OS_MACOSX)
42 g_service = new HidServiceMac(file_task_runner);
43 #elif defined(OS_WIN)
44 g_service = new HidServiceWin();
45 #endif
46 if (g_service != nullptr) {
47 base::AtExitManager::RegisterTask(base::Bind(
48 &base::DeletePointer<HidService>, base::Unretained(g_service)));
51 return g_service;
54 void HidService::SetInstanceForTest(HidService* instance) {
55 DCHECK(!g_service);
56 g_service = instance;
57 base::AtExitManager::RegisterTask(base::Bind(&base::DeletePointer<HidService>,
58 base::Unretained(g_service)));
61 void HidService::GetDevices(const GetDevicesCallback& callback) {
62 DCHECK(thread_checker_.CalledOnValidThread());
63 if (enumeration_ready_) {
64 std::vector<scoped_refptr<HidDeviceInfo>> devices;
65 for (const auto& map_entry : devices_) {
66 devices.push_back(map_entry.second);
68 base::MessageLoop::current()->PostTask(FROM_HERE,
69 base::Bind(callback, devices));
70 } else {
71 pending_enumerations_.push_back(callback);
75 void HidService::AddObserver(HidService::Observer* observer) {
76 observer_list_.AddObserver(observer);
79 void HidService::RemoveObserver(HidService::Observer* observer) {
80 observer_list_.RemoveObserver(observer);
83 // Fills in the device info struct of the given device_id.
84 scoped_refptr<HidDeviceInfo> HidService::GetDeviceInfo(
85 const HidDeviceId& device_id) const {
86 DCHECK(thread_checker_.CalledOnValidThread());
87 DeviceMap::const_iterator it = devices_.find(device_id);
88 if (it == devices_.end()) {
89 return nullptr;
91 return it->second;
94 HidService::HidService() : enumeration_ready_(false) {
97 HidService::~HidService() {
98 DCHECK(thread_checker_.CalledOnValidThread());
101 void HidService::AddDevice(scoped_refptr<HidDeviceInfo> device_info) {
102 DCHECK(thread_checker_.CalledOnValidThread());
103 if (!ContainsKey(devices_, device_info->device_id())) {
104 devices_[device_info->device_id()] = device_info;
106 if (enumeration_ready_) {
107 FOR_EACH_OBSERVER(Observer, observer_list_, OnDeviceAdded(device_info));
112 void HidService::RemoveDevice(const HidDeviceId& device_id) {
113 DCHECK(thread_checker_.CalledOnValidThread());
114 DeviceMap::iterator it = devices_.find(device_id);
115 if (it != devices_.end()) {
116 if (enumeration_ready_) {
117 FOR_EACH_OBSERVER(Observer, observer_list_, OnDeviceRemoved(it->second));
119 devices_.erase(it);
123 void HidService::FirstEnumerationComplete() {
124 enumeration_ready_ = true;
126 if (!pending_enumerations_.empty()) {
127 std::vector<scoped_refptr<HidDeviceInfo>> devices;
128 for (const auto& map_entry : devices_) {
129 devices.push_back(map_entry.second);
132 for (const GetDevicesCallback& callback : pending_enumerations_) {
133 callback.Run(devices);
135 pending_enumerations_.clear();
139 } // namespace device