Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #include <comdef.h> | 7 #include <comdef.h> |
| 8 #include <robuffer.h> | 8 #include <robuffer.h> |
| 9 #include <windows.devices.enumeration.h> | 9 #include <windows.devices.enumeration.h> |
| 10 #include <windows.devices.midi.h> | 10 #include <windows.devices.midi.h> |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 // Lifetime of the pointing buffer is controlled by the buffer object. | 111 // Lifetime of the pointing buffer is controlled by the buffer object. |
| 112 hr = buffer_byte_access->Buffer(out); | 112 hr = buffer_byte_access->Buffer(out); |
| 113 if (FAILED(hr)) { | 113 if (FAILED(hr)) { |
| 114 VLOG(1) << "Buffer failed: " << PrintHr(hr); | 114 VLOG(1) << "Buffer failed: " << PrintHr(hr); |
| 115 return hr; | 115 return hr; |
| 116 } | 116 } |
| 117 | 117 |
| 118 return S_OK; | 118 return S_OK; |
| 119 } | 119 } |
| 120 | 120 |
| 121 // Checks if given DeviceInformation represent a Microsoft GS Wavetable Synth | |
| 122 // instance. | |
| 123 bool IsMicrosoftSynthesizer(IDeviceInformation* info) { | |
| 124 auto midi_synthesizer_statics = | |
| 125 WrlStaticsFactory<IMidiSynthesizerStatics, | |
| 126 RuntimeClass_Windows_Devices_Midi_MidiSynthesizer>(); | |
| 127 boolean result = false; | |
| 128 HRESULT hr = midi_synthesizer_statics->IsSynthesizer(info, &result); | |
| 129 VLOG_IF(1, FAILED(hr)) << "IsSynthesizer failed: " << PrintHr(hr); | |
| 130 return result != 0; | |
|
Takashi Toyoshima
2016/08/31 07:10:21
|result| is bool from the beginning, right?
Shao-Chuan Lee
2016/08/31 07:16:51
'boolean' is actually unsigned char, casting it to
Takashi Toyoshima
2016/08/31 07:30:00
Wow, it isn't standard bool. OK, so as we discusse
Shao-Chuan Lee
2016/08/31 07:42:49
Done. https://msdn.microsoft.com/en-us/library/win
| |
| 131 } | |
| 132 | |
| 121 // Tokens with value = 0 are considered invalid (as in <wrl/event.h>). | 133 // Tokens with value = 0 are considered invalid (as in <wrl/event.h>). |
| 122 const int64_t kInvalidTokenValue = 0; | 134 const int64_t kInvalidTokenValue = 0; |
| 123 | 135 |
| 124 template <typename InterfaceType> | 136 template <typename InterfaceType> |
| 125 struct MidiPort { | 137 struct MidiPort { |
| 126 MidiPort() = default; | 138 MidiPort() = default; |
| 127 | 139 |
| 128 uint32_t index; | 140 uint32_t index; |
| 129 ScopedComPtr<InterfaceType> handle; | 141 ScopedComPtr<InterfaceType> handle; |
| 130 EventRegistrationToken token_MessageReceived; | 142 EventRegistrationToken token_MessageReceived; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 // thread. |weak_ptr| and |task_runner| are captured by lambda callbacks for | 194 // thread. |weak_ptr| and |task_runner| are captured by lambda callbacks for |
| 183 // posting jobs. Note that WinRT callback arguments should not be passed | 195 // posting jobs. Note that WinRT callback arguments should not be passed |
| 184 // outside the callback since the pointers may be unavailable afterwards. | 196 // outside the callback since the pointers may be unavailable afterwards. |
| 185 base::WeakPtr<MidiPortManager> weak_ptr = GetWeakPtrFromFactory(); | 197 base::WeakPtr<MidiPortManager> weak_ptr = GetWeakPtrFromFactory(); |
| 186 scoped_refptr<base::SingleThreadTaskRunner> task_runner = task_runner_; | 198 scoped_refptr<base::SingleThreadTaskRunner> task_runner = task_runner_; |
| 187 | 199 |
| 188 hr = watcher_->add_Added( | 200 hr = watcher_->add_Added( |
| 189 WRL::Callback<ITypedEventHandler<DeviceWatcher*, DeviceInformation*>>( | 201 WRL::Callback<ITypedEventHandler<DeviceWatcher*, DeviceInformation*>>( |
| 190 [weak_ptr, task_runner](IDeviceWatcher* watcher, | 202 [weak_ptr, task_runner](IDeviceWatcher* watcher, |
| 191 IDeviceInformation* info) { | 203 IDeviceInformation* info) { |
| 204 // Disable Microsoft GS Wavetable Synth due to security reasons. | |
| 205 // http://crbug.com/499279 | |
| 206 if (IsMicrosoftSynthesizer(info)) | |
| 207 return S_OK; | |
| 208 | |
| 192 std::string dev_id = GetIdString(info), | 209 std::string dev_id = GetIdString(info), |
| 193 dev_name = GetNameString(info); | 210 dev_name = GetNameString(info); |
| 194 | 211 |
| 195 task_runner->PostTask( | 212 task_runner->PostTask( |
| 196 FROM_HERE, base::Bind(&MidiPortManager::OnAdded, weak_ptr, | 213 FROM_HERE, base::Bind(&MidiPortManager::OnAdded, weak_ptr, |
| 197 dev_id, dev_name)); | 214 dev_id, dev_name)); |
| 198 | 215 |
| 199 return S_OK; | 216 return S_OK; |
| 200 }) | 217 }) |
| 201 .Get(), | 218 .Get(), |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 349 | 366 |
| 350 // Ensures all methods are called on the COM thread. | 367 // Ensures all methods are called on the COM thread. |
| 351 base::ThreadChecker thread_checker_; | 368 base::ThreadChecker thread_checker_; |
| 352 | 369 |
| 353 private: | 370 private: |
| 354 // DeviceWatcher callbacks: | 371 // DeviceWatcher callbacks: |
| 355 void OnAdded(std::string dev_id, std::string dev_name) { | 372 void OnAdded(std::string dev_id, std::string dev_name) { |
| 356 DCHECK(thread_checker_.CalledOnValidThread()); | 373 DCHECK(thread_checker_.CalledOnValidThread()); |
| 357 CHECK(is_initialized_); | 374 CHECK(is_initialized_); |
| 358 | 375 |
| 359 // TODO(shaochuan): Disable Microsoft GS Wavetable Synth due to security | |
| 360 // reasons. http://crbug.com/499279 | |
| 361 | |
| 362 port_names_[dev_id] = dev_name; | 376 port_names_[dev_id] = dev_name; |
| 363 | 377 |
| 364 WRL::Wrappers::HString dev_id_hstring; | 378 WRL::Wrappers::HString dev_id_hstring; |
| 365 HRESULT hr = dev_id_hstring.Set(base::UTF8ToWide(dev_id).c_str()); | 379 HRESULT hr = dev_id_hstring.Set(base::UTF8ToWide(dev_id).c_str()); |
| 366 if (FAILED(hr)) { | 380 if (FAILED(hr)) { |
| 367 VLOG(1) << "Set failed: " << PrintHr(hr); | 381 VLOG(1) << "Set failed: " << PrintHr(hr); |
| 368 return; | 382 return; |
| 369 } | 383 } |
| 370 | 384 |
| 371 IAsyncOperation<RuntimeType*>* async_op; | 385 IAsyncOperation<RuntimeType*>* async_op; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 416 if (async_ops_.empty()) | 430 if (async_ops_.empty()) |
| 417 midi_manager_->OnPortManagerReady(); | 431 midi_manager_->OnPortManagerReady(); |
| 418 else | 432 else |
| 419 enumeration_completed_not_ready_ = true; | 433 enumeration_completed_not_ready_ = true; |
| 420 } | 434 } |
| 421 | 435 |
| 422 void OnRemoved(std::string dev_id) { | 436 void OnRemoved(std::string dev_id) { |
| 423 DCHECK(thread_checker_.CalledOnValidThread()); | 437 DCHECK(thread_checker_.CalledOnValidThread()); |
| 424 CHECK(is_initialized_); | 438 CHECK(is_initialized_); |
| 425 | 439 |
| 440 // Note: in case Microsoft GS Wavetable Synth triggers this event for some | |
| 441 // reason, it will be ignored here with log emitted. | |
| 426 MidiPort<InterfaceType>* port = GetPortByDeviceId(dev_id); | 442 MidiPort<InterfaceType>* port = GetPortByDeviceId(dev_id); |
| 427 if (!port) { | 443 if (!port) { |
| 428 VLOG(1) << "Removing non-existent port " << dev_id; | 444 VLOG(1) << "Removing non-existent port " << dev_id; |
| 429 return; | 445 return; |
| 430 } | 446 } |
| 431 | 447 |
| 432 SetPortState(port->index, MIDI_PORT_DISCONNECTED); | 448 SetPortState(port->index, MIDI_PORT_DISCONNECTED); |
| 433 | 449 |
| 434 RemovePortEventHandlers(port); | 450 RemovePortEventHandlers(port); |
| 435 port->handle = nullptr; | 451 port->handle = nullptr; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 494 virtual void SetPortState(uint32_t port_index, MidiPortState state) = 0; | 510 virtual void SetPortState(uint32_t port_index, MidiPortState state) = 0; |
| 495 | 511 |
| 496 // WeakPtrFactory has to be declared in derived class, use this method to | 512 // WeakPtrFactory has to be declared in derived class, use this method to |
| 497 // retrieve upcasted WeakPtr for posting tasks. | 513 // retrieve upcasted WeakPtr for posting tasks. |
| 498 virtual base::WeakPtr<MidiPortManager> GetWeakPtrFromFactory() = 0; | 514 virtual base::WeakPtr<MidiPortManager> GetWeakPtrFromFactory() = 0; |
| 499 | 515 |
| 500 // Midi{In,Out}PortStatics instance. | 516 // Midi{In,Out}PortStatics instance. |
| 501 ScopedComPtr<StaticsInterfaceType> midi_port_statics_; | 517 ScopedComPtr<StaticsInterfaceType> midi_port_statics_; |
| 502 | 518 |
| 503 // DeviceWatcher instance and event registration tokens for unsubscribing | 519 // DeviceWatcher instance and event registration tokens for unsubscribing |
| 504 // events in destructor. | 520 // events in destructor. |
|
Shao-Chuan Lee
2016/08/31 06:55:28
Should be StopWatcher() instead of destructor.
May
Takashi Toyoshima
2016/08/31 07:10:21
OK, let's fix this in a separate CL.
| |
| 505 ScopedComPtr<IDeviceWatcher> watcher_; | 521 ScopedComPtr<IDeviceWatcher> watcher_; |
| 506 EventRegistrationToken token_Added_ = {kInvalidTokenValue}, | 522 EventRegistrationToken token_Added_ = {kInvalidTokenValue}, |
| 507 token_EnumerationCompleted_ = {kInvalidTokenValue}, | 523 token_EnumerationCompleted_ = {kInvalidTokenValue}, |
| 508 token_Removed_ = {kInvalidTokenValue}, | 524 token_Removed_ = {kInvalidTokenValue}, |
| 509 token_Stopped_ = {kInvalidTokenValue}, | 525 token_Stopped_ = {kInvalidTokenValue}, |
| 510 token_Updated_ = {kInvalidTokenValue}; | 526 token_Updated_ = {kInvalidTokenValue}; |
| 511 | 527 |
| 512 // All manipulations to these fields should be done on COM thread. | 528 // All manipulations to these fields should be done on COM thread. |
| 513 std::unordered_map<std::string, std::unique_ptr<MidiPort<InterfaceType>>> | 529 std::unordered_map<std::string, std::unique_ptr<MidiPort<InterfaceType>>> |
| 514 ports_; | 530 ports_; |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 805 if (++port_manager_ready_count_ == 2) | 821 if (++port_manager_ready_count_ == 2) |
| 806 CompleteInitialization(Result::OK); | 822 CompleteInitialization(Result::OK); |
| 807 } | 823 } |
| 808 | 824 |
| 809 MidiManager* MidiManager::Create() { | 825 MidiManager* MidiManager::Create() { |
| 810 return new MidiManagerWinrt(); | 826 return new MidiManagerWinrt(); |
| 811 } | 827 } |
| 812 | 828 |
| 813 } // namespace midi | 829 } // namespace midi |
| 814 } // namespace media | 830 } // namespace media |
| OLD | NEW |