diff options
author | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-12 19:54:57 +0000 |
---|---|---|
committer | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-12 19:54:57 +0000 |
commit | 89c7ed00c4d37c0b917d4a681d94d6a4ce782c33 (patch) | |
tree | a5fe16a1fcbed0acb5a111830fc7d2b3c4ca8fba /webkit | |
parent | 4a66920f66fe2c5db40f4e8c0efa9cb5d7bebfcb (diff) | |
download | chromium_src-89c7ed00c4d37c0b917d4a681d94d6a4ce782c33.zip chromium_src-89c7ed00c4d37c0b917d4a681d94d6a4ce782c33.tar.gz chromium_src-89c7ed00c4d37c0b917d4a681d94d6a4ce782c33.tar.bz2 |
WebKit resource requests now have a flag reportUploadProgress that tells us whether we should turn on the reporting of upload progress updates.
This CL adds plumbing in the SimpleResourceLoader for reporting upload progress updates, as is already done in ResourceDispatcherHost.
This makes 3 layout tests (XMLHttpRequest related) pass.
BUG=None
TEST=Run the layout tests.
Review URL: http://codereview.chromium.org/28341
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11567 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/glue/resource_handle_impl.cc | 9 | ||||
-rw-r--r-- | webkit/glue/resource_loader_bridge.h | 2 | ||||
-rw-r--r-- | webkit/tools/test_shell/simple_resource_loader_bridge.cc | 59 |
3 files changed, 68 insertions, 2 deletions
diff --git a/webkit/glue/resource_handle_impl.cc b/webkit/glue/resource_handle_impl.cc index dbc8606..961e788 100644 --- a/webkit/glue/resource_handle_impl.cc +++ b/webkit/glue/resource_handle_impl.cc @@ -222,6 +222,7 @@ class ResourceHandleInternal : public ResourceLoaderBridge::Peer { void SetDefersLoading(bool value); // ResourceLoaderBridge::Peer implementation + virtual void OnUploadProgress(uint64 position, uint64 size); virtual void OnReceivedRedirect(const GURL& new_url); virtual void OnReceivedResponse( const ResourceLoaderBridge::ResponseInfo& info, @@ -358,6 +359,9 @@ bool ResourceHandleInternal::Start( break; } + if (request_.reportUploadProgress()) + load_flags_ |= net::LOAD_ENABLE_UPLOAD_PROGRESS; + // Translate the table of request headers to a formatted string blob String headerBuf; const HTTPHeaderMap& headerMap = request_.httpHeaderFields(); @@ -511,6 +515,11 @@ void ResourceHandleInternal::SetDefersLoading(bool value) { // ResourceLoaderBridge::Peer impl -------------------------------------------- +void ResourceHandleInternal::OnUploadProgress(uint64 position, uint64 size) { + if (client_) + client_->didSendData(job_, position, size); +} + void ResourceHandleInternal::OnReceivedRedirect(const GURL& new_url) { DCHECK(pending_); diff --git a/webkit/glue/resource_loader_bridge.h b/webkit/glue/resource_loader_bridge.h index d5ca181..8d32f0c 100644 --- a/webkit/glue/resource_loader_bridge.h +++ b/webkit/glue/resource_loader_bridge.h @@ -93,7 +93,7 @@ class ResourceLoaderBridge { // Called as upload progress is made. // note: only for requests with LOAD_ENABLE_UPLOAD_PROGRESS set - virtual void OnUploadProgress(uint64 position, uint64 size) {}; + virtual void OnUploadProgress(uint64 position, uint64 size) = 0; // Called when a redirect occurs. virtual void OnReceivedRedirect(const GURL& new_url) = 0; diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc index 2e94f3f..0c10c966 100644 --- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc +++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc @@ -34,10 +34,12 @@ #include "base/message_loop.h" #include "base/ref_counted.h" +#include "base/time.h" #include "base/thread.h" #include "base/waitable_event.h" #include "net/base/cookie_monster.h" #include "net/base/io_buffer.h" +#include "net/base/load_flags.h" #include "net/base/net_util.h" #include "net/base/upload_data.h" #include "net/http/http_response_headers.h" @@ -100,6 +102,9 @@ struct RequestParams { scoped_refptr<net::UploadData> upload; }; +// The interval for calls to RequestProxy::MaybeUpdateUploadProgress +static const int kUpdateUploadProgressIntervalMsec = 100; + // The RequestProxy does most of its work on the IO thread. The Start and // Cancel methods are proxied over to the IO thread, where an URLRequest object // is instantiated. @@ -107,7 +112,9 @@ class RequestProxy : public URLRequest::Delegate, public base::RefCountedThreadSafe<RequestProxy> { public: // Takes ownership of the params. - RequestProxy() : buf_(new net::IOBuffer(kDataSize)) { + RequestProxy() + : buf_(new net::IOBuffer(kDataSize)), + last_upload_position_(0) { } virtual ~RequestProxy() { @@ -181,6 +188,11 @@ class RequestProxy : public URLRequest::Delegate, } } + void NotifyUploadProgress(uint64 position, uint64 size) { + if (peer_) + peer_->OnUploadProgress(position, size); + } + // -------------------------------------------------------------------------- // The following methods are called on the io thread. They correspond to // actions performed on the owner's thread. @@ -196,6 +208,13 @@ class RequestProxy : public URLRequest::Delegate, request_->set_context(request_context); request_->Start(); + if (request_->has_upload() && + params->load_flags & net::LOAD_ENABLE_UPLOAD_PROGRESS) { + upload_progress_timer_.Start( + base::TimeDelta::FromMilliseconds(kUpdateUploadProgressIntervalMsec), + this, &RequestProxy::MaybeUpdateUploadProgress); + } + delete params; } @@ -290,11 +309,42 @@ class RequestProxy : public URLRequest::Delegate, // Helpers and data: void Done() { + if (upload_progress_timer_.IsRunning()) { + MaybeUpdateUploadProgress(); + upload_progress_timer_.Stop(); + } DCHECK(request_.get()); OnCompletedRequest(request_->status(), std::string()); request_.reset(); // destroy on the io thread } + // Called on the IO thread. + void MaybeUpdateUploadProgress() { + uint64 size = request_->get_upload()->GetContentLength(); + uint64 position = request_->GetUploadProgress(); + if (position == last_upload_position_) + return; // no progress made since last time + + const uint64 kHalfPercentIncrements = 200; + const base::TimeDelta kOneSecond = base::TimeDelta::FromMilliseconds(1000); + + uint64 amt_since_last = position - last_upload_position_; + base::TimeDelta time_since_last = base::TimeTicks::Now() - + last_upload_ticks_; + + bool is_finished = (size == position); + bool enough_new_progress = (amt_since_last > (size / + kHalfPercentIncrements)); + bool too_much_time_passed = time_since_last > kOneSecond; + + if (is_finished || enough_new_progress || too_much_time_passed) { + owner_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, &RequestProxy::NotifyUploadProgress, position, size)); + last_upload_ticks_ = base::TimeTicks::Now(); + last_upload_position_ = position; + } + } + scoped_ptr<URLRequest> request_; // Size of our async IO data buffers @@ -309,6 +359,13 @@ class RequestProxy : public URLRequest::Delegate, // not manage its lifetime, and we may only access it from the owner's // message loop (owner_loop_). ResourceLoaderBridge::Peer* peer_; + + // Timer used to pull upload progress info. + base::RepeatingTimer<RequestProxy> upload_progress_timer_; + + // Info used to determine whether or not to send an upload progress update. + uint64 last_upload_position_; + base::TimeTicks last_upload_ticks_; }; //----------------------------------------------------------------------------- |