Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1656)

Side by Side Diff: media/midi/midi_manager_winrt.cc

Issue 2301513002: Remove RuntimeObject.lib dependency in Windows 10 Web MIDI backend (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« media/midi/BUILD.gn ('K') | « media/midi/BUILD.gn ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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>
11 #include <wrl/event.h> 11 #include <wrl/event.h>
12 12
13 #include <iomanip> 13 #include <iomanip>
14 #include <unordered_map> 14 #include <unordered_map>
15 #include <unordered_set> 15 #include <unordered_set>
16 16
17 #include "base/bind.h" 17 #include "base/bind.h"
18 #include "base/lazy_instance.h"
18 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
19 #include "base/threading/thread_checker.h" 20 #include "base/threading/thread_checker.h"
20 #include "base/threading/thread_task_runner_handle.h" 21 #include "base/threading/thread_task_runner_handle.h"
21 #include "base/timer/timer.h" 22 #include "base/timer/timer.h"
22 #include "base/win/scoped_comptr.h" 23 #include "base/win/scoped_comptr.h"
23 #include "base/win/windows_version.h" 24 #include "base/win/windows_version.h"
24 #include "media/midi/midi_scheduler.h" 25 #include "media/midi/midi_scheduler.h"
25 26
26 namespace media { 27 namespace media {
27 namespace midi { 28 namespace midi {
(...skipping 15 matching lines...) Expand all
43 }; 44 };
44 45
45 std::ostream& operator<<(std::ostream& os, const PrintHr& phr) { 46 std::ostream& operator<<(std::ostream& os, const PrintHr& phr) {
46 std::ios_base::fmtflags ff = os.flags(); 47 std::ios_base::fmtflags ff = os.flags();
47 os << _com_error(phr.hr).ErrorMessage() << " (0x" << std::hex 48 os << _com_error(phr.hr).ErrorMessage() << " (0x" << std::hex
48 << std::uppercase << std::setfill('0') << std::setw(8) << phr.hr << ")"; 49 << std::uppercase << std::setfill('0') << std::setw(8) << phr.hr << ")";
49 os.flags(ff); 50 os.flags(ff);
50 return os; 51 return os;
51 } 52 }
52 53
54 class CombaseFunctions {
55 public:
56 CombaseFunctions() = default;
57
58 ~CombaseFunctions() {
59 if (combase_dll_)
60 ::FreeLibrary(combase_dll_);
61 }
62
63 bool LoadFunctions() {
64 combase_dll_ = ::LoadLibrary(L"combase.dll");
65 if (!combase_dll_)
66 return false;
67
68 get_factory_func_ = reinterpret_cast<decltype(&::RoGetActivationFactory)>(
69 ::GetProcAddress(combase_dll_, "RoGetActivationFactory"));
70 if (!get_factory_func_)
71 return false;
72
73 create_string_func_ = reinterpret_cast<decltype(&::WindowsCreateString)>(
74 ::GetProcAddress(combase_dll_, "WindowsCreateString"));
75 if (!create_string_func_)
76 return false;
77
78 delete_string_func_ = reinterpret_cast<decltype(&::WindowsDeleteString)>(
79 ::GetProcAddress(combase_dll_, "WindowsDeleteString"));
80 if (!delete_string_func_)
81 return false;
82
83 get_string_raw_buffer_func_ =
84 reinterpret_cast<decltype(&::WindowsGetStringRawBuffer)>(
85 ::GetProcAddress(combase_dll_, "WindowsGetStringRawBuffer"));
86 if (!get_string_raw_buffer_func_)
87 return false;
88
89 return true;
90 }
91
92 HRESULT RoGetActivationFactory(HSTRING class_id,
93 const IID& iid,
94 void** out_factory) {
95 DCHECK(get_factory_func_);
96 return get_factory_func_(class_id, iid, out_factory);
97 }
98
99 HRESULT WindowsCreateString(const base::char16* src,
100 uint32_t len,
101 HSTRING* out_hstr) {
102 DCHECK(create_string_func_);
103 return create_string_func_(src, len, out_hstr);
104 }
105
106 HRESULT WindowsDeleteString(HSTRING hstr) {
107 DCHECK(delete_string_func_);
108 return delete_string_func_(hstr);
109 }
110
111 const base::char16* WindowsGetStringRawBuffer(HSTRING hstr,
112 uint32_t* out_len) {
113 DCHECK(get_string_raw_buffer_func_);
114 return get_string_raw_buffer_func_(hstr, out_len);
115 }
116
117 private:
118 HMODULE combase_dll_ = nullptr;
119
120 decltype(&::RoGetActivationFactory) get_factory_func_ = nullptr;
121 decltype(&::WindowsCreateString) create_string_func_ = nullptr;
122 decltype(&::WindowsDeleteString) delete_string_func_ = nullptr;
123 decltype(&::WindowsGetStringRawBuffer) get_string_raw_buffer_func_ = nullptr;
124 };
125
126 base::LazyInstance<CombaseFunctions> g_combase_functions =
127 LAZY_INSTANCE_INITIALIZER;
128
129 // Minimalist HSTRING wrapper class to properly maintain HSTRING lifetime.
Takashi Toyoshima 2016/08/31 10:10:29 Can you use base/scoped_generic.h infra to impleme
Shao-Chuan Lee 2016/09/01 03:06:44 Done.
130 class HStringWrapper {
131 public:
132 HStringWrapper() = default;
133 ~HStringWrapper() { Release(); }
134
135 HSTRING Get() { return hstring_; }
136
137 HRESULT Set(const base::char16* str) {
138 Release();
139 return g_combase_functions.Get().WindowsCreateString(
140 str, static_cast<uint32_t>(wcslen(str)), &hstring_);
141 }
142
143 private:
144 void Release() {
145 if (hstring_)
146 g_combase_functions.Get().WindowsDeleteString(hstring_);
147 hstring_ = nullptr;
148 }
149
150 HSTRING hstring_ = nullptr;
151
152 DISALLOW_COPY_AND_ASSIGN(HStringWrapper);
153 };
154
53 // Factory functions that activate and create WinRT components. The caller takes 155 // Factory functions that activate and create WinRT components. The caller takes
54 // ownership of the returning ComPtr. 156 // ownership of the returning ComPtr.
55 template <typename InterfaceType, base::char16 const* runtime_class_id> 157 template <typename InterfaceType, base::char16 const* runtime_class_id>
56 ScopedComPtr<InterfaceType> WrlStaticsFactory() { 158 ScopedComPtr<InterfaceType> WrlStaticsFactory() {
57 ScopedComPtr<InterfaceType> com_ptr; 159 ScopedComPtr<InterfaceType> com_ptr;
58 160
59 HRESULT hr = GetActivationFactory( 161 HStringWrapper class_id_hstring;
60 WRL::Wrappers::HStringReference(runtime_class_id).Get(), 162 HRESULT hr = class_id_hstring.Set(runtime_class_id);
Shao-Chuan Lee 2016/08/31 09:52:13 Here we create new HSTRINGs with WindowsCreateStri
61 com_ptr.Receive());
62 if (FAILED(hr)) { 163 if (FAILED(hr)) {
63 VLOG(1) << "GetActivationFactory failed: " << PrintHr(hr); 164 VLOG(1) << "WindowsCreateString failed: " << PrintHr(hr);
165 com_ptr = nullptr;
166 return com_ptr;
167 }
168
169 hr = g_combase_functions.Get().RoGetActivationFactory(
170 class_id_hstring.Get(), __uuidof(InterfaceType), com_ptr.ReceiveVoid());
171 if (FAILED(hr)) {
172 VLOG(1) << "RoGetActivationFactory failed: " << PrintHr(hr);
64 com_ptr = nullptr; 173 com_ptr = nullptr;
65 } 174 }
66 175
67 return com_ptr; 176 return com_ptr;
68 } 177 }
69 178
70 template <typename T, HRESULT (T::*method)(HSTRING*)> 179 template <typename T, HRESULT (T::*method)(HSTRING*)>
71 std::string GetStringFromObjectMethod(T* obj) { 180 std::string GetStringFromObjectMethod(T* obj) {
72 HSTRING result; 181 HSTRING result;
73 HRESULT hr = (obj->*method)(&result); 182 HRESULT hr = (obj->*method)(&result);
74 if (FAILED(hr)) { 183 if (FAILED(hr)) {
75 VLOG(1) << "GetStringFromObjectMethod failed: " << PrintHr(hr); 184 VLOG(1) << "GetStringFromObjectMethod failed: " << PrintHr(hr);
76 return std::string(); 185 return std::string();
77 } 186 }
78 187
79 // Note: empty HSTRINGs are represent as nullptr, and instantiating 188 // Note: empty HSTRINGs are represent as nullptr, and instantiating
80 // std::string with nullptr (in base::WideToUTF8) is undefined behavior. 189 // std::string with nullptr (in base::WideToUTF8) is undefined behavior.
81 const base::char16* buffer = WindowsGetStringRawBuffer(result, nullptr); 190 const base::char16* buffer =
191 g_combase_functions.Get().WindowsGetStringRawBuffer(result, nullptr);
82 if (buffer) 192 if (buffer)
83 return base::WideToUTF8(buffer); 193 return base::WideToUTF8(buffer);
84 return std::string(); 194 return std::string();
85 } 195 }
86 196
87 template <typename T> 197 template <typename T>
88 std::string GetIdString(T* obj) { 198 std::string GetIdString(T* obj) {
89 return GetStringFromObjectMethod<T, &T::get_Id>(obj); 199 return GetStringFromObjectMethod<T, &T::get_Id>(obj);
90 } 200 }
91 201
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 // DeviceWatcher callbacks: 464 // DeviceWatcher callbacks:
355 void OnAdded(std::string dev_id, std::string dev_name) { 465 void OnAdded(std::string dev_id, std::string dev_name) {
356 DCHECK(thread_checker_.CalledOnValidThread()); 466 DCHECK(thread_checker_.CalledOnValidThread());
357 CHECK(is_initialized_); 467 CHECK(is_initialized_);
358 468
359 // TODO(shaochuan): Disable Microsoft GS Wavetable Synth due to security 469 // TODO(shaochuan): Disable Microsoft GS Wavetable Synth due to security
360 // reasons. http://crbug.com/499279 470 // reasons. http://crbug.com/499279
361 471
362 port_names_[dev_id] = dev_name; 472 port_names_[dev_id] = dev_name;
363 473
364 WRL::Wrappers::HString dev_id_hstring; 474 HStringWrapper dev_id_hstring;
365 HRESULT hr = dev_id_hstring.Set(base::UTF8ToWide(dev_id).c_str()); 475 HRESULT hr = dev_id_hstring.Set(base::UTF8ToWide(dev_id).c_str());
366 if (FAILED(hr)) { 476 if (FAILED(hr)) {
367 VLOG(1) << "Set failed: " << PrintHr(hr); 477 VLOG(1) << "Set failed: " << PrintHr(hr);
368 return; 478 return;
369 } 479 }
370 480
371 IAsyncOperation<RuntimeType*>* async_op; 481 IAsyncOperation<RuntimeType*>* async_op;
372 482
373 hr = midi_port_statics_->FromIdAsync(dev_id_hstring.Get(), &async_op); 483 hr = midi_port_statics_->FromIdAsync(dev_id_hstring.Get(), &async_op);
374 if (FAILED(hr)) { 484 if (FAILED(hr)) {
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 CHECK(!scheduler_); 794 CHECK(!scheduler_);
685 } 795 }
686 796
687 void MidiManagerWinrt::StartInitialization() { 797 void MidiManagerWinrt::StartInitialization() {
688 if (base::win::GetVersion() < base::win::VERSION_WIN10) { 798 if (base::win::GetVersion() < base::win::VERSION_WIN10) {
689 VLOG(1) << "WinRT MIDI backend is only supported on Windows 10 or later."; 799 VLOG(1) << "WinRT MIDI backend is only supported on Windows 10 or later.";
690 CompleteInitialization(Result::INITIALIZATION_ERROR); 800 CompleteInitialization(Result::INITIALIZATION_ERROR);
691 return; 801 return;
692 } 802 }
693 803
804 if (!g_combase_functions.Get().LoadFunctions()) {
805 VLOG(1) << "Failed loading functions from Combase.dll: "
806 << PrintHr(HRESULT_FROM_WIN32(GetLastError()));
807 CompleteInitialization(Result::INITIALIZATION_ERROR);
808 return;
809 }
810
694 com_thread_.init_com_with_mta(true); 811 com_thread_.init_com_with_mta(true);
695 com_thread_.Start(); 812 com_thread_.Start();
696 813
697 com_thread_.task_runner()->PostTask( 814 com_thread_.task_runner()->PostTask(
698 FROM_HERE, base::Bind(&MidiManagerWinrt::InitializeOnComThread, 815 FROM_HERE, base::Bind(&MidiManagerWinrt::InitializeOnComThread,
699 base::Unretained(this))); 816 base::Unretained(this)));
700 } 817 }
701 818
702 void MidiManagerWinrt::Finalize() { 819 void MidiManagerWinrt::Finalize() {
703 com_thread_.task_runner()->PostTask( 820 com_thread_.task_runner()->PostTask(
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 if (++port_manager_ready_count_ == 2) 922 if (++port_manager_ready_count_ == 2)
806 CompleteInitialization(Result::OK); 923 CompleteInitialization(Result::OK);
807 } 924 }
808 925
809 MidiManager* MidiManager::Create() { 926 MidiManager* MidiManager::Create() {
810 return new MidiManagerWinrt(); 927 return new MidiManagerWinrt();
811 } 928 }
812 929
813 } // namespace midi 930 } // namespace midi
814 } // namespace media 931 } // namespace media
OLDNEW
« media/midi/BUILD.gn ('K') | « media/midi/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698