diff options
18 files changed, 425 insertions, 397 deletions
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index f6a992e7..1e8d87b 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -364,8 +364,10 @@ void PluginProcessHost::AddWindow(HWND window) { #endif // defined(OS_WIN) -PluginProcessHost::PluginProcessHost(MessageLoop* main_message_loop) - : ChildProcessHost(PLUGIN_PROCESS, main_message_loop), +PluginProcessHost::PluginProcessHost() + : ChildProcessHost( + PLUGIN_PROCESS, + PluginService::GetInstance()->resource_dispatcher_host()), ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)) { } @@ -551,11 +553,6 @@ void PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ShutdownRequest, OnPluginShutdownRequest) IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginMessage, OnPluginMessage) - IPC_MESSAGE_HANDLER(ViewHostMsg_RequestResource, OnRequestResource) - IPC_MESSAGE_HANDLER(ViewHostMsg_CancelRequest, OnCancelRequest) - IPC_MESSAGE_HANDLER(ViewHostMsg_DataReceived_ACK, OnDataReceivedACK) - IPC_MESSAGE_HANDLER(ViewHostMsg_UploadProgress_ACK, OnUploadProgressACK) - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncLoad, OnSyncLoad) IPC_MESSAGE_HANDLER(PluginProcessHostMsg_GetCookies, OnGetCookies) IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginProcessHostMsg_ResolveProxy, OnResolveProxy) @@ -606,53 +603,6 @@ void PluginProcessHost::OpenChannelToPlugin( RequestPluginChannel(renderer_message_filter, mime_type, reply_msg); } -void PluginProcessHost::OnRequestResource( - const IPC::Message& message, - int request_id, - const ViewHostMsg_Resource_Request& request) { - URLRequestContext* context = CPBrowsingContextManager::Instance()-> - ToURLRequestContext(request.request_context); - // TODO(mpcomplete): remove fallback case when Gears support is prevalent. - if (!context) - context = Profile::GetDefaultRequestContext(); - - PluginService::GetInstance()->resource_dispatcher_host()-> - BeginRequest(this, ChildProcessInfo::PLUGIN_PROCESS, handle(), - pid(), MSG_ROUTING_CONTROL, request_id, - request, context, NULL); -} - -void PluginProcessHost::OnCancelRequest(int request_id) { - PluginService::GetInstance()->resource_dispatcher_host()-> - CancelRequest(pid(), request_id, true); -} - -void PluginProcessHost::OnDataReceivedACK(int request_id) { - PluginService::GetInstance()->resource_dispatcher_host()-> - OnDataReceivedACK(pid(), request_id); -} - -void PluginProcessHost::OnUploadProgressACK(int request_id) { - PluginService::GetInstance()->resource_dispatcher_host()-> - OnUploadProgressACK(pid(), request_id); -} - -void PluginProcessHost::OnSyncLoad( - int request_id, - const ViewHostMsg_Resource_Request& request, - IPC::Message* sync_result) { - URLRequestContext* context = CPBrowsingContextManager::Instance()-> - ToURLRequestContext(request.request_context); - // TODO(mpcomplete): remove fallback case when Gears support is prevalent. - if (!context) - context = Profile::GetDefaultRequestContext(); - - PluginService::GetInstance()->resource_dispatcher_host()-> - BeginRequest(this, ChildProcessInfo::PLUGIN_PROCESS, handle(), - pid(), MSG_ROUTING_CONTROL, request_id, - request, context, sync_result); -} - void PluginProcessHost::OnGetCookies(uint32 request_context, const GURL& url, std::string* cookies) { @@ -694,6 +644,12 @@ void PluginProcessHost::ReplyToRenderer( 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) { diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h index 6885092..bc15ca2 100644 --- a/chrome/browser/plugin_process_host.h +++ b/chrome/browser/plugin_process_host.h @@ -20,7 +20,6 @@ #include "chrome/common/child_process_host.h" #include "webkit/glue/webplugin.h" -class ResourceDispatcherHost; class URLRequestContext; struct ViewHostMsg_Resource_Request; class GURL; @@ -36,7 +35,7 @@ class GURL; class PluginProcessHost : public ChildProcessHost, public ResolveProxyMsgHelper::Delegate { public: - PluginProcessHost(MessageLoop* main_message_loop); + PluginProcessHost(); ~PluginProcessHost(); // Initialize the new plugin process, returning true on success. This must @@ -89,6 +88,11 @@ class PluginProcessHost : public ChildProcessHost, private: friend class PluginResolveProxyHelper; + // ResourceDispatcherHost::Receiver implementation: + virtual URLRequestContext* GetRequestContext( + uint32 request_id, + const ViewHostMsg_Resource_Request& request_data); + // 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, @@ -99,15 +103,6 @@ class PluginProcessHost : public ChildProcessHost, void OnDownloadUrl(const std::string& url, int source_pid, gfx::NativeWindow caller_window); void OnGetPluginFinderUrl(std::string* plugin_finder_url); - void OnRequestResource(const IPC::Message& message, - int request_id, - const ViewHostMsg_Resource_Request& request); - void OnCancelRequest(int request_id); - void OnDataReceivedACK(int request_id); - void OnUploadProgressACK(int request_id); - void OnSyncLoad(int request_id, - const ViewHostMsg_Resource_Request& request, - IPC::Message* sync_result); void OnGetCookies(uint32 request_context, const GURL& url, std::string* cookies); void OnResolveProxy(const GURL& url, IPC::Message* reply_msg); diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc index ed9f042..26f791b 100644 --- a/chrome/browser/plugin_service.cc +++ b/chrome/browser/plugin_service.cc @@ -110,7 +110,7 @@ PluginProcessHost* PluginService::FindOrStartPluginProcess( } // This plugin isn't loaded by any plugin process, so create a new process. - plugin_host = new PluginProcessHost(main_message_loop_); + plugin_host = new PluginProcessHost(); if (!plugin_host->Init(info, clsid, ui_locale_)) { DCHECK(false); // Init is not expected to fail delete plugin_host; diff --git a/chrome/browser/renderer_host/async_resource_handler.cc b/chrome/browser/renderer_host/async_resource_handler.cc index 73aa227..038fc8c 100644 --- a/chrome/browser/renderer_host/async_resource_handler.cc +++ b/chrome/browser/renderer_host/async_resource_handler.cc @@ -102,7 +102,7 @@ bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { // to fix this. We can't move this call above the WillSendData because // it's killing our read_buffer_, and we don't want that when we pause // the request. - rdh_->OnDataReceivedACK(process_id_, request_id); + rdh_->DataReceivedACK(process_id_, request_id); // We just unmapped the memory. read_buffer_ = NULL; return false; diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc index 276693d..22d7bcb 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc @@ -19,6 +19,7 @@ #include "chrome/browser/download/save_file_manager.h" #include "chrome/browser/external_protocol_handler.h" #include "chrome/browser/plugin_service.h" +#include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/async_resource_handler.h" #include "chrome/browser/renderer_host/buffered_resource_handler.h" #include "chrome/browser/renderer_host/cross_site_resource_handler.h" @@ -145,7 +146,8 @@ ResourceDispatcherHost::ResourceDispatcherHost(MessageLoop* io_loop) ALLOW_THIS_IN_INITIALIZER_LIST(method_runner_(this)), is_shutdown_(false), max_outstanding_requests_cost_per_process_( - kMaxOutstandingRequestsCostPerProcess) { + kMaxOutstandingRequestsCostPerProcess), + receiver_(NULL) { } ResourceDispatcherHost::~ResourceDispatcherHost() { @@ -210,20 +212,68 @@ bool ResourceDispatcherHost::HandleExternalProtocol(int request_id, return true; } -void ResourceDispatcherHost::BeginRequest( - Receiver* receiver, - ChildProcessInfo::ProcessType process_type, - base::ProcessHandle process_handle, - int process_id, - int route_id, +bool ResourceDispatcherHost::OnMessageReceived(const IPC::Message& message, + Receiver* receiver, + bool* message_was_ok) { + if (!IsResourceDispatcherHostMessage(message)) + return false; + + *message_was_ok = true; + receiver_ = receiver; + + IPC_BEGIN_MESSAGE_MAP_EX(ResourceDispatcherHost, message, *message_was_ok) + IPC_MESSAGE_HANDLER(ViewHostMsg_RequestResource, OnRequestResource) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncLoad, OnSyncLoad) + IPC_MESSAGE_HANDLER(ViewHostMsg_DataReceived_ACK, OnDataReceivedACK) + IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadProgress_ACK, OnDownloadProgressACK) + IPC_MESSAGE_HANDLER(ViewHostMsg_UploadProgress_ACK, OnUploadProgressACK) + IPC_MESSAGE_HANDLER(ViewHostMsg_CancelRequest, OnCancelRequest) + IPC_MESSAGE_HANDLER(ViewHostMsg_ClosePage_ACK, OnClosePageACK) + IPC_END_MESSAGE_MAP_EX() + + receiver_ = NULL; + + return true; +} + +void ResourceDispatcherHost::OnRequestResource( + const IPC::Message& message, + int request_id, + const ViewHostMsg_Resource_Request& request_data) { + BeginRequest(request_id, request_data, NULL, message.routing_id()); +} + +// Begins a resource request with the given params on behalf of the specified +// child process. Responses will be dispatched through the given receiver. The +// process ID is used to lookup TabContents from routing_id's in the case of a +// request from a renderer. request_context is the cookie/cache context to be +// used for this request. +// +// If sync_result is non-null, then a SyncLoad reply will be generated, else +// a normal asynchronous set of response messages will be generated. +void ResourceDispatcherHost::OnSyncLoad( int request_id, const ViewHostMsg_Resource_Request& request_data, - URLRequestContext* request_context, IPC::Message* sync_result) { + BeginRequest(request_id, request_data, sync_result, 0); +} + +void ResourceDispatcherHost::BeginRequest( + int request_id, + const ViewHostMsg_Resource_Request& request_data, + IPC::Message* sync_result, // only valid for sync + int route_id) { + ChildProcessInfo::ProcessType process_type = receiver_->type(); + int process_id = receiver_->pid(); + URLRequestContext* context = + receiver_->GetRequestContext(request_id, request_data); + if (!context) + context = Profile::GetDefaultRequestContext(); + if (is_shutdown_ || !ShouldServiceRequest(process_type, process_id, request_data)) { // Tell the renderer that this request was disallowed. - receiver->Send(new ViewMsg_Resource_RequestComplete( + receiver_->Send(new ViewMsg_Resource_RequestComplete( route_id, request_id, URLRequestStatus(URLRequestStatus::FAILED, net::ERR_ABORTED), @@ -241,12 +291,12 @@ void ResourceDispatcherHost::BeginRequest( // Construct the event handler. scoped_refptr<ResourceHandler> handler; if (sync_result) { - handler = new SyncResourceHandler(receiver, request_data.url, sync_result); + handler = new SyncResourceHandler(receiver_, request_data.url, sync_result); } else { - handler = new AsyncResourceHandler(receiver, + handler = new AsyncResourceHandler(receiver_, process_id, route_id, - process_handle, + receiver_->handle(), request_data.url, this); // If the resource type is ResourceType::MEDIA and LOAD_ENABLE_DOWNLOAD_FILE @@ -254,10 +304,10 @@ void ResourceDispatcherHost::BeginRequest( if (request_data.resource_type == ResourceType::MEDIA && (request_data.load_flags & net::LOAD_ENABLE_DOWNLOAD_FILE)) { handler = new MediaResourceHandler(handler, - receiver, + receiver_, process_id, route_id, - process_handle, + receiver_->handle(), this); } } @@ -275,7 +325,7 @@ void ResourceDispatcherHost::BeginRequest( request->set_referrer(request_data.referrer.spec()); request->SetExtraRequestHeaders(request_data.headers); request->set_load_flags(request_data.load_flags); - request->set_context(request_context); + request->set_context(context); request->set_origin_pid(request_data.origin_pid); // Set upload data. @@ -326,13 +376,77 @@ void ResourceDispatcherHost::BeginRequest( request_data.mixed_content, request_data.resource_type, upload_size); - extra_info->allow_download = - ResourceType::IsFrame(request_data.resource_type); + extra_info->allow_download = ResourceType::IsFrame(request_data.resource_type); request->set_user_data(extra_info); // takes pointer ownership BeginRequestInternal(request, request_data.mixed_content); } +void ResourceDispatcherHost::OnDataReceivedACK(int request_id) { + DataReceivedACK(receiver_->pid(), request_id); +} + +void ResourceDispatcherHost::DataReceivedACK(int process_id, int request_id) { + PendingRequestList::iterator i = pending_requests_.find( + GlobalRequestID(process_id, request_id)); + if (i == pending_requests_.end()) + return; + + ExtraRequestInfo* info = ExtraInfoForRequest(i->second); + + // Decrement the number of pending data messages. + info->pending_data_count--; + + // If the pending data count was higher than the max, resume the request. + if (info->pending_data_count == kMaxPendingDataMessages) { + // Decrement the pending data count one more time because we also + // incremented it before pausing the request. + info->pending_data_count--; + + // Resume the request. + PauseRequest(process_id, request_id, false); + } +} + +void ResourceDispatcherHost::OnDownloadProgressACK(int request_id) { + // TODO(hclam): do something to help rate limiting the message. +} + +void ResourceDispatcherHost::OnUploadProgressACK(int request_id) { + int process_id = receiver_->pid(); + PendingRequestList::iterator i = pending_requests_.find( + GlobalRequestID(process_id, request_id)); + if (i == pending_requests_.end()) + return; + + ExtraRequestInfo* info = ExtraInfoForRequest(i->second); + info->waiting_for_upload_progress_ack = false; +} + +void ResourceDispatcherHost::OnCancelRequest(int request_id) { + CancelRequest(receiver_->pid(), request_id, true, true); +} + +void ResourceDispatcherHost::OnClosePageACK(int new_render_process_host_id, + int new_request_id) { + GlobalRequestID global_id(new_render_process_host_id, new_request_id); + PendingRequestList::iterator i = pending_requests_.find(global_id); + if (i == pending_requests_.end()) { + // If there are no matching pending requests, then this is not a + // cross-site navigation and we are just closing the tab/browser. + ui_loop_->PostTask(FROM_HERE, NewRunnableFunction( + &RenderViewHost::ClosePageIgnoringUnloadEvents, + new_render_process_host_id, + new_request_id)); + return; + } + + ExtraRequestInfo* info = ExtraInfoForRequest(i->second); + if (info->cross_site_handler) { + info->cross_site_handler->ResumeResponse(); + } +} + // We are explicitly forcing the download of 'url'. void ResourceDispatcherHost::BeginDownload(const GURL& url, const GURL& referrer, @@ -502,45 +616,6 @@ void ResourceDispatcherHost::CancelRequest(int process_id, // that. } -void ResourceDispatcherHost::OnDataReceivedACK(int process_id, - int request_id) { - PendingRequestList::iterator i = pending_requests_.find( - GlobalRequestID(process_id, request_id)); - if (i == pending_requests_.end()) - return; - - ExtraRequestInfo* info = ExtraInfoForRequest(i->second); - - // Decrement the number of pending data messages. - info->pending_data_count--; - - // If the pending data count was higher than the max, resume the request. - if (info->pending_data_count == kMaxPendingDataMessages) { - // Decrement the pending data count one more time because we also - // incremented it before pausing the request. - info->pending_data_count--; - - // Resume the request. - PauseRequest(process_id, request_id, false); - } -} - -void ResourceDispatcherHost::OnDownloadProgressACK(int process_id, - int request_id) { - // TODO(hclam): do something to help rate limiting the message. -} - -void ResourceDispatcherHost::OnUploadProgressACK(int process_id, - int request_id) { - PendingRequestList::iterator i = pending_requests_.find( - GlobalRequestID(process_id, request_id)); - if (i == pending_requests_.end()) - return; - - ExtraRequestInfo* info = ExtraInfoForRequest(i->second); - info->waiting_for_upload_progress_ack = false; -} - bool ResourceDispatcherHost::WillSendData(int process_id, int request_id) { PendingRequestList::iterator i = pending_requests_.find( @@ -602,26 +677,6 @@ int ResourceDispatcherHost::GetOutstandingRequestsMemoryCost( 0 : entry->second; } -void ResourceDispatcherHost::OnClosePageACK(int process_id, - int request_id) { - GlobalRequestID global_id(process_id, request_id); - PendingRequestList::iterator i = pending_requests_.find(global_id); - if (i == pending_requests_.end()) { - // If there are no matching pending requests, then this is not a - // cross-site navigation and we are just closing the tab/browser. - ui_loop_->PostTask(FROM_HERE, NewRunnableFunction( - &RenderViewHost::ClosePageIgnoringUnloadEvents, - process_id, - request_id)); - return; - } - - ExtraRequestInfo* info = ExtraInfoForRequest(i->second); - if (info->cross_site_handler) { - info->cross_site_handler->ResumeResponse(); - } -} - // The object died, so cancel and detach all requests associated with it except // for downloads, which belong to the browser process even if initiated via a // renderer. @@ -1458,3 +1513,21 @@ void ResourceDispatcherHost::ProcessBlockedRequestsForRoute( delete requests; } + +bool ResourceDispatcherHost::IsResourceDispatcherHostMessage( + const IPC::Message& message) { + switch (message.type()) { + case ViewHostMsg_RequestResource::ID: + case ViewHostMsg_CancelRequest::ID: + case ViewHostMsg_ClosePage_ACK::ID: + case ViewHostMsg_DataReceived_ACK::ID: + case ViewHostMsg_UploadProgress_ACK::ID: + case ViewHostMsg_SyncLoad::ID: + return true; + + default: + break; + } + + return false; +} diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.h b/chrome/browser/renderer_host/resource_dispatcher_host.h index 3d14213..44703aa 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.h +++ b/chrome/browser/renderer_host/resource_dispatcher_host.h @@ -49,7 +49,19 @@ class ResourceDispatcherHost : public URLRequest::Delegate { // false), then the ResourceDispatcherHost assumes the receiver has failed, // and the given request will be dropped. (This happens, for example, when a // renderer crashes and the channel dies). - typedef IPC::Message::Sender Receiver; + class Receiver : public IPC::Message::Sender, + public ChildProcessInfo { + public: + // Return the URLRequestContext for the given request. + // If NULL is returned, the default context for the profile is used. + virtual URLRequestContext* GetRequestContext( + uint32 request_id, + const ViewHostMsg_Resource_Request& request_data) = 0; + + protected: + Receiver(ChildProcessInfo::ProcessType type) : ChildProcessInfo(type) { } + virtual ~Receiver() { } + }; // Holds the data we would like to associate with each request class ExtraRequestInfo : public URLRequest::UserData { @@ -192,23 +204,11 @@ class ResourceDispatcherHost : public URLRequest::Delegate { // new requests). Cancels all pending requests. void Shutdown(); - // Begins a resource request with the given params on behalf of the specified - // child process. Responses will be dispatched through the given receiver. The - // process ID is used to lookup TabContents from routing_id's in the case of a - // request from a renderer. request_context is the cookie/cache context to be - // used for this request. - // - // If sync_result is non-null, then a SyncLoad reply will be generated, else - // a normal asynchronous set of response messages will be generated. - void BeginRequest(Receiver* receiver, - ChildProcessInfo::ProcessType process_type, - base::ProcessHandle process_handle, - int process_id, - int route_id, - int request_id, - const ViewHostMsg_Resource_Request& request, - URLRequestContext* request_context, - IPC::Message* sync_result); + // Returns true if the message was a resource message that was processed. + // If it was, message_was_ok will be false iff the message was corrupt. + bool OnMessageReceived(const IPC::Message& message, + Receiver* receiver, + bool* message_was_ok); // Initiates a download from the browser process (as opposed to a resource // request from the renderer or another child process). @@ -232,18 +232,6 @@ class ResourceDispatcherHost : public URLRequest::Delegate { int request_id, bool from_renderer); - // Decrements the pending_data_count for the request and resumes - // the request if it was paused due to too many pending data - // messages sent. - void OnDataReceivedACK(int process_id, int request_id); - - // Called when the renderer process confirms the reception of a download - // progress message. - void OnDownloadProgressACK(int process_id, int request_id); - - // Resets the waiting_for_upload_progress_ack flag. - void OnUploadProgressACK(int process_id, int request_id); - // Returns true if it's ok to send the data. If there are already too many // data messages pending, it pauses the request and returns false. In this // case the caller should not send the data. @@ -359,6 +347,14 @@ class ResourceDispatcherHost : public URLRequest::Delegate { // Cancels any blocked request for the specified route id. void CancelBlockedRequestsForRoute(int process_id, int route_id); + // Decrements the pending_data_count for the request and resumes + // the request if it was paused due to too many pending data + // messages sent. + void DataReceivedACK(int process_id, int request_id); + + // Needed for the sync IPC message dispatcher macros. + bool Send(IPC::Message* message) { delete message; return false; } + private: FRIEND_TEST(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies); FRIEND_TEST(ResourceDispatcherHostTest, @@ -465,6 +461,24 @@ class ResourceDispatcherHost : public URLRequest::Delegate { int route_id, bool cancel_requests); + void OnRequestResource(const IPC::Message& msg, + int request_id, + const ViewHostMsg_Resource_Request& request_data); + void OnSyncLoad(int request_id, + const ViewHostMsg_Resource_Request& request_data, + IPC::Message* sync_result); + void BeginRequest(int request_id, + const ViewHostMsg_Resource_Request& request_data, + IPC::Message* sync_result, // only valid for sync + int route_id); // only valid for async + void OnDataReceivedACK(int request_id); + void OnDownloadProgressACK(int request_id); + void OnUploadProgressACK(int request_id); + void OnCancelRequest(int request_id); + + // Returns true if the message passed in is a resource related message. + static bool IsResourceDispatcherHostMessage(const IPC::Message&); + PendingRequestList pending_requests_; // We cache the UI message loop so we can create new UI-related objects on it. @@ -528,6 +542,10 @@ class ResourceDispatcherHost : public URLRequest::Delegate { // kAvgBytesPerOutstandingRequest) int max_outstanding_requests_cost_per_process_; + // Used during IPC message dispatching so that the handlers can get a pointer + // to the source of the message. + Receiver* receiver_; + DISALLOW_COPY_AND_ASSIGN(ResourceDispatcherHost); }; diff --git a/chrome/browser/renderer_host/resource_dispatcher_host_unittest.cc b/chrome/browser/renderer_host/resource_dispatcher_host_unittest.cc index 2d05ffb..9e359a7 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host_unittest.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host_unittest.cc @@ -85,15 +85,23 @@ void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages* msgs) { class ResourceDispatcherHostTest : public testing::Test, public ResourceDispatcherHost::Receiver { public: - ResourceDispatcherHostTest() : host_(NULL) { + ResourceDispatcherHostTest() + : Receiver(ChildProcessInfo::RENDER_PROCESS), host_(NULL) { + set_handle(base::GetCurrentProcessHandle()); } - // ResourceDispatcherHost::Delegate implementation + // ResourceDispatcherHost::Receiver implementation virtual bool Send(IPC::Message* msg) { accum_.AddMessage(*msg); delete msg; return true; } + URLRequestContext* GetRequestContext( + uint32 request_id, + const ViewHostMsg_Resource_Request& request_data) { + return NULL; + } + protected: // testing::Test virtual void SetUp() { @@ -117,6 +125,11 @@ class ResourceDispatcherHostTest : public testing::Test, int render_view_id, int request_id, const GURL& url); + void MakeTestRequest(ResourceDispatcherHost::Receiver* receiver, + int render_process_id, + int render_view_id, + int request_id, + const GURL& url); void MakeCancelRequest(int request_id); void EnsureTestSchemeIsAllowed() { @@ -142,12 +155,23 @@ void ResourceDispatcherHostTest::MakeTestRequest(int render_process_id, int render_view_id, int request_id, const GURL& url) { - ViewHostMsg_Resource_Request request = CreateResourceRequest("GET", url); + MakeTestRequest(this, render_process_id, render_view_id, request_id, url); +} - host_.BeginRequest(this, ChildProcessInfo::RENDER_PROCESS, - base::GetCurrentProcessHandle(), render_process_id, - render_view_id, request_id, request, NULL, NULL); +void ResourceDispatcherHostTest::MakeTestRequest( + ResourceDispatcherHost::Receiver* receiver, + int render_process_id, + int render_view_id, + int request_id, + const GURL& url) { + int old_pid = pid(); + pid_ = render_process_id; + ViewHostMsg_Resource_Request request = CreateResourceRequest("GET", url); + ViewHostMsg_RequestResource msg(render_view_id, request_id, request); + bool msg_was_ok; + host_.OnMessageReceived(msg, receiver, &msg_was_ok); KickOffRequest(); + pid_ = old_pid; } void ResourceDispatcherHostTest::MakeCancelRequest(int request_id) { @@ -267,8 +291,11 @@ TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { // pending and some canceled class TestReceiver : public ResourceDispatcherHost::Receiver { public: - TestReceiver() : has_canceled_(false), received_after_canceled_(0) { - } + TestReceiver() + : Receiver(ChildProcessInfo::RENDER_PROCESS), + has_canceled_(false), + received_after_canceled_(0) { } + // ResourceDispatcherHost::Receiver implementation virtual bool Send(IPC::Message* msg) { // no messages should be received when the process has been canceled if (has_canceled_) @@ -276,6 +303,11 @@ TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { delete msg; return true; } + URLRequestContext* GetRequestContext( + uint32 request_id, + const ViewHostMsg_Resource_Request& request_data) { + return NULL; + } bool has_canceled_; int received_after_canceled_; }; @@ -287,20 +319,13 @@ TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); - host_.BeginRequest(&test_receiver, ChildProcessInfo::RENDER_PROCESS, - base::GetCurrentProcessHandle(), 0, MSG_ROUTING_NONE, 1, - request, NULL, NULL); - KickOffRequest(); + MakeTestRequest(&test_receiver, 0, 0, 1, URLRequestTestJob::test_url_1()); // request 2 goes to us MakeTestRequest(0, 0, 2, URLRequestTestJob::test_url_2()); // request 3 goes to the test delegate - request.url = URLRequestTestJob::test_url_3(); - host_.BeginRequest(&test_receiver, ChildProcessInfo::RENDER_PROCESS, - base::GetCurrentProcessHandle(), 0, MSG_ROUTING_NONE, 3, - request, NULL, NULL); - KickOffRequest(); + MakeTestRequest(&test_receiver, 0, 0, 3, URLRequestTestJob::test_url_3()); // TODO(mbelshe): // Now that the async IO path is in place, the IO always completes on the diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index 404e68b..e3b1887 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -106,14 +106,14 @@ ResourceMessageFilter::ResourceMessageFilter( Profile* profile, RenderWidgetHelper* render_widget_helper, SpellChecker* spellchecker) - : channel_(NULL), + : Receiver(RENDER_PROCESS), + channel_(NULL), resource_dispatcher_host_(resource_dispatcher_host), plugin_service_(plugin_service), print_job_manager_(print_job_manager), render_process_id_(-1), spellchecker_(spellchecker), ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)), - render_handle_(NULL), request_context_(profile->GetRequestContext()), media_request_context_(profile->GetRequestContextForMedia()), profile_(profile), @@ -129,8 +129,8 @@ ResourceMessageFilter::ResourceMessageFilter( ResourceMessageFilter::~ResourceMessageFilter() { WorkerService::GetInstance()->RendererShutdown(this); - if (render_handle_) - base::CloseProcessHandle(render_handle_); + if (handle()) + base::CloseProcessHandle(handle()); // This function should be called on the IO thread. DCHECK(MessageLoop::current() == @@ -159,9 +159,9 @@ void ResourceMessageFilter::OnFilterAdded(IPC::Channel* channel) { // Called on the IPC thread: void ResourceMessageFilter::OnChannelConnected(int32 peer_pid) { - DCHECK(!render_handle_); - render_handle_ = base::OpenProcessHandle(peer_pid); - DCHECK(render_handle_); + DCHECK(!handle()); + set_handle(base::OpenProcessHandle(peer_pid)); + DCHECK(handle()); // Hook AudioRendererHost to this object after channel is connected so it can // this object for sending messages. audio_renderer_host_->IPCChannelConnected(this); @@ -181,100 +181,93 @@ void ResourceMessageFilter::OnChannelClosing() { // Called on the IPC thread: bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message) { - bool handled = true; bool msg_is_ok = true; - IPC_BEGIN_MESSAGE_MAP_EX(ResourceMessageFilter, message, msg_is_ok) - IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindow, OnMsgCreateWindow) - IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidget, OnMsgCreateWidget) - // TODO(brettw): we should get the view ID for this so the resource - // dispatcher can prioritize things based on the visible view. - IPC_MESSAGE_HANDLER(ViewHostMsg_RequestResource, OnRequestResource) - IPC_MESSAGE_HANDLER(ViewHostMsg_CancelRequest, OnCancelRequest) - IPC_MESSAGE_HANDLER(ViewHostMsg_ClosePage_ACK, OnClosePageACK) - IPC_MESSAGE_HANDLER(ViewHostMsg_DataReceived_ACK, OnDataReceivedACK) - IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadProgress_ACK, OnDownloadProgressACK) - IPC_MESSAGE_HANDLER(ViewHostMsg_UploadProgress_ACK, OnUploadProgressACK) - - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncLoad, OnSyncLoad) - - IPC_MESSAGE_HANDLER(ViewHostMsg_SetCookie, OnSetCookie) - IPC_MESSAGE_HANDLER(ViewHostMsg_GetCookies, OnGetCookies) - IPC_MESSAGE_HANDLER(ViewHostMsg_GetDataDir, OnGetDataDir) - IPC_MESSAGE_HANDLER(ViewHostMsg_PluginMessage, OnPluginMessage) - IPC_MESSAGE_HANDLER(ViewHostMsg_PluginSyncMessage, OnPluginSyncMessage) + bool handled = resource_dispatcher_host_->OnMessageReceived( + message, this, &msg_is_ok); + if (!handled) { + handled = true; + IPC_BEGIN_MESSAGE_MAP_EX(ResourceMessageFilter, message, msg_is_ok) + IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindow, OnMsgCreateWindow) + IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidget, OnMsgCreateWidget) + IPC_MESSAGE_HANDLER(ViewHostMsg_SetCookie, OnSetCookie) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetCookies, OnGetCookies) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetDataDir, OnGetDataDir) + IPC_MESSAGE_HANDLER(ViewHostMsg_PluginMessage, OnPluginMessage) + IPC_MESSAGE_HANDLER(ViewHostMsg_PluginSyncMessage, OnPluginSyncMessage) #if defined(OS_WIN) // This hack is Windows-specific. - IPC_MESSAGE_HANDLER(ViewHostMsg_LoadFont, OnLoadFont) + IPC_MESSAGE_HANDLER(ViewHostMsg_LoadFont, OnLoadFont) #endif - IPC_MESSAGE_HANDLER(ViewHostMsg_GetScreenInfo, OnGetScreenInfo) - IPC_MESSAGE_HANDLER(ViewHostMsg_GetPlugins, OnGetPlugins) - IPC_MESSAGE_HANDLER(ViewHostMsg_GetPluginPath, OnGetPluginPath) - IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadUrl, OnDownloadUrl) - IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_ContextMenu, - OnReceiveContextMenuMsg(message)) - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenChannelToPlugin, - OnOpenChannelToPlugin) - IPC_MESSAGE_HANDLER(ViewHostMsg_CreateDedicatedWorker, - OnCreateDedicatedWorker) - IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardToWorker, - OnForwardToWorker) - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SpellCheck, OnSpellCheck) - IPC_MESSAGE_HANDLER(ViewHostMsg_DnsPrefetch, OnDnsPrefetch) - IPC_MESSAGE_HANDLER(ViewHostMsg_RendererHistograms, - OnRendererHistograms) - IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_PaintRect, - render_widget_helper_->DidReceivePaintMsg(message)) - IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteObjectsAsync, - OnClipboardWriteObjects) - IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteObjectsSync, - OnClipboardWriteObjects) - IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardIsFormatAvailable, - OnClipboardIsFormatAvailable) - IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardReadText, OnClipboardReadText) - IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardReadAsciiText, - OnClipboardReadAsciiText) - IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardReadHTML, - OnClipboardReadHTML) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetScreenInfo, OnGetScreenInfo) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetPlugins, OnGetPlugins) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetPluginPath, OnGetPluginPath) + IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadUrl, OnDownloadUrl) + IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_ContextMenu, + OnReceiveContextMenuMsg(message)) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenChannelToPlugin, + OnOpenChannelToPlugin) + IPC_MESSAGE_HANDLER(ViewHostMsg_CreateDedicatedWorker, + OnCreateDedicatedWorker) + IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardToWorker, + OnForwardToWorker) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SpellCheck, OnSpellCheck) + IPC_MESSAGE_HANDLER(ViewHostMsg_DnsPrefetch, OnDnsPrefetch) + IPC_MESSAGE_HANDLER(ViewHostMsg_RendererHistograms, + OnRendererHistograms) + IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_PaintRect, + render_widget_helper_->DidReceivePaintMsg(message)) + IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteObjectsAsync, + OnClipboardWriteObjects) + IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteObjectsSync, + OnClipboardWriteObjects) + IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardIsFormatAvailable, + OnClipboardIsFormatAvailable) + IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardReadText, OnClipboardReadText) + IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardReadAsciiText, + OnClipboardReadAsciiText) + IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardReadHTML, + OnClipboardReadHTML) #if defined(OS_WIN)|| defined(OS_LINUX) - IPC_MESSAGE_HANDLER(ViewHostMsg_GetWindowRect, OnGetWindowRect) - IPC_MESSAGE_HANDLER(ViewHostMsg_GetRootWindowRect, OnGetRootWindowRect) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetWindowRect, OnGetWindowRect) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetRootWindowRect, OnGetRootWindowRect) #endif - IPC_MESSAGE_HANDLER(ViewHostMsg_GetMimeTypeFromExtension, - OnGetMimeTypeFromExtension) - IPC_MESSAGE_HANDLER(ViewHostMsg_GetMimeTypeFromFile, - OnGetMimeTypeFromFile) - IPC_MESSAGE_HANDLER(ViewHostMsg_GetPreferredExtensionForMimeType, - OnGetPreferredExtensionForMimeType) - IPC_MESSAGE_HANDLER(ViewHostMsg_GetCPBrowsingContext, - OnGetCPBrowsingContext) - IPC_MESSAGE_HANDLER(ViewHostMsg_DuplicateSection, OnDuplicateSection) - IPC_MESSAGE_HANDLER(ViewHostMsg_ResourceTypeStats, OnResourceTypeStats) - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ResolveProxy, OnResolveProxy) - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetDefaultPrintSettings, - OnGetDefaultPrintSettings) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetMimeTypeFromExtension, + OnGetMimeTypeFromExtension) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetMimeTypeFromFile, + OnGetMimeTypeFromFile) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetPreferredExtensionForMimeType, + OnGetPreferredExtensionForMimeType) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetCPBrowsingContext, + OnGetCPBrowsingContext) + IPC_MESSAGE_HANDLER(ViewHostMsg_DuplicateSection, OnDuplicateSection) + IPC_MESSAGE_HANDLER(ViewHostMsg_ResourceTypeStats, OnResourceTypeStats) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ResolveProxy, OnResolveProxy) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetDefaultPrintSettings, + OnGetDefaultPrintSettings) #if defined(OS_WIN) - IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ScriptedPrint, - OnScriptedPrint) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ScriptedPrint, + OnScriptedPrint) #endif - IPC_MESSAGE_HANDLER(ViewHostMsg_CreateAudioStream, OnCreateAudioStream) - IPC_MESSAGE_HANDLER(ViewHostMsg_StartAudioStream, OnStartAudioStream) - IPC_MESSAGE_HANDLER(ViewHostMsg_CloseAudioStream, OnCloseAudioStream) - IPC_MESSAGE_HANDLER(ViewHostMsg_NotifyAudioPacketReady, - OnNotifyAudioPacketReady) - IPC_MESSAGE_HANDLER(ViewHostMsg_GetAudioVolume, OnGetAudioVolume) - IPC_MESSAGE_HANDLER(ViewHostMsg_SetAudioVolume, OnSetAudioVolume) + IPC_MESSAGE_HANDLER(ViewHostMsg_CreateAudioStream, OnCreateAudioStream) + IPC_MESSAGE_HANDLER(ViewHostMsg_StartAudioStream, OnStartAudioStream) + IPC_MESSAGE_HANDLER(ViewHostMsg_CloseAudioStream, OnCloseAudioStream) + IPC_MESSAGE_HANDLER(ViewHostMsg_NotifyAudioPacketReady, + OnNotifyAudioPacketReady) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetAudioVolume, OnGetAudioVolume) + IPC_MESSAGE_HANDLER(ViewHostMsg_SetAudioVolume, OnSetAudioVolume) #if defined(OS_MACOSX) - IPC_MESSAGE_HANDLER(ViewHostMsg_AllocTransportDIB, - OnAllocTransportDIB) - IPC_MESSAGE_HANDLER(ViewHostMsg_FreeTransportDIB, - OnFreeTransportDIB) + IPC_MESSAGE_HANDLER(ViewHostMsg_AllocTransportDIB, + OnAllocTransportDIB) + IPC_MESSAGE_HANDLER(ViewHostMsg_FreeTransportDIB, + OnFreeTransportDIB) #endif - IPC_MESSAGE_UNHANDLED( - handled = false) - IPC_END_MESSAGE_MAP_EX() + IPC_MESSAGE_UNHANDLED( + handled = false) + IPC_END_MESSAGE_MAP_EX() + } if (!msg_is_ok) { BrowserRenderProcessHost::BadMessageTerminateProcess(message.type(), - render_handle_); + handle()); } return handled; @@ -318,12 +311,27 @@ bool ResourceMessageFilter::Send(IPC::Message* message) { return channel_->Send(message); } +URLRequestContext* ResourceMessageFilter::GetRequestContext( + uint32 request_id, + const ViewHostMsg_Resource_Request& request_data) { + URLRequestContext* request_context = request_context_; + // If the request has resource type of ResourceType::MEDIA and + // LOAD_ENABLE_DOWNLOAD_FILE is set as a load flag, we use a request context + // specific to media for handling it because these resources have specific + // needs for caching and data passing. + if (request_data.resource_type == ResourceType::MEDIA && + (request_data.load_flags & net::LOAD_ENABLE_DOWNLOAD_FILE)) { + request_context = media_request_context_; + } + return request_context_; +} + void ResourceMessageFilter::OnMsgCreateWindow( int opener_id, bool user_gesture, int* route_id, ModalDialogEvent* modal_dialog_event) { render_widget_helper_->CreateNewWindow(opener_id, user_gesture, - render_handle_, + handle(), route_id, modal_dialog_event); } @@ -334,71 +342,6 @@ void ResourceMessageFilter::OnMsgCreateWidget(int opener_id, render_widget_helper_->CreateNewWidget(opener_id, activatable, route_id); } -void ResourceMessageFilter::OnRequestResource( - const IPC::Message& message, - int request_id, - const ViewHostMsg_Resource_Request& request) { - URLRequestContext* request_context = request_context_; - // If the request has resource type of ResourceType::MEDIA and - // LOAD_ENABLE_DOWNLOAD_FILE is set as a load flag, we use a request context - // specific to media for handling it because these resources have specific - // needs for caching and data passing. - if (request.resource_type == ResourceType::MEDIA && - (request.load_flags & net::LOAD_ENABLE_DOWNLOAD_FILE)) { - request_context = media_request_context_; - } - - resource_dispatcher_host_->BeginRequest(this, - ChildProcessInfo::RENDER_PROCESS, - render_handle_, - render_process_id_, - message.routing_id(), - request_id, - request, - request_context, - NULL); -} - -void ResourceMessageFilter::OnDataReceivedACK(int request_id) { - resource_dispatcher_host_->OnDataReceivedACK(render_process_id_, request_id); -} - -void ResourceMessageFilter::OnDownloadProgressACK(int request_id) { - resource_dispatcher_host_->OnDownloadProgressACK(render_process_id_, - request_id); -} - -void ResourceMessageFilter::OnUploadProgressACK(int request_id) { - resource_dispatcher_host_->OnUploadProgressACK(render_process_id_, - request_id); -} - -void ResourceMessageFilter::OnCancelRequest(int request_id) { - resource_dispatcher_host_->CancelRequest(render_process_id_, request_id, - true); -} - -void ResourceMessageFilter::OnClosePageACK(int new_render_process_host_id, - int new_request_id) { - resource_dispatcher_host_->OnClosePageACK(new_render_process_host_id, - new_request_id); -} - -void ResourceMessageFilter::OnSyncLoad( - int request_id, - const ViewHostMsg_Resource_Request& request, - IPC::Message* sync_result) { - resource_dispatcher_host_->BeginRequest(this, - ChildProcessInfo::RENDER_PROCESS, - render_handle_, - render_process_id_, - sync_result->routing_id(), - request_id, - request, - request_context_, - sync_result); -} - void ResourceMessageFilter::OnSetCookie(const GURL& url, const GURL& policy_url, const std::string& cookie) { @@ -552,11 +495,11 @@ void ResourceMessageFilter::OnClipboardWriteObjects( // a task to perform the write on the UI thread. Clipboard::ObjectMap* long_living_objects = new Clipboard::ObjectMap(objects); - // We pass the render_handle_ to assist the clipboard with using shared - // memory objects. render_handle_ is a handle to the process that would + // We pass the renderer handle to assist the clipboard with using shared + // memory objects. renderer handle is a handle to the process that would // own any shared memory that might be in the object list. #if defined(OS_WIN) - Clipboard::DuplicateRemoteHandles(render_handle_, long_living_objects); + Clipboard::DuplicateRemoteHandles(handle(), long_living_objects); #else NOTIMPLEMENTED(); // TODO(port) implement this. #endif @@ -665,7 +608,7 @@ void ResourceMessageFilter::OnDuplicateSection( base::SharedMemoryHandle* browser_handle) { // Duplicate the handle in this process right now so the memory is kept alive // (even if it is not mapped) - base::SharedMemory shared_buf(renderer_handle, true, render_handle_); + base::SharedMemory shared_buf(renderer_handle, true, handle()); shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), browser_handle); } @@ -855,7 +798,7 @@ void ResourceMessageFilter::OnCreateAudioStream( const IPC::Message& msg, int stream_id, const ViewHostMsg_Audio_CreateStream& params) { audio_renderer_host_->CreateStream( - render_handle_, msg.routing_id(), stream_id, params.format, + handle(), msg.routing_id(), stream_id, params.format, params.channels, params.sample_rate, params.bits_per_sample, params.packet_size); } diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h index 3269c89..59ba421 100644 --- a/chrome/browser/renderer_host/resource_message_filter.h +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -83,9 +83,14 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, // ResourceDispatcherHost::Receiver methods: virtual bool Send(IPC::Message* message); + virtual URLRequestContext* GetRequestContext( + uint32 request_id, + const ViewHostMsg_Resource_Request& request_data); - // Access to the spell checker. SpellChecker* spellchecker() { return spellchecker_.get(); } + ResourceDispatcherHost* resource_dispatcher_host() { + return resource_dispatcher_host_; + } // NotificationObserver implementation. virtual void Observe(NotificationType type, @@ -96,16 +101,6 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, void OnMsgCreateWindow(int opener_id, bool user_gesture, int* route_id, ModalDialogEvent* modal_dialog_event); void OnMsgCreateWidget(int opener_id, bool activatable, int* route_id); - void OnRequestResource(const IPC::Message& msg, int request_id, - const ViewHostMsg_Resource_Request& request); - void OnCancelRequest(int request_id); - void OnClosePageACK(int new_render_process_host_id, int new_request_id); - void OnDataReceivedACK(int request_id); - void OnDownloadProgressACK(int request_id); - void OnUploadProgressACK(int request_id); - void OnSyncLoad(int request_id, - const ViewHostMsg_Resource_Request& request, - IPC::Message* result_message); void OnSetCookie(const GURL& url, const GURL& policy_url, const std::string& cookie); void OnGetCookies(const GURL& url, const GURL& policy_url, @@ -246,9 +241,6 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, // the requests to the proxy service). ResolveProxyMsgHelper resolve_proxy_msg_helper_; - // Process handle of the renderer process. - base::ProcessHandle render_handle_; - // Contextual information to be used for requests created here. scoped_refptr<URLRequestContext> request_context_; diff --git a/chrome/browser/worker_host/worker_process_host.cc b/chrome/browser/worker_host/worker_process_host.cc index 8637a12..bf68bff 100644 --- a/chrome/browser/worker_host/worker_process_host.cc +++ b/chrome/browser/worker_host/worker_process_host.cc @@ -18,8 +18,9 @@ #include "chrome/common/worker_messages.h" -WorkerProcessHost::WorkerProcessHost(MessageLoop* main_message_loop) - : ChildProcessHost(WORKER_PROCESS, main_message_loop) { +WorkerProcessHost::WorkerProcessHost( + ResourceDispatcherHost* resource_dispatcher_host_) + : ChildProcessHost(WORKER_PROCESS, resource_dispatcher_host_) { } WorkerProcessHost::~WorkerProcessHost() { @@ -76,6 +77,12 @@ bool WorkerProcessHost::FilterMessage(const IPC::Message& message) { return false; } +URLRequestContext* WorkerProcessHost::GetRequestContext( + uint32 request_id, + const ViewHostMsg_Resource_Request& request_data) { + return NULL; +} + void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) { for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { if (i->worker_route_id == message.routing_id()) { diff --git a/chrome/browser/worker_host/worker_process_host.h b/chrome/browser/worker_host/worker_process_host.h index e0ff095..15a61e2 100644 --- a/chrome/browser/worker_host/worker_process_host.h +++ b/chrome/browser/worker_host/worker_process_host.h @@ -16,7 +16,7 @@ class ResourceMessageFilter; class WorkerProcessHost : public ChildProcessHost { public: - WorkerProcessHost(MessageLoop* main_message_loop); + WorkerProcessHost(ResourceDispatcherHost* resource_dispatcher_host_); ~WorkerProcessHost(); // Starts the process. Returns true iff it succeeded. @@ -35,6 +35,11 @@ class WorkerProcessHost : public ChildProcessHost { void RendererShutdown(ResourceMessageFilter* filter); private: + // ResourceDispatcherHost::Receiver implementation: + virtual URLRequestContext* GetRequestContext( + uint32 request_id, + const ViewHostMsg_Resource_Request& request_data); + // Called when a message arrives from the worker process. void OnMessageReceived(const IPC::Message& message); diff --git a/chrome/browser/worker_host/worker_service.cc b/chrome/browser/worker_host/worker_service.cc index cdbf69c..7eb5c69 100644 --- a/chrome/browser/worker_host/worker_service.cc +++ b/chrome/browser/worker_host/worker_service.cc @@ -34,10 +34,7 @@ bool WorkerService::CreateDedicatedWorker(const GURL &url, } if (!worker) { - // TODO(jabdelmalek): there has to be a better way to get the main message - // loop than to go through PluginService. - worker = new WorkerProcessHost( - PluginService::GetInstance()->main_message_loop()); + worker = new WorkerProcessHost(filter->resource_dispatcher_host()); if (!worker->Init()) { delete worker; return false; diff --git a/chrome/common/child_process_host.cc b/chrome/common/child_process_host.cc index cb37d30..4269678 100644 --- a/chrome/common/child_process_host.cc +++ b/chrome/common/child_process_host.cc @@ -7,6 +7,7 @@ #include "base/compiler_specific.h" #include "base/logging.h" #include "base/message_loop.h" +#include "base/process_util.h" #include "base/singleton.h" #include "base/waitable_event.h" #include "chrome/browser/chrome_thread.h" @@ -14,6 +15,7 @@ #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" #include "chrome/common/process_watcher.h" +#include "chrome/common/result_codes.h" typedef std::list<ChildProcessInfo*> ChildProcessList; @@ -39,10 +41,10 @@ class ChildNotificationTask : public Task { ChildProcessHost::ChildProcessHost( - ProcessType type, MessageLoop* main_message_loop) - : ChildProcessInfo(type), + ProcessType type, ResourceDispatcherHost* resource_dispatcher_host) + : Receiver(type), ALLOW_THIS_IN_INITIALIZER_LIST(listener_(this)), - main_message_loop_(main_message_loop), + resource_dispatcher_host_(resource_dispatcher_host), opening_channel_(false), process_event_(NULL) { Singleton<ChildProcessList>::get()->push_back(this); @@ -99,7 +101,7 @@ bool ChildProcessHost::Send(IPC::Message* msg) { } void ChildProcessHost::Notify(NotificationType type) { - main_message_loop_->PostTask( + resource_dispatcher_host_->ui_loop()->PostTask( FROM_HERE, new ChildNotificationTask(type, this)); } @@ -138,7 +140,14 @@ void ChildProcessHost::ListenerHook::OnMessageReceived( logger->OnPreDispatchMessage(msg); #endif - host_->OnMessageReceived(msg); + bool msg_is_ok = true; + bool handled = host_->resource_dispatcher_host_->OnMessageReceived( + msg, host_, &msg_is_ok); + if (!handled) + host_->OnMessageReceived(msg); + + if (!msg_is_ok) + base::KillProcess(host_->handle(), ResultCodes::KILLED_BAD_MESSAGE, false); #ifdef IPC_MESSAGE_LOG_ENABLED if (logger->Enabled()) diff --git a/chrome/common/child_process_host.h b/chrome/common/child_process_host.h index 4f173fc..cef940c 100644 --- a/chrome/common/child_process_host.h +++ b/chrome/common/child_process_host.h @@ -12,22 +12,21 @@ #include "base/basictypes.h" #include "base/scoped_ptr.h" #include "base/waitable_event_watcher.h" +#include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/common/child_process_info.h" #include "chrome/common/ipc_channel.h" -class MessageLoop; class NotificationType; // Plugins/workers and other child processes that live on the IO thread should // derive from this class. -class ChildProcessHost : public ChildProcessInfo, +class ChildProcessHost : public ResourceDispatcherHost::Receiver, public base::WaitableEventWatcher::Delegate, - public IPC::Channel::Listener, - public IPC::Message::Sender { + public IPC::Channel::Listener { public: virtual ~ChildProcessHost(); - // IPC::Message::Sender implementation: + // ResourceDispatcherHost::Receiver implementation: virtual bool Send(IPC::Message* msg); // The Iterator class allows iteration through either all child processes, or @@ -51,7 +50,8 @@ class ChildProcessHost : public ChildProcessInfo, }; protected: - ChildProcessHost(ProcessType type, MessageLoop* main_message_loop); + ChildProcessHost(ProcessType type, + ResourceDispatcherHost* resource_dispatcher_host); // Creates the IPC channel. Returns true iff it succeeded. bool CreateChannel(); @@ -93,7 +93,7 @@ class ChildProcessHost : public ChildProcessInfo, ListenerHook listener_; - MessageLoop* main_message_loop_; + ResourceDispatcherHost* resource_dispatcher_host_; // True while we're waiting the channel to be opened. bool opening_channel_; diff --git a/chrome/common/child_process_info.cc b/chrome/common/child_process_info.cc index 1521dab..5ef4469 100644 --- a/chrome/common/child_process_info.cc +++ b/chrome/common/child_process_info.cc @@ -60,6 +60,7 @@ ChildProcessInfo::ChildProcessInfo(ProcessType type) { // just a simple object that contains information about it. So add it to our // list of running processes. type_ = type; + pid_ = -1; } diff --git a/chrome/common/child_process_info.h b/chrome/common/child_process_info.h index eee468d..2af3e10 100644 --- a/chrome/common/child_process_info.h +++ b/chrome/common/child_process_info.h @@ -30,7 +30,13 @@ class ChildProcessInfo { // Getter to the process handle. base::ProcessHandle handle() const { return process_.handle(); } - int pid() const { return process_.pid(); } + int pid() const { + if (pid_ != -1) + return pid_; + + pid_ = process_.pid(); + return pid_; + } void SetProcessBackgrounded() const { process_.SetProcessBackgrounded(true); } void ReduceWorkingSet() const { process_.ReduceWorkingSet(); } @@ -46,6 +52,7 @@ class ChildProcessInfo { type_ = original.type_; name_ = original.name_; process_ = original.process_; + pid_ = original.pid_; } ChildProcessInfo& operator=(const ChildProcessInfo& original) { @@ -53,6 +60,7 @@ class ChildProcessInfo { type_ = original.type_; name_ = original.name_; process_ = original.process_; + pid_ = original.pid_; } return *this; } @@ -78,20 +86,20 @@ class ChildProcessInfo { protected: void set_type(ProcessType type) { type_ = type; } void set_name(const std::wstring& name) { name_ = name; } - void set_handle(base::ProcessHandle handle) { process_.set_handle(handle); } + void set_handle(base::ProcessHandle handle) { + process_.set_handle(handle); + pid_ = -1; + } // Derived objects need to use this constructor so we know what type we are. ChildProcessInfo(ProcessType type); private: - // By making the constructor private, we can ensure that ChildProcessInfo - // objects can only be created by creating objects derived from them (i.e. - // PluginProcessHost) or by using the copy constructor or assignment operator - // to create an object from the former. - ChildProcessInfo() { } + friend class ResourceDispatcherHostTest; ProcessType type_; std::wstring name_; + mutable int pid_; // Cache of the process id. // The handle to the process. mutable base::Process process_; diff --git a/chrome/common/resource_dispatcher.cc b/chrome/common/resource_dispatcher.cc index be45a38..f29fa24 100644 --- a/chrome/common/resource_dispatcher.cc +++ b/chrome/common/resource_dispatcher.cc @@ -242,7 +242,7 @@ ResourceDispatcher::~ResourceDispatcher() { // ResourceDispatcher implementation ------------------------------------------ bool ResourceDispatcher::OnMessageReceived(const IPC::Message& message) { - if (!IsResourceMessage(message)) { + if (!IsResourceDispatcherMessage(message)) { return false; } @@ -523,8 +523,8 @@ webkit_glue::ResourceLoaderBridge* ResourceDispatcher::CreateBridge( route_id); } - -bool ResourceDispatcher::IsResourceMessage(const IPC::Message& message) const { +bool ResourceDispatcher::IsResourceDispatcherMessage( + const IPC::Message& message) { switch (message.type()) { case ViewMsg_Resource_DownloadProgress::ID: case ViewMsg_Resource_UploadProgress::ID: diff --git a/chrome/common/resource_dispatcher.h b/chrome/common/resource_dispatcher.h index 5ea97e4..53fc665 100644 --- a/chrome/common/resource_dispatcher.h +++ b/chrome/common/resource_dispatcher.h @@ -64,10 +64,6 @@ class ResourceDispatcher { // Toggles the is_deferred attribute for the specified request. void SetDefersLoading(int request_id, bool value); - // Returns true if the message passed in is a resource related - // message. - bool IsResourceMessage(const IPC::Message& message) const; - private: friend class ResourceDispatcherTest; @@ -117,6 +113,9 @@ class ResourceDispatcher { // again in the deferred state. void FlushDeferredMessages(int request_id); + // Returns true if the message passed in is a resource related message. + static bool IsResourceDispatcherMessage(const IPC::Message& message); + IPC::Message::Sender* message_sender_; // All pending requests issued to the host |