summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-13 20:06:57 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-13 20:06:57 +0000
commit363347b61871d82d0f84d14d5a24288ac79eddc3 (patch)
tree5cfc6dc4c874e9d23d3fc66ae4b9294bf549921b /chrome/browser/renderer_host
parentcc7948aeb5fe21af08a2d5e868c0087ded0d244a (diff)
downloadchromium_src-363347b61871d82d0f84d14d5a24288ac79eddc3.zip
chromium_src-363347b61871d82d0f84d14d5a24288ac79eddc3.tar.gz
chromium_src-363347b61871d82d0f84d14d5a24288ac79eddc3.tar.bz2
Highlights of changes:
1. Added entry to ResourceResponseHead so that it contains either a base::PlatformFile (OS_WIN) or base::FileDescriptor (OS_POSIX) for passing the file handle from browser to renderer process. 2. Also added IPC messages for reporting download progress and ACK message for it. ResourceLoaderBridge::Peer::OnDownloadProgress is added so that the peer is notified of the download progress in the renderer process. 3. Load flag to kick start the resource loading for media files. LOAD_MEDIA_RESOURCE is added so that ResourceDispatcherHost knows how to use a different ResourceHandler for handling media resource request. Review URL: http://codereview.chromium.org/27168 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11661 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host')
-rw-r--r--chrome/browser/renderer_host/media_resource_handler.cc98
-rw-r--r--chrome/browser/renderer_host/media_resource_handler.h50
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.cc26
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.h4
-rw-r--r--chrome/browser/renderer_host/resource_handler.h19
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc22
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h4
7 files changed, 222 insertions, 1 deletions
diff --git a/chrome/browser/renderer_host/media_resource_handler.cc b/chrome/browser/renderer_host/media_resource_handler.cc
new file mode 100644
index 0000000..ca79b0d
--- /dev/null
+++ b/chrome/browser/renderer_host/media_resource_handler.cc
@@ -0,0 +1,98 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/renderer_host/media_resource_handler.h"
+
+#include "base/process.h"
+#include "chrome/common/render_messages.h"
+#include "net/base/load_flags.h"
+
+MediaResourceHandler::MediaResourceHandler(
+ ResourceHandler* resource_handler,
+ ResourceDispatcherHost::Receiver* receiver,
+ int render_process_host_id,
+ int routing_id,
+ base::ProcessHandle render_process,
+ ResourceDispatcherHost* resource_dispatcher_host)
+ : receiver_(receiver),
+ render_process_host_id_(render_process_host_id),
+ routing_id_(routing_id),
+ render_process_(render_process),
+ handler_(resource_handler),
+ rdh_(resource_dispatcher_host),
+ has_file_handle_(false),
+ position_(0),
+ size_(-1) {
+}
+
+bool MediaResourceHandler::OnUploadProgress(int request_id,
+ uint64 position,
+ uint64 size) {
+ return handler_->OnUploadProgress(request_id, position, size);
+}
+
+bool MediaResourceHandler::OnRequestRedirected(int request_id,
+ const GURL& new_url) {
+ return handler_->OnRequestRedirected(request_id, new_url);
+}
+
+bool MediaResourceHandler::OnResponseStarted(int request_id,
+ ResourceResponse* response) {
+#if defined(OS_POSIX)
+ if (response->response_head.response_data_file.fd !=
+ base::kInvalidPlatformFileValue) {
+ // On POSIX, we will just set auto_close to true, and the IPC infrastructure
+ // will send this file handle through and close it automatically.
+ response->response_head.response_data_file.auto_close = true;
+ has_file_handle_ = true;
+ }
+#elif defined(OS_WIN)
+ if (response->response_head.response_data_file !=
+ base::kInvalidPlatformFileValue) {
+ // On Windows, we duplicate the file handle for the renderer process and
+ // close the original manually.
+ base::PlatformFile foreign_handle;
+ if (DuplicateHandle(GetCurrentProcess(),
+ response->response_head.response_data_file,
+ render_process_,
+ &foreign_handle,
+ FILE_READ_DATA, // Only allow read access to data.
+ false, // Foreign handle is not inheritable.
+ // Close the file handle after duplication.
+ DUPLICATE_CLOSE_SOURCE)){
+ response->response_head.response_data_file = foreign_handle;
+ has_file_handle_ = true;
+ } else {
+ has_file_handle_ = false;
+ }
+ }
+#endif
+ size_ = response->response_head.content_length;
+ return handler_->OnResponseStarted(request_id, response);
+}
+
+bool MediaResourceHandler::OnWillRead(int request_id,
+ net::IOBuffer** buf, int* buf_size,
+ int min_size) {
+ return handler_->OnWillRead(request_id, buf, buf_size, min_size);
+}
+
+bool MediaResourceHandler::OnReadCompleted(int request_id, int* bytes_read) {
+ if (has_file_handle_) {
+ // If we have received a file handle before we will be sending a progress
+ // update for download.
+ // TODO(hclam): rate limit this message so we won't be sending too much to
+ // the renderer process.
+ receiver_->Send(
+ new ViewMsg_Resource_DownloadProgress(routing_id_, request_id,
+ position_, size_));
+ position_ += *bytes_read;
+ }
+ return handler_->OnReadCompleted(request_id, bytes_read);
+}
+
+bool MediaResourceHandler::OnResponseCompleted(int request_id,
+ const URLRequestStatus& status, const std::string& security_info) {
+ return handler_->OnResponseCompleted(request_id, status, security_info);
+}
diff --git a/chrome/browser/renderer_host/media_resource_handler.h b/chrome/browser/renderer_host/media_resource_handler.h
new file mode 100644
index 0000000..93be6d706
--- /dev/null
+++ b/chrome/browser/renderer_host/media_resource_handler.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_RENDERER_HOST_MEDIA_RESOURCE_HANDLER_H_
+#define CHROME_BROWSER_RENDERER_HOST_MEDIA_RESOURCE_HANDLER_H_
+
+#include "base/process.h"
+#include "base/platform_file.h"
+#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
+#include "chrome/browser/renderer_host/resource_handler.h"
+
+// Used to complete a media resource request in response to resource load events
+// from the resource dispatcher host. This handler only works asynchronously and
+// tries to work with file for response data if possible. If a response data
+// file is not available, it redirects calls to underlying handler.
+class MediaResourceHandler : public ResourceHandler {
+ public:
+ MediaResourceHandler(ResourceHandler* resource_handler,
+ ResourceDispatcherHost::Receiver* receiver,
+ int render_process_host_id,
+ int routing_id,
+ base::ProcessHandle render_process,
+ ResourceDispatcherHost* resource_dispatcher_host);
+
+ // ResourceHandler implementation:
+ bool OnUploadProgress(int request_id, uint64 position, uint64 size);
+ bool OnRequestRedirected(int request_id, const GURL& new_url);
+ bool OnResponseStarted(int request_id, ResourceResponse* response);
+ bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size,
+ int min_size);
+ bool OnReadCompleted(int request_id, int* bytes_read);
+ bool OnResponseCompleted(int request_id, const URLRequestStatus& status,
+ const std::string& security_info);
+
+ private:
+ ResourceDispatcherHost::Receiver* receiver_;
+ int render_process_host_id_;
+ int routing_id_;
+ base::ProcessHandle render_process_;
+ scoped_refptr<ResourceHandler> handler_;
+ ResourceDispatcherHost* rdh_;
+ bool has_file_handle_;
+ int64 position_;
+ int64 size_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaResourceHandler);
+};
+
+#endif // CHROME_BROWSER_RENDERER_HOST_MEDIA_RESOURCE_HANDLER_H_
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc
index b4535ca..057343d 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.cc
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc
@@ -22,6 +22,7 @@
#include "chrome/browser/renderer_host/buffered_resource_handler.h"
#include "chrome/browser/renderer_host/cross_site_resource_handler.h"
#include "chrome/browser/renderer_host/download_resource_handler.h"
+#include "chrome/browser/renderer_host/media_resource_handler.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/renderer_security_policy.h"
#include "chrome/browser/renderer_host/resource_request_details.h"
@@ -248,6 +249,17 @@ void ResourceDispatcherHost::BeginRequest(
process_handle,
request_data.url,
this);
+ // If the resource type is ResourceType::MEDIA and LOAD_ENABLE_DOWNLOAD_FILE
+ // is enabled we insert a media resource handler.
+ if (request_data.resource_type == ResourceType::MEDIA &&
+ (request_data.load_flags & net::LOAD_ENABLE_DOWNLOAD_FILE)) {
+ handler = new MediaResourceHandler(handler,
+ receiver,
+ process_id,
+ route_id,
+ process_handle,
+ this);
+ }
}
if (HandleExternalProtocol(request_id, process_id, route_id,
@@ -513,6 +525,11 @@ void ResourceDispatcherHost::OnDataReceivedACK(int process_id,
}
}
+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(
@@ -811,6 +828,15 @@ bool ResourceDispatcherHost::CompleteResponseStarted(URLRequest* request) {
response->response_head.content_length = request->GetExpectedContentSize();
request->GetMimeType(&response->response_head.mime_type);
+ // Make sure we don't get a file handle if LOAD_ENABLE_FILE is not set.
+ DCHECK((request->load_flags() & net::LOAD_ENABLE_DOWNLOAD_FILE) ||
+ request->response_data_file() == base::kInvalidPlatformFileValue);
+#if defined(OS_POSIX)
+ response->response_head.response_data_file.fd = request->response_data_file();
+#elif defined(OS_WIN)
+ response->response_head.response_data_file = request->response_data_file();
+#endif
+
if (request->ssl_info().cert) {
int cert_id =
CertStore::GetSharedInstance()->StoreCert(
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.h b/chrome/browser/renderer_host/resource_dispatcher_host.h
index 931401e..3d14213 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.h
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.h
@@ -237,6 +237,10 @@ class ResourceDispatcherHost : public URLRequest::Delegate {
// 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);
diff --git a/chrome/browser/renderer_host/resource_handler.h b/chrome/browser/renderer_host/resource_handler.h
index 2b843f9..e0713d9 100644
--- a/chrome/browser/renderer_host/resource_handler.h
+++ b/chrome/browser/renderer_host/resource_handler.h
@@ -14,6 +14,11 @@
#include <string>
+#include "build/build_config.h"
+#if defined(OS_POSIX)
+#include "base/file_descriptor_posix.h"
+#endif
+#include "base/platform_file.h"
#include "chrome/common/filter_policy.h"
#include "net/url_request/url_request_status.h"
#include "webkit/glue/resource_loader_bridge.h"
@@ -31,6 +36,20 @@ struct ResourceResponseHead
// Specifies if the resource should be filtered before being displayed
// (insecure resources can be filtered to keep the page secure).
FilterPolicy::Type filter_policy;
+
+ // A platform specific handle for a file that carries response data. This
+ // entry is used if the resource request is of type ResourceType::MEDIA and
+ // the underlying cache layer keeps the response data in a standalone file.
+#if defined(OS_POSIX)
+ // If the response data file is available, the file handle is stored in
+ // response_data_file.fd, its value is base::kInvalidPlatformFileValue
+ // otherwise.
+ base::FileDescriptor response_data_file;
+#elif defined(OS_WIN)
+ // An asynchronous file handle to the response data file, its value is
+ // base::kInvalidPlatformFileValue if the file is not available.
+ base::PlatformFile response_data_file;
+#endif
};
// Parameters for a synchronous resource response.
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index 02ae30a..404e68b 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -32,6 +32,7 @@
#include "chrome/common/render_messages.h"
#include "net/base/cookie_monster.h"
#include "net/base/mime_util.h"
+#include "net/base/load_flags.h"
#include "net/url_request/url_request_context.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webplugin.h"
@@ -114,11 +115,14 @@ ResourceMessageFilter::ResourceMessageFilter(
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),
render_widget_helper_(render_widget_helper),
audio_renderer_host_(audio_renderer_host) {
DCHECK(request_context_.get());
DCHECK(request_context_->cookie_store());
+ DCHECK(media_request_context_.get());
+ DCHECK(media_request_context_->cookie_store());
DCHECK(audio_renderer_host_.get());
}
@@ -188,6 +192,7 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message) {
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)
@@ -333,6 +338,16 @@ 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_,
@@ -340,7 +355,7 @@ void ResourceMessageFilter::OnRequestResource(
message.routing_id(),
request_id,
request,
- request_context_,
+ request_context,
NULL);
}
@@ -348,6 +363,11 @@ 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);
diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h
index 10a12ed..3269c89 100644
--- a/chrome/browser/renderer_host/resource_message_filter.h
+++ b/chrome/browser/renderer_host/resource_message_filter.h
@@ -101,6 +101,7 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
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,
@@ -251,6 +252,9 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
// Contextual information to be used for requests created here.
scoped_refptr<URLRequestContext> request_context_;
+ // A request context specific for media resources.
+ scoped_refptr<URLRequestContext> media_request_context_;
+
// A pointer to the profile associated with this filter.
//
// DANGER! Do not dereference this pointer! This class lives on the I/O thread