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 #pragma warning(disable : 4467) | 7 #pragma warning(disable : 4467) |
8 | 8 |
9 #include <initguid.h> // Required by <devpkey.h> | 9 #include <initguid.h> // Required by <devpkey.h> |
10 | 10 |
11 #include <cfgmgr32.h> | 11 #include <cfgmgr32.h> |
12 #include <comdef.h> | 12 #include <comdef.h> |
13 #include <devpkey.h> | 13 #include <devpkey.h> |
14 #include <robuffer.h> | 14 #include <robuffer.h> |
15 #include <windows.devices.enumeration.h> | 15 #include <windows.devices.enumeration.h> |
16 #include <windows.devices.midi.h> | 16 #include <windows.devices.midi.h> |
17 #include <wrl/event.h> | 17 #include <wrl/event.h> |
18 | 18 |
19 #include <iomanip> | 19 #include <iomanip> |
20 #include <unordered_map> | 20 #include <unordered_map> |
21 #include <unordered_set> | 21 #include <unordered_set> |
22 | 22 |
23 #include "base/bind.h" | 23 #include "base/bind.h" |
24 #include "base/lazy_instance.h" | |
25 #include "base/scoped_generic.h" | 24 #include "base/scoped_generic.h" |
26 #include "base/strings/string_util.h" | 25 #include "base/strings/string_util.h" |
27 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
28 #include "base/threading/thread_checker.h" | 27 #include "base/threading/thread_checker.h" |
29 #include "base/threading/thread_task_runner_handle.h" | 28 #include "base/threading/thread_task_runner_handle.h" |
30 #include "base/timer/timer.h" | 29 #include "base/timer/timer.h" |
31 #include "base/win/scoped_comptr.h" | 30 #include "base/win/scoped_comptr.h" |
32 #include "media/midi/midi_scheduler.h" | 31 #include "media/midi/midi_scheduler.h" |
33 | 32 |
34 namespace midi { | 33 namespace midi { |
(...skipping 19 matching lines...) Expand all Loading... | |
54 std::ostream& operator<<(std::ostream& os, const PrintHr& phr) { | 53 std::ostream& operator<<(std::ostream& os, const PrintHr& phr) { |
55 std::ios_base::fmtflags ff = os.flags(); | 54 std::ios_base::fmtflags ff = os.flags(); |
56 os << _com_error(phr.hr).ErrorMessage() << " (0x" << std::hex | 55 os << _com_error(phr.hr).ErrorMessage() << " (0x" << std::hex |
57 << std::uppercase << std::setfill('0') << std::setw(8) << phr.hr << ")"; | 56 << std::uppercase << std::setfill('0') << std::setw(8) << phr.hr << ")"; |
58 os.flags(ff); | 57 os.flags(ff); |
59 return os; | 58 return os; |
60 } | 59 } |
61 | 60 |
62 // Provides access to functions in combase.dll which may not be available on | 61 // Provides access to functions in combase.dll which may not be available on |
63 // Windows 7. Loads functions dynamically at runtime to prevent library | 62 // Windows 7. Loads functions dynamically at runtime to prevent library |
64 // dependencies. Use this class through the global LazyInstance | 63 // dependencies. |
65 // |g_combase_functions|. | |
66 class CombaseFunctions { | 64 class CombaseFunctions { |
67 public: | 65 public: |
68 CombaseFunctions() = default; | 66 CombaseFunctions() = default; |
69 | 67 |
70 ~CombaseFunctions() { | 68 ~CombaseFunctions() { |
71 if (combase_dll_) | 69 if (combase_dll_) |
72 ::FreeLibrary(combase_dll_); | 70 ::FreeLibrary(combase_dll_); |
73 } | 71 } |
74 | 72 |
75 bool LoadFunctions() { | 73 bool LoadFunctions() { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
128 | 126 |
129 private: | 127 private: |
130 HMODULE combase_dll_ = nullptr; | 128 HMODULE combase_dll_ = nullptr; |
131 | 129 |
132 decltype(&::RoGetActivationFactory) get_factory_func_ = nullptr; | 130 decltype(&::RoGetActivationFactory) get_factory_func_ = nullptr; |
133 decltype(&::WindowsCreateString) create_string_func_ = nullptr; | 131 decltype(&::WindowsCreateString) create_string_func_ = nullptr; |
134 decltype(&::WindowsDeleteString) delete_string_func_ = nullptr; | 132 decltype(&::WindowsDeleteString) delete_string_func_ = nullptr; |
135 decltype(&::WindowsGetStringRawBuffer) get_string_raw_buffer_func_ = nullptr; | 133 decltype(&::WindowsGetStringRawBuffer) get_string_raw_buffer_func_ = nullptr; |
136 }; | 134 }; |
137 | 135 |
138 base::LazyInstance<CombaseFunctions> g_combase_functions = | 136 static CombaseFunctions* GetCombaseFunctions() { |
Mark Mentovai
2017/01/31 21:33:56
No need for “static” in an unnamed namespace.
| |
139 LAZY_INSTANCE_INITIALIZER; | 137 static CombaseFunctions* functions = new CombaseFunctions(); |
138 return functions; | |
139 } | |
140 | 140 |
141 // Scoped HSTRING class to maintain lifetime of HSTRINGs allocated with | 141 // Scoped HSTRING class to maintain lifetime of HSTRINGs allocated with |
142 // WindowsCreateString(). | 142 // WindowsCreateString(). |
143 class ScopedHStringTraits { | 143 class ScopedHStringTraits { |
144 public: | 144 public: |
145 static HSTRING InvalidValue() { return nullptr; } | 145 static HSTRING InvalidValue() { return nullptr; } |
146 | 146 |
147 static void Free(HSTRING hstr) { | 147 static void Free(HSTRING hstr) { |
148 g_combase_functions.Get().WindowsDeleteString(hstr); | 148 GetCombaseFunctions()->WindowsDeleteString(hstr); |
149 } | 149 } |
150 }; | 150 }; |
151 | 151 |
152 class ScopedHString : public base::ScopedGeneric<HSTRING, ScopedHStringTraits> { | 152 class ScopedHString : public base::ScopedGeneric<HSTRING, ScopedHStringTraits> { |
153 public: | 153 public: |
154 explicit ScopedHString(const base::char16* str) : ScopedGeneric(nullptr) { | 154 explicit ScopedHString(const base::char16* str) : ScopedGeneric(nullptr) { |
155 HSTRING hstr; | 155 HSTRING hstr; |
156 HRESULT hr = g_combase_functions.Get().WindowsCreateString( | 156 HRESULT hr = GetCombaseFunctions()->WindowsCreateString( |
157 str, static_cast<uint32_t>(wcslen(str)), &hstr); | 157 str, static_cast<uint32_t>(wcslen(str)), &hstr); |
158 if (FAILED(hr)) | 158 if (FAILED(hr)) |
159 VLOG(1) << "WindowsCreateString failed: " << PrintHr(hr); | 159 VLOG(1) << "WindowsCreateString failed: " << PrintHr(hr); |
160 else | 160 else |
161 reset(hstr); | 161 reset(hstr); |
162 } | 162 } |
163 }; | 163 }; |
164 | 164 |
165 // Factory functions that activate and create WinRT components. The caller takes | 165 // Factory functions that activate and create WinRT components. The caller takes |
166 // ownership of the returning ComPtr. | 166 // ownership of the returning ComPtr. |
167 template <typename InterfaceType, base::char16 const* runtime_class_id> | 167 template <typename InterfaceType, base::char16 const* runtime_class_id> |
168 ScopedComPtr<InterfaceType> WrlStaticsFactory() { | 168 ScopedComPtr<InterfaceType> WrlStaticsFactory() { |
169 ScopedComPtr<InterfaceType> com_ptr; | 169 ScopedComPtr<InterfaceType> com_ptr; |
170 | 170 |
171 ScopedHString class_id_hstring(runtime_class_id); | 171 ScopedHString class_id_hstring(runtime_class_id); |
172 if (!class_id_hstring.is_valid()) { | 172 if (!class_id_hstring.is_valid()) { |
173 com_ptr = nullptr; | 173 com_ptr = nullptr; |
174 return com_ptr; | 174 return com_ptr; |
175 } | 175 } |
176 | 176 |
177 HRESULT hr = g_combase_functions.Get().RoGetActivationFactory( | 177 HRESULT hr = GetCombaseFunctions()->RoGetActivationFactory( |
178 class_id_hstring.get(), __uuidof(InterfaceType), com_ptr.ReceiveVoid()); | 178 class_id_hstring.get(), __uuidof(InterfaceType), com_ptr.ReceiveVoid()); |
179 if (FAILED(hr)) { | 179 if (FAILED(hr)) { |
180 VLOG(1) << "RoGetActivationFactory failed: " << PrintHr(hr); | 180 VLOG(1) << "RoGetActivationFactory failed: " << PrintHr(hr); |
181 com_ptr = nullptr; | 181 com_ptr = nullptr; |
182 } | 182 } |
183 | 183 |
184 return com_ptr; | 184 return com_ptr; |
185 } | 185 } |
186 | 186 |
187 std::string HStringToString(HSTRING hstr) { | 187 std::string HStringToString(HSTRING hstr) { |
188 // Note: empty HSTRINGs are represent as nullptr, and instantiating | 188 // Note: empty HSTRINGs are represent as nullptr, and instantiating |
189 // std::string with nullptr (in base::WideToUTF8) is undefined behavior. | 189 // std::string with nullptr (in base::WideToUTF8) is undefined behavior. |
190 const base::char16* buffer = | 190 const base::char16* buffer = |
191 g_combase_functions.Get().WindowsGetStringRawBuffer(hstr, nullptr); | 191 GetCombaseFunctions()->WindowsGetStringRawBuffer(hstr, nullptr); |
192 if (buffer) | 192 if (buffer) |
193 return base::WideToUTF8(buffer); | 193 return base::WideToUTF8(buffer); |
194 return std::string(); | 194 return std::string(); |
195 } | 195 } |
196 | 196 |
197 template <typename T> | 197 template <typename T> |
198 std::string GetIdString(T* obj) { | 198 std::string GetIdString(T* obj) { |
199 HSTRING result; | 199 HSTRING result; |
200 HRESULT hr = obj->get_Id(&result); | 200 HRESULT hr = obj->get_Id(&result); |
201 if (FAILED(hr)) { | 201 if (FAILED(hr)) { |
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
947 client, data.size(), timestamp, | 947 client, data.size(), timestamp, |
948 base::Bind(&MidiManagerWinrt::SendOnComThread, base::Unretained(this), | 948 base::Bind(&MidiManagerWinrt::SendOnComThread, base::Unretained(this), |
949 port_index, data)); | 949 port_index, data)); |
950 } | 950 } |
951 | 951 |
952 void MidiManagerWinrt::InitializeOnComThread() { | 952 void MidiManagerWinrt::InitializeOnComThread() { |
953 base::AutoLock auto_lock(lazy_init_member_lock_); | 953 base::AutoLock auto_lock(lazy_init_member_lock_); |
954 | 954 |
955 com_thread_checker_.reset(new base::ThreadChecker); | 955 com_thread_checker_.reset(new base::ThreadChecker); |
956 | 956 |
957 if (!g_combase_functions.Get().LoadFunctions()) { | 957 if (!GetCombaseFunctions()->LoadFunctions()) { |
958 VLOG(1) << "Failed loading functions from combase.dll: " | 958 VLOG(1) << "Failed loading functions from combase.dll: " |
959 << PrintHr(HRESULT_FROM_WIN32(GetLastError())); | 959 << PrintHr(HRESULT_FROM_WIN32(GetLastError())); |
960 CompleteInitialization(Result::INITIALIZATION_ERROR); | 960 CompleteInitialization(Result::INITIALIZATION_ERROR); |
961 return; | 961 return; |
962 } | 962 } |
963 | 963 |
964 port_manager_in_.reset(new MidiInPortManager(this)); | 964 port_manager_in_.reset(new MidiInPortManager(this)); |
965 port_manager_out_.reset(new MidiOutPortManager(this)); | 965 port_manager_out_.reset(new MidiOutPortManager(this)); |
966 | 966 |
967 scheduler_.reset(new MidiScheduler(this)); | 967 scheduler_.reset(new MidiScheduler(this)); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1040 | 1040 |
1041 void MidiManagerWinrt::OnPortManagerReady() { | 1041 void MidiManagerWinrt::OnPortManagerReady() { |
1042 DCHECK(com_thread_checker_->CalledOnValidThread()); | 1042 DCHECK(com_thread_checker_->CalledOnValidThread()); |
1043 DCHECK(port_manager_ready_count_ < 2); | 1043 DCHECK(port_manager_ready_count_ < 2); |
1044 | 1044 |
1045 if (++port_manager_ready_count_ == 2) | 1045 if (++port_manager_ready_count_ == 2) |
1046 CompleteInitialization(Result::OK); | 1046 CompleteInitialization(Result::OK); |
1047 } | 1047 } |
1048 | 1048 |
1049 } // namespace midi | 1049 } // namespace midi |
OLD | NEW |