diff options
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_; }; //----------------------------------------------------------------------------- |