Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/resource_controller.h" | 12 #include "content/public/browser/resource_controller.h" |
| 13 #include "content/public/browser/resource_request_info.h" | 13 #include "content/public/browser/resource_request_info.h" |
| 14 #include "content/public/browser/resource_throttle.h" | 14 #include "content/public/browser/resource_throttle.h" |
| 15 #include "content/public/browser/web_contents_observer.h" | |
| 15 #include "ipc/ipc_message_macros.h" | 16 #include "ipc/ipc_message_macros.h" |
| 16 #include "net/base/host_port_pair.h" | 17 #include "net/base/host_port_pair.h" |
| 17 #include "net/base/load_flags.h" | 18 #include "net/base/load_flags.h" |
| 18 #include "net/base/request_priority.h" | 19 #include "net/base/request_priority.h" |
| 19 #include "net/http/http_server_properties.h" | 20 #include "net/http/http_server_properties.h" |
| 20 #include "net/url_request/url_request.h" | 21 #include "net/url_request/url_request.h" |
| 21 #include "net/url_request/url_request_context.h" | 22 #include "net/url_request/url_request_context.h" |
| 22 | 23 |
| 23 namespace content { | 24 namespace content { |
| 24 | 25 |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 221 } | 222 } |
| 222 | 223 |
| 223 void ResourceScheduler::RequestQueue::Insert( | 224 void ResourceScheduler::RequestQueue::Insert( |
| 224 ScheduledResourceRequest* request) { | 225 ScheduledResourceRequest* request) { |
| 225 DCHECK(!ContainsKey(pointers_, request)); | 226 DCHECK(!ContainsKey(pointers_, request)); |
| 226 request->set_fifo_ordering(MakeFifoOrderingId()); | 227 request->set_fifo_ordering(MakeFifoOrderingId()); |
| 227 pointers_[request] = queue_.insert(request); | 228 pointers_[request] = queue_.insert(request); |
| 228 } | 229 } |
| 229 | 230 |
| 230 // Each client represents a tab. | 231 // Each client represents a tab. |
| 231 class ResourceScheduler::Client { | 232 class ResourceScheduler::Client : public content::WebContentsObserver { |
| 232 public: | 233 public: |
| 233 explicit Client(ResourceScheduler* scheduler) | 234 explicit Client(ResourceScheduler* scheduler, |
| 234 : is_audible_(false), | 235 int child_id, |
| 236 int route_id, | |
| 237 WebContents* web_contents) | |
| 238 : child_id_(child_id), | |
| 239 route_id_(route_id), | |
| 240 is_audible_(false), | |
| 235 is_visible_(false), | 241 is_visible_(false), |
| 236 is_loaded_(false), | 242 is_loaded_(false), |
| 237 is_paused_(false), | 243 is_paused_(false), |
| 238 has_body_(false), | 244 has_body_(false), |
| 239 using_spdy_proxy_(false), | 245 using_spdy_proxy_(false), |
| 240 total_delayable_count_(0), | 246 total_delayable_count_(0), |
| 241 throttle_state_(ResourceScheduler::THROTTLED) { | 247 throttle_state_(ResourceScheduler::THROTTLED) { |
| 242 scheduler_ = scheduler; | 248 scheduler_ = scheduler; |
| 249 Observe(web_contents); | |
|
aiolos (Not reviewing)
2014/08/13 21:40:33
Do you need to set the initial visibility on Clien
Zhen Wang
2014/08/14 22:19:52
I set the visibility here now. Test added.
On 201
| |
| 243 } | 250 } |
| 244 | 251 |
| 245 ~Client() { | 252 virtual ~Client() { |
| 246 // Update to default state and pause to ensure the scheduler has a | 253 // Update to default state and pause to ensure the scheduler has a |
| 247 // correct count of relevant types of clients. | 254 // correct count of relevant types of clients. |
| 248 is_visible_ = false; | 255 is_visible_ = false; |
| 249 is_audible_ = false; | 256 is_audible_ = false; |
| 250 is_paused_ = true; | 257 is_paused_ = true; |
| 251 UpdateThrottleState(); | 258 UpdateThrottleState(); |
| 252 } | 259 } |
| 253 | 260 |
| 261 // WebContentsObserver implementation. | |
| 262 virtual void WasShown() OVERRIDE { | |
| 263 scheduler_->OnVisibilityChanged(child_id_, route_id_, true); | |
|
aiolos (Not reviewing)
2014/08/13 21:40:33
This makes a longer loop than needed to set the in
Zhen Wang
2014/08/14 22:19:52
Done.
| |
| 264 } | |
| 265 | |
| 266 // WebContentsObserver implementation. | |
| 267 virtual void WasHidden() OVERRIDE { | |
| 268 scheduler_->OnVisibilityChanged(child_id_, route_id_, false); | |
|
aiolos (Not reviewing)
2014/08/13 21:40:33
Same as above.
Zhen Wang
2014/08/14 22:19:52
Done.
| |
| 269 } | |
| 270 | |
| 254 void ScheduleRequest( | 271 void ScheduleRequest( |
| 255 net::URLRequest* url_request, | 272 net::URLRequest* url_request, |
| 256 ScheduledResourceRequest* request) { | 273 ScheduledResourceRequest* request) { |
| 257 if (ShouldStartRequest(request) == START_REQUEST) { | 274 if (ShouldStartRequest(request) == START_REQUEST) { |
| 258 StartRequest(request); | 275 StartRequest(request); |
| 259 } else { | 276 } else { |
| 260 pending_requests_.Insert(request); | 277 pending_requests_.Insert(request); |
| 261 } | 278 } |
| 262 } | 279 } |
| 263 | 280 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 281 (*it)->set_accounted_as_delayable_request(false); | 298 (*it)->set_accounted_as_delayable_request(false); |
| 282 } | 299 } |
| 283 ClearInFlightRequests(); | 300 ClearInFlightRequests(); |
| 284 return unowned_requests; | 301 return unowned_requests; |
| 285 } | 302 } |
| 286 | 303 |
| 287 bool is_active() const { return is_visible_ || is_audible_; } | 304 bool is_active() const { return is_visible_ || is_audible_; } |
| 288 | 305 |
| 289 bool is_loaded() const { return is_loaded_; } | 306 bool is_loaded() const { return is_loaded_; } |
| 290 | 307 |
| 308 bool IsVisible() const { return is_visible_; } | |
| 309 | |
| 291 void OnAudibilityChanged(bool is_audible) { | 310 void OnAudibilityChanged(bool is_audible) { |
| 292 if (is_audible == is_audible_) { | 311 if (is_audible == is_audible_) { |
| 293 return; | 312 return; |
| 294 } | 313 } |
| 295 is_audible_ = is_audible; | 314 is_audible_ = is_audible; |
| 296 UpdateThrottleState(); | 315 UpdateThrottleState(); |
| 297 } | 316 } |
| 298 | 317 |
| 299 void OnVisibilityChanged(bool is_visible) { | 318 void OnVisibilityChanged(bool is_visible) { |
| 300 if (is_visible == is_visible_) { | 319 if (is_visible == is_visible_) { |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 640 } else if (query_result == DO_NOT_START_REQUEST_AND_KEEP_SEARCHING) { | 659 } else if (query_result == DO_NOT_START_REQUEST_AND_KEEP_SEARCHING) { |
| 641 ++request_iter; | 660 ++request_iter; |
| 642 continue; | 661 continue; |
| 643 } else { | 662 } else { |
| 644 DCHECK(query_result == DO_NOT_START_REQUEST_AND_STOP_SEARCHING); | 663 DCHECK(query_result == DO_NOT_START_REQUEST_AND_STOP_SEARCHING); |
| 645 break; | 664 break; |
| 646 } | 665 } |
| 647 } | 666 } |
| 648 } | 667 } |
| 649 | 668 |
| 669 const int child_id_; | |
| 670 const int route_id_; | |
| 650 bool is_audible_; | 671 bool is_audible_; |
| 651 bool is_visible_; | 672 bool is_visible_; |
| 652 bool is_loaded_; | 673 bool is_loaded_; |
| 653 bool is_paused_; | 674 bool is_paused_; |
| 654 bool has_body_; | 675 bool has_body_; |
| 655 bool using_spdy_proxy_; | 676 bool using_spdy_proxy_; |
| 656 RequestQueue pending_requests_; | 677 RequestQueue pending_requests_; |
| 657 RequestSet in_flight_requests_; | 678 RequestSet in_flight_requests_; |
| 658 ResourceScheduler* scheduler_; | 679 ResourceScheduler* scheduler_; |
| 659 // The number of delayable in-flight requests. | 680 // The number of delayable in-flight requests. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 724 | 745 |
| 725 ClientMap::iterator client_it = client_map_.find(request->client_id()); | 746 ClientMap::iterator client_it = client_map_.find(request->client_id()); |
| 726 if (client_it == client_map_.end()) { | 747 if (client_it == client_map_.end()) { |
| 727 return; | 748 return; |
| 728 } | 749 } |
| 729 | 750 |
| 730 Client* client = client_it->second; | 751 Client* client = client_it->second; |
| 731 client->RemoveRequest(request); | 752 client->RemoveRequest(request); |
| 732 } | 753 } |
| 733 | 754 |
| 734 void ResourceScheduler::OnClientCreated(int child_id, int route_id) { | 755 void ResourceScheduler::OnClientCreated(int child_id, |
| 756 int route_id, | |
| 757 WebContents* web_contents) { | |
| 735 DCHECK(CalledOnValidThread()); | 758 DCHECK(CalledOnValidThread()); |
| 736 ClientId client_id = MakeClientId(child_id, route_id); | 759 ClientId client_id = MakeClientId(child_id, route_id); |
| 737 DCHECK(!ContainsKey(client_map_, client_id)); | 760 DCHECK(!ContainsKey(client_map_, client_id)); |
| 738 | 761 |
| 739 Client* client = new Client(this); | 762 Client* client = new Client(this, child_id, route_id, web_contents); |
| 740 client_map_[client_id] = client; | 763 client_map_[client_id] = client; |
| 741 | 764 |
| 742 // TODO(aiolos): set Client visibility/audibility when signals are added | 765 // TODO(aiolos): set Client visibility/audibility when signals are added |
| 743 // this will UNTHROTTLE Clients as needed | 766 // this will UNTHROTTLE Clients as needed |
| 744 client->UpdateThrottleState(); | 767 client->UpdateThrottleState(); |
| 745 } | 768 } |
| 746 | 769 |
| 747 void ResourceScheduler::OnClientDeleted(int child_id, int route_id) { | 770 void ResourceScheduler::OnClientDeleted(int child_id, int route_id) { |
| 748 DCHECK(CalledOnValidThread()); | 771 DCHECK(CalledOnValidThread()); |
| 749 ClientId client_id = MakeClientId(child_id, route_id); | 772 ClientId client_id = MakeClientId(child_id, route_id); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 826 } | 849 } |
| 827 | 850 |
| 828 void ResourceScheduler::OnLoadingStateChanged(int child_id, | 851 void ResourceScheduler::OnLoadingStateChanged(int child_id, |
| 829 int route_id, | 852 int route_id, |
| 830 bool is_loaded) { | 853 bool is_loaded) { |
| 831 Client* client = GetClient(child_id, route_id); | 854 Client* client = GetClient(child_id, route_id); |
| 832 DCHECK(client); | 855 DCHECK(client); |
| 833 client->OnLoadingStateChanged(is_loaded); | 856 client->OnLoadingStateChanged(is_loaded); |
| 834 } | 857 } |
| 835 | 858 |
| 859 bool ResourceScheduler::ClientIsVisible(int child_id, int route_id) { | |
|
aiolos (Not reviewing)
2014/08/13 21:40:33
nit: IsClientVisible instead.
Zhen Wang
2014/08/14 22:19:52
Done.
| |
| 860 Client* client = GetClient(child_id, route_id); | |
| 861 DCHECK(client); | |
| 862 return client->IsVisible(); | |
| 863 } | |
| 864 | |
| 836 ResourceScheduler::Client* ResourceScheduler::GetClient(int child_id, | 865 ResourceScheduler::Client* ResourceScheduler::GetClient(int child_id, |
| 837 int route_id) { | 866 int route_id) { |
| 838 ClientId client_id = MakeClientId(child_id, route_id); | 867 ClientId client_id = MakeClientId(child_id, route_id); |
| 839 ClientMap::iterator client_it = client_map_.find(client_id); | 868 ClientMap::iterator client_it = client_map_.find(client_id); |
| 840 if (client_it == client_map_.end()) { | 869 if (client_it == client_map_.end()) { |
| 841 return NULL; | 870 return NULL; |
| 842 } | 871 } |
| 843 return client_it->second; | 872 return client_it->second; |
| 844 } | 873 } |
| 845 | 874 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 960 client->ReprioritizeRequest( | 989 client->ReprioritizeRequest( |
| 961 request, old_priority_params, new_priority_params); | 990 request, old_priority_params, new_priority_params); |
| 962 } | 991 } |
| 963 | 992 |
| 964 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( | 993 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( |
| 965 int child_id, int route_id) { | 994 int child_id, int route_id) { |
| 966 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; | 995 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; |
| 967 } | 996 } |
| 968 | 997 |
| 969 } // namespace content | 998 } // namespace content |
| OLD | NEW |