summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authordarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-25 04:23:56 +0000
committerdarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-25 04:23:56 +0000
commit094e5b2e797fd244c1ac0ec543ac91cb14e32a3e (patch)
treeccd15d7dd0ef95b889c5e51bdb85a4ce1da09378 /chrome/browser
parent320eee7c40dd3fdfef7926c526b79ca60b7a3c45 (diff)
downloadchromium_src-094e5b2e797fd244c1ac0ec543ac91cb14e32a3e.zip
chromium_src-094e5b2e797fd244c1ac0ec543ac91cb14e32a3e.tar.gz
chromium_src-094e5b2e797fd244c1ac0ec543ac91cb14e32a3e.tar.bz2
Implemented upload progress indicator in status bar.
When sending an HTTP POST request with sufficiently large payload data (such as uploading a file or several), the status bar should display the progress in the form of a percentage. The ResourceDispatcherHost periodically sends upload progress messages to the UI thread as well as to the renderer. If an upload is occurring, other potential LoadStateChanged messages to the same RenderViewHost are ignored; this prevents the upload progress display from being interrupted periodically by "Waiting for <site>" messages. Original code review: http://codereview.chromium.org/211050 Original patch by Simon Radford r=darin BUG=4715 TEST=Try uploading one or more files (e.g. at a file hosting site) and confirm that the percentage is shown in the status bar. Review URL: http://codereview.chromium.org/244001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27169 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc6
-rw-r--r--chrome/browser/renderer_host/render_view_host.h3
-rw-r--r--chrome/browser/renderer_host/render_view_host_delegate.h3
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.cc58
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.h2
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc17
-rw-r--r--chrome/browser/tab_contents/tab_contents.h7
7 files changed, 76 insertions, 20 deletions
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index 41a30f2..fba69fb 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -714,8 +714,10 @@ void RenderViewHost::MultiFilesSelected(
}
void RenderViewHost::LoadStateChanged(const GURL& url,
- net::LoadState load_state) {
- delegate_->LoadStateChanged(url, load_state);
+ net::LoadState load_state,
+ uint64 upload_position,
+ uint64 upload_size) {
+ delegate_->LoadStateChanged(url, load_state, upload_position, upload_size);
}
bool RenderViewHost::SuddenTerminationAllowed() const {
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index d22ec74..2044349 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -378,7 +378,8 @@ class RenderViewHost : public RenderWidgetHost,
void MultiFilesSelected(const std::vector<FilePath>& files);
// Notifies the RenderViewHost that its load state changed.
- void LoadStateChanged(const GURL& url, net::LoadState load_state);
+ void LoadStateChanged(const GURL& url, net::LoadState load_state,
+ uint64 upload_position, uint64 upload_size);
bool SuddenTerminationAllowed() const;
void set_sudden_termination_allowed(bool enabled) {
diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h
index 74dc44e..d38d4f6 100644
--- a/chrome/browser/renderer_host/render_view_host_delegate.h
+++ b/chrome/browser/renderer_host/render_view_host_delegate.h
@@ -537,7 +537,8 @@ class RenderViewHostDelegate {
virtual void RendererResponsive(RenderViewHost* render_view_host) {}
// Notification that the RenderViewHost's load state changed.
- virtual void LoadStateChanged(const GURL& url, net::LoadState load_state) {}
+ virtual void LoadStateChanged(const GURL& url, net::LoadState load_state,
+ uint64 upload_position, uint64 upload_size) {}
// Returns true if this view is used to host an external tab container.
virtual bool IsExternalTabContainer() const;
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc
index bac4f62..1acecbc 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.cc
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc
@@ -1579,6 +1579,8 @@ net::LoadState MoreInterestingLoadState(net::LoadState a, net::LoadState b) {
struct LoadInfo {
GURL url;
net::LoadState load_state;
+ uint64 upload_position;
+ uint64 upload_size;
};
// Map from ProcessID+ViewID pair to LoadState
@@ -1594,7 +1596,9 @@ class LoadInfoUpdateTask : public Task {
RenderViewHost* view =
RenderViewHost::FromID(i->first.first, i->first.second);
if (view) // The view could be gone at this point.
- view->LoadStateChanged(i->second.url, i->second.load_state);
+ view->LoadStateChanged(i->second.url, i->second.load_state,
+ i->second.upload_position,
+ i->second.upload_size);
}
}
LoadInfoMap info_map;
@@ -1608,6 +1612,21 @@ void ResourceDispatcherHost::UpdateLoadStates() {
LoadInfoMap info_map;
PendingRequestList::const_iterator i;
+
+ // Determine the largest upload size of all requests
+ // in each View (good chance it's zero).
+ std::map<std::pair<int, int>, uint64> largest_upload_size;
+ for (i = pending_requests_.begin(); i != pending_requests_.end(); ++i) {
+ URLRequest* request = i->second;
+ ResourceDispatcherHostRequestInfo* info = InfoForRequest(request);
+ uint64 upload_size = info->upload_size();
+ if (request->GetLoadState() != net::LOAD_STATE_SENDING_REQUEST)
+ upload_size = 0;
+ std::pair<int, int> key(info->child_id(), info->route_id());
+ if (upload_size && largest_upload_size[key] < upload_size)
+ largest_upload_size[key] = upload_size;
+ }
+
for (i = pending_requests_.begin(); i != pending_requests_.end(); ++i) {
URLRequest* request = i->second;
net::LoadState load_state = request->GetLoadState();
@@ -1615,12 +1634,19 @@ void ResourceDispatcherHost::UpdateLoadStates() {
// We also poll for upload progress on this timer and send upload
// progress ipc messages to the plugin process.
- MaybeUpdateUploadProgress(info, request);
+ bool update_upload_progress = MaybeUpdateUploadProgress(info, request);
+
+ if (info->last_load_state() != load_state || update_upload_progress) {
+ std::pair<int, int> key(info->child_id(), info->route_id());
+
+ // If a request is uploading data, ignore all other requests so that the
+ // upload progress takes priority for being shown in the status bar.
+ if (largest_upload_size.find(key) != largest_upload_size.end() &&
+ info->upload_size() < largest_upload_size[key])
+ continue;
- if (info->last_load_state() != load_state) {
info->set_last_load_state(load_state);
- std::pair<int, int> key(info->child_id(), info->route_id());
net::LoadState to_insert;
LoadInfoMap::iterator existing = info_map.find(key);
if (existing == info_map.end()) {
@@ -1634,6 +1660,8 @@ void ResourceDispatcherHost::UpdateLoadStates() {
LoadInfo& load_info = info_map[key];
load_info.url = request->url();
load_info.load_state = to_insert;
+ load_info.upload_size = info->upload_size();
+ load_info.upload_position = request->GetUploadProgress();
}
}
@@ -1645,17 +1673,19 @@ void ResourceDispatcherHost::UpdateLoadStates() {
ui_loop_->PostTask(FROM_HERE, task);
}
-void ResourceDispatcherHost::MaybeUpdateUploadProgress(
+// Calls the ResourceHandler to send upload progress messages to the renderer.
+// Returns true iff an upload progress message should be sent to the UI thread.
+bool ResourceDispatcherHost::MaybeUpdateUploadProgress(
ResourceDispatcherHostRequestInfo *info,
URLRequest *request) {
- if (!info->upload_size() || info->waiting_for_upload_progress_ack() ||
- !(request->load_flags() & net::LOAD_ENABLE_UPLOAD_PROGRESS))
- return;
+
+ if (!info->upload_size() || info->waiting_for_upload_progress_ack())
+ return false;
uint64 size = info->upload_size();
uint64 position = request->GetUploadProgress();
if (position == info->last_upload_position())
- return; // no progress made since last time
+ return false; // no progress made since last time
const uint64 kHalfPercentIncrements = 200;
const TimeDelta kOneSecond = TimeDelta::FromMilliseconds(1000);
@@ -1668,12 +1698,16 @@ void ResourceDispatcherHost::MaybeUpdateUploadProgress(
bool too_much_time_passed = time_since_last > kOneSecond;
if (is_finished || enough_new_progress || too_much_time_passed) {
- info->resource_handler()->OnUploadProgress(info->request_id(),
- position, size);
- info->set_waiting_for_upload_progress_ack(true);
+ if (request->load_flags() & net::LOAD_ENABLE_UPLOAD_PROGRESS) {
+ info->resource_handler()->OnUploadProgress(info->request_id(),
+ position, size);
+ info->set_waiting_for_upload_progress_ack(true);
+ }
info->set_last_upload_ticks(TimeTicks::Now());
info->set_last_upload_position(position);
+ return true;
}
+ return false;
}
void ResourceDispatcherHost::BlockRequestsForRoute(int child_id, int route_id) {
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.h b/chrome/browser/renderer_host/resource_dispatcher_host.h
index 98f59fe..fc86453 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.h
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.h
@@ -381,7 +381,7 @@ class ResourceDispatcherHost : public URLRequest::Delegate {
void UpdateLoadStates();
// Checks the upload state and sends an update if one is necessary.
- void MaybeUpdateUploadProgress(ResourceDispatcherHostRequestInfo *info,
+ bool MaybeUpdateUploadProgress(ResourceDispatcherHostRequestInfo *info,
URLRequest *request);
// Resumes or cancels (if |cancel_requests| is true) any blocked requests.
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index e80deda..2483d47 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -237,6 +237,8 @@ TabContents::TabContents(Profile* profile,
current_load_start_(),
load_state_(net::LOAD_STATE_IDLE),
load_state_host_(),
+ upload_size_(0),
+ upload_position_(0),
received_page_title_(false),
is_starred_(false),
contents_mime_type_(),
@@ -553,7 +555,12 @@ std::wstring TabContents::GetStatusText() const {
case net::LOAD_STATE_CONNECTING:
return l10n_util::GetString(IDS_LOAD_STATE_CONNECTING);
case net::LOAD_STATE_SENDING_REQUEST:
- return l10n_util::GetString(IDS_LOAD_STATE_SENDING_REQUEST);
+ if (upload_size_)
+ return l10n_util::GetStringF(
+ IDS_LOAD_STATE_SENDING_REQUEST_WITH_PROGRESS,
+ static_cast<int>((100 * upload_position_) / upload_size_));
+ else
+ return l10n_util::GetString(IDS_LOAD_STATE_SENDING_REQUEST);
case net::LOAD_STATE_WAITING_FOR_RESPONSE:
return l10n_util::GetStringF(IDS_LOAD_STATE_WAITING_FOR_RESPONSE,
load_state_host_);
@@ -1161,6 +1168,8 @@ void TabContents::SetIsLoading(bool is_loading,
if (!is_loading) {
load_state_ = net::LOAD_STATE_IDLE;
load_state_host_.clear();
+ upload_size_ = 0;
+ upload_position_ = 0;
}
render_manager_.SetIsLoading(is_loading);
@@ -2384,8 +2393,12 @@ void TabContents::RendererResponsive(RenderViewHost* render_view_host) {
}
void TabContents::LoadStateChanged(const GURL& url,
- net::LoadState load_state) {
+ net::LoadState load_state,
+ uint64 upload_position,
+ uint64 upload_size) {
load_state_ = load_state;
+ upload_position_ = upload_position;
+ upload_size_ = upload_size;
std::wstring languages =
profile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
load_state_host_.clear();
diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h
index cd8ec58..1d39921 100644
--- a/chrome/browser/tab_contents/tab_contents.h
+++ b/chrome/browser/tab_contents/tab_contents.h
@@ -894,7 +894,8 @@ class TabContents : public PageNavigator,
virtual void RendererUnresponsive(RenderViewHost* render_view_host,
bool is_during_unload);
virtual void RendererResponsive(RenderViewHost* render_view_host);
- virtual void LoadStateChanged(const GURL& url, net::LoadState load_state);
+ virtual void LoadStateChanged(const GURL& url, net::LoadState load_state,
+ uint64 upload_position, uint64 upload_size);
virtual bool IsExternalTabContainer() const;
virtual void DidInsertCSS();
virtual void FocusedNodeChanged();
@@ -1020,6 +1021,10 @@ class TabContents : public PageNavigator,
// The current load state and the URL associated with it.
net::LoadState load_state_;
std::wstring load_state_host_;
+ // Upload progress, for displaying in the status bar.
+ // Set to zero when there is no significant upload happening.
+ uint64 upload_size_;
+ uint64 upload_position_;
// Data for current page -----------------------------------------------------