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

Side by Side Diff: chrome/browser/page_load_metrics/metrics_web_contents_observer.cc

Issue 2624283004: Associate a main resource request with its PageLoadTracker. (Closed)
Patch Set: fix comment Created 3 years, 11 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" 5 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <ostream> 8 #include <ostream>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/metrics/user_metrics.h" 15 #include "base/metrics/user_metrics.h"
16 #include "chrome/browser/page_load_metrics/browser_page_track_decider.h" 16 #include "chrome/browser/page_load_metrics/browser_page_track_decider.h"
17 #include "chrome/browser/page_load_metrics/page_load_metrics_embedder_interface. h" 17 #include "chrome/browser/page_load_metrics/page_load_metrics_embedder_interface. h"
18 #include "chrome/browser/page_load_metrics/page_load_metrics_util.h" 18 #include "chrome/browser/page_load_metrics/page_load_metrics_util.h"
19 #include "chrome/browser/page_load_metrics/page_load_tracker.h" 19 #include "chrome/browser/page_load_metrics/page_load_tracker.h"
20 #include "chrome/common/page_load_metrics/page_load_metrics_messages.h" 20 #include "chrome/common/page_load_metrics/page_load_metrics_messages.h"
21 #include "chrome/common/page_load_metrics/page_load_timing.h" 21 #include "chrome/common/page_load_metrics/page_load_timing.h"
22 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/global_request_id.h"
23 #include "content/public/browser/navigation_details.h" 24 #include "content/public/browser/navigation_details.h"
24 #include "content/public/browser/navigation_handle.h" 25 #include "content/public/browser/navigation_handle.h"
25 #include "content/public/browser/render_frame_host.h" 26 #include "content/public/browser/render_frame_host.h"
26 #include "content/public/browser/render_view_host.h" 27 #include "content/public/browser/render_view_host.h"
27 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
28 #include "content/public/browser/web_contents_observer.h" 29 #include "content/public/browser/web_contents_observer.h"
29 #include "content/public/browser/web_contents_user_data.h" 30 #include "content/public/browser/web_contents_user_data.h"
30 #include "ipc/ipc_message.h" 31 #include "ipc/ipc_message.h"
31 #include "ipc/ipc_message_macros.h" 32 #include "ipc/ipc_message_macros.h"
32 #include "net/base/net_errors.h" 33 #include "net/base/net_errors.h"
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 // after the PageLoadTracker. The PageLoadTracker does not hold on to 169 // after the PageLoadTracker. The PageLoadTracker does not hold on to
169 // committed_load_ or navigation_handle beyond the scope of the constructor. 170 // committed_load_ or navigation_handle beyond the scope of the constructor.
170 provisional_loads_.insert(std::make_pair( 171 provisional_loads_.insert(std::make_pair(
171 navigation_handle, 172 navigation_handle,
172 base::MakeUnique<PageLoadTracker>( 173 base::MakeUnique<PageLoadTracker>(
173 in_foreground_, embedder_interface_.get(), currently_committed_url, 174 in_foreground_, embedder_interface_.get(), currently_committed_url,
174 navigation_handle, user_initiated_info, chain_size, 175 navigation_handle, user_initiated_info, chain_size,
175 chain_size_same_url))); 176 chain_size_same_url)));
176 } 177 }
177 178
179 void MetricsWebContentsObserver::WillProcessNavigationResponse(
180 content::NavigationHandle* navigation_handle) {
181 auto it = provisional_loads_.find(navigation_handle);
182 if (it == provisional_loads_.end())
183 return;
184 it->second->WillProcessNavigationResponse(navigation_handle);
185 }
186
187 PageLoadTracker* MetricsWebContentsObserver::GetTrackerOrNullForRequest(
188 const content::GlobalRequestID& request_id,
189 content::ResourceType resource_type,
190 base::TimeTicks creation_time) {
191 if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME) {
192 // The main frame request can complete either before or after commit, so we
193 // look at both provisional loads and the committed load to find a
194 // PageLoadTracker with a matching request id. See https://goo.gl/6TzCYN for
195 // more details.
196 for (const auto& kv : provisional_loads_) {
197 PageLoadTracker* candidate = kv.second.get();
198 if (candidate->HasMatchingNavigationRequestID(request_id)) {
199 return candidate;
200 }
201 }
202 if (committed_load_ &&
203 committed_load_->HasMatchingNavigationRequestID(request_id)) {
204 return committed_load_.get();
205 }
206 } else {
207 // Non main frame resources are always associated with the currently
208 // committed load. If the resource request was started before this
209 // navigation then it should be ignored.
210
211 // TODO(jkarlin): There is a race here. Consider the following sequence:
212 // 1. renderer has a committed page A
213 // 2. navigation is initiated to page B
214 // 3. page A initiates URLRequests (e.g. in the unload handler)
215 // 4. page B commits
216 // 5. the URLRequests initiated by A complete
217 // In the above example, the URLRequests initiated by A will be attributed
218 // to page load B. This should be relatively rare but we may want to fix
219 // this at some point. We could fix this by comparing the URLRequest
220 // creation time against the committed load's commit time, however more
221 // investigation is needed to confirm that all cases would be handled
222 // correctly (for example Link: preloads).
223 if (committed_load_ &&
224 creation_time >= committed_load_->navigation_start()) {
225 return committed_load_.get();
226 }
227 }
228 return nullptr;
229 }
230
178 void MetricsWebContentsObserver::OnRequestComplete( 231 void MetricsWebContentsObserver::OnRequestComplete(
232 const content::GlobalRequestID& request_id,
179 content::ResourceType resource_type, 233 content::ResourceType resource_type,
180 bool was_cached, 234 bool was_cached,
181 bool used_data_reduction_proxy, 235 bool used_data_reduction_proxy,
182 int64_t raw_body_bytes, 236 int64_t raw_body_bytes,
183 int64_t original_content_length, 237 int64_t original_content_length,
184 base::TimeTicks creation_time) { 238 base::TimeTicks creation_time) {
185 // If the navigation hasn't committed yet then we'll miss the resource (this 239 PageLoadTracker* tracker =
186 // happens on the new tab page). Also, if the resource request was started 240 GetTrackerOrNullForRequest(request_id, resource_type, creation_time);
187 // before this navigation then it should be ignored. 241 if (tracker) {
188 // TODO(jkarlin): There is a race here. If a renderer starts URLRequests for 242 ExtraRequestInfo extra_request_info(
189 // page A after navigating (but before comitting) to page B, then page A's 243 was_cached, raw_body_bytes, used_data_reduction_proxy,
190 // requests might wind up counting toward page B's size. This should be 244 was_cached ? 0 : original_content_length);
191 // relatively rare but we may want to fix this at some point. 245 tracker->OnLoadedResource(extra_request_info);
192 if (!committed_load_ || creation_time < committed_load_->navigation_start()) {
193 return;
194 } 246 }
195
196 ExtraRequestInfo extra_request_info(was_cached, raw_body_bytes,
197 used_data_reduction_proxy,
198 was_cached ? 0 : original_content_length);
199
200 committed_load_->OnLoadedResource(extra_request_info);
201 } 247 }
202 248
203 const PageLoadExtraInfo 249 const PageLoadExtraInfo
204 MetricsWebContentsObserver::GetPageLoadExtraInfoForCommittedLoad() { 250 MetricsWebContentsObserver::GetPageLoadExtraInfoForCommittedLoad() {
205 DCHECK(committed_load_); 251 DCHECK(committed_load_);
206 return committed_load_->ComputePageLoadExtraInfo(); 252 return committed_load_->ComputePageLoadExtraInfo();
207 } 253 }
208 254
209 void MetricsWebContentsObserver::DidFinishNavigation( 255 void MetricsWebContentsObserver::DidFinishNavigation(
210 content::NavigationHandle* navigation_handle) { 256 content::NavigationHandle* navigation_handle) {
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 content::NavigationHandle* navigation_handle) const { 529 content::NavigationHandle* navigation_handle) const {
484 DCHECK(navigation_handle->IsInMainFrame()); 530 DCHECK(navigation_handle->IsInMainFrame());
485 DCHECK(!navigation_handle->HasCommitted() || 531 DCHECK(!navigation_handle->HasCommitted() ||
486 !navigation_handle->IsSamePage()); 532 !navigation_handle->IsSamePage());
487 533
488 return BrowserPageTrackDecider(embedder_interface_.get(), web_contents(), 534 return BrowserPageTrackDecider(embedder_interface_.get(), web_contents(),
489 navigation_handle).ShouldTrack(); 535 navigation_handle).ShouldTrack();
490 } 536 }
491 537
492 } // namespace page_load_metrics 538 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698