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 // TODO(shaochuan): Remove this once clang supports uuid syntax in <robuffer.h>. | |
| 8 // https://reviews.llvm.org/D23895 | |
|
Shao-Chuan Lee
2016/09/01 09:48:20
Definition in <robuffer.h> is using
[uuid(...)] s
| |
| 9 namespace Windows { | |
| 10 namespace Storage { | |
| 11 namespace Streams { | |
| 12 struct __declspec(uuid("905a0fef-bc53-11df-8c49-001e4fc686da")) | |
| 13 IBufferByteAccess; | |
| 14 } | |
| 15 } | |
| 16 } | |
| 17 | |
| 7 #include <comdef.h> | 18 #include <comdef.h> |
| 8 #include <robuffer.h> | 19 #include <robuffer.h> |
| 9 #include <windows.devices.enumeration.h> | 20 #include <windows.devices.enumeration.h> |
| 10 #include <windows.devices.midi.h> | 21 #include <windows.devices.midi.h> |
| 11 #include <wrl/event.h> | 22 #include <wrl/event.h> |
| 12 | 23 |
| 13 #include <iomanip> | 24 #include <iomanip> |
| 14 #include <unordered_map> | 25 #include <unordered_map> |
| 15 #include <unordered_set> | 26 #include <unordered_set> |
| 16 | 27 |
| 17 #include "base/bind.h" | 28 #include "base/bind.h" |
| 18 #include "base/lazy_instance.h" | 29 #include "base/lazy_instance.h" |
| 19 #include "base/scoped_generic.h" | 30 #include "base/scoped_generic.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 31 #include "base/strings/utf_string_conversions.h" |
| 21 #include "base/threading/thread_checker.h" | 32 #include "base/threading/thread_checker.h" |
| 22 #include "base/threading/thread_task_runner_handle.h" | 33 #include "base/threading/thread_task_runner_handle.h" |
| 23 #include "base/timer/timer.h" | 34 #include "base/timer/timer.h" |
| 24 #include "base/win/scoped_comptr.h" | 35 #include "base/win/scoped_comptr.h" |
| 25 #include "base/win/windows_version.h" | |
| 26 #include "media/midi/midi_scheduler.h" | 36 #include "media/midi/midi_scheduler.h" |
| 27 | 37 |
| 28 namespace media { | 38 namespace media { |
| 29 namespace midi { | 39 namespace midi { |
| 30 namespace { | 40 namespace { |
| 31 | 41 |
| 32 namespace WRL = Microsoft::WRL; | 42 namespace WRL = Microsoft::WRL; |
| 33 | 43 |
| 34 using namespace ABI::Windows::Devices::Enumeration; | 44 using namespace ABI::Windows::Devices::Enumeration; |
| 35 using namespace ABI::Windows::Devices::Midi; | 45 using namespace ABI::Windows::Devices::Midi; |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 170 HRESULT hr = g_combase_functions.Get().RoGetActivationFactory( | 180 HRESULT hr = g_combase_functions.Get().RoGetActivationFactory( |
| 171 class_id_hstring.get(), __uuidof(InterfaceType), com_ptr.ReceiveVoid()); | 181 class_id_hstring.get(), __uuidof(InterfaceType), com_ptr.ReceiveVoid()); |
| 172 if (FAILED(hr)) { | 182 if (FAILED(hr)) { |
| 173 VLOG(1) << "RoGetActivationFactory failed: " << PrintHr(hr); | 183 VLOG(1) << "RoGetActivationFactory failed: " << PrintHr(hr); |
| 174 com_ptr = nullptr; | 184 com_ptr = nullptr; |
| 175 } | 185 } |
| 176 | 186 |
| 177 return com_ptr; | 187 return com_ptr; |
| 178 } | 188 } |
| 179 | 189 |
| 180 template <typename T, HRESULT (T::*method)(HSTRING*)> | 190 std::string HStringToString(HSTRING hstr) { |
| 181 std::string GetStringFromObjectMethod(T* obj) { | |
| 182 HSTRING result; | |
| 183 HRESULT hr = (obj->*method)(&result); | |
| 184 if (FAILED(hr)) { | |
| 185 VLOG(1) << "GetStringFromObjectMethod failed: " << PrintHr(hr); | |
| 186 return std::string(); | |
| 187 } | |
| 188 | |
| 189 // Note: empty HSTRINGs are represent as nullptr, and instantiating | 191 // Note: empty HSTRINGs are represent as nullptr, and instantiating |
| 190 // std::string with nullptr (in base::WideToUTF8) is undefined behavior. | 192 // std::string with nullptr (in base::WideToUTF8) is undefined behavior. |
| 191 const base::char16* buffer = | 193 const base::char16* buffer = |
| 192 g_combase_functions.Get().WindowsGetStringRawBuffer(result, nullptr); | 194 g_combase_functions.Get().WindowsGetStringRawBuffer(hstr, nullptr); |
| 193 if (buffer) | 195 if (buffer) |
| 194 return base::WideToUTF8(buffer); | 196 return base::WideToUTF8(buffer); |
| 195 return std::string(); | 197 return std::string(); |
| 196 } | 198 } |
| 197 | 199 |
| 198 template <typename T> | 200 template <typename T> |
| 199 std::string GetIdString(T* obj) { | 201 std::string GetIdString(T* obj) { |
| 200 return GetStringFromObjectMethod<T, &T::get_Id>(obj); | 202 HSTRING result; |
| 203 HRESULT hr = obj->get_Id(&result); | |
| 204 if (FAILED(hr)) { | |
| 205 VLOG(1) << "get_Id failed: " << PrintHr(hr); | |
| 206 return std::string(); | |
| 207 } | |
| 208 return HStringToString(result); | |
| 201 } | 209 } |
| 202 | 210 |
| 203 template <typename T> | 211 template <typename T> |
| 204 std::string GetDeviceIdString(T* obj) { | 212 std::string GetDeviceIdString(T* obj) { |
| 205 return GetStringFromObjectMethod<T, &T::get_DeviceId>(obj); | 213 HSTRING result; |
| 214 HRESULT hr = obj->get_DeviceId(&result); | |
| 215 if (FAILED(hr)) { | |
| 216 VLOG(1) << "get_DeviceId failed: " << PrintHr(hr); | |
| 217 return std::string(); | |
| 218 } | |
| 219 return HStringToString(result); | |
| 206 } | 220 } |
| 207 | 221 |
| 208 std::string GetNameString(IDeviceInformation* info) { | 222 std::string GetNameString(IDeviceInformation* info) { |
| 209 return GetStringFromObjectMethod<IDeviceInformation, | 223 HSTRING result; |
| 210 &IDeviceInformation::get_Name>(info); | 224 HRESULT hr = info->get_Name(&result); |
| 225 if (FAILED(hr)) { | |
| 226 VLOG(1) << "get_Name failed: " << PrintHr(hr); | |
| 227 return std::string(); | |
| 228 } | |
| 229 return HStringToString(result); | |
| 211 } | 230 } |
| 212 | 231 |
| 213 HRESULT GetPointerToBufferData(IBuffer* buffer, uint8_t** out) { | 232 HRESULT GetPointerToBufferData(IBuffer* buffer, uint8_t** out) { |
| 214 ScopedComPtr<Windows::Storage::Streams::IBufferByteAccess> buffer_byte_access; | 233 ScopedComPtr<Windows::Storage::Streams::IBufferByteAccess> buffer_byte_access; |
| 215 | 234 |
| 216 HRESULT hr = buffer_byte_access.QueryFrom(buffer); | 235 HRESULT hr = buffer_byte_access.QueryFrom(buffer); |
| 217 if (FAILED(hr)) { | 236 if (FAILED(hr)) { |
| 218 VLOG(1) << "QueryInterface failed: " << PrintHr(hr); | 237 VLOG(1) << "QueryInterface failed: " << PrintHr(hr); |
| 219 return hr; | 238 return hr; |
| 220 } | 239 } |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 803 MidiManagerWinrt::~MidiManagerWinrt() { | 822 MidiManagerWinrt::~MidiManagerWinrt() { |
| 804 base::AutoLock auto_lock(lazy_init_member_lock_); | 823 base::AutoLock auto_lock(lazy_init_member_lock_); |
| 805 | 824 |
| 806 CHECK(!com_thread_checker_); | 825 CHECK(!com_thread_checker_); |
| 807 CHECK(!port_manager_in_); | 826 CHECK(!port_manager_in_); |
| 808 CHECK(!port_manager_out_); | 827 CHECK(!port_manager_out_); |
| 809 CHECK(!scheduler_); | 828 CHECK(!scheduler_); |
| 810 } | 829 } |
| 811 | 830 |
| 812 void MidiManagerWinrt::StartInitialization() { | 831 void MidiManagerWinrt::StartInitialization() { |
| 813 if (base::win::GetVersion() < base::win::VERSION_WIN10) { | |
| 814 VLOG(1) << "WinRT MIDI backend is only supported on Windows 10 or later."; | |
| 815 CompleteInitialization(Result::INITIALIZATION_ERROR); | |
| 816 return; | |
| 817 } | |
| 818 | |
| 819 com_thread_.init_com_with_mta(true); | 832 com_thread_.init_com_with_mta(true); |
| 820 com_thread_.Start(); | 833 com_thread_.Start(); |
| 821 | 834 |
| 822 com_thread_.task_runner()->PostTask( | 835 com_thread_.task_runner()->PostTask( |
| 823 FROM_HERE, base::Bind(&MidiManagerWinrt::InitializeOnComThread, | 836 FROM_HERE, base::Bind(&MidiManagerWinrt::InitializeOnComThread, |
| 824 base::Unretained(this))); | 837 base::Unretained(this))); |
| 825 } | 838 } |
| 826 | 839 |
| 827 void MidiManagerWinrt::Finalize() { | 840 void MidiManagerWinrt::Finalize() { |
| 828 com_thread_.task_runner()->PostTask( | 841 com_thread_.task_runner()->PostTask( |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 936 } | 949 } |
| 937 | 950 |
| 938 void MidiManagerWinrt::OnPortManagerReady() { | 951 void MidiManagerWinrt::OnPortManagerReady() { |
| 939 DCHECK(com_thread_checker_->CalledOnValidThread()); | 952 DCHECK(com_thread_checker_->CalledOnValidThread()); |
| 940 DCHECK(port_manager_ready_count_ < 2); | 953 DCHECK(port_manager_ready_count_ < 2); |
| 941 | 954 |
| 942 if (++port_manager_ready_count_ == 2) | 955 if (++port_manager_ready_count_ == 2) |
| 943 CompleteInitialization(Result::OK); | 956 CompleteInitialization(Result::OK); |
| 944 } | 957 } |
| 945 | 958 |
| 946 MidiManager* MidiManager::Create() { | |
| 947 return new MidiManagerWinrt(); | |
| 948 } | |
| 949 | |
| 950 } // namespace midi | 959 } // namespace midi |
| 951 } // namespace media | 960 } // namespace media |
| OLD | NEW |