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 // 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 "content/browser/loader/resource_dispatcher_host_impl.h" | 7 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
8 | 8 |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 | 10 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 #include "content/browser/loader/async_revalidation_manager.h" | 49 #include "content/browser/loader/async_revalidation_manager.h" |
50 #include "content/browser/loader/cross_site_resource_handler.h" | 50 #include "content/browser/loader/cross_site_resource_handler.h" |
51 #include "content/browser/loader/detachable_resource_handler.h" | 51 #include "content/browser/loader/detachable_resource_handler.h" |
52 #include "content/browser/loader/mime_type_resource_handler.h" | 52 #include "content/browser/loader/mime_type_resource_handler.h" |
53 #include "content/browser/loader/navigation_resource_handler.h" | 53 #include "content/browser/loader/navigation_resource_handler.h" |
54 #include "content/browser/loader/navigation_resource_throttle.h" | 54 #include "content/browser/loader/navigation_resource_throttle.h" |
55 #include "content/browser/loader/navigation_url_loader_impl_core.h" | 55 #include "content/browser/loader/navigation_url_loader_impl_core.h" |
56 #include "content/browser/loader/power_save_block_resource_throttle.h" | 56 #include "content/browser/loader/power_save_block_resource_throttle.h" |
57 #include "content/browser/loader/redirect_to_file_resource_handler.h" | 57 #include "content/browser/loader/redirect_to_file_resource_handler.h" |
58 #include "content/browser/loader/resource_message_filter.h" | 58 #include "content/browser/loader/resource_message_filter.h" |
59 #include "content/browser/loader/resource_request_info_impl.h" | |
60 #include "content/browser/loader/stream_resource_handler.h" | 59 #include "content/browser/loader/stream_resource_handler.h" |
61 #include "content/browser/loader/sync_resource_handler.h" | 60 #include "content/browser/loader/sync_resource_handler.h" |
62 #include "content/browser/loader/throttling_resource_handler.h" | 61 #include "content/browser/loader/throttling_resource_handler.h" |
63 #include "content/browser/loader/upload_data_stream_builder.h" | 62 #include "content/browser/loader/upload_data_stream_builder.h" |
64 #include "content/browser/renderer_host/render_view_host_delegate.h" | 63 #include "content/browser/renderer_host/render_view_host_delegate.h" |
65 #include "content/browser/renderer_host/render_view_host_impl.h" | 64 #include "content/browser/renderer_host/render_view_host_impl.h" |
66 #include "content/browser/resource_context_impl.h" | 65 #include "content/browser/resource_context_impl.h" |
67 #include "content/browser/service_worker/foreign_fetch_request_handler.h" | 66 #include "content/browser/service_worker/foreign_fetch_request_handler.h" |
68 #include "content/browser/service_worker/link_header_support.h" | 67 #include "content/browser/service_worker/link_header_support.h" |
69 #include "content/browser/service_worker/service_worker_request_handler.h" | 68 #include "content/browser/service_worker/service_worker_request_handler.h" |
(...skipping 2369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2439 | 2438 |
2440 net::URLRequest* ResourceDispatcherHostImpl::GetURLRequest( | 2439 net::URLRequest* ResourceDispatcherHostImpl::GetURLRequest( |
2441 const GlobalRequestID& id) { | 2440 const GlobalRequestID& id) { |
2442 ResourceLoader* loader = GetLoader(id); | 2441 ResourceLoader* loader = GetLoader(id); |
2443 if (!loader) | 2442 if (!loader) |
2444 return NULL; | 2443 return NULL; |
2445 | 2444 |
2446 return loader->request(); | 2445 return loader->request(); |
2447 } | 2446 } |
2448 | 2447 |
2449 // static | 2448 ResourceDispatcherHostImpl::LoadInfo::LoadInfo() {} |
2450 bool ResourceDispatcherHostImpl::LoadInfoIsMoreInteresting(const LoadInfo& a, | |
2451 const LoadInfo& b) { | |
2452 // Set |*_uploading_size| to be the size of the corresponding upload body if | |
2453 // it's currently being uploaded. | |
2454 | 2449 |
2455 uint64_t a_uploading_size = 0; | 2450 ResourceDispatcherHostImpl::LoadInfo::~LoadInfo() {} |
2456 if (a.load_state.state == net::LOAD_STATE_SENDING_REQUEST) | |
2457 a_uploading_size = a.upload_size; | |
2458 | 2451 |
2459 uint64_t b_uploading_size = 0; | 2452 ResourceDispatcherHostImpl::LoadInfo::LoadInfo(const LoadInfo& info) = default; |
2460 if (b.load_state.state == net::LOAD_STATE_SENDING_REQUEST) | |
2461 b_uploading_size = b.upload_size; | |
2462 | 2453 |
2463 if (a_uploading_size != b_uploading_size) | 2454 bool ResourceDispatcherHostImpl::LoadInfo::IsUploading() const { |
2464 return a_uploading_size > b_uploading_size; | 2455 return load_state.state == net::LOAD_STATE_SENDING_REQUEST && upload_size > 0; |
2465 | |
2466 return a.load_state.state > b.load_state.state; | |
2467 } | 2456 } |
2468 | 2457 |
2469 // static | 2458 bool ResourceDispatcherHostImpl::LoadInfo::IsMoreInteresting( |
| 2459 const LoadInfo& other) const { |
| 2460 if (IsUploading()) |
| 2461 return !other.IsUploading() || upload_size > other.upload_size; |
| 2462 return !other.IsUploading() && load_state.state > other.load_state.state; |
| 2463 } |
| 2464 |
2470 void ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread( | 2465 void ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread( |
2471 std::unique_ptr<LoadInfoMap> info_map) { | 2466 std::unique_ptr<LoadInfoMap> info_map) { |
2472 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466285 | 2467 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466285 |
2473 // is fixed. | 2468 // is fixed. |
2474 tracked_objects::ScopedTracker tracking_profile( | 2469 tracked_objects::ScopedTracker tracking_profile( |
2475 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2470 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
2476 "466285 ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread")); | 2471 "466285 ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread")); |
2477 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 2472 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 2473 std::map<WebContents*, const LoadInfo*> contents_map; |
2478 for (const auto& load_info : *info_map) { | 2474 for (const auto& load_info : *info_map) { |
2479 RenderViewHostImpl* view = RenderViewHostImpl::FromID( | 2475 WebContents* web_contents = load_info.second.web_contents_getter.Run(); |
2480 load_info.first.child_id, load_info.first.route_id); | 2476 if (!web_contents) |
2481 // The view could be gone at this point. | 2477 continue; |
2482 if (view) { | 2478 auto existing = contents_map.find(web_contents); |
2483 view->LoadStateChanged(load_info.second.url, load_info.second.load_state, | 2479 if (existing == contents_map.end() || |
2484 load_info.second.upload_position, | 2480 load_info.second.IsMoreInteresting(*existing->second)) { |
2485 load_info.second.upload_size); | 2481 contents_map[web_contents] = &load_info.second; |
| 2482 } |
| 2483 } |
| 2484 for (const auto& it : contents_map) { |
| 2485 // Re-run the getter to prevent use after free errors if calling |
| 2486 // LoadStateChanged on one WebContents deletes another one. |
| 2487 WebContentsImpl* web_contents = |
| 2488 static_cast<WebContentsImpl*>(it.second->web_contents_getter.Run()); |
| 2489 if (web_contents) { |
| 2490 web_contents->LoadStateChanged(it.second->url, it.second->load_state, |
| 2491 it.second->upload_position, |
| 2492 it.second->upload_size); |
2486 } | 2493 } |
2487 } | 2494 } |
2488 } | 2495 } |
2489 | 2496 |
2490 std::unique_ptr<ResourceDispatcherHostImpl::LoadInfoMap> | 2497 std::unique_ptr<ResourceDispatcherHostImpl::LoadInfoMap> |
2491 ResourceDispatcherHostImpl::GetLoadInfoForAllRoutes() { | 2498 ResourceDispatcherHostImpl::GetLoadInfoForAllRoutes() { |
2492 // Populate this map with load state changes, and then send them on to the UI | 2499 // Populate this map with load state changes, and then send them on to the UI |
2493 // thread where they can be passed along to the respective RVHs. | 2500 // thread where they can be passed along to the respective WebContents. |
2494 std::unique_ptr<LoadInfoMap> info_map(new LoadInfoMap()); | 2501 std::unique_ptr<LoadInfoMap> info_map(new LoadInfoMap()); |
2495 | 2502 |
2496 for (const auto& loader : pending_loaders_) { | 2503 for (const auto& loader : pending_loaders_) { |
2497 net::URLRequest* request = loader.second->request(); | 2504 net::URLRequest* request = loader.second->request(); |
2498 net::UploadProgress upload_progress = request->GetUploadProgress(); | 2505 net::UploadProgress upload_progress = request->GetUploadProgress(); |
2499 | 2506 |
2500 LoadInfo load_info; | 2507 LoadInfo load_info; |
2501 load_info.url = request->url(); | 2508 load_info.url = request->url(); |
2502 load_info.load_state = request->GetLoadState(); | 2509 load_info.load_state = request->GetLoadState(); |
2503 load_info.upload_size = upload_progress.size(); | 2510 load_info.upload_size = upload_progress.size(); |
2504 load_info.upload_position = upload_progress.position(); | 2511 load_info.upload_position = upload_progress.position(); |
| 2512 load_info.web_contents_getter = |
| 2513 loader.second->GetRequestInfo()->GetWebContentsGetterForRequest(); |
2505 | 2514 |
2506 GlobalRoutingID id(loader.second->GetRequestInfo()->GetGlobalRoutingID()); | 2515 ResourceType type = loader.second->GetRequestInfo()->GetResourceType(); |
| 2516 // The WebContents is only really interested in navigation updates. Send |
| 2517 // those along with requests that are sending data. |
| 2518 // TODO(csharrison): Consider updating this logic to send separate updates |
| 2519 // for uploads and navigation requests. |
| 2520 if (!load_info.IsUploading() && |
| 2521 type != ResourceType::RESOURCE_TYPE_MAIN_FRAME && |
| 2522 type != ResourceType::RESOURCE_TYPE_SUB_FRAME) { |
| 2523 continue; |
| 2524 } |
| 2525 |
| 2526 GlobalFrameRoutingId id( |
| 2527 loader.second->GetRequestInfo()->GetGlobalFrameRoutingId()); |
2507 LoadInfoMap::iterator existing = info_map->find(id); | 2528 LoadInfoMap::iterator existing = info_map->find(id); |
2508 | 2529 |
2509 if (existing == info_map->end() || | 2530 if (existing == info_map->end() || |
2510 LoadInfoIsMoreInteresting(load_info, existing->second)) { | 2531 load_info.IsMoreInteresting(existing->second)) { |
2511 (*info_map)[id] = load_info; | 2532 (*info_map)[id] = load_info; |
2512 } | 2533 } |
2513 } | 2534 } |
2514 return info_map; | 2535 return info_map; |
2515 } | 2536 } |
2516 | 2537 |
2517 void ResourceDispatcherHostImpl::UpdateLoadInfo() { | 2538 void ResourceDispatcherHostImpl::UpdateLoadInfo() { |
| 2539 // Group LoadInfo by frame, then pass to the UI thread where each WebContents |
| 2540 // picks the most interesting one. |
2518 std::unique_ptr<LoadInfoMap> info_map(GetLoadInfoForAllRoutes()); | 2541 std::unique_ptr<LoadInfoMap> info_map(GetLoadInfoForAllRoutes()); |
2519 | 2542 |
2520 // Stop the timer if there are no more pending requests. Future new requests | 2543 // Stop the timer if there are no more pending requests. Future new requests |
2521 // will restart it as necessary. | 2544 // will restart it as necessary. |
2522 // Also stop the timer if there are no loading clients, to avoid waking up | 2545 // Also stop the timer if there are no loading clients, to avoid waking up |
2523 // unnecessarily when there is a long running (hanging get) request. | 2546 // unnecessarily when there is a long running (hanging get) request. |
2524 if (info_map->empty() || !scheduler_->HasLoadingClients()) { | 2547 if (info_map->empty() || !scheduler_->HasLoadingClients()) { |
2525 update_load_states_timer_->Stop(); | 2548 update_load_states_timer_->Stop(); |
2526 return; | 2549 return; |
2527 } | 2550 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2690 ssl.cert_id = GetCertStore()->StoreCert(ssl_info.cert.get(), child_id); | 2713 ssl.cert_id = GetCertStore()->StoreCert(ssl_info.cert.get(), child_id); |
2691 response->head.security_info = SerializeSecurityInfo(ssl); | 2714 response->head.security_info = SerializeSecurityInfo(ssl); |
2692 } | 2715 } |
2693 | 2716 |
2694 CertStore* ResourceDispatcherHostImpl::GetCertStore() { | 2717 CertStore* ResourceDispatcherHostImpl::GetCertStore() { |
2695 return cert_store_for_testing_ ? cert_store_for_testing_ | 2718 return cert_store_for_testing_ ? cert_store_for_testing_ |
2696 : CertStore::GetInstance(); | 2719 : CertStore::GetInstance(); |
2697 } | 2720 } |
2698 | 2721 |
2699 } // namespace content | 2722 } // namespace content |
OLD | NEW |