Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: device/hid/hid_service_win.cc

Issue 1312993008: Manage HidService lifetime in DeviceClient implementations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@remove_usb_service_get_instance
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/hid/hid_service_win.h ('k') | device/test/test_device_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "device/hid/hid_service_win.h" 5 #include "device/hid/hid_service_win.h"
6 6
7 #define INITGUID 7 #define INITGUID
8 8
9 #include <dbt.h> 9 #include <dbt.h>
10 #include <setupapi.h> 10 #include <setupapi.h>
(...skipping 11 matching lines...) Expand all
22 #include "device/hid/hid_connection_win.h" 22 #include "device/hid/hid_connection_win.h"
23 #include "device/hid/hid_device_info.h" 23 #include "device/hid/hid_device_info.h"
24 #include "net/base/io_buffer.h" 24 #include "net/base/io_buffer.h"
25 25
26 // Setup API is required to enumerate HID devices. 26 // Setup API is required to enumerate HID devices.
27 #pragma comment(lib, "setupapi.lib") 27 #pragma comment(lib, "setupapi.lib")
28 #pragma comment(lib, "hid.lib") 28 #pragma comment(lib, "hid.lib")
29 29
30 namespace device { 30 namespace device {
31 31
32 namespace {
33
34 void Noop() {
35 // This function does nothing.
36 }
37 }
38
39 HidServiceWin::HidServiceWin( 32 HidServiceWin::HidServiceWin(
40 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) 33 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner)
41 : file_task_runner_(file_task_runner), 34 : file_task_runner_(file_task_runner),
42 device_observer_(this), 35 device_observer_(this),
43 weak_factory_(this) { 36 weak_factory_(this) {
44 task_runner_ = base::ThreadTaskRunnerHandle::Get(); 37 task_runner_ = base::ThreadTaskRunnerHandle::Get();
45 DCHECK(task_runner_.get()); 38 DCHECK(task_runner_.get());
46 DeviceMonitorWin* device_monitor = 39 DeviceMonitorWin* device_monitor =
47 DeviceMonitorWin::GetForDeviceInterface(GUID_DEVINTERFACE_HID); 40 DeviceMonitorWin::GetForDeviceInterface(GUID_DEVINTERFACE_HID);
48 if (device_monitor) { 41 if (device_monitor) {
49 device_observer_.Add(device_monitor); 42 device_observer_.Add(device_monitor);
50 } 43 }
51 file_task_runner_->PostTask( 44 file_task_runner_->PostTask(
52 FROM_HERE, base::Bind(&HidServiceWin::EnumerateOnFileThread, 45 FROM_HERE, base::Bind(&HidServiceWin::EnumerateOnFileThread,
53 weak_factory_.GetWeakPtr(), task_runner_)); 46 weak_factory_.GetWeakPtr(), task_runner_));
54 } 47 }
55 48
49 HidServiceWin::~HidServiceWin() {}
50
56 void HidServiceWin::Connect(const HidDeviceId& device_id, 51 void HidServiceWin::Connect(const HidDeviceId& device_id,
57 const ConnectCallback& callback) { 52 const ConnectCallback& callback) {
58 DCHECK(thread_checker_.CalledOnValidThread()); 53 DCHECK(thread_checker_.CalledOnValidThread());
59 const auto& map_entry = devices().find(device_id); 54 const auto& map_entry = devices().find(device_id);
60 if (map_entry == devices().end()) { 55 if (map_entry == devices().end()) {
61 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); 56 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr));
62 return; 57 return;
63 } 58 }
64 scoped_refptr<HidDeviceInfo> device_info = map_entry->second; 59 scoped_refptr<HidDeviceInfo> device_info = map_entry->second;
65 60
66 base::win::ScopedHandle file(OpenDevice(device_info->device_id())); 61 base::win::ScopedHandle file(OpenDevice(device_info->device_id()));
67 if (!file.IsValid()) { 62 if (!file.IsValid()) {
68 HID_PLOG(EVENT) << "Failed to open device"; 63 HID_PLOG(EVENT) << "Failed to open device";
69 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); 64 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr));
70 return; 65 return;
71 } 66 }
72 67
73 task_runner_->PostTask( 68 task_runner_->PostTask(
74 FROM_HERE, 69 FROM_HERE,
75 base::Bind(callback, new HidConnectionWin(device_info, file.Pass()))); 70 base::Bind(callback, new HidConnectionWin(device_info, file.Pass())));
76 } 71 }
77 72
78 HidServiceWin::~HidServiceWin() {
79 }
80
81 // static 73 // static
82 void HidServiceWin::EnumerateOnFileThread( 74 void HidServiceWin::EnumerateOnFileThread(
83 base::WeakPtr<HidServiceWin> service, 75 base::WeakPtr<HidServiceWin> service,
84 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { 76 scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
85 HDEVINFO device_info_set = 77 HDEVINFO device_info_set =
86 SetupDiGetClassDevs(&GUID_DEVINTERFACE_HID, NULL, NULL, 78 SetupDiGetClassDevs(&GUID_DEVINTERFACE_HID, NULL, NULL,
87 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 79 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
88 80
89 if (device_info_set != INVALID_HANDLE_VALUE) { 81 if (device_info_set != INVALID_HANDLE_VALUE) {
90 SP_DEVICE_INTERFACE_DATA device_interface_data; 82 SP_DEVICE_INTERFACE_DATA device_interface_data;
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 FROM_HERE, 271 FROM_HERE,
280 base::Bind(&HidServiceWin::AddDeviceOnFileThread, 272 base::Bind(&HidServiceWin::AddDeviceOnFileThread,
281 weak_factory_.GetWeakPtr(), task_runner_, device_path)); 273 weak_factory_.GetWeakPtr(), task_runner_, device_path));
282 } 274 }
283 275
284 void HidServiceWin::OnDeviceRemoved(const GUID& class_guid, 276 void HidServiceWin::OnDeviceRemoved(const GUID& class_guid,
285 const std::string& device_path) { 277 const std::string& device_path) {
286 // Execute a no-op closure on the file task runner to synchronize with any 278 // Execute a no-op closure on the file task runner to synchronize with any
287 // devices that are still being enumerated. 279 // devices that are still being enumerated.
288 file_task_runner_->PostTaskAndReply( 280 file_task_runner_->PostTaskAndReply(
289 FROM_HERE, base::Bind(&Noop), 281 FROM_HERE, base::Bind(&base::DoNothing),
290 base::Bind(&HidServiceWin::RemoveDevice, weak_factory_.GetWeakPtr(), 282 base::Bind(&HidServiceWin::RemoveDevice, weak_factory_.GetWeakPtr(),
291 device_path)); 283 device_path));
292 } 284 }
293 285
294 // static 286 // static
295 base::win::ScopedHandle HidServiceWin::OpenDevice( 287 base::win::ScopedHandle HidServiceWin::OpenDevice(
296 const std::string& device_path) { 288 const std::string& device_path) {
297 base::win::ScopedHandle file( 289 base::win::ScopedHandle file(
298 CreateFileA(device_path.c_str(), GENERIC_WRITE | GENERIC_READ, 290 CreateFileA(device_path.c_str(), GENERIC_WRITE | GENERIC_READ,
299 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 291 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
300 FILE_FLAG_OVERLAPPED, NULL)); 292 FILE_FLAG_OVERLAPPED, NULL));
301 if (!file.IsValid() && 293 if (!file.IsValid() &&
302 GetLastError() == base::File::FILE_ERROR_ACCESS_DENIED) { 294 GetLastError() == base::File::FILE_ERROR_ACCESS_DENIED) {
303 file.Set(CreateFileA(device_path.c_str(), GENERIC_READ, FILE_SHARE_READ, 295 file.Set(CreateFileA(device_path.c_str(), GENERIC_READ, FILE_SHARE_READ,
304 NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)); 296 NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL));
305 } 297 }
306 return file.Pass(); 298 return file.Pass();
307 } 299 }
308 300
309 } // namespace device 301 } // namespace device
OLDNEW
« no previous file with comments | « device/hid/hid_service_win.h ('k') | device/test/test_device_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698