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 #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 |