summaryrefslogtreecommitdiffstats
path: root/chrome/plugin
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-20 07:15:17 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-20 07:15:17 +0000
commitea51de3307a6a5947ca047fa9d0e20359fdcf658 (patch)
treec1a49c1d41c4bfbf74ddbc28c371f840dd2848fa /chrome/plugin
parentb6aedfff89cd93f07c1c38a13062801e81bf26e4 (diff)
downloadchromium_src-ea51de3307a6a5947ca047fa9d0e20359fdcf658.zip
chromium_src-ea51de3307a6a5947ca047fa9d0e20359fdcf658.tar.gz
chromium_src-ea51de3307a6a5947ca047fa9d0e20359fdcf658.tar.bz2
Reverting 10080.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10082 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/plugin')
-rw-r--r--chrome/plugin/chrome_plugin_host.cc17
-rw-r--r--chrome/plugin/plugin_channel.cc8
-rw-r--r--chrome/plugin/plugin_channel_base.cc6
-rw-r--r--chrome/plugin/plugin_main.cc9
-rw-r--r--chrome/plugin/plugin_process.cc49
-rw-r--r--chrome/plugin/plugin_process.h28
-rw-r--r--chrome/plugin/plugin_thread.cc146
-rw-r--r--chrome/plugin/plugin_thread.h48
-rw-r--r--chrome/plugin/webplugin_proxy.cc4
9 files changed, 218 insertions, 97 deletions
diff --git a/chrome/plugin/chrome_plugin_host.cc b/chrome/plugin/chrome_plugin_host.cc
index f1d2794..159d4b2 100644
--- a/chrome/plugin/chrome_plugin_host.cc
+++ b/chrome/plugin/chrome_plugin_host.cc
@@ -138,7 +138,7 @@ class PluginRequestHandlerProxy
CPError Start() {
bridge_.reset(
- PluginThread::current()->resource_dispatcher()->CreateBridge(
+ PluginThread::GetPluginThread()->resource_dispatcher()->CreateBridge(
cprequest_->method,
GURL(cprequest_->url),
GURL(cprequest_->url), // TODO(jackson): policy url?
@@ -252,9 +252,9 @@ void STDCALL CPB_SetKeepProcessAlive(CPID id, CPBool keep_alive) {
if (desired_value != g_keep_process_alive) {
g_keep_process_alive = desired_value;
if (g_keep_process_alive)
- PluginProcess::current()->AddRefProcess();
+ PluginProcess::AddRefProcess();
else
- PluginProcess::current()->ReleaseProcess();
+ PluginProcess::ReleaseProcess();
}
}
@@ -276,7 +276,7 @@ CPError STDCALL CPB_GetCookies(CPID id, CPBrowsingContext context,
if (webplugin) {
cookies_str = webplugin->GetCookies(GURL(url), GURL(url));
} else {
- PluginThread::current()->Send(
+ PluginThread::GetPluginThread()->Send(
new PluginProcessHostMsg_GetCookies(context, GURL(url), &cookies_str));
}
@@ -507,9 +507,10 @@ CPError STDCALL CPB_SendMessage(CPID id, const void *data, uint32 data_len) {
CHECK(ChromePluginLib::IsPluginThread());
const uint8* data_ptr = static_cast<const uint8*>(data);
std::vector<uint8> v(data_ptr, data_ptr + data_len);
- if (!PluginThread::current()->Send(new PluginProcessHostMsg_PluginMessage(v)))
+ if (!PluginThread::GetPluginThread()->Send(
+ new PluginProcessHostMsg_PluginMessage(v))) {
return CPERR_FAILURE;
-
+ }
return CPERR_SUCCESS;
}
@@ -519,7 +520,7 @@ CPError STDCALL CPB_SendSyncMessage(CPID id, const void *data, uint32 data_len,
const uint8* data_ptr = static_cast<const uint8*>(data);
std::vector<uint8> v(data_ptr, data_ptr + data_len);
std::vector<uint8> r;
- if (!PluginThread::current()->Send(
+ if (!PluginThread::GetPluginThread()->Send(
new PluginProcessHostMsg_PluginSyncMessage(v, &r))) {
return CPERR_FAILURE;
}
@@ -539,7 +540,7 @@ CPError STDCALL CPB_SendSyncMessage(CPID id, const void *data, uint32 data_len,
CPError STDCALL CPB_PluginThreadAsyncCall(CPID id,
void (*func)(void *),
void *user_data) {
- MessageLoop *message_loop = PluginThread::current()->message_loop();
+ MessageLoop *message_loop = PluginThread::GetPluginThread()->message_loop();
if (!message_loop) {
return CPERR_FAILURE;
}
diff --git a/chrome/plugin/plugin_channel.cc b/chrome/plugin/plugin_channel.cc
index ab2d508..605feab 100644
--- a/chrome/plugin/plugin_channel.cc
+++ b/chrome/plugin/plugin_channel.cc
@@ -8,8 +8,8 @@
#include "chrome/common/plugin_messages.h"
#include "base/string_util.h"
-#include "chrome/plugin/plugin_process.h"
#include "chrome/plugin/plugin_thread.h"
+#include "chrome/plugin/plugin_process.h"
PluginChannel* PluginChannel::GetPluginChannel(
int process_id, HANDLE renderer_handle, MessageLoop* ipc_message_loop) {
@@ -33,11 +33,11 @@ PluginChannel* PluginChannel::GetPluginChannel(
PluginChannel::PluginChannel() : in_send_(0) {
SendUnblockingOnlyDuringDispatch();
- PluginProcess::current()->AddRefProcess();
+ PluginProcess::AddRefProcess();
}
PluginChannel::~PluginChannel() {
- PluginProcess::current()->ReleaseProcess();
+ PluginProcess::ReleaseProcess();
}
bool PluginChannel::Send(IPC::Message* msg) {
@@ -84,7 +84,7 @@ void PluginChannel::OnGenerateRouteID(int* route_id) {
}
int PluginChannel::GenerateRouteID() {
- static LONG last_id = 0;
+ static LONG last_id = 0;
return InterlockedIncrement(&last_id);
}
diff --git a/chrome/plugin/plugin_channel_base.cc b/chrome/plugin/plugin_channel_base.cc
index 2785328..c44c52e 100644
--- a/chrome/plugin/plugin_channel_base.cc
+++ b/chrome/plugin/plugin_channel_base.cc
@@ -76,9 +76,9 @@ void PluginChannelBase::CleanupChannels() {
bool PluginChannelBase::Init(MessageLoop* ipc_message_loop,
bool create_pipe_now) {
- channel_.reset(new IPC::SyncChannel(
- channel_name_, mode_, this, NULL, ipc_message_loop, create_pipe_now,
- PluginProcess::current()->GetShutDownEvent()));
+ channel_.reset(new IPC::SyncChannel(channel_name_, mode_, this, NULL,
+ ipc_message_loop, create_pipe_now,
+ PluginProcess::GetShutDownEvent()));
channel_valid_ = true;
return true;
}
diff --git a/chrome/plugin/plugin_main.cc b/chrome/plugin/plugin_main.cc
index bc40fb9..c7bb53d 100644
--- a/chrome/plugin/plugin_main.cc
+++ b/chrome/plugin/plugin_main.cc
@@ -53,8 +53,12 @@ int PluginMain(const MainFunctionParams& parameters) {
MB_OK | MB_SETFOREGROUND);
}
- {
- PluginProcess plugin_process;
+ std::wstring channel_name =
+ parsed_command_line.GetSwitchValue(switches::kProcessChannelID);
+ FilePath plugin_path =
+ FilePath::FromWStringHack(
+ parsed_command_line.GetSwitchValue(switches::kPluginPath));
+ if (PluginProcess::GlobalInit(channel_name, plugin_path)) {
if (!no_sandbox && target_services) {
target_services->LowerToken();
}
@@ -79,6 +83,7 @@ int PluginMain(const MainFunctionParams& parameters) {
// message loop to use it when translating messages.
MessageLoop::current()->Run();
}
+ PluginProcess::GlobalCleanup();
CoUninitialize();
return 0;
diff --git a/chrome/plugin/plugin_process.cc b/chrome/plugin/plugin_process.cc
index 9d0f567..fe19b9b 100644
--- a/chrome/plugin/plugin_process.cc
+++ b/chrome/plugin/plugin_process.cc
@@ -13,6 +13,20 @@
#include "chrome/common/render_messages.h"
#include "webkit/glue/webkit_glue.h"
+// Custom factory to allow us to pass additional ctor arguments.
+class PluginProcessFactory : public ChildProcessFactoryInterface {
+ public:
+ explicit PluginProcessFactory(const FilePath& plugin_path)
+ : plugin_path_(plugin_path) {
+ }
+
+ virtual ChildProcess* Create(const std::wstring& channel_name) {
+ return new PluginProcess(channel_name, plugin_path_);
+ }
+
+ const FilePath& plugin_path_;
+};
+
// How long to wait after there are no more plugin instances before killing the
// process.
static const int kProcessShutdownDelayMs = 10 * 1000;
@@ -25,21 +39,31 @@ template <> struct RunnableMethodTraits<PluginProcess> {
static void ReleaseCallee(PluginProcess*) {}
};
-PluginProcess::PluginProcess()
- : ChildProcess(new PluginThread()) {
+PluginProcess::PluginProcess(const std::wstring& channel_name,
+ const FilePath& plugin_path) :
+ plugin_path_(plugin_path),
+#pragma warning(suppress: 4355) // Okay to pass "this" here.
+ plugin_thread_(this, channel_name) {
}
PluginProcess::~PluginProcess() {
}
+bool PluginProcess::GlobalInit(const std::wstring &channel_name,
+ const FilePath &plugin_path) {
+ PluginProcessFactory factory(plugin_path);
+ return ChildProcess::GlobalInit(channel_name, &factory);
+}
+
+
// Note: may be called on any thread
void PluginProcess::OnFinalRelease() {
// We override this to have the process linger for a few seconds to
// better accomdate back/forth navigation. This avoids shutting down and
// immediately starting a new plugin process. If a new channel is
// opened in the interim, the current process will not be shutdown.
- child_thread()->owner_loop()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
- this, &PluginProcess::OnProcessShutdownTimeout),
+ main_thread_loop_->PostDelayedTask(FROM_HERE, NewRunnableMethod(
+ this, &PluginProcess::OnProcessShutdownTimeout),
kProcessShutdownDelayMs);
}
@@ -50,10 +74,25 @@ void PluginProcess::OnProcessShutdownTimeout() {
// process host instance in the browser to verify if it is ok to shutdown
// the plugin process. The browser then sends back a response indicating
// whether it is ok to shutdown.
- child_thread()->Send(new PluginProcessHostMsg_ShutdownRequest);
+ plugin_thread_.Send(new PluginProcessHostMsg_ShutdownRequest);
+ }
+}
+
+// static
+void PluginProcess::ShutdownProcessResponse(bool ok_to_shutdown) {
+ if (ok_to_shutdown) {
+ PluginProcess* plugin_process =
+ static_cast<PluginProcess*>(child_process_);
+ DCHECK(plugin_process);
+ plugin_process->Shutdown();
}
}
+void PluginProcess::BrowserShutdown() {
+ ShutdownProcessResponse(true);
+}
+
void PluginProcess::Shutdown() {
ChildProcess::OnFinalRelease();
}
+
diff --git a/chrome/plugin/plugin_process.h b/chrome/plugin/plugin_process.h
index 467b46d..b315bce 100644
--- a/chrome/plugin/plugin_process.h
+++ b/chrome/plugin/plugin_process.h
@@ -14,24 +14,38 @@
// each plugin.
class PluginProcess : public ChildProcess {
public:
- PluginProcess();
- virtual ~PluginProcess();
+ static bool GlobalInit(const std::wstring& channel_name,
+ const FilePath& plugin_path);
+
+ // Invoked with the response from the browser indicating whether it is
+ // ok to shutdown the plugin process.
+ static void ShutdownProcessResponse(bool ok_to_shutdown);
// Invoked when the browser is shutdown. This ensures that the plugin
// process does not hang around waiting for future invocations
// from the browser.
- void Shutdown();
+ static void BrowserShutdown();
- // Returns a pointer to the PluginProcess singleton instance.
- static PluginProcess* current() {
- return static_cast<PluginProcess*>(ChildProcess::current());
- }
+ // File path of the plugin this process hosts.
+ const FilePath& plugin_path() { return plugin_path_; }
private:
+ friend class PluginProcessFactory;
+ PluginProcess(const std::wstring& channel_name,
+ const FilePath& plugin_path);
+ virtual ~PluginProcess();
virtual void OnFinalRelease();
+ void Shutdown();
void OnProcessShutdownTimeout();
+ const FilePath plugin_path_;
+
+ // The thread where plugin instances live. Since NPAPI plugins weren't
+ // created with multi-threading in mind, running multiple instances on
+ // different threads would be asking for trouble.
+ PluginThread plugin_thread_;
+
DISALLOW_EVIL_CONSTRUCTORS(PluginProcess);
};
diff --git a/chrome/plugin/plugin_thread.cc b/chrome/plugin/plugin_thread.cc
index 671e977..d37edf4 100644
--- a/chrome/plugin/plugin_thread.cc
+++ b/chrome/plugin/plugin_thread.cc
@@ -7,63 +7,84 @@
#include "chrome/plugin/plugin_thread.h"
-#include "base/command_line.h"
#include "chrome/common/chrome_plugin_lib.h"
-#include "chrome/common/chrome_switches.h"
+#include "chrome/common/ipc_logging.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/plugin_messages.h"
-#include "chrome/common/render_messages.h"
#include "chrome/plugin/chrome_plugin_host.h"
#include "chrome/plugin/npobject_util.h"
#include "chrome/plugin/plugin_process.h"
-#include "chrome/renderer/render_thread.h"
#include "net/base/net_errors.h"
#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/webkit_glue.h"
-
-PluginThread::PluginThread()
- : ChildThread(base::Thread::Options(MessageLoop::TYPE_UI, 0)),
- preloaded_plugin_module_(NULL) {
- plugin_path_ = FilePath::FromWStringHack(
- CommandLine::ForCurrentProcess()->GetSwitchValue(switches::kPluginPath));
+PluginThread* PluginThread::plugin_thread_;
+
+PluginThread::PluginThread(PluginProcess* process,
+ const std::wstring& channel_name)
+ : plugin_process_(process),
+ channel_name_(channel_name),
+ owner_loop_(MessageLoop::current()),
+ preloaded_plugin_module_(NULL),
+ Thread("Chrome_PluginThread") {
+ DCHECK(plugin_process_);
+ DCHECK(owner_loop_);
+ DCHECK(!plugin_thread_);
+ plugin_thread_ = this;
+
+ // We need to run a UI message loop to support plugin execution.
+ base::Thread::Options options;
+ options.message_loop_type = MessageLoop::TYPE_UI;
+ StartWithOptions(options);
}
PluginThread::~PluginThread() {
+ Stop();
+ plugin_thread_ = NULL;
}
-PluginThread* PluginThread::current() {
- DCHECK(IsPluginProcess());
- return static_cast<PluginThread*>(ChildThread::current());
+void PluginThread::OnChannelError() {
+ owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
}
-void PluginThread::OnControlMessageReceived(const IPC::Message& msg) {
- // Resource responses are sent to the resource dispatcher.
- if (resource_dispatcher_->OnMessageReceived(msg))
- return;
+bool PluginThread::Send(IPC::Message* msg) {
+ return channel_.get() ? channel_->Send(msg) : false;
+}
- IPC_BEGIN_MESSAGE_MAP(PluginThread, msg)
- IPC_MESSAGE_HANDLER(PluginProcessMsg_CreateChannel, OnCreateChannel)
- IPC_MESSAGE_HANDLER(PluginProcessMsg_ShutdownResponse, OnShutdownResponse)
- IPC_MESSAGE_HANDLER(PluginProcessMsg_PluginMessage, OnPluginMessage)
- IPC_MESSAGE_HANDLER(PluginProcessMsg_BrowserShutdown, OnBrowserShutdown)
- IPC_END_MESSAGE_MAP()
+void PluginThread::OnMessageReceived(const IPC::Message& msg) {
+ if (msg.routing_id() == MSG_ROUTING_CONTROL) {
+ // Resource responses are sent to the resource dispatcher.
+ if (resource_dispatcher_->OnMessageReceived(msg))
+ return;
+ IPC_BEGIN_MESSAGE_MAP(PluginThread, msg)
+ IPC_MESSAGE_HANDLER(PluginProcessMsg_CreateChannel, OnCreateChannel)
+ IPC_MESSAGE_HANDLER(PluginProcessMsg_ShutdownResponse, OnShutdownResponse)
+ IPC_MESSAGE_HANDLER(PluginProcessMsg_PluginMessage, OnPluginMessage)
+ IPC_MESSAGE_HANDLER(PluginProcessMsg_BrowserShutdown, OnBrowserShutdown)
+ IPC_END_MESSAGE_MAP()
+ } else {
+ NOTREACHED() << "Only control messages should reach PluginThread.";
+ }
}
void PluginThread::Init() {
- ChildThread::Init();
PatchNPNFunctions();
CoInitialize(NULL);
+ channel_.reset(new IPC::SyncChannel(channel_name_,
+ IPC::Channel::MODE_CLIENT, this, NULL, owner_loop_, true,
+ PluginProcess::GetShutDownEvent()));
notification_service_.reset(new NotificationService);
resource_dispatcher_ = new ResourceDispatcher(this);
// Preload the library to avoid loading, unloading then reloading
- preloaded_plugin_module_ = NPAPI::PluginLib::LoadNativeLibrary(plugin_path_);
+ preloaded_plugin_module_ = NPAPI::PluginLib::LoadNativeLibrary(
+ plugin_process_->plugin_path());
- ChromePluginLib::Create(plugin_path_, GetCPBrowserFuncsForPlugin());
+ ChromePluginLib::Create(plugin_process_->plugin_path(),
+ GetCPBrowserFuncsForPlugin());
scoped_refptr<NPAPI::PluginLib> plugin =
- NPAPI::PluginLib::CreatePluginLib(plugin_path_);
+ NPAPI::PluginLib::CreatePluginLib(plugin_process_->plugin_path());
if (plugin.get()) {
plugin->NP_Initialize();
}
@@ -71,14 +92,23 @@ void PluginThread::Init() {
// Certain plugins, such as flash, steal the unhandled exception filter
// thus we never get crash reports when they fault. This call fixes it.
message_loop()->set_exception_restoration(true);
+
+#ifdef IPC_MESSAGE_LOG_ENABLED
+ IPC::Logging::current()->SetIPCSender(this);
+#endif
}
void PluginThread::CleanUp() {
- ChildThread::CleanUp();
+#ifdef IPC_MESSAGE_LOG_ENABLED
+ IPC::Logging::current()->SetIPCSender(NULL);
+#endif
if (preloaded_plugin_module_) {
FreeLibrary(preloaded_plugin_module_);
preloaded_plugin_module_ = NULL;
}
+ // Need to destruct the SyncChannel to the browser before we go away because
+ // it caches a pointer to this thread.
+ channel_.reset();
PluginChannelBase::CleanupChannels();
NPAPI::PluginLib::UnloadAllPlugins();
ChromePluginLib::UnloadAllPlugins();
@@ -88,12 +118,13 @@ void PluginThread::CleanUp() {
if (webkit_glue::ShouldForcefullyTerminatePluginProcess())
TerminateProcess(GetCurrentProcess(), 0);
+
}
-void PluginThread::OnCreateChannel(int process_id, HANDLE renderer) {
+void PluginThread::OnCreateChannel(int process_id, HANDLE renderer_handle) {
std::wstring channel_name;
scoped_refptr<PluginChannel> channel =
- PluginChannel::GetPluginChannel(process_id, renderer, owner_loop());
+ PluginChannel::GetPluginChannel(process_id, renderer_handle, owner_loop_);
if (channel.get())
channel_name = channel->channel_name();
@@ -101,32 +132,32 @@ void PluginThread::OnCreateChannel(int process_id, HANDLE renderer) {
}
void PluginThread::OnShutdownResponse(bool ok_to_shutdown) {
- if (ok_to_shutdown)
- PluginProcess::current()->Shutdown();
+ PluginProcess::ShutdownProcessResponse(ok_to_shutdown);
}
void PluginThread::OnBrowserShutdown() {
- PluginProcess::current()->Shutdown();
+ PluginProcess::BrowserShutdown();
}
void PluginThread::OnPluginMessage(const std::vector<unsigned char> &data) {
// We Add/Release ref here to ensure that something will trigger the
// shutdown mechanism for processes started in the absence of renderer's
// opening a plugin channel.
- PluginProcess::current()->AddRefProcess();
- ChromePluginLib *chrome_plugin = ChromePluginLib::Find(plugin_path_);
+ PluginProcess::AddRefProcess();
+ ChromePluginLib *chrome_plugin =
+ ChromePluginLib::Find(plugin_process_->plugin_path());
if (chrome_plugin) {
void *data_ptr = const_cast<void*>(reinterpret_cast<const void*>(&data[0]));
uint32 data_len = static_cast<uint32>(data.size());
chrome_plugin->functions().on_message(data_ptr, data_len);
}
- PluginProcess::current()->ReleaseProcess();
+ PluginProcess::ReleaseProcess();
}
namespace webkit_glue {
bool DownloadUrl(const std::string& url, HWND caller_window) {
- PluginThread* plugin_thread = PluginThread::current();
+ PluginThread* plugin_thread = PluginThread::GetPluginThread();
if (!plugin_thread) {
return false;
}
@@ -144,9 +175,10 @@ bool GetPluginFinderURL(std::string* plugin_finder_url) {
return false;
}
- PluginThread* plugin_thread = PluginThread::current();
- if (!plugin_thread)
+ PluginThread* plugin_thread = PluginThread::GetPluginThread();
+ if (!plugin_thread) {
return false;
+ }
plugin_thread->Send(
new PluginProcessHostMsg_GetPluginFinderUrl(plugin_finder_url));
@@ -158,26 +190,36 @@ bool IsDefaultPluginEnabled() {
return true;
}
+static int ResolveProxyFromPluginThread(const GURL& url,
+ std::string* proxy_result) {
+ int net_error;
+ bool ipc_ok = PluginThread::GetPluginThread()->Send(
+ new PluginProcessHostMsg_ResolveProxy(url, &net_error, proxy_result));
+ return ipc_ok ? net_error : net::ERR_UNEXPECTED;
+}
+
+extern int ResolveProxyFromRenderThread(const GURL&, std::string*);
// Dispatch the resolve proxy resquest to the right code, depending on which
// process the plugin is running in {renderer, browser, plugin}.
+//
+// TODO(eroman): Find a better place to put this; plugin_thread.cc isn't really
+// correct since this depends on the renderer thread. One solution is to save
+// the function pointers into a table during initialization.
bool FindProxyForUrl(const GURL& url, std::string* proxy_list) {
int net_error;
std::string proxy_result;
- bool result;
- if (IsPluginProcess()) {
- result = PluginThread::current()->Send(
- new PluginProcessHostMsg_ResolveProxy(url, &net_error, &proxy_result));
- } else {
- result = RenderThread::current()->Send(
- new ViewHostMsg_ResolveProxy(url, &net_error, &proxy_result));
- }
+ if (PluginThread::GetPluginThread())
+ net_error = ResolveProxyFromPluginThread(url, &proxy_result);
+ else
+ net_error = ResolveProxyFromRenderThread(url, &proxy_result);
- if (!result || net_error != net::OK)
- return false;
-
- *proxy_list = proxy_result;
- return true;
+ if (net_error == net::OK) {
+ *proxy_list = proxy_result;
+ return true; // Success.
+ }
+ return false; // Fail.
}
} // namespace webkit_glue
+
diff --git a/chrome/plugin/plugin_thread.h b/chrome/plugin/plugin_thread.h
index 38b989e..46da0e4 100644
--- a/chrome/plugin/plugin_thread.h
+++ b/chrome/plugin/plugin_thread.h
@@ -5,39 +5,59 @@
#ifndef CHROME_PLUGIN_PLUGIN_THREAD_H_
#define CHROME_PLUGIN_PLUGIN_THREAD_H_
-#include "base/file_path.h"
-#include "chrome/common/child_thread.h"
+#include "base/thread.h"
+#include "chrome/common/ipc_sync_channel.h"
+#include "chrome/common/message_router.h"
#include "chrome/common/resource_dispatcher.h"
#include "chrome/plugin/plugin_channel.h"
+class PluginProcess;
class NotificationService;
// The PluginThread class represents a background thread where plugin instances
// live. Communication occurs between WebPluginDelegateProxy in the renderer
// process and WebPluginDelegateStub in this thread through IPC messages.
-class PluginThread : public ChildThread {
+class PluginThread : public IPC::Channel::Listener,
+ public IPC::Message::Sender,
+ public base::Thread {
public:
- PluginThread();
+ PluginThread(PluginProcess *process, const std::wstring& channel_name);
~PluginThread();
+ // IPC::Channel::Listener implementation:
+ virtual void OnMessageReceived(const IPC::Message& msg);
+ virtual void OnChannelError();
+
+ // IPC::Message::Sender implementation:
+ virtual bool Send(IPC::Message* msg);
+
// Returns the one plugin thread.
- static PluginThread* current();
+ static PluginThread* GetPluginThread() { return plugin_thread_; }
// Returns the one true dispatcher.
- ResourceDispatcher* resource_dispatcher() { return resource_dispatcher_.get(); }
+ ResourceDispatcher* resource_dispatcher() {
+ return resource_dispatcher_.get();
+ }
private:
- virtual void OnControlMessageReceived(const IPC::Message& msg);
-
- // Thread implementation:
- virtual void Init();
- virtual void CleanUp();
+ // Thread implementation:
+ void Init();
+ void CleanUp();
- void OnCreateChannel(int process_id, HANDLE renderer);
+ void OnCreateChannel(int process_id, HANDLE renderer_handle);
void OnShutdownResponse(bool ok_to_shutdown);
void OnPluginMessage(const std::vector<uint8> &data);
void OnBrowserShutdown();
+ // The process that has created this thread
+ PluginProcess *plugin_process_;
+
+ // The message loop used to run tasks on the thread that started this thread.
+ MessageLoop* owner_loop_;
+
+ std::wstring channel_name_;
+ scoped_ptr<IPC::SyncChannel> channel_;
+
scoped_ptr<NotificationService> notification_service_;
// Handles resource loads for this view.
@@ -47,8 +67,8 @@ class PluginThread : public ChildThread {
// The plugin module which is preloaded in Init
HMODULE preloaded_plugin_module_;
- // Points to the plugin file that this process hosts.
- FilePath plugin_path_;
+ // Points to the one PluginThread object in the process.
+ static PluginThread* plugin_thread_;
DISALLOW_EVIL_CONSTRUCTORS(PluginThread);
};
diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc
index 478300a..448064a 100644
--- a/chrome/plugin/webplugin_proxy.cc
+++ b/chrome/plugin/webplugin_proxy.cc
@@ -58,7 +58,7 @@ WebPluginProxy::~WebPluginProxy() {
GetContextMap().erase(cp_browsing_context_);
if (parent_window_) {
- PluginThread::current()->Send(
+ PluginThread::GetPluginThread()->Send(
new PluginProcessHostMsg_DestroyWindow(parent_window_));
}
}
@@ -90,7 +90,7 @@ void WebPluginProxy::SetWindow(HWND window, HANDLE pump_messages_event) {
// the browser paints or sends any other (synchronous) WM_ message to the
// plugin window.
msg->EnableMessagePumping();
- PluginThread::current()->Send(msg);
+ PluginThread::GetPluginThread()->Send(msg);
SetParent(window, parent_window_);