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 "extensions/browser/api/hid/hid_device_manager.h"
10 #include "base/lazy_instance.h"
11 #include "device/hid/hid_service.h"
12 #include "extensions/browser/api/extensions_api_client.h"
14 using device::HidService
;
15 using device::HidUsageAndPage
;
17 namespace extensions
{
19 HidDeviceManager::HidDeviceManager(content::BrowserContext
* context
)
20 : next_resource_id_(0) {}
22 HidDeviceManager::~HidDeviceManager() {}
25 BrowserContextKeyedAPIFactory
<HidDeviceManager
>*
26 HidDeviceManager::GetFactoryInstance() {
27 static base::LazyInstance
<BrowserContextKeyedAPIFactory
<HidDeviceManager
> >
28 factory
= LAZY_INSTANCE_INITIALIZER
;
29 return &factory
.Get();
32 scoped_ptr
<base::ListValue
> HidDeviceManager::GetApiDevices(
34 uint16_t product_id
) {
37 HidService
* hid_service
= ExtensionsAPIClient::Get()->GetHidService();
39 base::ListValue
* api_devices
= new base::ListValue();
40 for (ResourceIdToDeviceIdMap::const_iterator device_iter
=
42 device_iter
!= device_ids_
.end();
44 int resource_id
= device_iter
->first
;
45 device::HidDeviceId device_id
= device_iter
->second
;
46 device::HidDeviceInfo device_info
;
48 if (hid_service
->GetDeviceInfo(device_id
, &device_info
)) {
49 if (device_info
.vendor_id
== vendor_id
&&
50 device_info
.product_id
== product_id
) {
51 core_api::hid::HidDeviceInfo api_device_info
;
52 api_device_info
.device_id
= resource_id
;
53 api_device_info
.vendor_id
= device_info
.vendor_id
;
54 api_device_info
.product_id
= device_info
.product_id
;
55 api_device_info
.max_input_report_size
=
56 device_info
.max_input_report_size
;
57 api_device_info
.max_output_report_size
=
58 device_info
.max_output_report_size
;
59 api_device_info
.max_feature_report_size
=
60 device_info
.max_feature_report_size
;
62 for (std::vector
<device::HidCollectionInfo
>::const_iterator
63 collections_iter
= device_info
.collections
.begin();
64 collections_iter
!= device_info
.collections
.end();
66 device::HidCollectionInfo collection
= *collections_iter
;
68 // Don't expose sensitive data.
69 if (collection
.usage
.IsProtected()) {
73 core_api::hid::HidCollectionInfo
* api_collection
=
74 new core_api::hid::HidCollectionInfo();
75 api_collection
->usage_page
= collection
.usage
.usage_page
;
76 api_collection
->usage
= collection
.usage
.usage
;
78 api_collection
->report_ids
.resize(collection
.report_ids
.size());
79 std::copy(collection
.report_ids
.begin(),
80 collection
.report_ids
.end(),
81 api_collection
->report_ids
.begin());
83 api_device_info
.collections
.push_back(
84 make_linked_ptr(api_collection
));
87 // Expose devices with which user can communicate.
88 if (api_device_info
.collections
.size() > 0)
89 api_devices
->Append(api_device_info
.ToValue().release());
94 return scoped_ptr
<base::ListValue
>(api_devices
);
97 bool HidDeviceManager::GetDeviceInfo(int resource_id
,
98 device::HidDeviceInfo
* device_info
) {
100 HidService
* hid_service
= ExtensionsAPIClient::Get()->GetHidService();
103 ResourceIdToDeviceIdMap::const_iterator device_iter
=
104 device_ids_
.find(resource_id
);
105 if (device_iter
== device_ids_
.end())
108 return hid_service
->GetDeviceInfo(device_iter
->second
, device_info
);
111 void HidDeviceManager::UpdateDevices() {
112 thread_checker_
.CalledOnValidThread();
113 HidService
* hid_service
= ExtensionsAPIClient::Get()->GetHidService();
116 std::vector
<device::HidDeviceInfo
> devices
;
117 hid_service
->GetDevices(&devices
);
119 // Build an updated bidi mapping between resource ID and underlying device ID.
120 DeviceIdToResourceIdMap new_resource_ids
;
121 ResourceIdToDeviceIdMap new_device_ids
;
122 for (std::vector
<device::HidDeviceInfo
>::const_iterator iter
=
124 iter
!= devices
.end();
126 const device::HidDeviceInfo
& device_info
= *iter
;
127 DeviceIdToResourceIdMap::iterator resource_iter
=
128 resource_ids_
.find(device_info
.device_id
);
130 if (resource_iter
!= resource_ids_
.end()) {
131 new_id
= resource_iter
->second
;
133 DCHECK_LT(next_resource_id_
, std::numeric_limits
<int>::max());
134 new_id
= next_resource_id_
++;
136 new_resource_ids
[device_info
.device_id
] = new_id
;
137 new_device_ids
[new_id
] = device_info
.device_id
;
139 device_ids_
.swap(new_device_ids
);
140 resource_ids_
.swap(new_resource_ids
);
143 } // namespace extensions