Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Side by Side Diff: chrome/browser/renderer_host/resource_dispatcher_host.cc

Issue 211050: Implemented upload progress indicator in status bar. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading
6 6
7 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" 7 #include "chrome/browser/renderer_host/resource_dispatcher_host.h"
8 8
9 #include <vector> 9 #include <vector>
10 10
(...skipping 1561 matching lines...) Expand 10 before | Expand all | Expand 10 after
1572 // whereas waiting for a host name to resolve implies being stuck. 1572 // whereas waiting for a host name to resolve implies being stuck.
1573 // 1573 //
1574 net::LoadState MoreInterestingLoadState(net::LoadState a, net::LoadState b) { 1574 net::LoadState MoreInterestingLoadState(net::LoadState a, net::LoadState b) {
1575 return (a < b) ? b : a; 1575 return (a < b) ? b : a;
1576 } 1576 }
1577 1577
1578 // Carries information about a load state change. 1578 // Carries information about a load state change.
1579 struct LoadInfo { 1579 struct LoadInfo {
1580 GURL url; 1580 GURL url;
1581 net::LoadState load_state; 1581 net::LoadState load_state;
1582 uint64 upload_position;
1583 uint64 upload_size;
1582 }; 1584 };
1583 1585
1584 // Map from ProcessID+ViewID pair to LoadState 1586 // Map from ProcessID+ViewID pair to LoadState
1585 typedef std::map<std::pair<int, int>, LoadInfo> LoadInfoMap; 1587 typedef std::map<std::pair<int, int>, LoadInfo> LoadInfoMap;
1586 1588
1587 // Used to marshall calls to LoadStateChanged from the IO to UI threads. We do 1589 // Used to marshall calls to LoadStateChanged from the IO to UI threads. We do
1588 // them all as a single task to avoid spamming the UI thread. 1590 // them all as a single task to avoid spamming the UI thread.
1589 class LoadInfoUpdateTask : public Task { 1591 class LoadInfoUpdateTask : public Task {
1590 public: 1592 public:
1591 virtual void Run() { 1593 virtual void Run() {
1592 LoadInfoMap::const_iterator i; 1594 LoadInfoMap::const_iterator i;
1593 for (i = info_map.begin(); i != info_map.end(); ++i) { 1595 for (i = info_map.begin(); i != info_map.end(); ++i) {
1594 RenderViewHost* view = 1596 RenderViewHost* view =
1595 RenderViewHost::FromID(i->first.first, i->first.second); 1597 RenderViewHost::FromID(i->first.first, i->first.second);
1596 if (view) // The view could be gone at this point. 1598 if (view) // The view could be gone at this point.
1597 view->LoadStateChanged(i->second.url, i->second.load_state); 1599 view->LoadStateChanged(i->second.url, i->second.load_state,
1600 i->second.upload_position,
1601 i->second.upload_size);
1598 } 1602 }
1599 } 1603 }
1600 LoadInfoMap info_map; 1604 LoadInfoMap info_map;
1601 }; 1605 };
1602 1606
1603 } // namespace 1607 } // namespace
1604 1608
1605 void ResourceDispatcherHost::UpdateLoadStates() { 1609 void ResourceDispatcherHost::UpdateLoadStates() {
1606 // Populate this map with load state changes, and then send them on to the UI 1610 // Populate this map with load state changes, and then send them on to the UI
1607 // thread where they can be passed along to the respective RVHs. 1611 // thread where they can be passed along to the respective RVHs.
1608 LoadInfoMap info_map; 1612 LoadInfoMap info_map;
1609 1613
1610 PendingRequestList::const_iterator i; 1614 PendingRequestList::const_iterator i;
1615
1616 // Determine the largest upload size of all requests
1617 // in each View (good chance it's zero).
1618 std::map<std::pair<int, int>, uint64> largest_upload_size;
1619 for (i = pending_requests_.begin(); i != pending_requests_.end(); ++i) {
1620 URLRequest* request = i->second;
1621 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request);
1622 uint64 upload_size = info->upload_size();
1623 if (request->GetLoadState() != net::LOAD_STATE_SENDING_REQUEST)
1624 upload_size = 0;
1625 std::pair<int, int> key(info->child_id(), info->route_id());
1626 if (upload_size && largest_upload_size[key] < upload_size)
1627 largest_upload_size[key] = upload_size;
1628 }
1629
1611 for (i = pending_requests_.begin(); i != pending_requests_.end(); ++i) { 1630 for (i = pending_requests_.begin(); i != pending_requests_.end(); ++i) {
1612 URLRequest* request = i->second; 1631 URLRequest* request = i->second;
1613 net::LoadState load_state = request->GetLoadState(); 1632 net::LoadState load_state = request->GetLoadState();
1614 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); 1633 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request);
1615 1634
1616 // We also poll for upload progress on this timer and send upload 1635 // We also poll for upload progress on this timer and send upload
1617 // progress ipc messages to the plugin process. 1636 // progress ipc messages to the plugin process.
1618 MaybeUpdateUploadProgress(info, request); 1637 bool update_upload_progress = MaybeUpdateUploadProgress(info, request);
1619 1638
1620 if (info->last_load_state() != load_state) { 1639 if (info->last_load_state() != load_state || update_upload_progress) {
1640 std::pair<int, int> key(info->child_id(), info->route_id());
1641
1642 // If a request is uploading data, ignore all other requests so that the
1643 // upload progress takes priority for being shown in the status bar.
1644 if (largest_upload_size.find(key) != largest_upload_size.end() &&
1645 info->upload_size() < largest_upload_size[key])
1646 continue;
1647
1621 info->set_last_load_state(load_state); 1648 info->set_last_load_state(load_state);
1622 1649
1623 std::pair<int, int> key(info->child_id(), info->route_id());
1624 net::LoadState to_insert; 1650 net::LoadState to_insert;
1625 LoadInfoMap::iterator existing = info_map.find(key); 1651 LoadInfoMap::iterator existing = info_map.find(key);
1626 if (existing == info_map.end()) { 1652 if (existing == info_map.end()) {
1627 to_insert = load_state; 1653 to_insert = load_state;
1628 } else { 1654 } else {
1629 to_insert = 1655 to_insert =
1630 MoreInterestingLoadState(existing->second.load_state, load_state); 1656 MoreInterestingLoadState(existing->second.load_state, load_state);
1631 if (to_insert == existing->second.load_state) 1657 if (to_insert == existing->second.load_state)
1632 continue; 1658 continue;
1633 } 1659 }
1634 LoadInfo& load_info = info_map[key]; 1660 LoadInfo& load_info = info_map[key];
1635 load_info.url = request->url(); 1661 load_info.url = request->url();
1636 load_info.load_state = to_insert; 1662 load_info.load_state = to_insert;
1663 load_info.upload_size = info->upload_size();
1664 load_info.upload_position = request->GetUploadProgress();
1637 } 1665 }
1638 } 1666 }
1639 1667
1640 if (info_map.empty()) 1668 if (info_map.empty())
1641 return; 1669 return;
1642 1670
1643 LoadInfoUpdateTask* task = new LoadInfoUpdateTask; 1671 LoadInfoUpdateTask* task = new LoadInfoUpdateTask;
1644 task->info_map.swap(info_map); 1672 task->info_map.swap(info_map);
1645 ui_loop_->PostTask(FROM_HERE, task); 1673 ui_loop_->PostTask(FROM_HERE, task);
1646 } 1674 }
1647 1675
1648 void ResourceDispatcherHost::MaybeUpdateUploadProgress( 1676 // Calls the ResourceHandler to send upload progress messages to the renderer.
1677 // Returns true iff an upload progress message should be sent to the UI thread.
1678 bool ResourceDispatcherHost::MaybeUpdateUploadProgress(
1649 ResourceDispatcherHostRequestInfo *info, 1679 ResourceDispatcherHostRequestInfo *info,
1650 URLRequest *request) { 1680 URLRequest *request) {
1651 if (!info->upload_size() || info->waiting_for_upload_progress_ack() || 1681
1652 !(request->load_flags() & net::LOAD_ENABLE_UPLOAD_PROGRESS)) 1682 if (!info->upload_size() || info->waiting_for_upload_progress_ack())
1653 return; 1683 return false;
1654 1684
1655 uint64 size = info->upload_size(); 1685 uint64 size = info->upload_size();
1656 uint64 position = request->GetUploadProgress(); 1686 uint64 position = request->GetUploadProgress();
1657 if (position == info->last_upload_position()) 1687 if (position == info->last_upload_position())
1658 return; // no progress made since last time 1688 return false; // no progress made since last time
1659 1689
1660 const uint64 kHalfPercentIncrements = 200; 1690 const uint64 kHalfPercentIncrements = 200;
1661 const TimeDelta kOneSecond = TimeDelta::FromMilliseconds(1000); 1691 const TimeDelta kOneSecond = TimeDelta::FromMilliseconds(1000);
1662 1692
1663 uint64 amt_since_last = position - info->last_upload_position(); 1693 uint64 amt_since_last = position - info->last_upload_position();
1664 TimeDelta time_since_last = TimeTicks::Now() - info->last_upload_ticks(); 1694 TimeDelta time_since_last = TimeTicks::Now() - info->last_upload_ticks();
1665 1695
1666 bool is_finished = (size == position); 1696 bool is_finished = (size == position);
1667 bool enough_new_progress = (amt_since_last > (size / kHalfPercentIncrements)); 1697 bool enough_new_progress = (amt_since_last > (size / kHalfPercentIncrements));
1668 bool too_much_time_passed = time_since_last > kOneSecond; 1698 bool too_much_time_passed = time_since_last > kOneSecond;
1669 1699
1670 if (is_finished || enough_new_progress || too_much_time_passed) { 1700 if (is_finished || enough_new_progress || too_much_time_passed) {
1671 info->resource_handler()->OnUploadProgress(info->request_id(), 1701 if (request->load_flags() & net::LOAD_ENABLE_UPLOAD_PROGRESS) {
1672 position, size); 1702 info->resource_handler()->OnUploadProgress(info->request_id(),
1673 info->set_waiting_for_upload_progress_ack(true); 1703 position, size);
1704 info->set_waiting_for_upload_progress_ack(true);
1705 }
1674 info->set_last_upload_ticks(TimeTicks::Now()); 1706 info->set_last_upload_ticks(TimeTicks::Now());
1675 info->set_last_upload_position(position); 1707 info->set_last_upload_position(position);
1708 return true;
1676 } 1709 }
1710 return false;
1677 } 1711 }
1678 1712
1679 void ResourceDispatcherHost::BlockRequestsForRoute(int child_id, int route_id) { 1713 void ResourceDispatcherHost::BlockRequestsForRoute(int child_id, int route_id) {
1680 std::pair<int, int> key(child_id, route_id); 1714 std::pair<int, int> key(child_id, route_id);
1681 DCHECK(blocked_requests_map_.find(key) == blocked_requests_map_.end()) << 1715 DCHECK(blocked_requests_map_.find(key) == blocked_requests_map_.end()) <<
1682 "BlockRequestsForRoute called multiple time for the same RVH"; 1716 "BlockRequestsForRoute called multiple time for the same RVH";
1683 blocked_requests_map_[key] = new BlockedRequestsList(); 1717 blocked_requests_map_[key] = new BlockedRequestsList();
1684 } 1718 }
1685 1719
1686 void ResourceDispatcherHost::ResumeBlockedRequestsForRoute(int child_id, 1720 void ResourceDispatcherHost::ResumeBlockedRequestsForRoute(int child_id,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 case ViewHostMsg_UploadProgress_ACK::ID: 1773 case ViewHostMsg_UploadProgress_ACK::ID:
1740 case ViewHostMsg_SyncLoad::ID: 1774 case ViewHostMsg_SyncLoad::ID:
1741 return true; 1775 return true;
1742 1776
1743 default: 1777 default:
1744 break; 1778 break;
1745 } 1779 }
1746 1780
1747 return false; 1781 return false;
1748 } 1782 }
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/resource_dispatcher_host.h ('k') | chrome/browser/tab_contents/tab_contents.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698