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

Side by Side Diff: chrome/browser/plugin_service.cc

Issue 6486034: Share PPAPI out-of-process plugins between renderer processes.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/plugin_service.h ('k') | chrome/browser/plugin_service_browsertest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 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 "chrome/browser/plugin_service.h" 5 #include "chrome/browser/plugin_service.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/path_service.h" 10 #include "base/path_service.h"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "base/threading/thread.h" 12 #include "base/threading/thread.h"
13 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
14 #include "base/values.h" 14 #include "base/values.h"
15 #include "base/synchronization/waitable_event.h" 15 #include "base/synchronization/waitable_event.h"
16 #include "chrome/browser/browser_process.h" 16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/browser_thread.h" 17 #include "chrome/browser/browser_thread.h"
18 #include "chrome/browser/chrome_plugin_host.h" 18 #include "chrome/browser/chrome_plugin_host.h"
19 #include "chrome/browser/extensions/extension_service.h" 19 #include "chrome/browser/extensions/extension_service.h"
20 #include "chrome/browser/plugin_updater.h" 20 #include "chrome/browser/plugin_updater.h"
21 #include "chrome/browser/ppapi_plugin_process_host.h"
21 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/renderer_host/render_process_host.h" 23 #include "chrome/browser/renderer_host/render_process_host.h"
23 #include "chrome/browser/renderer_host/render_view_host.h" 24 #include "chrome/browser/renderer_host/render_view_host.h"
24 #include "chrome/common/chrome_plugin_lib.h" 25 #include "chrome/common/chrome_plugin_lib.h"
25 #include "chrome/common/chrome_paths.h" 26 #include "chrome/common/chrome_paths.h"
26 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/default_plugin.h" 28 #include "chrome/common/default_plugin.h"
28 #include "chrome/common/extensions/extension.h" 29 #include "chrome/common/extensions/extension.h"
29 #include "chrome/common/gpu_plugin.h" 30 #include "chrome/common/gpu_plugin.h"
30 #include "chrome/common/logging_chrome.h" 31 #include "chrome/common/logging_chrome.h"
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 } 234 }
234 235
235 const FilePath& PluginService::GetChromePluginDataDir() { 236 const FilePath& PluginService::GetChromePluginDataDir() {
236 return chrome_plugin_data_dir_; 237 return chrome_plugin_data_dir_;
237 } 238 }
238 239
239 const std::string& PluginService::GetUILocale() { 240 const std::string& PluginService::GetUILocale() {
240 return ui_locale_; 241 return ui_locale_;
241 } 242 }
242 243
243 PluginProcessHost* PluginService::FindPluginProcess( 244 PluginProcessHost* PluginService::FindNpapiPluginProcess(
244 const FilePath& plugin_path) { 245 const FilePath& plugin_path) {
245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
246 247
247 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS); 248 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS);
248 !iter.Done(); ++iter) { 249 !iter.Done(); ++iter) {
249 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter); 250 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter);
250 if (plugin->info().path == plugin_path) 251 if (plugin->info().path == plugin_path)
251 return plugin; 252 return plugin;
252 } 253 }
253 254
254 return NULL; 255 return NULL;
255 } 256 }
256 257
257 PluginProcessHost* PluginService::FindOrStartPluginProcess( 258 PpapiPluginProcessHost* PluginService::FindPpapiPluginProcess(
258 const FilePath& plugin_path) { 259 const FilePath& plugin_path) {
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 260 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
260 261
261 PluginProcessHost* plugin_host = FindPluginProcess(plugin_path); 262 for (BrowserChildProcessHost::Iterator iter(
263 ChildProcessInfo::PPAPI_PLUGIN_PROCESS);
264 !iter.Done(); ++iter) {
265 PpapiPluginProcessHost* plugin =
266 static_cast<PpapiPluginProcessHost*>(*iter);
267 if (plugin->plugin_path() == plugin_path)
268 return plugin;
269 }
270
271 return NULL;
272 }
273
274 PluginProcessHost* PluginService::FindOrStartNpapiPluginProcess(
275 const FilePath& plugin_path) {
276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
277
278 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path);
262 if (plugin_host) 279 if (plugin_host)
263 return plugin_host; 280 return plugin_host;
264 281
265 webkit::npapi::WebPluginInfo info; 282 webkit::npapi::WebPluginInfo info;
266 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath( 283 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath(
267 plugin_path, &info)) { 284 plugin_path, &info)) {
268 return NULL; 285 return NULL;
269 } 286 }
270 287
271 // This plugin isn't loaded by any plugin process, so create a new process. 288 // This plugin isn't loaded by any plugin process, so create a new process.
272 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost()); 289 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost());
273 if (!new_host->Init(info, ui_locale_)) { 290 if (!new_host->Init(info, ui_locale_)) {
274 NOTREACHED(); // Init is not expected to fail 291 NOTREACHED(); // Init is not expected to fail.
275 return NULL; 292 return NULL;
276 } 293 }
277
278 return new_host.release(); 294 return new_host.release();
279 } 295 }
280 296
281 void PluginService::OpenChannelToPlugin( 297 PpapiPluginProcessHost* PluginService::FindOrStartPpapiPluginProcess(
298 const FilePath& plugin_path) {
299 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
300
301 PpapiPluginProcessHost* plugin_host = FindPpapiPluginProcess(plugin_path);
302 if (plugin_host)
303 return plugin_host;
304
305 // Validate that the plugin is actually registered. There should generally
306 // be very few plugins so a brute-force search is fine.
307 PepperPluginInfo* info = NULL;
308 for (size_t i = 0; i < ppapi_plugins_.size(); i++) {
309 if (ppapi_plugins_[i].path == plugin_path) {
310 info = &ppapi_plugins_[i];
311 break;
312 }
313 }
314 if (!info)
315 return NULL;
316
317 // This plugin isn't loaded by any plugin process, so create a new process.
318 scoped_ptr<PpapiPluginProcessHost> new_host(new PpapiPluginProcessHost);
319 if (!new_host->Init(plugin_path)) {
320 NOTREACHED(); // Init is not expected to fail.
321 return NULL;
322 }
323 return new_host.release();
324 }
325
326 void PluginService::OpenChannelToNpapiPlugin(
282 int render_process_id, 327 int render_process_id,
283 int render_view_id, 328 int render_view_id,
284 const GURL& url, 329 const GURL& url,
285 const std::string& mime_type, 330 const std::string& mime_type,
286 PluginProcessHost::Client* client) { 331 PluginProcessHost::Client* client) {
287 // The PluginList::GetFirstAllowedPluginInfo may need to load the 332 // The PluginList::GetFirstAllowedPluginInfo may need to load the
288 // plugins. Don't do it on the IO thread. 333 // plugins. Don't do it on the IO thread.
289 BrowserThread::PostTask( 334 BrowserThread::PostTask(
290 BrowserThread::FILE, FROM_HERE, 335 BrowserThread::FILE, FROM_HERE,
291 NewRunnableMethod( 336 NewRunnableMethod(
292 this, &PluginService::GetAllowedPluginForOpenChannelToPlugin, 337 this, &PluginService::GetAllowedPluginForOpenChannelToPlugin,
293 render_process_id, render_view_id, url, mime_type, client)); 338 render_process_id, render_view_id, url, mime_type, client));
294 } 339 }
295 340
341 void PluginService::OpenChannelToPpapiPlugin(
342 const FilePath& path,
343 PpapiPluginProcessHost::Client* client) {
344 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess(path);
345 if (plugin_host)
346 plugin_host->OpenChannelToPlugin(client);
347 else // Send error.
348 client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle());
349 }
350
296 void PluginService::GetAllowedPluginForOpenChannelToPlugin( 351 void PluginService::GetAllowedPluginForOpenChannelToPlugin(
297 int render_process_id, 352 int render_process_id,
298 int render_view_id, 353 int render_view_id,
299 const GURL& url, 354 const GURL& url,
300 const std::string& mime_type, 355 const std::string& mime_type,
301 PluginProcessHost::Client* client) { 356 PluginProcessHost::Client* client) {
302 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
303 webkit::npapi::WebPluginInfo info; 358 webkit::npapi::WebPluginInfo info;
304 bool found = GetFirstAllowedPluginInfo( 359 bool found = GetFirstAllowedPluginInfo(
305 render_process_id, render_view_id, url, mime_type, &info, NULL); 360 render_process_id, render_view_id, url, mime_type, &info, NULL);
306 FilePath plugin_path; 361 FilePath plugin_path;
307 if (found && webkit::npapi::IsPluginEnabled(info)) 362 if (found && webkit::npapi::IsPluginEnabled(info))
308 plugin_path = FilePath(info.path); 363 plugin_path = FilePath(info.path);
309 364
310 // Now we jump back to the IO thread to finish opening the channel. 365 // Now we jump back to the IO thread to finish opening the channel.
311 BrowserThread::PostTask( 366 BrowserThread::PostTask(
312 BrowserThread::IO, FROM_HERE, 367 BrowserThread::IO, FROM_HERE,
313 NewRunnableMethod( 368 NewRunnableMethod(
314 this, &PluginService::FinishOpenChannelToPlugin, 369 this, &PluginService::FinishOpenChannelToPlugin,
315 plugin_path, client)); 370 plugin_path, client));
316 } 371 }
317 372
318 void PluginService::FinishOpenChannelToPlugin( 373 void PluginService::FinishOpenChannelToPlugin(
319 const FilePath& plugin_path, 374 const FilePath& plugin_path,
320 PluginProcessHost::Client* client) { 375 PluginProcessHost::Client* client) {
321 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 376 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
322 377
323 PluginProcessHost* plugin_host = FindOrStartPluginProcess(plugin_path); 378 PluginProcessHost* plugin_host = FindOrStartNpapiPluginProcess(plugin_path);
324 if (plugin_host) 379 if (plugin_host)
325 plugin_host->OpenChannelToPlugin(client); 380 plugin_host->OpenChannelToPlugin(client);
326 else 381 else
327 client->OnError(); 382 client->OnError();
328 } 383 }
329 384
330 bool PluginService::GetFirstAllowedPluginInfo( 385 bool PluginService::GetFirstAllowedPluginInfo(
331 int render_process_id, 386 int render_process_id,
332 int render_view_id, 387 int render_view_id,
333 const GURL& url, 388 const GURL& url,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); 440 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
386 PurgePluginListCache(true); 441 PurgePluginListCache(true);
387 #else 442 #else
388 // This event should only get signaled on a Windows machine. 443 // This event should only get signaled on a Windows machine.
389 NOTREACHED(); 444 NOTREACHED();
390 #endif // defined(OS_WIN) 445 #endif // defined(OS_WIN)
391 } 446 }
392 447
393 static void ForceShutdownPlugin(const FilePath& plugin_path) { 448 static void ForceShutdownPlugin(const FilePath& plugin_path) {
394 PluginProcessHost* plugin = 449 PluginProcessHost* plugin =
395 PluginService::GetInstance()->FindPluginProcess(plugin_path); 450 PluginService::GetInstance()->FindNpapiPluginProcess(plugin_path);
396 if (plugin) 451 if (plugin)
397 plugin->ForceShutdown(); 452 plugin->ForceShutdown();
398 } 453 }
399 454
400 void PluginService::Observe(NotificationType type, 455 void PluginService::Observe(NotificationType type,
401 const NotificationSource& source, 456 const NotificationSource& source,
402 const NotificationDetails& details) { 457 const NotificationDetails& details) {
403 switch (type.value) { 458 switch (type.value) {
404 case NotificationType::EXTENSION_LOADED: { 459 case NotificationType::EXTENSION_LOADED: {
405 const Extension* extension = Details<const Extension>(details).ptr(); 460 const Extension* extension = Details<const Extension>(details).ptr();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 return (url.scheme() == required_url.scheme() && 538 return (url.scheme() == required_url.scheme() &&
484 url.host() == required_url.host()); 539 url.host() == required_url.host());
485 } 540 }
486 541
487 void PluginService::OverridePluginForTab(OverriddenPlugin plugin) { 542 void PluginService::OverridePluginForTab(OverriddenPlugin plugin) {
488 base::AutoLock auto_lock(overridden_plugins_lock_); 543 base::AutoLock auto_lock(overridden_plugins_lock_);
489 overridden_plugins_.push_back(plugin); 544 overridden_plugins_.push_back(plugin);
490 } 545 }
491 546
492 void PluginService::RegisterPepperPlugins() { 547 void PluginService::RegisterPepperPlugins() {
493 std::vector<PepperPluginInfo> plugins; 548 PepperPluginRegistry::ComputeList(&ppapi_plugins_);
494 PepperPluginRegistry::ComputeList(&plugins); 549 for (size_t i = 0; i < ppapi_plugins_.size(); ++i) {
495 for (size_t i = 0; i < plugins.size(); ++i) {
496 webkit::npapi::WebPluginInfo info; 550 webkit::npapi::WebPluginInfo info;
497 info.path = plugins[i].path; 551 info.path = ppapi_plugins_[i].path;
498 info.name = plugins[i].name.empty() ? 552 info.name = ppapi_plugins_[i].name.empty() ?
499 plugins[i].path.BaseName().LossyDisplayName() : 553 ppapi_plugins_[i].path.BaseName().LossyDisplayName() :
500 ASCIIToUTF16(plugins[i].name); 554 ASCIIToUTF16(ppapi_plugins_[i].name);
501 info.desc = ASCIIToUTF16(plugins[i].description); 555 info.desc = ASCIIToUTF16(ppapi_plugins_[i].description);
502 info.enabled = webkit::npapi::WebPluginInfo::USER_ENABLED_POLICY_UNMANAGED; 556 info.enabled = webkit::npapi::WebPluginInfo::USER_ENABLED_POLICY_UNMANAGED;
503 557
504 // TODO(evan): Pepper shouldn't require us to parse strings to get 558 // TODO(evan): Pepper shouldn't require us to parse strings to get
505 // the list of mime types out. 559 // the list of mime types out.
506 if (!webkit::npapi::PluginList::ParseMimeTypes( 560 if (!webkit::npapi::PluginList::ParseMimeTypes(
507 JoinString(plugins[i].mime_types, '|'), 561 JoinString(ppapi_plugins_[i].mime_types, '|'),
508 plugins[i].file_extensions, 562 ppapi_plugins_[i].file_extensions,
509 ASCIIToUTF16(plugins[i].type_descriptions), 563 ASCIIToUTF16(ppapi_plugins_[i].type_descriptions),
510 &info.mime_types)) { 564 &info.mime_types)) {
511 LOG(ERROR) << "Error parsing mime types for " 565 LOG(ERROR) << "Error parsing mime types for "
512 << plugins[i].path.LossyDisplayName(); 566 << ppapi_plugins_[i].path.LossyDisplayName();
513 return; 567 return;
514 } 568 }
515 569
516 webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(info); 570 webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(info);
517 } 571 }
518 } 572 }
519 573
520 #if defined(OS_LINUX) 574 #if defined(OS_LINUX)
521 // static 575 // static
522 void PluginService::RegisterFilePathWatcher( 576 void PluginService::RegisterFilePathWatcher(
523 FilePathWatcher *watcher, 577 FilePathWatcher *watcher,
524 const FilePath& path, 578 const FilePath& path,
525 FilePathWatcher::Delegate* delegate) { 579 FilePathWatcher::Delegate* delegate) {
526 bool result = watcher->Watch(path, delegate); 580 bool result = watcher->Watch(path, delegate);
527 DCHECK(result); 581 DCHECK(result);
528 } 582 }
529 #endif 583 #endif
OLDNEW
« no previous file with comments | « chrome/browser/plugin_service.h ('k') | chrome/browser/plugin_service_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698