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