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 |