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

Side by Side Diff: media/midi/midi_manager_winrt.cc

Issue 2309253002: Retrieve driver information in WinRT WebMIDI backend (Closed)
Patch Set: move comment Created 4 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "media/midi/midi_manager_winrt.h" 5 #include "media/midi/midi_manager_winrt.h"
6 6
7 // TODO(shaochuan): Remove this once clang supports uuid syntax in <robuffer.h>. 7 // TODO(shaochuan): Remove this once clang supports uuid syntax in <robuffer.h>.
8 // https://reviews.llvm.org/D23895 8 // https://reviews.llvm.org/D23895
9 namespace Windows { 9 namespace Windows {
10 namespace Storage { 10 namespace Storage {
11 namespace Streams { 11 namespace Streams {
12 #pragma warning(disable : 4467) 12 #pragma warning(disable : 4467)
13 struct __declspec(uuid("905a0fef-bc53-11df-8c49-001e4fc686da")) 13 struct __declspec(uuid("905a0fef-bc53-11df-8c49-001e4fc686da"))
14 IBufferByteAccess; 14 IBufferByteAccess;
15 } 15 }
16 } 16 }
17 } 17 }
18 18
19 #include <comdef.h> 19 #include <comdef.h>
20 #include <robuffer.h> 20 #include <robuffer.h>
21 #include <setupapi.h>
21 #include <windows.devices.enumeration.h> 22 #include <windows.devices.enumeration.h>
22 #include <windows.devices.midi.h> 23 #include <windows.devices.midi.h>
23 #include <wrl/event.h> 24 #include <wrl/event.h>
24 25
25 #include <iomanip> 26 #include <iomanip>
26 #include <unordered_map> 27 #include <unordered_map>
27 #include <unordered_set> 28 #include <unordered_set>
28 29
29 #include "base/bind.h" 30 #include "base/bind.h"
30 #include "base/lazy_instance.h" 31 #include "base/lazy_instance.h"
31 #include "base/scoped_generic.h" 32 #include "base/scoped_generic.h"
33 #include "base/strings/string_util.h"
32 #include "base/strings/utf_string_conversions.h" 34 #include "base/strings/utf_string_conversions.h"
33 #include "base/threading/thread_checker.h" 35 #include "base/threading/thread_checker.h"
34 #include "base/threading/thread_task_runner_handle.h" 36 #include "base/threading/thread_task_runner_handle.h"
35 #include "base/timer/timer.h" 37 #include "base/timer/timer.h"
36 #include "base/win/scoped_comptr.h" 38 #include "base/win/scoped_comptr.h"
37 #include "media/midi/midi_scheduler.h" 39 #include "media/midi/midi_scheduler.h"
38 40
39 namespace media { 41 namespace media {
40 namespace midi { 42 namespace midi {
41 namespace { 43 namespace {
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 bool IsMicrosoftSynthesizer(IDeviceInformation* info) { 256 bool IsMicrosoftSynthesizer(IDeviceInformation* info) {
255 auto midi_synthesizer_statics = 257 auto midi_synthesizer_statics =
256 WrlStaticsFactory<IMidiSynthesizerStatics, 258 WrlStaticsFactory<IMidiSynthesizerStatics,
257 RuntimeClass_Windows_Devices_Midi_MidiSynthesizer>(); 259 RuntimeClass_Windows_Devices_Midi_MidiSynthesizer>();
258 boolean result = FALSE; 260 boolean result = FALSE;
259 HRESULT hr = midi_synthesizer_statics->IsSynthesizer(info, &result); 261 HRESULT hr = midi_synthesizer_statics->IsSynthesizer(info, &result);
260 VLOG_IF(1, FAILED(hr)) << "IsSynthesizer failed: " << PrintHr(hr); 262 VLOG_IF(1, FAILED(hr)) << "IsSynthesizer failed: " << PrintHr(hr);
261 return result != FALSE; 263 return result != FALSE;
262 } 264 }
263 265
266 class ScopedDeviceInfoListTraits {
267 public:
268 static HDEVINFO InvalidValue() { return INVALID_HANDLE_VALUE; }
269
270 static void Free(HDEVINFO devinfo_set) {
271 SetupDiDestroyDeviceInfoList(devinfo_set);
272 }
273 };
274
275 using ScopedDeviceInfoList =
276 base::ScopedGeneric<HDEVINFO, ScopedDeviceInfoListTraits>;
277
278 // Retrieves manufacturer (provider) and version information of underlying
279 // device driver using Setup API, given device (interface) ID provided by WinRT.
280 // |out_manufacturer| and |out_driver_version| won't be modified if retrieval
281 // fails. Note that SetupDiBuildDriverInfoList() would block for a few hundred
282 // milliseconds so consider calling this function in an asynchronous manner.
283 //
284 // Device instance ID is extracted from device (interface) ID provided by WinRT
285 // APIs, for example from the following interface ID:
286 // \\?\SWD#MMDEVAPI#MIDII_60F39FCA.P_0002#{504be32c-ccf6-4d2c-b73f-6f8b3747e22b}
287 // we extract the device instance ID: SWD\MMDEVAPI\MIDII_60F39FCA.P_0002
288 void GetDriverInfoFromDeviceId(const std::string& dev_id,
289 std::string* out_manufacturer,
290 std::string* out_driver_version) {
291 base::string16 dev_instance_id =
292 base::UTF8ToWide(dev_id.substr(4, dev_id.size() - 43));
293 base::ReplaceChars(dev_instance_id, L"#", L"\\", &dev_instance_id);
294
295 ScopedDeviceInfoList devinfo_list(
296 SetupDiCreateDeviceInfoList(nullptr, nullptr));
297 if (!devinfo_list.is_valid()) {
298 VLOG(1) << "SetupDiCreateDeviceInfoList failed: "
299 << PrintHr(HRESULT_FROM_WIN32(GetLastError()));
300 return;
301 }
302
303 SP_DEVINFO_DATA devinfo_data = {0};
304 devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);
305 SP_DRVINFO_DATA drvinfo_data = {0};
306 drvinfo_data.cbSize = sizeof(SP_DRVINFO_DATA);
307
308 if (!SetupDiOpenDeviceInfo(devinfo_list.get(), dev_instance_id.c_str(),
309 nullptr, 0, &devinfo_data)) {
310 VLOG(1) << "SetupDiOpenDeviceInfo failed: "
311 << PrintHr(HRESULT_FROM_WIN32(GetLastError()));
312 return;
313 }
314
315 if (!SetupDiBuildDriverInfoList(devinfo_list.get(), &devinfo_data,
316 SPDIT_COMPATDRIVER)) {
317 VLOG(1) << "SetupDiBuildDriverInfoList failed: "
318 << PrintHr(HRESULT_FROM_WIN32(GetLastError()));
319 return;
320 }
321
322 // Assume only one entry in driver info list.
323 if (SetupDiEnumDriverInfo(devinfo_list.get(), &devinfo_data,
324 SPDIT_COMPATDRIVER, 0, &drvinfo_data)) {
325 *out_manufacturer = base::WideToUTF8(drvinfo_data.ProviderName);
326
327 std::stringstream ss;
328 ss << (drvinfo_data.DriverVersion >> 48) << "."
329 << (drvinfo_data.DriverVersion >> 32 & 0xffff) << "."
330 << (drvinfo_data.DriverVersion >> 16 & 0xffff) << "."
331 << (drvinfo_data.DriverVersion & 0xffff);
332 *out_driver_version = ss.str();
333 } else {
334 VLOG(1) << "SetupDiEnumDriverInfo failed: "
335 << PrintHr(HRESULT_FROM_WIN32(GetLastError()));
336 }
337
338 if (!SetupDiDestroyDriverInfoList(devinfo_list.get(), &devinfo_data,
339 SPDIT_COMPATDRIVER))
340 VLOG(1) << "SetupDiDestroyDriverInfoList failed: "
341 << PrintHr(HRESULT_FROM_WIN32(GetLastError()));
342 }
343
264 // Tokens with value = 0 are considered invalid (as in <wrl/event.h>). 344 // Tokens with value = 0 are considered invalid (as in <wrl/event.h>).
265 const int64_t kInvalidTokenValue = 0; 345 const int64_t kInvalidTokenValue = 0;
266 346
267 template <typename InterfaceType> 347 template <typename InterfaceType>
268 struct MidiPort { 348 struct MidiPort {
269 MidiPort() = default; 349 MidiPort() = default;
270 350
271 uint32_t index; 351 uint32_t index;
272 ScopedComPtr<InterfaceType> handle; 352 ScopedComPtr<InterfaceType> handle;
273 EventRegistrationToken token_MessageReceived; 353 EventRegistrationToken token_MessageReceived;
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 667
588 EventRegistrationToken token = {kInvalidTokenValue}; 668 EventRegistrationToken token = {kInvalidTokenValue};
589 if (!RegisterOnMessageReceived(handle, &token)) 669 if (!RegisterOnMessageReceived(handle, &token))
590 return; 670 return;
591 671
592 std::string dev_id = GetDeviceIdString(handle); 672 std::string dev_id = GetDeviceIdString(handle);
593 673
594 MidiPort<InterfaceType>* port = GetPortByDeviceId(dev_id); 674 MidiPort<InterfaceType>* port = GetPortByDeviceId(dev_id);
595 675
596 if (port == nullptr) { 676 if (port == nullptr) {
597 // TODO(crbug.com/642604): Fill in manufacturer and driver version. 677 std::string manufacturer = "Unknown", driver_version = "Unknown";
598 AddPort(MidiPortInfo(dev_id, std::string("Manufacturer"), 678 GetDriverInfoFromDeviceId(dev_id, &manufacturer, &driver_version);
599 port_names_[dev_id], std::string("DriverVersion"), 679
600 MIDI_PORT_OPENED)); 680 AddPort(MidiPortInfo(dev_id, manufacturer, port_names_[dev_id],
681 driver_version, MIDI_PORT_OPENED));
601 682
602 port = new MidiPort<InterfaceType>; 683 port = new MidiPort<InterfaceType>;
603 port->index = static_cast<uint32_t>(port_ids_.size()); 684 port->index = static_cast<uint32_t>(port_ids_.size());
604 685
605 ports_[dev_id].reset(port); 686 ports_[dev_id].reset(port);
606 port_ids_.push_back(dev_id); 687 port_ids_.push_back(dev_id);
607 } else { 688 } else {
608 SetPortState(port->index, MIDI_PORT_CONNECTED); 689 SetPortState(port->index, MIDI_PORT_CONNECTED);
609 } 690 }
610 691
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 void MidiManagerWinrt::OnPortManagerReady() { 1033 void MidiManagerWinrt::OnPortManagerReady() {
953 DCHECK(com_thread_checker_->CalledOnValidThread()); 1034 DCHECK(com_thread_checker_->CalledOnValidThread());
954 DCHECK(port_manager_ready_count_ < 2); 1035 DCHECK(port_manager_ready_count_ < 2);
955 1036
956 if (++port_manager_ready_count_ == 2) 1037 if (++port_manager_ready_count_ == 2)
957 CompleteInitialization(Result::OK); 1038 CompleteInitialization(Result::OK);
958 } 1039 }
959 1040
960 } // namespace midi 1041 } // namespace midi
961 } // namespace media 1042 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698