summaryrefslogtreecommitdiffstats
path: root/chrome/browser/plugin_service.cc
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/browser/plugin_service.cc
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/plugin_service.cc')
-rw-r--r--chrome/browser/plugin_service.cc240
1 files changed, 240 insertions, 0 deletions
diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc
new file mode 100644
index 0000000..8b5c979
--- /dev/null
+++ b/chrome/browser/plugin_service.cc
@@ -0,0 +1,240 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "chrome/browser/plugin_service.h"
+
+#include "base/singleton.h"
+#include "base/thread.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_plugin_host.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/plugin_process_host.h"
+#include "chrome/browser/render_process_host.h"
+#include "chrome/browser/resource_message_filter.h"
+#include "chrome/common/chrome_plugin_lib.h"
+#include "chrome/common/logging_chrome.h"
+#include "webkit/glue/plugins/plugin_list.h"
+
+// static
+PluginService* PluginService::GetInstance() {
+ return Singleton<PluginService>::get();
+}
+
+PluginService::PluginService()
+ : main_message_loop_(MessageLoop::current()),
+ ui_locale_(g_browser_process->GetApplicationLocale()),
+ resource_dispatcher_host_(NULL),
+ plugin_shutdown_handler_(new ShutdownHandler) {
+ // Have the NPAPI plugin list search for Chrome plugins as well.
+ ChromePluginLib::RegisterPluginsWithNPAPI();
+}
+
+PluginService::~PluginService() {
+}
+
+void PluginService::GetPlugins(bool refresh,
+ std::vector<WebPluginInfo>* plugins) {
+ AutoLock lock(lock_);
+ NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins);
+}
+
+void PluginService::LoadChromePlugins(
+ ResourceDispatcherHost* resource_dispatcher_host) {
+ resource_dispatcher_host_ = resource_dispatcher_host;
+ ChromePluginLib::LoadChromePlugins(GetCPBrowserFuncsForBrowser());
+}
+
+void PluginService::SetChromePluginDataDir(const std::wstring& data_dir) {
+ AutoLock lock(lock_);
+ chrome_plugin_data_dir_ = data_dir;
+}
+
+const std::wstring& PluginService::GetChromePluginDataDir() {
+ AutoLock lock(lock_);
+ return chrome_plugin_data_dir_;
+}
+
+const std::wstring& PluginService::GetUILocale() {
+ return ui_locale_;
+}
+
+PluginProcessHost* PluginService::FindPluginProcess(const std::wstring& dll) {
+ DCHECK(MessageLoop::current() ==
+ ChromeThread::GetMessageLoop(ChromeThread::IO));
+
+ if (dll.empty()) {
+ NOTREACHED() << "should only be called if we have a plugin dll to load";
+ return NULL;
+ }
+
+ PluginMap::iterator found = plugin_hosts_.find(dll);
+ if (found != plugin_hosts_.end())
+ return found->second;
+ return NULL;
+}
+
+PluginProcessHost* PluginService::FindOrStartPluginProcess(
+ const std::wstring& dll,
+ const std::string& clsid) {
+ DCHECK(MessageLoop::current() ==
+ ChromeThread::GetMessageLoop(ChromeThread::IO));
+
+ PluginProcessHost *plugin_host = FindPluginProcess(dll);
+ if (plugin_host)
+ return plugin_host;
+
+ // This plugin isn't loaded by any plugin process, so create a new process.
+ plugin_host = new PluginProcessHost(this);
+ if (!plugin_host->Init(dll, clsid, ui_locale_)) {
+ DCHECK(false); // Init is not expected to fail
+ delete plugin_host;
+ return NULL;
+ }
+ plugin_hosts_[dll] = plugin_host;
+ return plugin_host;
+
+ // TODO(jabdelmalek): adding a new channel means we can have one less
+ // renderer process (since each child process uses one handle in the
+ // IPC thread and main thread's WaitForMultipleObjects call). Limit the
+ // number of plugin processes.
+}
+
+void PluginService::OpenChannelToPlugin(
+ ResourceMessageFilter* renderer_msg_filter, const GURL& url,
+ const std::string& mime_type, const std::string& clsid,
+ const std::wstring& locale, IPC::Message* reply_msg) {
+ DCHECK(MessageLoop::current() ==
+ ChromeThread::GetMessageLoop(ChromeThread::IO));
+ std::wstring dll = GetPluginPath(url, mime_type, clsid, NULL);
+ PluginProcessHost* plugin_host = FindOrStartPluginProcess(dll, clsid);
+ if (plugin_host) {
+ plugin_host->OpenChannelToPlugin(renderer_msg_filter, mime_type, reply_msg);
+ } else {
+ PluginProcessHost::ReplyToRenderer(renderer_msg_filter,
+ std::wstring(),
+ std::wstring(),
+ reply_msg);
+ }
+}
+
+void PluginService::OnPluginProcessIsShuttingDown(PluginProcessHost* host) {
+ RemoveHost(host);
+}
+
+void PluginService::OnPluginProcessExited(PluginProcessHost* host) {
+ RemoveHost(host); // in case shutdown was not graceful
+ delete host;
+}
+
+void PluginService::RemoveHost(PluginProcessHost* host) {
+ DCHECK(MessageLoop::current() ==
+ ChromeThread::GetMessageLoop(ChromeThread::IO));
+ // Search for the instance rather than lookup by dll path,
+ // there is a small window where two instances for the same
+ // dll path can co-exists.
+ PluginMap::iterator i = plugin_hosts_.begin();
+ while (i != plugin_hosts_.end()) {
+ if (i->second == host) {
+ plugin_hosts_.erase(i);
+ return;
+ }
+ i++;
+ }
+}
+
+std::wstring PluginService::GetPluginPath(const GURL& url,
+ const std::string& mime_type,
+ const std::string& clsid,
+ std::string* actual_mime_type) {
+ AutoLock lock(lock_);
+ bool allow_wildcard = true;
+ WebPluginInfo info;
+ NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, clsid,
+ allow_wildcard, &info,
+ actual_mime_type);
+ return info.file;
+}
+
+bool PluginService::GetPluginInfoByDllPath(const std::wstring& dll_path,
+ WebPluginInfo* info) {
+ AutoLock lock(lock_);
+ return NPAPI::PluginList::Singleton()->GetPluginInfoByDllPath(dll_path, info);
+}
+
+bool PluginService::HavePluginFor(const std::string& mime_type,
+ bool allow_wildcard) {
+ AutoLock lock(lock_);
+
+ GURL url;
+ WebPluginInfo info;
+ return NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, "",
+ allow_wildcard, &info,
+ NULL);
+}
+
+void PluginService::Shutdown() {
+ plugin_shutdown_handler_->InitiateShutdown();
+}
+
+void PluginService::OnShutdown() {
+ PluginMap::iterator host_index;
+ for (host_index = plugin_hosts_.begin(); host_index != plugin_hosts_.end();
+ ++host_index) {
+ host_index->second->Shutdown();
+ }
+}
+
+PluginProcessHostIterator::PluginProcessHostIterator()
+ : iterator_(PluginService::GetInstance()->plugin_hosts_.begin()),
+ end_(PluginService::GetInstance()->plugin_hosts_.end()) {
+ DCHECK(MessageLoop::current() ==
+ ChromeThread::GetMessageLoop(ChromeThread::IO)) <<
+ "PluginProcessHostIterator must be used on the IO thread.";
+}
+
+PluginProcessHostIterator::PluginProcessHostIterator(
+ const PluginProcessHostIterator& instance)
+ : iterator_(instance.iterator_) {
+ DCHECK(MessageLoop::current() ==
+ ChromeThread::GetMessageLoop(ChromeThread::IO)) <<
+ "PluginProcessHostIterator must be used on the IO thread.";
+}
+
+void PluginService::ShutdownHandler::InitiateShutdown() {
+ g_browser_process->io_thread()->message_loop()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &ShutdownHandler::OnShutdown));
+}
+
+void PluginService::ShutdownHandler::OnShutdown() {
+ PluginService* plugin_service = PluginService::GetInstance();
+ if (plugin_service) {
+ plugin_service->OnShutdown();
+ }
+}