OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/ppapi_plugin/ppapi_thread.h" | 5 #include "content/ppapi_plugin/ppapi_thread.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/cpu.h" | 10 #include "base/cpu.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 #include "ipc/ipc_sync_channel.h" | 35 #include "ipc/ipc_sync_channel.h" |
36 #include "ipc/ipc_sync_message_filter.h" | 36 #include "ipc/ipc_sync_message_filter.h" |
37 #include "ppapi/c/dev/ppp_network_state_dev.h" | 37 #include "ppapi/c/dev/ppp_network_state_dev.h" |
38 #include "ppapi/c/pp_errors.h" | 38 #include "ppapi/c/pp_errors.h" |
39 #include "ppapi/c/ppp.h" | 39 #include "ppapi/c/ppp.h" |
40 #include "ppapi/proxy/interface_list.h" | 40 #include "ppapi/proxy/interface_list.h" |
41 #include "ppapi/proxy/plugin_globals.h" | 41 #include "ppapi/proxy/plugin_globals.h" |
42 #include "ppapi/proxy/plugin_message_filter.h" | 42 #include "ppapi/proxy/plugin_message_filter.h" |
43 #include "ppapi/proxy/ppapi_messages.h" | 43 #include "ppapi/proxy/ppapi_messages.h" |
44 #include "ppapi/proxy/resource_reply_thread_registrar.h" | 44 #include "ppapi/proxy/resource_reply_thread_registrar.h" |
45 #include "ppapi/shared_impl/proxy_lock.h" | |
46 #include "third_party/WebKit/public/web/WebKit.h" | 45 #include "third_party/WebKit/public/web/WebKit.h" |
47 #include "ui/base/ui_base_switches.h" | 46 #include "ui/base/ui_base_switches.h" |
48 | 47 |
49 #if defined(OS_WIN) | 48 #if defined(OS_WIN) |
50 #include "base/win/iat_patch_function.h" | |
51 #include "base/win/win_util.h" | 49 #include "base/win/win_util.h" |
52 #include "base/win/windows_version.h" | 50 #include "base/win/windows_version.h" |
53 #include "sandbox/win/src/sandbox.h" | 51 #include "sandbox/win/src/sandbox.h" |
54 #elif defined(OS_MACOSX) | 52 #elif defined(OS_MACOSX) |
55 #include "content/common/sandbox_init_mac.h" | 53 #include "content/common/sandbox_init_mac.h" |
56 #endif | 54 #endif |
57 | 55 |
58 #if defined(OS_WIN) | 56 #if defined(OS_WIN) |
59 const char kWidevineCdmAdapterFileName[] = "widevinecdmadapter.dll"; | 57 const char kWidevineCdmAdapterFileName[] = "widevinecdmadapter.dll"; |
60 | 58 |
(...skipping 26 matching lines...) Expand all Loading... |
87 reinterpret_cast<PfnEnumSystemLocalesEx> | 85 reinterpret_cast<PfnEnumSystemLocalesEx> |
88 (GetProcAddress(handle_kern32, "EnumSystemLocalesEx")); | 86 (GetProcAddress(handle_kern32, "EnumSystemLocalesEx")); |
89 | 87 |
90 enum_sys_locales_ex(EnumLocalesProcEx, LOCALE_WINDOWS, 0, 0); | 88 enum_sys_locales_ex(EnumLocalesProcEx, LOCALE_WINDOWS, 0, 0); |
91 } else { | 89 } else { |
92 EnumSystemLocalesW(EnumLocalesProc, LCID_INSTALLED); | 90 EnumSystemLocalesW(EnumLocalesProc, LCID_INSTALLED); |
93 } | 91 } |
94 } | 92 } |
95 } | 93 } |
96 | 94 |
97 // TODO(scottmg): http://crbug.com/448473. This code should be removed from the | |
98 // renderer once PDF is always OOP and/or PDF is made to use Skia instead of GDI | |
99 // directly. | |
100 const wchar_t kPdfFileName[] = L"pdf.dll"; | |
101 | |
102 static base::win::IATPatchFunction g_iat_patch_createdca; | |
103 HDC WINAPI CreateDCAPatch(LPCSTR driver_name, | |
104 LPCSTR device_name, | |
105 LPCSTR output, | |
106 const void* init_data) { | |
107 DCHECK(std::string("DISPLAY") == std::string(driver_name)); | |
108 DCHECK(!device_name); | |
109 DCHECK(!output); | |
110 DCHECK(!init_data); | |
111 | |
112 // CreateDC fails behind the sandbox, but not CreateCompatibleDC. | |
113 return CreateCompatibleDC(NULL); | |
114 } | |
115 | |
116 static base::win::IATPatchFunction g_iat_patch_get_font_data; | |
117 DWORD WINAPI GetFontDataPatch(HDC hdc, | |
118 DWORD table, | |
119 DWORD offset, | |
120 LPVOID buffer, | |
121 DWORD length) { | |
122 int rv = GetFontData(hdc, table, offset, buffer, length); | |
123 if (rv == GDI_ERROR && hdc) { | |
124 HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT)); | |
125 | |
126 LOGFONT logfont; | |
127 if (GetObject(font, sizeof(LOGFONT), &logfont)) { | |
128 std::vector<char> font_data; | |
129 { | |
130 ppapi::ProxyAutoLock lock; | |
131 // In the sandbox, font loading will fail. We ask the browser to load it | |
132 // which causes it to be loaded by the kernel, which then makes the | |
133 // subsequent call succeed. | |
134 ppapi::proxy::PluginGlobals::Get()->PreCacheFontForFlash( | |
135 reinterpret_cast<const void*>(&logfont)); | |
136 } | |
137 rv = GetFontData(hdc, table, offset, buffer, length); | |
138 } | |
139 } | |
140 return rv; | |
141 } | |
142 | |
143 #else | |
144 extern void* g_target_services; | |
145 #endif | 95 #endif |
146 | 96 |
147 namespace content { | 97 namespace content { |
148 | 98 |
149 typedef int32_t (*InitializeBrokerFunc) | 99 typedef int32_t (*InitializeBrokerFunc) |
150 (PP_ConnectInstance_Func* connect_instance_func); | 100 (PP_ConnectInstance_Func* connect_instance_func); |
151 | 101 |
152 PpapiThread::PpapiThread(const base::CommandLine& command_line, bool is_broker) | 102 PpapiThread::PpapiThread(const base::CommandLine& command_line, bool is_broker) |
153 : is_broker_(is_broker), | 103 : is_broker_(is_broker), |
154 connect_instance_func_(NULL), | 104 connect_instance_func_(NULL), |
(...skipping 11 matching lines...) Expand all Loading... |
166 channel()->AddFilter( | 116 channel()->AddFilter( |
167 new ppapi::proxy::PluginMessageFilter( | 117 new ppapi::proxy::PluginMessageFilter( |
168 NULL, globals->resource_reply_thread_registrar())); | 118 NULL, globals->resource_reply_thread_registrar())); |
169 } | 119 } |
170 } | 120 } |
171 | 121 |
172 PpapiThread::~PpapiThread() { | 122 PpapiThread::~PpapiThread() { |
173 } | 123 } |
174 | 124 |
175 void PpapiThread::Shutdown() { | 125 void PpapiThread::Shutdown() { |
176 ChildThread::Shutdown(); | 126 ChildThreadImpl::Shutdown(); |
177 | 127 |
178 ppapi::proxy::PluginGlobals::Get()->ResetPluginProxyDelegate(); | 128 ppapi::proxy::PluginGlobals::Get()->ResetPluginProxyDelegate(); |
179 if (plugin_entry_points_.shutdown_module) | 129 if (plugin_entry_points_.shutdown_module) |
180 plugin_entry_points_.shutdown_module(); | 130 plugin_entry_points_.shutdown_module(); |
181 blink_platform_impl_->Shutdown(); | 131 blink_platform_impl_->Shutdown(); |
182 blink::shutdown(); | 132 blink::shutdown(); |
183 } | 133 } |
184 | 134 |
185 bool PpapiThread::Send(IPC::Message* msg) { | 135 bool PpapiThread::Send(IPC::Message* msg) { |
186 // Allow access from multiple threads. | 136 // Allow access from multiple threads. |
187 if (base::MessageLoop::current() == message_loop()) | 137 if (base::MessageLoop::current() == message_loop()) |
188 return ChildThread::Send(msg); | 138 return ChildThreadImpl::Send(msg); |
189 | 139 |
190 return sync_message_filter()->Send(msg); | 140 return sync_message_filter()->Send(msg); |
191 } | 141 } |
192 | 142 |
193 // Note that this function is called only for messages from the channel to the | 143 // Note that this function is called only for messages from the channel to the |
194 // browser process. Messages from the renderer process are sent via a different | 144 // browser process. Messages from the renderer process are sent via a different |
195 // channel that ends up at Dispatcher::OnMessageReceived. | 145 // channel that ends up at Dispatcher::OnMessageReceived. |
196 bool PpapiThread::OnControlMessageReceived(const IPC::Message& msg) { | 146 bool PpapiThread::OnControlMessageReceived(const IPC::Message& msg) { |
197 bool handled = true; | 147 bool handled = true; |
198 IPC_BEGIN_MESSAGE_MAP(PpapiThread, msg) | 148 IPC_BEGIN_MESSAGE_MAP(PpapiThread, msg) |
199 IPC_MESSAGE_HANDLER(PpapiMsg_LoadPlugin, OnLoadPlugin) | 149 IPC_MESSAGE_HANDLER(PpapiMsg_LoadPlugin, OnLoadPlugin) |
200 IPC_MESSAGE_HANDLER(PpapiMsg_CreateChannel, OnCreateChannel) | 150 IPC_MESSAGE_HANDLER(PpapiMsg_CreateChannel, OnCreateChannel) |
201 IPC_MESSAGE_HANDLER(PpapiMsg_SetNetworkState, OnSetNetworkState) | 151 IPC_MESSAGE_HANDLER(PpapiMsg_SetNetworkState, OnSetNetworkState) |
202 IPC_MESSAGE_HANDLER(PpapiMsg_Crash, OnCrash) | 152 IPC_MESSAGE_HANDLER(PpapiMsg_Crash, OnCrash) |
203 IPC_MESSAGE_HANDLER(PpapiMsg_Hang, OnHang) | 153 IPC_MESSAGE_HANDLER(PpapiMsg_Hang, OnHang) |
204 IPC_MESSAGE_UNHANDLED(handled = false) | 154 IPC_MESSAGE_UNHANDLED(handled = false) |
205 IPC_END_MESSAGE_MAP() | 155 IPC_END_MESSAGE_MAP() |
206 return handled; | 156 return handled; |
207 } | 157 } |
208 | 158 |
209 void PpapiThread::OnChannelConnected(int32 peer_pid) { | 159 void PpapiThread::OnChannelConnected(int32 peer_pid) { |
210 ChildThread::OnChannelConnected(peer_pid); | 160 ChildThreadImpl::OnChannelConnected(peer_pid); |
211 #if defined(OS_WIN) | 161 #if defined(OS_WIN) |
212 if (is_broker_) | 162 if (is_broker_) |
213 peer_handle_.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, peer_pid)); | 163 peer_handle_.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, peer_pid)); |
214 #endif | 164 #endif |
215 } | 165 } |
216 | 166 |
217 base::MessageLoopProxy* PpapiThread::GetIPCMessageLoop() { | 167 base::MessageLoopProxy* PpapiThread::GetIPCMessageLoop() { |
218 return ChildProcess::current()->io_message_loop_proxy(); | 168 return ChildProcess::current()->io_message_loop_proxy(); |
219 } | 169 } |
220 | 170 |
(...skipping 25 matching lines...) Expand all Loading... |
246 return this; | 196 return this; |
247 } | 197 } |
248 | 198 |
249 std::string PpapiThread::GetUILanguage() { | 199 std::string PpapiThread::GetUILanguage() { |
250 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 200 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
251 return command_line->GetSwitchValueASCII(switches::kLang); | 201 return command_line->GetSwitchValueASCII(switches::kLang); |
252 } | 202 } |
253 | 203 |
254 void PpapiThread::PreCacheFont(const void* logfontw) { | 204 void PpapiThread::PreCacheFont(const void* logfontw) { |
255 #if defined(OS_WIN) | 205 #if defined(OS_WIN) |
256 Send(new ChildProcessHostMsg_PreCacheFont( | 206 ChildThreadImpl::PreCacheFont(*static_cast<const LOGFONTW*>(logfontw)); |
257 *static_cast<const LOGFONTW*>(logfontw))); | |
258 #endif | 207 #endif |
259 } | 208 } |
260 | 209 |
261 void PpapiThread::SetActiveURL(const std::string& url) { | 210 void PpapiThread::SetActiveURL(const std::string& url) { |
262 GetContentClient()->SetActiveURL(GURL(url)); | 211 GetContentClient()->SetActiveURL(GURL(url)); |
263 } | 212 } |
264 | 213 |
265 PP_Resource PpapiThread::CreateBrowserFont( | 214 PP_Resource PpapiThread::CreateBrowserFont( |
266 ppapi::proxy::Connection connection, | 215 ppapi::proxy::Connection connection, |
267 PP_Instance instance, | 216 PP_Instance instance, |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 return; | 316 return; |
368 } | 317 } |
369 } | 318 } |
370 } | 319 } |
371 | 320 |
372 #if defined(OS_WIN) | 321 #if defined(OS_WIN) |
373 // If code subsequently tries to exit using abort(), force a crash (since | 322 // If code subsequently tries to exit using abort(), force a crash (since |
374 // otherwise these would be silent terminations and fly under the radar). | 323 // otherwise these would be silent terminations and fly under the radar). |
375 base::win::SetAbortBehaviorForCrashReporting(); | 324 base::win::SetAbortBehaviorForCrashReporting(); |
376 | 325 |
377 // Need to patch a few functions for font loading to work correctly. This can | |
378 // be removed once we switch PDF to use Skia. | |
379 if (GetModuleHandle(kPdfFileName)) { | |
380 g_iat_patch_createdca.Patch(kPdfFileName, "gdi32.dll", "CreateDCA", | |
381 CreateDCAPatch); | |
382 g_iat_patch_get_font_data.Patch(kPdfFileName, "gdi32.dll", "GetFontData", | |
383 GetFontDataPatch); | |
384 } | |
385 | |
386 // Once we lower the token the sandbox is locked down and no new modules | 326 // Once we lower the token the sandbox is locked down and no new modules |
387 // can be loaded. TODO(cpu): consider changing to the loading style of | 327 // can be loaded. TODO(cpu): consider changing to the loading style of |
388 // regular plugins. | 328 // regular plugins. |
389 if (g_target_services) { | 329 if (g_target_services) { |
390 // Let Flash and Widevine CDM adapter load DXVA before lockdown on Vista+. | 330 // Let Flash and Widevine CDM adapter load DXVA before lockdown on Vista+. |
391 if (permissions.HasPermission(ppapi::PERMISSION_FLASH) || | 331 if (permissions.HasPermission(ppapi::PERMISSION_FLASH) || |
392 path.BaseName().MaybeAsASCII() == kWidevineCdmAdapterFileName) { | 332 path.BaseName().MaybeAsASCII() == kWidevineCdmAdapterFileName) { |
393 if (base::win::OSInfo::GetInstance()->version() >= | 333 if (base::win::OSInfo::GetInstance()->version() >= |
394 base::win::VERSION_VISTA) { | 334 base::win::VERSION_VISTA) { |
395 LoadLibraryA("dxva2.dll"); | 335 LoadLibraryA("dxva2.dll"); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 std::string("Plugin.Ppapi") + (is_broker_ ? "Broker" : "Plugin") + | 540 std::string("Plugin.Ppapi") + (is_broker_ ? "Broker" : "Plugin") + |
601 "LoadErrorCode_" + path.BaseName().MaybeAsASCII(); | 541 "LoadErrorCode_" + path.BaseName().MaybeAsASCII(); |
602 | 542 |
603 // For sparse histograms, we can use the macro, as it does not incorporate a | 543 // For sparse histograms, we can use the macro, as it does not incorporate a |
604 // static. | 544 // static. |
605 UMA_HISTOGRAM_SPARSE_SLOWLY(histogram_name, error.code); | 545 UMA_HISTOGRAM_SPARSE_SLOWLY(histogram_name, error.code); |
606 #endif | 546 #endif |
607 } | 547 } |
608 | 548 |
609 } // namespace content | 549 } // namespace content |
OLD | NEW |