diff options
author | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-02 12:26:39 +0000 |
---|---|---|
committer | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-02 12:26:39 +0000 |
commit | 46b69e4863d4a6ee40e5d7369656c5884430245c (patch) | |
tree | 057f87a66da9d134dc77c7deab3b01c290b5e6f8 | |
parent | 8a59def48e460ceef05e4521c997d582373cd32d (diff) | |
download | chromium_src-46b69e4863d4a6ee40e5d7369656c5884430245c.zip chromium_src-46b69e4863d4a6ee40e5d7369656c5884430245c.tar.gz chromium_src-46b69e4863d4a6ee40e5d7369656c5884430245c.tar.bz2 |
Add PluginProcessHost::Client.
BUG=58235
TEST=none
Review URL: http://codereview.chromium.org/4119005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64734 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/plugin_process_host.cc | 78 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host.h | 53 | ||||
-rw-r--r-- | chrome/browser/plugin_service.cc | 26 | ||||
-rw-r--r-- | chrome/browser/plugin_service.h | 15 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.cc | 49 |
5 files changed, 110 insertions, 111 deletions
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index 4b5f5a1..8e459ee 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -144,6 +144,8 @@ PluginProcessHost::~PluginProcessHost() { } } #endif + // Cancel all pending and sent requests. + CancelRequests(); } bool PluginProcessHost::Init(const WebPluginInfo& info, @@ -307,49 +309,40 @@ void PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { void PluginProcessHost::OnChannelConnected(int32 peer_pid) { for (size_t i = 0; i < pending_requests_.size(); ++i) { - RequestPluginChannel(pending_requests_[i].renderer_message_filter_.get(), - pending_requests_[i].mime_type, - pending_requests_[i].reply_msg); + RequestPluginChannel(pending_requests_[i]); } pending_requests_.clear(); } void PluginProcessHost::OnChannelError() { - for (size_t i = 0; i < pending_requests_.size(); ++i) { - ReplyToRenderer(pending_requests_[i].renderer_message_filter_.get(), - IPC::ChannelHandle(), - info_, - pending_requests_[i].reply_msg); - } + CancelRequests(); +} +void PluginProcessHost::CancelRequests() { + for (size_t i = 0; i < pending_requests_.size(); ++i) + pending_requests_[i]->OnError(); pending_requests_.clear(); while (!sent_requests_.empty()) { - ReplyToRenderer(sent_requests_.front().renderer_message_filter_.get(), - IPC::ChannelHandle(), - info_, - sent_requests_.front().reply_msg); + sent_requests_.front()->OnError(); sent_requests_.pop(); } } -void PluginProcessHost::OpenChannelToPlugin( - ResourceMessageFilter* renderer_message_filter, - const std::string& mime_type, - IPC::Message* reply_msg) { +void PluginProcessHost::OpenChannelToPlugin(Client* client) { InstanceCreated(); + client->SetPluginInfo(info_); if (opening_channel()) { // The channel is already in the process of being opened. Put // this "open channel" request into a queue of requests that will // be run once the channel is open. - pending_requests_.push_back( - ChannelRequest(renderer_message_filter, mime_type, reply_msg)); + pending_requests_.push_back(client); return; } // We already have an open channel, send a request right away to plugin. - RequestPluginChannel(renderer_message_filter, mime_type, reply_msg); + RequestPluginChannel(client); } void PluginProcessHost::OnGetCookies(uint32 request_context, @@ -402,52 +395,34 @@ void PluginProcessHost::OnResolveProxyCompleted(IPC::Message* reply_msg, Send(reply_msg); } -void PluginProcessHost::ReplyToRenderer( - ResourceMessageFilter* renderer_message_filter, - const IPC::ChannelHandle& channel, - const WebPluginInfo& info, - IPC::Message* reply_msg) { - ViewHostMsg_OpenChannelToPlugin::WriteReplyParams(reply_msg, channel, info); - renderer_message_filter->Send(reply_msg); -} - URLRequestContext* PluginProcessHost::GetRequestContext( uint32 request_id, const ViewHostMsg_Resource_Request& request_data) { return CPBrowsingContextManager::Instance()->ToURLRequestContext(request_id); } -void PluginProcessHost::RequestPluginChannel( - ResourceMessageFilter* renderer_message_filter, - const std::string& mime_type, IPC::Message* reply_msg) { +void PluginProcessHost::RequestPluginChannel(Client* client) { // We can't send any sync messages from the browser because it might lead to // a hang. However this async messages must be answered right away by the // plugin process (i.e. unblocks a Send() call like a sync message) otherwise // a deadlock can occur if the plugin creation request from the renderer is // a result of a sync message by the plugin process. - PluginProcessMsg_CreateChannel* msg = new PluginProcessMsg_CreateChannel( - renderer_message_filter->id(), - renderer_message_filter->off_the_record()); + PluginProcessMsg_CreateChannel* msg = + new PluginProcessMsg_CreateChannel(client->ID(), + client->OffTheRecord()); msg->set_unblock(true); if (Send(msg)) { - sent_requests_.push(ChannelRequest( - renderer_message_filter, mime_type, reply_msg)); + sent_requests_.push(client); } else { - ReplyToRenderer(renderer_message_filter, - IPC::ChannelHandle(), - info_, - reply_msg); + client->OnError(); } } void PluginProcessHost::OnChannelCreated( const IPC::ChannelHandle& channel_handle) { - const ChannelRequest& request = sent_requests_.front(); + Client* client = sent_requests_.front(); - ReplyToRenderer(request.renderer_message_filter_.get(), - channel_handle, - info_, - request.reply_msg); + client->OnChannelOpened(channel_handle); sent_requests_.pop(); } @@ -473,14 +448,3 @@ void PluginProcessHost::OnPluginMessage( chrome_plugin->functions().on_message(data_ptr, data_len); } } - -PluginProcessHost::ChannelRequest::ChannelRequest( - ResourceMessageFilter* renderer_message_filter, - const std::string& m, - IPC::Message* r) - : mime_type(m), - reply_msg(r), - renderer_message_filter_(renderer_message_filter) { -} - -PluginProcessHost::ChannelRequest::~ChannelRequest() {} diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h index 79e34a1..3857c73 100644 --- a/chrome/browser/plugin_process_host.h +++ b/chrome/browser/plugin_process_host.h @@ -17,14 +17,17 @@ #include "base/ref_counted.h" #include "chrome/browser/browser_child_process_host.h" #include "chrome/browser/net/resolve_proxy_msg_helper.h" -#include "chrome/browser/renderer_host/resource_message_filter.h" -#include "ipc/ipc_channel_handle.h" +#include "gfx/native_widget_types.h" #include "webkit/glue/plugins/webplugininfo.h" namespace gfx { class Rect; } +namespace IPC { +struct ChannelHandle; +} + class URLRequestContext; struct ViewHostMsg_Resource_Request; class GURL; @@ -40,6 +43,21 @@ class GURL; class PluginProcessHost : public BrowserChildProcessHost, public ResolveProxyMsgHelper::Delegate { public: + class Client { + public: + // Returns a opaque unique identifier for the process requesting + // the channel. + virtual int ID() = 0; + virtual bool OffTheRecord() = 0; + virtual void SetPluginInfo(const WebPluginInfo& info) = 0; + // The client should delete itself when one of these methods is called. + virtual void OnChannelOpened(const IPC::ChannelHandle& handle) = 0; + virtual void OnError() = 0; + + protected: + virtual ~Client() {} + }; + PluginProcessHost(); virtual ~PluginProcessHost(); @@ -61,17 +79,8 @@ class PluginProcessHost : public BrowserChildProcessHost, // Tells the plugin process to create a new channel for communication with a // renderer. When the plugin process responds with the channel name, - // reply_msg is used to send the name to the renderer. - void OpenChannelToPlugin(ResourceMessageFilter* renderer_message_filter, - const std::string& mime_type, - IPC::Message* reply_msg); - - // Sends the reply to an open channel request to the renderer with the given - // channel name. - static void ReplyToRenderer(ResourceMessageFilter* renderer_message_filter, - const IPC::ChannelHandle& channel, - const WebPluginInfo& info, - IPC::Message* reply_msg); + // OnChannelOpened in the client is called. + void OpenChannelToPlugin(Client* client); // This function is called on the IO thread once we receive a reply from the // modal HTML dialog (in the form of a JSON string). This function forwards @@ -102,9 +111,7 @@ class PluginProcessHost : public BrowserChildProcessHost, // Sends a message to the plugin process to request creation of a new channel // for the given mime type. - void RequestPluginChannel(ResourceMessageFilter* renderer_message_filter, - const std::string& mime_type, - IPC::Message* reply_msg); + void RequestPluginChannel(Client* client); virtual void OnProcessLaunched(); @@ -139,23 +146,15 @@ class PluginProcessHost : public BrowserChildProcessHost, virtual bool CanShutdown() { return sent_requests_.empty(); } - struct ChannelRequest { - ChannelRequest(ResourceMessageFilter* renderer_message_filter, - const std::string& m, IPC::Message* r); - ~ChannelRequest(); - - std::string mime_type; - IPC::Message* reply_msg; - scoped_refptr<ResourceMessageFilter> renderer_message_filter_; - }; + void CancelRequests(); // These are channel requests that we are waiting to send to the // plugin process once the channel is opened. - std::vector<ChannelRequest> pending_requests_; + std::vector<Client*> pending_requests_; // These are the channel requests that we have already sent to // the plugin process, but haven't heard back about yet. - std::queue<ChannelRequest> sent_requests_; + std::queue<Client*> sent_requests_; // Information about the plugin. WebPluginInfo info_; diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc index b8c54f3..cc6408f 100644 --- a/chrome/browser/plugin_service.cc +++ b/chrome/browser/plugin_service.cc @@ -17,7 +17,6 @@ #include "chrome/browser/browser_thread.h" #include "chrome/browser/chrome_plugin_host.h" #include "chrome/browser/extensions/extensions_service.h" -#include "chrome/browser/plugin_process_host.h" #include "chrome/browser/plugin_updater.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profile.h" @@ -250,24 +249,22 @@ PluginProcessHost* PluginService::FindOrStartPluginProcess( } void PluginService::OpenChannelToPlugin( - ResourceMessageFilter* renderer_msg_filter, const GURL& url, const std::string& mime_type, - IPC::Message* reply_msg) { + PluginProcessHost::Client* client) { // The PluginList::GetFirstAllowedPluginInfo may need to load the // plugins. Don't do it on the IO thread. BrowserThread::PostTask( BrowserThread::FILE, FROM_HERE, NewRunnableMethod( this, &PluginService::GetAllowedPluginForOpenChannelToPlugin, - make_scoped_refptr(renderer_msg_filter), url, mime_type, reply_msg)); + url, mime_type, client)); } void PluginService::GetAllowedPluginForOpenChannelToPlugin( - ResourceMessageFilter* renderer_msg_filter, const GURL& url, const std::string& mime_type, - IPC::Message* reply_msg) { + PluginProcessHost::Client* client) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); WebPluginInfo info; bool found = GetFirstAllowedPluginInfo(url, mime_type, &info, NULL); @@ -280,24 +277,19 @@ void PluginService::GetAllowedPluginForOpenChannelToPlugin( BrowserThread::IO, FROM_HERE, NewRunnableMethod( this, &PluginService::FinishOpenChannelToPlugin, - make_scoped_refptr(renderer_msg_filter), mime_type, plugin_path, - reply_msg)); + plugin_path, client)); } void PluginService::FinishOpenChannelToPlugin( - ResourceMessageFilter* renderer_msg_filter, - const std::string& mime_type, const FilePath& plugin_path, - IPC::Message* reply_msg) { + PluginProcessHost::Client* client) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); PluginProcessHost* plugin_host = FindOrStartPluginProcess(plugin_path); - if (plugin_host) { - plugin_host->OpenChannelToPlugin(renderer_msg_filter, mime_type, reply_msg); - } else { - PluginProcessHost::ReplyToRenderer( - renderer_msg_filter, IPC::ChannelHandle(), WebPluginInfo(), reply_msg); - } + if (plugin_host) + plugin_host->OpenChannelToPlugin(client); + else + client->OnError(); } bool PluginService::GetFirstAllowedPluginInfo( diff --git a/chrome/browser/plugin_service.h b/chrome/browser/plugin_service.h index abb55a1..d6de864 100644 --- a/chrome/browser/plugin_service.h +++ b/chrome/browser/plugin_service.h @@ -16,9 +16,11 @@ #include "base/hash_tables.h" #include "base/singleton.h" #include "base/waitable_event_watcher.h" +#include "chrome/browser/plugin_process_host.h" #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" #include "googleurl/src/gurl.h" +#include "ipc/ipc_channel_handle.h" #if defined(OS_WIN) #include "base/scoped_ptr.h" @@ -36,7 +38,6 @@ class Message; } class MessageLoop; -class PluginProcessHost; class Profile; class ResourceDispatcherHost; class ResourceMessageFilter; @@ -82,10 +83,9 @@ class PluginService // Opens a channel to a plugin process for the given mime type, starting // a new plugin process if necessary. This must be called on the IO thread // or else a deadlock can occur. - void OpenChannelToPlugin(ResourceMessageFilter* renderer_msg_filter, - const GURL& url, + void OpenChannelToPlugin(const GURL& url, const std::string& mime_type, - IPC::Message* reply_msg); + PluginProcessHost::Client* client); // Gets the first allowed plugin in the list of plugins that matches // the given url and mime type. Must be called on the FILE thread. @@ -126,18 +126,15 @@ class PluginService // Helper so we can do the plugin lookup on the FILE thread. void GetAllowedPluginForOpenChannelToPlugin( - ResourceMessageFilter* renderer_msg_filter, const GURL& url, const std::string& mime_type, - IPC::Message* reply_msg); + PluginProcessHost::Client* client); // Helper so we can finish opening the channel after looking up the // plugin. void FinishOpenChannelToPlugin( - ResourceMessageFilter* renderer_msg_filter, - const std::string& mime_type, const FilePath& plugin_path, - IPC::Message* reply_msg); + PluginProcessHost::Client* client); // mapping between plugin path and PluginProcessHost typedef base::hash_map<FilePath, PluginProcessHost*> PluginMap; diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index adbe1cf..62998e0 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -39,6 +39,7 @@ #include "chrome/browser/notifications/notifications_prefs_cache.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/plugin_service.h" +#include "chrome/browser/plugin_process_host.h" #include "chrome/browser/printing/printer_query.h" #include "chrome/browser/printing/print_job_manager.h" #include "chrome/browser/profile.h" @@ -64,6 +65,7 @@ #include "chrome/common/render_messages.h" #include "chrome/common/render_messages_params.h" #include "chrome/common/url_constants.h" +#include "ipc/ipc_channel_handle.h" #include "net/base/cookie_monster.h" #include "net/base/io_buffer.h" #include "net/base/keygen_handler.h" @@ -193,6 +195,48 @@ class ClearCacheCompletion : public net::CompletionCallback { scoped_refptr<ResourceMessageFilter> filter_; }; +class OpenChannelToPluginCallback : public PluginProcessHost::Client { + public: + OpenChannelToPluginCallback(ResourceMessageFilter* filter, + IPC::Message* reply_msg) + : filter_(filter), + reply_msg_(reply_msg) { + } + + virtual int ID() { + return filter_->id(); + } + + virtual bool OffTheRecord() { + return filter_->off_the_record(); + } + + virtual void SetPluginInfo(const WebPluginInfo& info) { + info_ = info; + } + + virtual void OnChannelOpened(const IPC::ChannelHandle& handle) { + WriteReply(handle); + } + + virtual void OnError() { + WriteReply(IPC::ChannelHandle()); + } + + private: + void WriteReply(const IPC::ChannelHandle& handle) { + ViewHostMsg_OpenChannelToPlugin::WriteReplyParams(reply_msg_, + handle, + info_); + filter_->Send(reply_msg_); + delete this; + } + + scoped_refptr<ResourceMessageFilter> filter_; + IPC::Message* reply_msg_; + WebPluginInfo info_; +}; + } // namespace ResourceMessageFilter::ResourceMessageFilter( @@ -827,7 +871,10 @@ void ResourceMessageFilter::OnGotPluginInfo(bool found, void ResourceMessageFilter::OnOpenChannelToPlugin(const GURL& url, const std::string& mime_type, IPC::Message* reply_msg) { - plugin_service_->OpenChannelToPlugin(this, url, mime_type, reply_msg); + plugin_service_->OpenChannelToPlugin( + url, + mime_type, + new OpenChannelToPluginCallback(this, reply_msg)); } void ResourceMessageFilter::OnLaunchNaCl( |