| 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/browser/plugin_service_impl.h" | 5 #include "content/browser/plugin_service_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 if (LoadPluginListInProcess()) { | 92 if (LoadPluginListInProcess()) { |
| 93 CHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread( | 93 CHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread( |
| 94 token)); | 94 token)); |
| 95 } else { | 95 } else { |
| 96 CHECK(false) << "Plugin loading should happen out-of-process."; | 96 CHECK(false) << "Plugin loading should happen out-of-process."; |
| 97 } | 97 } |
| 98 } | 98 } |
| 99 | 99 |
| 100 #if defined(OS_MACOSX) | 100 #if defined(OS_MACOSX) |
| 101 void NotifyPluginsOfActivation() { | 101 void NotifyPluginsOfActivation() { |
| 102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 102 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 103 | 103 |
| 104 for (PluginProcessHostIterator iter; !iter.Done(); ++iter) | 104 for (PluginProcessHostIterator iter; !iter.Done(); ++iter) |
| 105 iter->OnAppActivation(); | 105 iter->OnAppActivation(); |
| 106 } | 106 } |
| 107 #endif | 107 #endif |
| 108 | 108 |
| 109 #if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID) | 109 #if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID) |
| 110 void NotifyPluginDirChanged(const base::FilePath& path, bool error) { | 110 void NotifyPluginDirChanged(const base::FilePath& path, bool error) { |
| 111 if (error) { | 111 if (error) { |
| 112 // TODO(pastarmovj): Add some sensible error handling. Maybe silently | 112 // TODO(pastarmovj): Add some sensible error handling. Maybe silently |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 if (iter->plugin_path() == broker_path) | 270 if (iter->plugin_path() == broker_path) |
| 271 return *iter; | 271 return *iter; |
| 272 } | 272 } |
| 273 | 273 |
| 274 return NULL; | 274 return NULL; |
| 275 } | 275 } |
| 276 | 276 |
| 277 PluginProcessHost* PluginServiceImpl::FindOrStartNpapiPluginProcess( | 277 PluginProcessHost* PluginServiceImpl::FindOrStartNpapiPluginProcess( |
| 278 int render_process_id, | 278 int render_process_id, |
| 279 const base::FilePath& plugin_path) { | 279 const base::FilePath& plugin_path) { |
| 280 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 280 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 281 | 281 |
| 282 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) | 282 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) |
| 283 return NULL; | 283 return NULL; |
| 284 | 284 |
| 285 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path); | 285 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path); |
| 286 if (plugin_host) | 286 if (plugin_host) |
| 287 return plugin_host; | 287 return plugin_host; |
| 288 | 288 |
| 289 WebPluginInfo info; | 289 WebPluginInfo info; |
| 290 if (!GetPluginInfoByPath(plugin_path, &info)) { | 290 if (!GetPluginInfoByPath(plugin_path, &info)) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 311 NOTREACHED(); // Init is not expected to fail. | 311 NOTREACHED(); // Init is not expected to fail. |
| 312 return NULL; | 312 return NULL; |
| 313 } | 313 } |
| 314 return new_host.release(); | 314 return new_host.release(); |
| 315 } | 315 } |
| 316 | 316 |
| 317 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess( | 317 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess( |
| 318 int render_process_id, | 318 int render_process_id, |
| 319 const base::FilePath& plugin_path, | 319 const base::FilePath& plugin_path, |
| 320 const base::FilePath& profile_data_directory) { | 320 const base::FilePath& profile_data_directory) { |
| 321 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 321 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 322 | 322 |
| 323 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) { | 323 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) { |
| 324 VLOG(1) << "Unable to load ppapi plugin: " << plugin_path.MaybeAsASCII(); | 324 VLOG(1) << "Unable to load ppapi plugin: " << plugin_path.MaybeAsASCII(); |
| 325 return NULL; | 325 return NULL; |
| 326 } | 326 } |
| 327 | 327 |
| 328 PpapiPluginProcessHost* plugin_host = | 328 PpapiPluginProcessHost* plugin_host = |
| 329 FindPpapiPluginProcess(plugin_path, profile_data_directory); | 329 FindPpapiPluginProcess(plugin_path, profile_data_directory); |
| 330 if (plugin_host) | 330 if (plugin_host) |
| 331 return plugin_host; | 331 return plugin_host; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 354 VLOG(1) << "Unable to create ppapi plugin process for: " | 354 VLOG(1) << "Unable to create ppapi plugin process for: " |
| 355 << plugin_path.MaybeAsASCII(); | 355 << plugin_path.MaybeAsASCII(); |
| 356 } | 356 } |
| 357 | 357 |
| 358 return plugin_host; | 358 return plugin_host; |
| 359 } | 359 } |
| 360 | 360 |
| 361 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess( | 361 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess( |
| 362 int render_process_id, | 362 int render_process_id, |
| 363 const base::FilePath& plugin_path) { | 363 const base::FilePath& plugin_path) { |
| 364 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 364 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 365 | 365 |
| 366 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) | 366 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) |
| 367 return NULL; | 367 return NULL; |
| 368 | 368 |
| 369 PpapiPluginProcessHost* plugin_host = FindPpapiBrokerProcess(plugin_path); | 369 PpapiPluginProcessHost* plugin_host = FindPpapiBrokerProcess(plugin_path); |
| 370 if (plugin_host) | 370 if (plugin_host) |
| 371 return plugin_host; | 371 return plugin_host; |
| 372 | 372 |
| 373 // Validate that the plugin is actually registered. | 373 // Validate that the plugin is actually registered. |
| 374 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path); | 374 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path); |
| 375 if (!info) | 375 if (!info) |
| 376 return NULL; | 376 return NULL; |
| 377 | 377 |
| 378 // TODO(ddorwin): Uncomment once out of process is supported. | 378 // TODO(ddorwin): Uncomment once out of process is supported. |
| 379 // DCHECK(info->is_out_of_process); | 379 // DCHECK(info->is_out_of_process); |
| 380 | 380 |
| 381 // This broker isn't loaded by any broker process, so create a new process. | 381 // This broker isn't loaded by any broker process, so create a new process. |
| 382 return PpapiPluginProcessHost::CreateBrokerHost(*info); | 382 return PpapiPluginProcessHost::CreateBrokerHost(*info); |
| 383 } | 383 } |
| 384 | 384 |
| 385 void PluginServiceImpl::OpenChannelToNpapiPlugin( | 385 void PluginServiceImpl::OpenChannelToNpapiPlugin( |
| 386 int render_process_id, | 386 int render_process_id, |
| 387 int render_frame_id, | 387 int render_frame_id, |
| 388 const GURL& url, | 388 const GURL& url, |
| 389 const GURL& page_url, | 389 const GURL& page_url, |
| 390 const std::string& mime_type, | 390 const std::string& mime_type, |
| 391 PluginProcessHost::Client* client) { | 391 PluginProcessHost::Client* client) { |
| 392 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 392 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 393 DCHECK(!ContainsKey(pending_plugin_clients_, client)); | 393 DCHECK(!ContainsKey(pending_plugin_clients_, client)); |
| 394 pending_plugin_clients_.insert(client); | 394 pending_plugin_clients_.insert(client); |
| 395 | 395 |
| 396 // Make sure plugins are loaded if necessary. | 396 // Make sure plugins are loaded if necessary. |
| 397 PluginServiceFilterParams params = { | 397 PluginServiceFilterParams params = { |
| 398 render_process_id, | 398 render_process_id, |
| 399 render_frame_id, | 399 render_frame_id, |
| 400 page_url, | 400 page_url, |
| 401 client->GetResourceContext() | 401 client->GetResourceContext() |
| 402 }; | 402 }; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 429 if (plugin_host) { | 429 if (plugin_host) { |
| 430 plugin_host->OpenChannelToPlugin(client); | 430 plugin_host->OpenChannelToPlugin(client); |
| 431 } else { | 431 } else { |
| 432 // Send error. | 432 // Send error. |
| 433 client->OnPpapiChannelOpened(IPC::ChannelHandle(), base::kNullProcessId, 0); | 433 client->OnPpapiChannelOpened(IPC::ChannelHandle(), base::kNullProcessId, 0); |
| 434 } | 434 } |
| 435 } | 435 } |
| 436 | 436 |
| 437 void PluginServiceImpl::CancelOpenChannelToNpapiPlugin( | 437 void PluginServiceImpl::CancelOpenChannelToNpapiPlugin( |
| 438 PluginProcessHost::Client* client) { | 438 PluginProcessHost::Client* client) { |
| 439 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 439 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 440 DCHECK(ContainsKey(pending_plugin_clients_, client)); | 440 DCHECK(ContainsKey(pending_plugin_clients_, client)); |
| 441 pending_plugin_clients_.erase(client); | 441 pending_plugin_clients_.erase(client); |
| 442 } | 442 } |
| 443 | 443 |
| 444 void PluginServiceImpl::ForwardGetAllowedPluginForOpenChannelToPlugin( | 444 void PluginServiceImpl::ForwardGetAllowedPluginForOpenChannelToPlugin( |
| 445 const PluginServiceFilterParams& params, | 445 const PluginServiceFilterParams& params, |
| 446 const GURL& url, | 446 const GURL& url, |
| 447 const std::string& mime_type, | 447 const std::string& mime_type, |
| 448 PluginProcessHost::Client* client, | 448 PluginProcessHost::Client* client, |
| 449 const std::vector<WebPluginInfo>&) { | 449 const std::vector<WebPluginInfo>&) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 477 base::Unretained(this), | 477 base::Unretained(this), |
| 478 render_process_id, | 478 render_process_id, |
| 479 plugin_path, | 479 plugin_path, |
| 480 client)); | 480 client)); |
| 481 } | 481 } |
| 482 | 482 |
| 483 void PluginServiceImpl::FinishOpenChannelToPlugin( | 483 void PluginServiceImpl::FinishOpenChannelToPlugin( |
| 484 int render_process_id, | 484 int render_process_id, |
| 485 const base::FilePath& plugin_path, | 485 const base::FilePath& plugin_path, |
| 486 PluginProcessHost::Client* client) { | 486 PluginProcessHost::Client* client) { |
| 487 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 487 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 488 | 488 |
| 489 // Make sure it hasn't been canceled yet. | 489 // Make sure it hasn't been canceled yet. |
| 490 if (!ContainsKey(pending_plugin_clients_, client)) | 490 if (!ContainsKey(pending_plugin_clients_, client)) |
| 491 return; | 491 return; |
| 492 pending_plugin_clients_.erase(client); | 492 pending_plugin_clients_.erase(client); |
| 493 | 493 |
| 494 PluginProcessHost* plugin_host = FindOrStartNpapiPluginProcess( | 494 PluginProcessHost* plugin_host = FindOrStartNpapiPluginProcess( |
| 495 render_process_id, plugin_path); | 495 render_process_id, plugin_path); |
| 496 if (plugin_host) { | 496 if (plugin_host) { |
| 497 client->OnFoundPluginProcessHost(plugin_host); | 497 client->OnFoundPluginProcessHost(plugin_host); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 PluginList::Singleton()->GetPlugins(&plugins, NPAPIPluginsSupported()); | 616 PluginList::Singleton()->GetPlugins(&plugins, NPAPIPluginsSupported()); |
| 617 | 617 |
| 618 target_loop->PostTask(FROM_HERE, | 618 target_loop->PostTask(FROM_HERE, |
| 619 base::Bind(callback, plugins)); | 619 base::Bind(callback, plugins)); |
| 620 } | 620 } |
| 621 | 621 |
| 622 #if defined(OS_POSIX) | 622 #if defined(OS_POSIX) |
| 623 void PluginServiceImpl::GetPluginsOnIOThread( | 623 void PluginServiceImpl::GetPluginsOnIOThread( |
| 624 base::MessageLoopProxy* target_loop, | 624 base::MessageLoopProxy* target_loop, |
| 625 const GetPluginsCallback& callback) { | 625 const GetPluginsCallback& callback) { |
| 626 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 626 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 627 | 627 |
| 628 // If we switch back to loading plugins in process, then we need to make | 628 // If we switch back to loading plugins in process, then we need to make |
| 629 // sure g_thread_init() gets called since plugins may call glib at load. | 629 // sure g_thread_init() gets called since plugins may call glib at load. |
| 630 | 630 |
| 631 if (!plugin_loader_.get()) | 631 if (!plugin_loader_.get()) |
| 632 plugin_loader_ = new PluginLoaderPosix; | 632 plugin_loader_ = new PluginLoaderPosix; |
| 633 | 633 |
| 634 plugin_loader_->GetPlugins( | 634 plugin_loader_->GetPlugins( |
| 635 base::Bind(&ForwardCallback, make_scoped_refptr(target_loop), callback)); | 635 base::Bind(&ForwardCallback, make_scoped_refptr(target_loop), callback)); |
| 636 } | 636 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 | 710 |
| 711 PluginProcessHost* plugin = FindNpapiPluginProcess(plugin_path); | 711 PluginProcessHost* plugin = FindNpapiPluginProcess(plugin_path); |
| 712 if (plugin) | 712 if (plugin) |
| 713 plugin->ForceShutdown(); | 713 plugin->ForceShutdown(); |
| 714 } | 714 } |
| 715 | 715 |
| 716 static const unsigned int kMaxCrashesPerInterval = 3; | 716 static const unsigned int kMaxCrashesPerInterval = 3; |
| 717 static const unsigned int kCrashesInterval = 120; | 717 static const unsigned int kCrashesInterval = 120; |
| 718 | 718 |
| 719 void PluginServiceImpl::RegisterPluginCrash(const base::FilePath& path) { | 719 void PluginServiceImpl::RegisterPluginCrash(const base::FilePath& path) { |
| 720 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 720 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 721 std::map<base::FilePath, std::vector<base::Time> >::iterator i = | 721 std::map<base::FilePath, std::vector<base::Time> >::iterator i = |
| 722 crash_times_.find(path); | 722 crash_times_.find(path); |
| 723 if (i == crash_times_.end()) { | 723 if (i == crash_times_.end()) { |
| 724 crash_times_[path] = std::vector<base::Time>(); | 724 crash_times_[path] = std::vector<base::Time>(); |
| 725 i = crash_times_.find(path); | 725 i = crash_times_.find(path); |
| 726 } | 726 } |
| 727 if (i->second.size() == kMaxCrashesPerInterval) { | 727 if (i->second.size() == kMaxCrashesPerInterval) { |
| 728 i->second.erase(i->second.begin()); | 728 i->second.erase(i->second.begin()); |
| 729 } | 729 } |
| 730 base::Time time = base::Time::Now(); | 730 base::Time time = base::Time::Now(); |
| 731 i->second.push_back(time); | 731 i->second.push_back(time); |
| 732 } | 732 } |
| 733 | 733 |
| 734 bool PluginServiceImpl::IsPluginUnstable(const base::FilePath& path) { | 734 bool PluginServiceImpl::IsPluginUnstable(const base::FilePath& path) { |
| 735 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 735 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 736 std::map<base::FilePath, std::vector<base::Time> >::const_iterator i = | 736 std::map<base::FilePath, std::vector<base::Time> >::const_iterator i = |
| 737 crash_times_.find(path); | 737 crash_times_.find(path); |
| 738 if (i == crash_times_.end()) { | 738 if (i == crash_times_.end()) { |
| 739 return false; | 739 return false; |
| 740 } | 740 } |
| 741 if (i->second.size() != kMaxCrashesPerInterval) { | 741 if (i->second.size() != kMaxCrashesPerInterval) { |
| 742 return false; | 742 return false; |
| 743 } | 743 } |
| 744 base::TimeDelta delta = base::Time::Now() - i->second[0]; | 744 base::TimeDelta delta = base::Time::Now() - i->second[0]; |
| 745 return delta.InSeconds() <= kCrashesInterval; | 745 return delta.InSeconds() <= kCrashesInterval; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 #endif | 864 #endif |
| 865 | 865 |
| 866 bool PluginServiceImpl::PpapiDevChannelSupported( | 866 bool PluginServiceImpl::PpapiDevChannelSupported( |
| 867 BrowserContext* browser_context, | 867 BrowserContext* browser_context, |
| 868 const GURL& document_url) { | 868 const GURL& document_url) { |
| 869 return content::GetContentClient()->browser()-> | 869 return content::GetContentClient()->browser()-> |
| 870 IsPluginAllowedToUseDevChannelAPIs(browser_context, document_url); | 870 IsPluginAllowedToUseDevChannelAPIs(browser_context, document_url); |
| 871 } | 871 } |
| 872 | 872 |
| 873 } // namespace content | 873 } // namespace content |
| OLD | NEW |