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

Side by Side Diff: content/browser/loader/resource_scheduler.cc

Issue 465363003: ResourceScheduler get visual signal from RenderViewHostImpl (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add VisualObserver Created 6 years, 4 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include <set> 5 #include <set>
6 6
7 #include "content/browser/loader/resource_scheduler.h" 7 #include "content/browser/loader/resource_scheduler.h"
8 8
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "content/common/resource_messages.h" 10 #include "content/common/resource_messages.h"
11 #include "content/browser/loader/resource_message_delegate.h" 11 #include "content/browser/loader/resource_message_delegate.h"
12 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/resource_controller.h" 13 #include "content/public/browser/resource_controller.h"
13 #include "content/public/browser/resource_request_info.h" 14 #include "content/public/browser/resource_request_info.h"
14 #include "content/public/browser/resource_throttle.h" 15 #include "content/public/browser/resource_throttle.h"
16 #include "content/public/browser/web_contents_observer.h"
15 #include "ipc/ipc_message_macros.h" 17 #include "ipc/ipc_message_macros.h"
16 #include "net/base/host_port_pair.h" 18 #include "net/base/host_port_pair.h"
17 #include "net/base/load_flags.h" 19 #include "net/base/load_flags.h"
18 #include "net/base/request_priority.h" 20 #include "net/base/request_priority.h"
19 #include "net/http/http_server_properties.h" 21 #include "net/http/http_server_properties.h"
20 #include "net/url_request/url_request.h" 22 #include "net/url_request/url_request.h"
21 #include "net/url_request/url_request_context.h" 23 #include "net/url_request/url_request_context.h"
22 24
23 namespace content { 25 namespace content {
24 26
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 return a->fifo_ordering() < b->fifo_ordering(); 222 return a->fifo_ordering() < b->fifo_ordering();
221 } 223 }
222 224
223 void ResourceScheduler::RequestQueue::Insert( 225 void ResourceScheduler::RequestQueue::Insert(
224 ScheduledResourceRequest* request) { 226 ScheduledResourceRequest* request) {
225 DCHECK(!ContainsKey(pointers_, request)); 227 DCHECK(!ContainsKey(pointers_, request));
226 request->set_fifo_ordering(MakeFifoOrderingId()); 228 request->set_fifo_ordering(MakeFifoOrderingId());
227 pointers_[request] = queue_.insert(request); 229 pointers_[request] = queue_.insert(request);
228 } 230 }
229 231
232 // VisualObserver lives on UI thread
233 class ResourceScheduler::VisualObserver : public content::WebContentsObserver {
234 public:
235 explicit VisualObserver(WebContentsImpl* web_contents);
236 virtual ~VisualObserver() { }
237
238 void SetClient(Client* client);
239 bool IsVisible();
240
241 // WebContentsObserver implementation.
242 virtual void WasShown() OVERRIDE;
243 virtual void WasHidden() OVERRIDE;
244
245 private:
246 Client* client_;
247 };
248
230 // Each client represents a tab. 249 // Each client represents a tab.
231 class ResourceScheduler::Client { 250 class ResourceScheduler::Client {
232 public: 251 public:
233 explicit Client(ResourceScheduler* scheduler) 252 explicit Client(ResourceScheduler* scheduler,
253 VisualObserver* visual_observer,
254 bool is_visible)
234 : is_audible_(false), 255 : is_audible_(false),
235 is_visible_(false), 256 is_visible_(is_visible),
236 is_loaded_(false), 257 is_loaded_(false),
237 is_paused_(false), 258 is_paused_(false),
238 has_body_(false), 259 has_body_(false),
239 using_spdy_proxy_(false), 260 using_spdy_proxy_(false),
240 total_delayable_count_(0), 261 total_delayable_count_(0),
241 throttle_state_(ResourceScheduler::THROTTLED) { 262 throttle_state_(ResourceScheduler::THROTTLED),
263 visual_observer_(visual_observer) {
242 scheduler_ = scheduler; 264 scheduler_ = scheduler;
265 if (visual_observer)
266 BrowserThread::PostTask(
267 BrowserThread::UI, FROM_HERE,
268 base::Bind(&ResourceScheduler::VisualObserver::SetClient,
269 base::Unretained(visual_observer_),
270 base::Unretained(this)));
243 } 271 }
244 272
245 ~Client() { 273 virtual ~Client() {
246 // Update to default state and pause to ensure the scheduler has a 274 // Update to default state and pause to ensure the scheduler has a
247 // correct count of relevant types of clients. 275 // correct count of relevant types of clients.
248 is_visible_ = false; 276 is_visible_ = false;
249 is_audible_ = false; 277 is_audible_ = false;
250 is_paused_ = true; 278 is_paused_ = true;
251 UpdateThrottleState(); 279 UpdateThrottleState();
280 BrowserThread::PostTask(
281 BrowserThread::UI, FROM_HERE,
282 base::Bind(&ResourceScheduler::DeleteVisualObserver,
283 base::Unretained(scheduler_),
284 base::Unretained(visual_observer_)));
252 } 285 }
253 286
254 void ScheduleRequest( 287 void ScheduleRequest(
255 net::URLRequest* url_request, 288 net::URLRequest* url_request,
256 ScheduledResourceRequest* request) { 289 ScheduledResourceRequest* request) {
257 if (ShouldStartRequest(request) == START_REQUEST) { 290 if (ShouldStartRequest(request) == START_REQUEST) {
258 StartRequest(request); 291 StartRequest(request);
259 } else { 292 } else {
260 pending_requests_.Insert(request); 293 pending_requests_.Insert(request);
261 } 294 }
(...skipping 19 matching lines...) Expand all
281 (*it)->set_accounted_as_delayable_request(false); 314 (*it)->set_accounted_as_delayable_request(false);
282 } 315 }
283 ClearInFlightRequests(); 316 ClearInFlightRequests();
284 return unowned_requests; 317 return unowned_requests;
285 } 318 }
286 319
287 bool is_active() const { return is_visible_ || is_audible_; } 320 bool is_active() const { return is_visible_ || is_audible_; }
288 321
289 bool is_loaded() const { return is_loaded_; } 322 bool is_loaded() const { return is_loaded_; }
290 323
324 bool IsVisible() const { return is_visible_; }
325
291 void OnAudibilityChanged(bool is_audible) { 326 void OnAudibilityChanged(bool is_audible) {
292 if (is_audible == is_audible_) { 327 if (is_audible == is_audible_) {
293 return; 328 return;
294 } 329 }
295 is_audible_ = is_audible; 330 is_audible_ = is_audible;
296 UpdateThrottleState(); 331 UpdateThrottleState();
297 } 332 }
298 333
299 void OnVisibilityChanged(bool is_visible) { 334 void OnVisibilityChanged(bool is_visible) {
300 if (is_visible == is_visible_) { 335 if (is_visible == is_visible_) {
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 bool is_loaded_; 687 bool is_loaded_;
653 bool is_paused_; 688 bool is_paused_;
654 bool has_body_; 689 bool has_body_;
655 bool using_spdy_proxy_; 690 bool using_spdy_proxy_;
656 RequestQueue pending_requests_; 691 RequestQueue pending_requests_;
657 RequestSet in_flight_requests_; 692 RequestSet in_flight_requests_;
658 ResourceScheduler* scheduler_; 693 ResourceScheduler* scheduler_;
659 // The number of delayable in-flight requests. 694 // The number of delayable in-flight requests.
660 size_t total_delayable_count_; 695 size_t total_delayable_count_;
661 ResourceScheduler::ClientThrottleState throttle_state_; 696 ResourceScheduler::ClientThrottleState throttle_state_;
697 VisualObserver* visual_observer_;
662 }; 698 };
663 699
700 ResourceScheduler::VisualObserver::VisualObserver(WebContentsImpl* web_contents)
701 : client_(NULL) {
702 Observe(web_contents);
703 }
704
705 void ResourceScheduler::VisualObserver::SetClient(Client* client) {
706 client_ = client;
707 }
708
709 // WebContentsObserver implementation.
710 void ResourceScheduler::VisualObserver::WasShown() {
711 if (client_)
mmenke 2014/08/19 14:38:27 So we ignore events if the visibility changes if w
Zhen Wang 2014/08/19 17:53:41 Yes. It may happen that the Client hasn't been cre
712 BrowserThread::PostTask(
713 BrowserThread::IO, FROM_HERE,
714 base::Bind(&ResourceScheduler::Client::OnVisibilityChanged,
715 base::Unretained(client_),
716 true));
mmenke 2014/08/19 14:38:27 This isn't safe. The client may already have been
Zhen Wang 2014/08/19 17:53:41 I think you are right. I override OnRenderViewHost
717 }
718
719 // WebContentsObserver implementation.
720 void ResourceScheduler::VisualObserver::WasHidden() {
721 if (client_)
722 BrowserThread::PostTask(
723 BrowserThread::IO, FROM_HERE,
724 base::Bind(&ResourceScheduler::Client::OnVisibilityChanged,
725 base::Unretained(client_),
726 false));
727 }
728
729 ResourceScheduler::VisualObserver* ResourceScheduler::CreateVisualObserver(
730 WebContentsImpl* web_content) {
731 return new ResourceScheduler::VisualObserver(web_content);
732 }
733
734 void ResourceScheduler::DeleteVisualObserver(VisualObserver* observer) {
735 delete observer;
736 }
737
664 ResourceScheduler::ResourceScheduler() 738 ResourceScheduler::ResourceScheduler()
665 : should_coalesce_(false), 739 : should_coalesce_(false),
666 should_throttle_(false), 740 should_throttle_(false),
667 active_clients_loading_(0), 741 active_clients_loading_(0),
668 coalesced_clients_(0), 742 coalesced_clients_(0),
669 coalescing_timer_(new base::Timer(true /* retain_user_task */, 743 coalescing_timer_(new base::Timer(true /* retain_user_task */,
670 true /* is_repeating */)) { 744 true /* is_repeating */)) {
671 } 745 }
672 746
673 ResourceScheduler::~ResourceScheduler() { 747 ResourceScheduler::~ResourceScheduler() {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 798
725 ClientMap::iterator client_it = client_map_.find(request->client_id()); 799 ClientMap::iterator client_it = client_map_.find(request->client_id());
726 if (client_it == client_map_.end()) { 800 if (client_it == client_map_.end()) {
727 return; 801 return;
728 } 802 }
729 803
730 Client* client = client_it->second; 804 Client* client = client_it->second;
731 client->RemoveRequest(request); 805 client->RemoveRequest(request);
732 } 806 }
733 807
734 void ResourceScheduler::OnClientCreated(int child_id, int route_id) { 808 void ResourceScheduler::OnClientCreated(int child_id,
809 int route_id,
810 VisualObserver* visual_observer,
811 bool is_visible) {
735 DCHECK(CalledOnValidThread()); 812 DCHECK(CalledOnValidThread());
736 ClientId client_id = MakeClientId(child_id, route_id); 813 ClientId client_id = MakeClientId(child_id, route_id);
737 DCHECK(!ContainsKey(client_map_, client_id)); 814 DCHECK(!ContainsKey(client_map_, client_id));
738 815
739 Client* client = new Client(this); 816 Client* client = new Client(this, visual_observer, is_visible);
740 client_map_[client_id] = client; 817 client_map_[client_id] = client;
741 818
742 // TODO(aiolos): set Client visibility/audibility when signals are added 819 // TODO(aiolos): set Client visibility/audibility when signals are added
743 // this will UNTHROTTLE Clients as needed 820 // this will UNTHROTTLE Clients as needed
744 client->UpdateThrottleState(); 821 client->UpdateThrottleState();
745 } 822 }
746 823
747 void ResourceScheduler::OnClientDeleted(int child_id, int route_id) { 824 void ResourceScheduler::OnClientDeleted(int child_id, int route_id) {
748 DCHECK(CalledOnValidThread()); 825 DCHECK(CalledOnValidThread());
749 ClientId client_id = MakeClientId(child_id, route_id); 826 ClientId client_id = MakeClientId(child_id, route_id);
827
750 DCHECK(ContainsKey(client_map_, client_id)); 828 DCHECK(ContainsKey(client_map_, client_id));
751 ClientMap::iterator it = client_map_.find(client_id); 829 ClientMap::iterator it = client_map_.find(client_id);
752 if (it == client_map_.end()) 830 if (it == client_map_.end())
753 return; 831 return;
754 832
755 Client* client = it->second; 833 Client* client = it->second;
756 // FYI, ResourceDispatcherHost cancels all of the requests after this function 834 // FYI, ResourceDispatcherHost cancels all of the requests after this function
757 // is called. It should end up canceling all of the requests except for a 835 // is called. It should end up canceling all of the requests except for a
758 // cross-renderer navigation. 836 // cross-renderer navigation.
759 RequestSet client_unowned_requests = client->RemoveAllRequests(); 837 RequestSet client_unowned_requests = client->RemoveAllRequests();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 } 888 }
811 889
812 void ResourceScheduler::OnAudibilityChanged(int child_id, 890 void ResourceScheduler::OnAudibilityChanged(int child_id,
813 int route_id, 891 int route_id,
814 bool is_audible) { 892 bool is_audible) {
815 Client* client = GetClient(child_id, route_id); 893 Client* client = GetClient(child_id, route_id);
816 DCHECK(client); 894 DCHECK(client);
817 client->OnAudibilityChanged(is_audible); 895 client->OnAudibilityChanged(is_audible);
818 } 896 }
819 897
820 void ResourceScheduler::OnVisibilityChanged(int child_id,
821 int route_id,
822 bool is_visible) {
823 Client* client = GetClient(child_id, route_id);
824 DCHECK(client);
825 client->OnVisibilityChanged(is_visible);
826 }
827
828 void ResourceScheduler::OnLoadingStateChanged(int child_id, 898 void ResourceScheduler::OnLoadingStateChanged(int child_id,
829 int route_id, 899 int route_id,
830 bool is_loaded) { 900 bool is_loaded) {
831 Client* client = GetClient(child_id, route_id); 901 Client* client = GetClient(child_id, route_id);
832 DCHECK(client); 902 DCHECK(client);
833 client->OnLoadingStateChanged(is_loaded); 903 client->OnLoadingStateChanged(is_loaded);
834 } 904 }
835 905
906 bool ResourceScheduler::IsClientVisibleForTesting(int child_id, int route_id) {
907 Client* client = GetClient(child_id, route_id);
908 DCHECK(client);
909 return client->IsVisible();
910 }
911
836 ResourceScheduler::Client* ResourceScheduler::GetClient(int child_id, 912 ResourceScheduler::Client* ResourceScheduler::GetClient(int child_id,
837 int route_id) { 913 int route_id) {
838 ClientId client_id = MakeClientId(child_id, route_id); 914 ClientId client_id = MakeClientId(child_id, route_id);
839 ClientMap::iterator client_it = client_map_.find(client_id); 915 ClientMap::iterator client_it = client_map_.find(client_id);
840 if (client_it == client_map_.end()) { 916 if (client_it == client_map_.end()) {
841 return NULL; 917 return NULL;
842 } 918 }
843 return client_it->second; 919 return client_it->second;
844 } 920 }
845 921
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 client->ReprioritizeRequest( 1036 client->ReprioritizeRequest(
961 request, old_priority_params, new_priority_params); 1037 request, old_priority_params, new_priority_params);
962 } 1038 }
963 1039
964 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( 1040 ResourceScheduler::ClientId ResourceScheduler::MakeClientId(
965 int child_id, int route_id) { 1041 int child_id, int route_id) {
966 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; 1042 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id;
967 } 1043 }
968 1044
969 } // namespace content 1045 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/resource_scheduler.h ('k') | content/browser/loader/resource_scheduler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698