OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/browser/plugin_process_host.h" | 5 #include "content/browser/plugin_process_host.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <windows.h> | 8 #include <windows.h> |
9 #elif defined(OS_POSIX) | 9 #elif defined(OS_POSIX) |
10 #include <utility> // for pair<> | 10 #include <utility> // for pair<> |
11 #endif | 11 #endif |
12 | 12 |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include "app/app_switches.h" | 15 #include "app/app_switches.h" |
16 #include "base/command_line.h" | 16 #include "base/command_line.h" |
17 #include "base/file_path.h" | 17 #include "base/file_path.h" |
18 #include "base/file_util.h" | 18 #include "base/file_util.h" |
19 #include "base/logging.h" | 19 #include "base/logging.h" |
20 #include "base/path_service.h" | 20 #include "base/path_service.h" |
21 #include "base/string_util.h" | 21 #include "base/string_util.h" |
22 #include "base/utf_string_conversions.h" | 22 #include "base/utf_string_conversions.h" |
23 #include "chrome/browser/browser_process.h" | 23 #include "chrome/browser/browser_process.h" |
24 #include "chrome/browser/chrome_plugin_browsing_context.h" | |
25 #include "chrome/browser/net/url_request_tracking.h" | 24 #include "chrome/browser/net/url_request_tracking.h" |
26 #include "chrome/browser/plugin_download_helper.h" | 25 #include "chrome/browser/plugin_download_helper.h" |
27 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
28 #include "chrome/common/chrome_paths.h" | 27 #include "chrome/common/chrome_paths.h" |
29 #include "chrome/common/chrome_plugin_lib.h" | |
30 #include "chrome/common/chrome_switches.h" | 28 #include "chrome/common/chrome_switches.h" |
31 #include "chrome/common/logging_chrome.h" | 29 #include "chrome/common/logging_chrome.h" |
32 #include "chrome/common/net/url_request_context_getter.h" | 30 #include "chrome/common/net/url_request_context_getter.h" |
33 #include "chrome/common/plugin_messages.h" | 31 #include "chrome/common/plugin_messages.h" |
34 #include "chrome/common/render_messages.h" | 32 #include "chrome/common/render_messages.h" |
35 #include "chrome/common/render_messages_params.h" | 33 #include "chrome/common/render_messages_params.h" |
36 #include "content/browser/browser_thread.h" | 34 #include "content/browser/browser_thread.h" |
37 #include "content/browser/child_process_security_policy.h" | |
38 #include "content/browser/plugin_service.h" | 35 #include "content/browser/plugin_service.h" |
39 #include "content/browser/renderer_host/resource_dispatcher_host.h" | 36 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
40 #include "content/browser/renderer_host/resource_message_filter.h" | 37 #include "content/browser/renderer_host/resource_message_filter.h" |
41 #include "content/common/resource_messages.h" | 38 #include "content/common/resource_messages.h" |
42 #include "ipc/ipc_switches.h" | 39 #include "ipc/ipc_switches.h" |
43 #include "net/base/cookie_store.h" | |
44 #include "net/base/io_buffer.h" | 40 #include "net/base/io_buffer.h" |
45 #include "net/url_request/url_request.h" | 41 #include "net/url_request/url_request.h" |
46 #include "net/url_request/url_request_context.h" | 42 #include "net/url_request/url_request_context.h" |
47 #include "ui/base/ui_base_switches.h" | 43 #include "ui/base/ui_base_switches.h" |
48 #include "ui/gfx/native_widget_types.h" | 44 #include "ui/gfx/native_widget_types.h" |
49 | 45 |
50 #if defined(USE_X11) | 46 #if defined(USE_X11) |
51 #include "ui/gfx/gtk_native_view_id_manager.h" | 47 #include "ui/gfx/gtk_native_view_id_manager.h" |
52 #endif | 48 #endif |
53 | 49 |
54 #if defined(OS_MACOSX) | 50 #if defined(OS_MACOSX) |
55 #include "base/mac/mac_util.h" | 51 #include "base/mac/mac_util.h" |
56 #include "chrome/common/plugin_carbon_interpose_constants_mac.h" | 52 #include "chrome/common/plugin_carbon_interpose_constants_mac.h" |
57 #include "ui/gfx/rect.h" | 53 #include "ui/gfx/rect.h" |
58 #endif | 54 #endif |
59 | 55 |
60 static const char kDefaultPluginFinderURL[] = | 56 static const char kDefaultPluginFinderURL[] = |
61 "https://dl-ssl.google.com/edgedl/chrome/plugins/plugins2.xml"; | 57 "https://dl-ssl.google.com/edgedl/chrome/plugins/plugins2.xml"; |
62 | 58 |
63 namespace { | |
64 | |
65 // Helper class that we pass to ResourceMessageFilter so that it can find the | |
66 // right net::URLRequestContext for a request. | |
67 class PluginURLRequestContextOverride | |
68 : public ResourceMessageFilter::URLRequestContextOverride { | |
69 public: | |
70 PluginURLRequestContextOverride() { | |
71 } | |
72 | |
73 virtual net::URLRequestContext* GetRequestContext( | |
74 const ResourceHostMsg_Request& resource_request) { | |
75 return CPBrowsingContextManager::GetInstance()->ToURLRequestContext( | |
76 resource_request.request_context); | |
77 } | |
78 | |
79 private: | |
80 virtual ~PluginURLRequestContextOverride() {} | |
81 }; | |
82 | |
83 } // namespace | |
84 | |
85 #if defined(OS_WIN) | 59 #if defined(OS_WIN) |
86 void PluginProcessHost::OnPluginWindowDestroyed(HWND window, HWND parent) { | 60 void PluginProcessHost::OnPluginWindowDestroyed(HWND window, HWND parent) { |
87 // The window is destroyed at this point, we just care about its parent, which | 61 // The window is destroyed at this point, we just care about its parent, which |
88 // is the intermediate window we created. | 62 // is the intermediate window we created. |
89 std::set<HWND>::iterator window_index = | 63 std::set<HWND>::iterator window_index = |
90 plugin_parent_windows_set_.find(parent); | 64 plugin_parent_windows_set_.find(parent); |
91 if (window_index == plugin_parent_windows_set_.end()) | 65 if (window_index == plugin_parent_windows_set_.end()) |
92 return; | 66 return; |
93 | 67 |
94 plugin_parent_windows_set_.erase(window_index); | 68 plugin_parent_windows_set_.erase(window_index); |
(...skipping 19 matching lines...) Expand all Loading... |
114 void PluginProcessHost::OnMapNativeViewId(gfx::NativeViewId id, | 88 void PluginProcessHost::OnMapNativeViewId(gfx::NativeViewId id, |
115 gfx::PluginWindowHandle* output) { | 89 gfx::PluginWindowHandle* output) { |
116 *output = 0; | 90 *output = 0; |
117 GtkNativeViewManager::GetInstance()->GetXIDForId(output, id); | 91 GtkNativeViewManager::GetInstance()->GetXIDForId(output, id); |
118 } | 92 } |
119 #endif // defined(TOOLKIT_USES_GTK) | 93 #endif // defined(TOOLKIT_USES_GTK) |
120 | 94 |
121 PluginProcessHost::PluginProcessHost() | 95 PluginProcessHost::PluginProcessHost() |
122 : BrowserChildProcessHost( | 96 : BrowserChildProcessHost( |
123 PLUGIN_PROCESS, | 97 PLUGIN_PROCESS, |
124 PluginService::GetInstance()->resource_dispatcher_host(), | 98 PluginService::GetInstance()->resource_dispatcher_host()), |
125 new PluginURLRequestContextOverride()), | |
126 ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)) | 99 ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)) |
127 #if defined(OS_MACOSX) | 100 #if defined(OS_MACOSX) |
128 , plugin_cursor_visible_(true) | 101 , plugin_cursor_visible_(true) |
129 #endif | 102 #endif |
130 { | 103 { |
131 } | 104 } |
132 | 105 |
133 PluginProcessHost::~PluginProcessHost() { | 106 PluginProcessHost::~PluginProcessHost() { |
134 #if defined(OS_WIN) | 107 #if defined(OS_WIN) |
135 // We erase HWNDs from the plugin_parent_windows_set_ when we receive a | 108 // We erase HWNDs from the plugin_parent_windows_set_ when we receive a |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 // If specified, prepend a launcher program to the command line. | 207 // If specified, prepend a launcher program to the command line. |
235 if (!plugin_launcher.empty()) | 208 if (!plugin_launcher.empty()) |
236 cmd_line->PrependWrapper(plugin_launcher); | 209 cmd_line->PrependWrapper(plugin_launcher); |
237 | 210 |
238 if (!locale.empty()) { | 211 if (!locale.empty()) { |
239 // Pass on the locale so the null plugin will use the right language in the | 212 // Pass on the locale so the null plugin will use the right language in the |
240 // prompt to install the desired plugin. | 213 // prompt to install the desired plugin. |
241 cmd_line->AppendSwitchASCII(switches::kLang, locale); | 214 cmd_line->AppendSwitchASCII(switches::kLang, locale); |
242 } | 215 } |
243 | 216 |
244 // Gears requires the data dir to be available on startup. | |
245 FilePath data_dir = | |
246 PluginService::GetInstance()->GetChromePluginDataDir(); | |
247 DCHECK(!data_dir.empty()); | |
248 cmd_line->AppendSwitchPath(switches::kPluginDataDir, data_dir); | |
249 | |
250 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id()); | 217 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id()); |
251 | 218 |
252 SetCrashReporterCommandLine(cmd_line); | 219 SetCrashReporterCommandLine(cmd_line); |
253 | 220 |
254 #if defined(OS_POSIX) | 221 #if defined(OS_POSIX) |
255 base::environment_vector env; | 222 base::environment_vector env; |
256 #if defined(OS_MACOSX) && !defined(__LP64__) | 223 #if defined(OS_MACOSX) && !defined(__LP64__) |
257 // Add our interposing library for Carbon. This is stripped back out in | 224 // Add our interposing library for Carbon. This is stripped back out in |
258 // plugin_main.cc, so changes here should be reflected there. | 225 // plugin_main.cc, so changes here should be reflected there. |
259 std::string interpose_list(plugin_interpose_strings::kInterposeLibraryPath); | 226 std::string interpose_list(plugin_interpose_strings::kInterposeLibraryPath); |
(...skipping 20 matching lines...) Expand all Loading... |
280 | 247 |
281 return true; | 248 return true; |
282 } | 249 } |
283 | 250 |
284 void PluginProcessHost::ForceShutdown() { | 251 void PluginProcessHost::ForceShutdown() { |
285 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
286 Send(new PluginProcessMsg_NotifyRenderersOfPendingShutdown()); | 253 Send(new PluginProcessMsg_NotifyRenderersOfPendingShutdown()); |
287 BrowserChildProcessHost::ForceShutdown(); | 254 BrowserChildProcessHost::ForceShutdown(); |
288 } | 255 } |
289 | 256 |
290 void PluginProcessHost::OnProcessLaunched() { | |
291 FilePath gears_path; | |
292 if (PathService::Get(chrome::FILE_GEARS_PLUGIN, &gears_path)) { | |
293 FilePath::StringType gears_path_lc = StringToLowerASCII(gears_path.value()); | |
294 FilePath::StringType plugin_path_lc = | |
295 StringToLowerASCII(info_.path.value()); | |
296 if (plugin_path_lc == gears_path_lc) { | |
297 // Give Gears plugins "background" priority. See http://b/1280317. | |
298 SetProcessBackgrounded(); | |
299 } | |
300 } | |
301 } | |
302 | |
303 bool PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { | 257 bool PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { |
304 bool handled = true; | 258 bool handled = true; |
305 IPC_BEGIN_MESSAGE_MAP(PluginProcessHost, msg) | 259 IPC_BEGIN_MESSAGE_MAP(PluginProcessHost, msg) |
306 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ChannelCreated, OnChannelCreated) | 260 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ChannelCreated, OnChannelCreated) |
307 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_GetPluginFinderUrl, | 261 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_GetPluginFinderUrl, |
308 OnGetPluginFinderUrl) | 262 OnGetPluginFinderUrl) |
309 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginMessage, OnPluginMessage) | |
310 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_GetCookies, OnGetCookies) | |
311 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_AccessFiles, OnAccessFiles) | |
312 IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginProcessHostMsg_ResolveProxy, | 263 IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginProcessHostMsg_ResolveProxy, |
313 OnResolveProxy) | 264 OnResolveProxy) |
314 #if defined(OS_WIN) | 265 #if defined(OS_WIN) |
315 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginWindowDestroyed, | 266 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginWindowDestroyed, |
316 OnPluginWindowDestroyed) | 267 OnPluginWindowDestroyed) |
317 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_DownloadUrl, OnDownloadUrl) | 268 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_DownloadUrl, OnDownloadUrl) |
318 #endif | 269 #endif |
319 #if defined(TOOLKIT_USES_GTK) | 270 #if defined(TOOLKIT_USES_GTK) |
320 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_MapNativeViewId, | 271 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_MapNativeViewId, |
321 OnMapNativeViewId) | 272 OnMapNativeViewId) |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 // this "open channel" request into a queue of requests that will | 323 // this "open channel" request into a queue of requests that will |
373 // be run once the channel is open. | 324 // be run once the channel is open. |
374 pending_requests_.push_back(client); | 325 pending_requests_.push_back(client); |
375 return; | 326 return; |
376 } | 327 } |
377 | 328 |
378 // We already have an open channel, send a request right away to plugin. | 329 // We already have an open channel, send a request right away to plugin. |
379 RequestPluginChannel(client); | 330 RequestPluginChannel(client); |
380 } | 331 } |
381 | 332 |
382 void PluginProcessHost::OnGetCookies(uint32 request_context, | |
383 const GURL& url, | |
384 std::string* cookies) { | |
385 net::URLRequestContext* context = CPBrowsingContextManager::GetInstance()-> | |
386 ToURLRequestContext(request_context); | |
387 // TODO(mpcomplete): remove fallback case when Gears support is prevalent. | |
388 if (!context) | |
389 context = Profile::GetDefaultRequestContext()->GetURLRequestContext(); | |
390 | |
391 // Note: We don't have a first_party_for_cookies check because plugins bypass | |
392 // third-party cookie blocking. | |
393 if (context && context->cookie_store()) { | |
394 *cookies = context->cookie_store()->GetCookies(url); | |
395 } else { | |
396 DLOG(ERROR) << "Could not serve plugin cookies request."; | |
397 cookies->clear(); | |
398 } | |
399 } | |
400 | |
401 void PluginProcessHost::OnAccessFiles(int renderer_id, | |
402 const std::vector<std::string>& files, | |
403 bool* allowed) { | |
404 ChildProcessSecurityPolicy* policy = | |
405 ChildProcessSecurityPolicy::GetInstance(); | |
406 | |
407 for (size_t i = 0; i < files.size(); ++i) { | |
408 const FilePath path = FilePath::FromWStringHack(UTF8ToWide(files[i])); | |
409 if (!policy->CanReadFile(renderer_id, path)) { | |
410 VLOG(1) << "Denied unauthorized request for file " << files[i]; | |
411 *allowed = false; | |
412 return; | |
413 } | |
414 } | |
415 | |
416 *allowed = true; | |
417 } | |
418 | |
419 void PluginProcessHost::OnResolveProxy(const GURL& url, | 333 void PluginProcessHost::OnResolveProxy(const GURL& url, |
420 IPC::Message* reply_msg) { | 334 IPC::Message* reply_msg) { |
421 resolve_proxy_msg_helper_.Start(url, reply_msg); | 335 resolve_proxy_msg_helper_.Start(url, reply_msg); |
422 } | 336 } |
423 | 337 |
424 void PluginProcessHost::OnResolveProxyCompleted(IPC::Message* reply_msg, | 338 void PluginProcessHost::OnResolveProxyCompleted(IPC::Message* reply_msg, |
425 int result, | 339 int result, |
426 const std::string& proxy_list) { | 340 const std::string& proxy_list) { |
427 PluginProcessHostMsg_ResolveProxy::WriteReplyParams( | 341 PluginProcessHostMsg_ResolveProxy::WriteReplyParams( |
428 reply_msg, result, proxy_list); | 342 reply_msg, result, proxy_list); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 } | 376 } |
463 | 377 |
464 if (!g_browser_process->plugin_finder_disabled()) { | 378 if (!g_browser_process->plugin_finder_disabled()) { |
465 // TODO(iyengar): Add the plumbing to retrieve the default | 379 // TODO(iyengar): Add the plumbing to retrieve the default |
466 // plugin finder URL. | 380 // plugin finder URL. |
467 *plugin_finder_url = kDefaultPluginFinderURL; | 381 *plugin_finder_url = kDefaultPluginFinderURL; |
468 } else { | 382 } else { |
469 plugin_finder_url->clear(); | 383 plugin_finder_url->clear(); |
470 } | 384 } |
471 } | 385 } |
472 | |
473 void PluginProcessHost::OnPluginMessage( | |
474 const std::vector<uint8>& data) { | |
475 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
476 | |
477 ChromePluginLib *chrome_plugin = ChromePluginLib::Find(info_.path); | |
478 if (chrome_plugin) { | |
479 void *data_ptr = const_cast<void*>(reinterpret_cast<const void*>(&data[0])); | |
480 uint32 data_len = static_cast<uint32>(data.size()); | |
481 chrome_plugin->functions().on_message(data_ptr, data_len); | |
482 } | |
483 } | |
OLD | NEW |