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

Side by Side Diff: device/core/device_monitor_win.cc

Issue 2417043002: Move device/core files to device/base directory. (Closed)
Patch Set: Fix ChromeOS build Created 4 years, 2 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/core/device_monitor_win.h ('k') | device/core/mock_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
(Empty)
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.
4
5 #include "device/core/device_monitor_win.h"
6
7 #include <dbt.h>
8 #include <windows.h>
9
10 #include <map>
11 #include <memory>
12
13 #include "base/at_exit.h"
14 #include "base/bind.h"
15 #include "base/macros.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/sys_string_conversions.h"
18 #include "base/win/message_window.h"
19
20 namespace device {
21
22 class DeviceMonitorMessageWindow;
23
24 namespace {
25
26 const wchar_t kWindowClassName[] = L"DeviceMonitorMessageWindow";
27 DeviceMonitorMessageWindow* g_message_window;
28
29 // Provides basic comparability for GUIDs so that they can be used as keys to an
30 // STL map.
31 struct CompareGUID {
32 bool operator()(const GUID& a, const GUID& b) const {
33 return memcmp(&a, &b, sizeof a) < 0;
34 }
35 };
36 }
37
38 // This singleton class manages a shared message window for all registered
39 // device notification observers. It vends one instance of DeviceManagerWin for
40 // each unique GUID it sees.
41 class DeviceMonitorMessageWindow {
42 public:
43 static DeviceMonitorMessageWindow* GetInstance() {
44 if (!g_message_window) {
45 g_message_window = new DeviceMonitorMessageWindow();
46 if (g_message_window->Init()) {
47 base::AtExitManager::RegisterTask(
48 base::Bind(&base::DeletePointer<DeviceMonitorMessageWindow>,
49 base::Unretained(g_message_window)));
50 } else {
51 delete g_message_window;
52 g_message_window = nullptr;
53 }
54 }
55 return g_message_window;
56 }
57
58 DeviceMonitorWin* GetForDeviceInterface(const GUID& device_interface) {
59 std::unique_ptr<DeviceMonitorWin>& device_monitor =
60 device_monitors_[device_interface];
61 if (!device_monitor) {
62 device_monitor.reset(new DeviceMonitorWin());
63 }
64 return device_monitor.get();
65 }
66
67 DeviceMonitorWin* GetForAllInterfaces() { return &all_device_monitor_; }
68
69 private:
70 friend void base::DeletePointer<DeviceMonitorMessageWindow>(
71 DeviceMonitorMessageWindow* message_window);
72
73 DeviceMonitorMessageWindow() {
74 }
75
76 ~DeviceMonitorMessageWindow() {
77 if (notify_handle_) {
78 UnregisterDeviceNotification(notify_handle_);
79 }
80 }
81
82 bool Init() {
83 window_.reset(new base::win::MessageWindow());
84 if (!window_->CreateNamed(
85 base::Bind(&DeviceMonitorMessageWindow::HandleMessage,
86 base::Unretained(this)),
87 base::string16(kWindowClassName))) {
88 LOG(ERROR) << "Failed to create message window: " << kWindowClassName;
89 return false;
90 }
91
92 DEV_BROADCAST_DEVICEINTERFACE db = {sizeof(DEV_BROADCAST_DEVICEINTERFACE),
93 DBT_DEVTYP_DEVICEINTERFACE};
94 notify_handle_ = RegisterDeviceNotification(
95 window_->hwnd(), &db,
96 DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
97 if (!notify_handle_) {
98 PLOG(ERROR) << "Failed to register for device notifications";
99 return false;
100 }
101
102 return true;
103 }
104
105 bool HandleMessage(UINT message,
106 WPARAM wparam,
107 LPARAM lparam,
108 LRESULT* result) {
109 if (message == WM_DEVICECHANGE &&
110 (wparam == DBT_DEVICEARRIVAL || wparam == DBT_DEVICEREMOVECOMPLETE)) {
111 DEV_BROADCAST_HDR* hdr = reinterpret_cast<DEV_BROADCAST_HDR*>(lparam);
112 if (hdr->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
113 return false;
114
115 DEV_BROADCAST_DEVICEINTERFACE* db =
116 reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(hdr);
117
118 DeviceMonitorWin* device_monitor = nullptr;
119 const auto& map_entry = device_monitors_.find(db->dbcc_classguid);
120 if (map_entry != device_monitors_.end())
121 device_monitor = map_entry->second.get();
122
123 std::string device_path(base::SysWideToUTF8(db->dbcc_name));
124 DCHECK(base::IsStringASCII(device_path));
125 device_path = base::ToLowerASCII(device_path);
126
127 if (wparam == DBT_DEVICEARRIVAL) {
128 if (device_monitor) {
129 device_monitor->NotifyDeviceAdded(db->dbcc_classguid, device_path);
130 }
131 all_device_monitor_.NotifyDeviceAdded(db->dbcc_classguid, device_path);
132 } else if (wparam == DBT_DEVICEREMOVECOMPLETE) {
133 if (device_monitor) {
134 device_monitor->NotifyDeviceRemoved(db->dbcc_classguid, device_path);
135 }
136 all_device_monitor_.NotifyDeviceRemoved(db->dbcc_classguid,
137 device_path);
138 }
139 *result = NULL;
140 return true;
141 }
142 return false;
143 }
144
145 std::map<GUID, std::unique_ptr<DeviceMonitorWin>, CompareGUID>
146 device_monitors_;
147 DeviceMonitorWin all_device_monitor_;
148 std::unique_ptr<base::win::MessageWindow> window_;
149 HDEVNOTIFY notify_handle_ = NULL;
150
151 DISALLOW_COPY_AND_ASSIGN(DeviceMonitorMessageWindow);
152 };
153
154 void DeviceMonitorWin::Observer::OnDeviceAdded(const GUID& class_guid,
155 const std::string& device_path) {
156 }
157
158 void DeviceMonitorWin::Observer::OnDeviceRemoved(
159 const GUID& class_guid,
160 const std::string& device_path) {
161 }
162
163 // static
164 DeviceMonitorWin* DeviceMonitorWin::GetForDeviceInterface(
165 const GUID& device_interface) {
166 DeviceMonitorMessageWindow* message_window =
167 DeviceMonitorMessageWindow::GetInstance();
168 if (message_window) {
169 return message_window->GetForDeviceInterface(device_interface);
170 }
171 return nullptr;
172 }
173
174 // static
175 DeviceMonitorWin* DeviceMonitorWin::GetForAllInterfaces() {
176 DeviceMonitorMessageWindow* message_window =
177 DeviceMonitorMessageWindow::GetInstance();
178 if (message_window) {
179 return message_window->GetForAllInterfaces();
180 }
181 return nullptr;
182 }
183
184 DeviceMonitorWin::~DeviceMonitorWin() {
185 }
186
187 void DeviceMonitorWin::AddObserver(Observer* observer) {
188 observer_list_.AddObserver(observer);
189 }
190
191 void DeviceMonitorWin::RemoveObserver(Observer* observer) {
192 observer_list_.RemoveObserver(observer);
193 }
194
195 DeviceMonitorWin::DeviceMonitorWin() {
196 }
197
198 void DeviceMonitorWin::NotifyDeviceAdded(const GUID& class_guid,
199 const std::string& device_path) {
200 FOR_EACH_OBSERVER(Observer, observer_list_,
201 OnDeviceAdded(class_guid, device_path));
202 }
203
204 void DeviceMonitorWin::NotifyDeviceRemoved(const GUID& class_guid,
205 const std::string& device_path) {
206 FOR_EACH_OBSERVER(Observer, observer_list_,
207 OnDeviceRemoved(class_guid, device_path));
208 }
209
210 } // namespace device
OLDNEW
« no previous file with comments | « device/core/device_monitor_win.h ('k') | device/core/mock_device_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698