OLD | NEW |
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> |
(...skipping 15 matching lines...) Expand all Loading... |
26 #include "content/public/browser/web_contents.h" | 26 #include "content/public/browser/web_contents.h" |
27 #include "content/public/browser/web_contents_observer.h" | 27 #include "content/public/browser/web_contents_observer.h" |
28 #include "content/public/browser/web_contents_user_data.h" | 28 #include "content/public/browser/web_contents_user_data.h" |
29 #include "ipc/ipc_message.h" | 29 #include "ipc/ipc_message.h" |
30 #include "ipc/ipc_message_macros.h" | 30 #include "ipc/ipc_message_macros.h" |
31 #include "ui/base/page_transition_types.h" | 31 #include "ui/base/page_transition_types.h" |
32 | 32 |
33 DEFINE_WEB_CONTENTS_USER_DATA_KEY( | 33 DEFINE_WEB_CONTENTS_USER_DATA_KEY( |
34 page_load_metrics::MetricsWebContentsObserver); | 34 page_load_metrics::MetricsWebContentsObserver); |
35 | 35 |
| 36 // This macro invokes the specified method on each observer, passing the |
| 37 // variable length arguments as the method's arguments, and removes the observer |
| 38 // from the list of observers if the given method returns STOP_OBSERVING. |
| 39 #define INVOKE_AND_PRUNE_OBSERVERS(observers, Method, ...) \ |
| 40 for (auto it = observers.begin(); it != observers.end();) { \ |
| 41 if ((*it)->Method(__VA_ARGS__) == \ |
| 42 PageLoadMetricsObserver::STOP_OBSERVING) { \ |
| 43 it = observers.erase(it); \ |
| 44 } else { \ |
| 45 ++it; \ |
| 46 } \ |
| 47 } |
| 48 |
36 namespace page_load_metrics { | 49 namespace page_load_metrics { |
37 | 50 |
38 namespace internal { | 51 namespace internal { |
39 | 52 |
40 const char kErrorEvents[] = "PageLoad.Internal.ErrorCode"; | 53 const char kErrorEvents[] = "PageLoad.Internal.ErrorCode"; |
41 const char kAbortChainSizeReload[] = | 54 const char kAbortChainSizeReload[] = |
42 "PageLoad.Internal.ProvisionalAbortChainSize.Reload"; | 55 "PageLoad.Internal.ProvisionalAbortChainSize.Reload"; |
43 const char kAbortChainSizeForwardBack[] = | 56 const char kAbortChainSizeForwardBack[] = |
44 "PageLoad.Internal.ProvisionalAbortChainSize.ForwardBack"; | 57 "PageLoad.Internal.ProvisionalAbortChainSize.ForwardBack"; |
45 const char kAbortChainSizeNewNavigation[] = | 58 const char kAbortChainSizeNewNavigation[] = |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 | 448 |
436 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) { | 449 void PageLoadTracker::Commit(content::NavigationHandle* navigation_handle) { |
437 // TODO(bmcquade): To improve accuracy, consider adding commit time to | 450 // TODO(bmcquade): To improve accuracy, consider adding commit time to |
438 // NavigationHandle. Taking a timestamp here should be close enough for now. | 451 // NavigationHandle. Taking a timestamp here should be close enough for now. |
439 commit_time_ = base::TimeTicks::Now(); | 452 commit_time_ = base::TimeTicks::Now(); |
440 ClampBrowserTimestampIfInterProcessTimeTickSkew(&commit_time_); | 453 ClampBrowserTimestampIfInterProcessTimeTickSkew(&commit_time_); |
441 url_ = navigation_handle->GetURL(); | 454 url_ = navigation_handle->GetURL(); |
442 // Some transitions (like CLIENT_REDIRECT) are only known at commit time. | 455 // Some transitions (like CLIENT_REDIRECT) are only known at commit time. |
443 page_transition_ = navigation_handle->GetPageTransition(); | 456 page_transition_ = navigation_handle->GetPageTransition(); |
444 user_gesture_ = navigation_handle->HasUserGesture(); | 457 user_gesture_ = navigation_handle->HasUserGesture(); |
445 for (const auto& observer : observers_) { | 458 |
446 observer->OnCommit(navigation_handle); | 459 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnCommit, navigation_handle); |
447 } | |
448 LogAbortChainHistograms(navigation_handle); | 460 LogAbortChainHistograms(navigation_handle); |
449 } | 461 } |
450 | 462 |
451 void PageLoadTracker::FailedProvisionalLoad( | 463 void PageLoadTracker::FailedProvisionalLoad( |
452 content::NavigationHandle* navigation_handle) { | 464 content::NavigationHandle* navigation_handle) { |
453 DCHECK(!failed_provisional_load_info_); | 465 DCHECK(!failed_provisional_load_info_); |
454 failed_provisional_load_info_.reset(new FailedProvisionalLoadInfo( | 466 failed_provisional_load_info_.reset(new FailedProvisionalLoadInfo( |
455 base::TimeTicks::Now() - navigation_handle->NavigationStart(), | 467 base::TimeTicks::Now() - navigation_handle->NavigationStart(), |
456 navigation_handle->GetNetErrorCode())); | 468 navigation_handle->GetNetErrorCode())); |
457 } | 469 } |
(...skipping 10 matching lines...) Expand all Loading... |
468 } | 480 } |
469 } | 481 } |
470 | 482 |
471 void PageLoadTracker::FlushMetricsOnAppEnterBackground() { | 483 void PageLoadTracker::FlushMetricsOnAppEnterBackground() { |
472 if (!app_entered_background_) { | 484 if (!app_entered_background_) { |
473 RecordAppBackgroundPageLoadCompleted(false); | 485 RecordAppBackgroundPageLoadCompleted(false); |
474 app_entered_background_ = true; | 486 app_entered_background_ = true; |
475 } | 487 } |
476 | 488 |
477 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); | 489 const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); |
478 for (auto it = observers_.begin(); it != observers_.end();) { | 490 INVOKE_AND_PRUNE_OBSERVERS(observers_, FlushMetricsOnAppEnterBackground, |
479 if ((*it)->FlushMetricsOnAppEnterBackground(timing_, info) == | 491 timing_, info); |
480 PageLoadMetricsObserver::STOP_OBSERVING) { | |
481 it = observers_.erase(it); | |
482 } else { | |
483 ++it; | |
484 } | |
485 } | |
486 } | 492 } |
487 | 493 |
488 void PageLoadTracker::NotifyClientRedirectTo( | 494 void PageLoadTracker::NotifyClientRedirectTo( |
489 const PageLoadTracker& destination) { | 495 const PageLoadTracker& destination) { |
490 if (timing_.first_paint) { | 496 if (timing_.first_paint) { |
491 base::TimeTicks first_paint_time = | 497 base::TimeTicks first_paint_time = |
492 navigation_start() + timing_.first_paint.value(); | 498 navigation_start() + timing_.first_paint.value(); |
493 base::TimeDelta first_paint_to_navigation; | 499 base::TimeDelta first_paint_to_navigation; |
494 if (destination.navigation_start() > first_paint_time) | 500 if (destination.navigation_start() > first_paint_time) |
495 first_paint_to_navigation = | 501 first_paint_to_navigation = |
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1088 content::NavigationHandle* navigation_handle) const { | 1094 content::NavigationHandle* navigation_handle) const { |
1089 DCHECK(navigation_handle->IsInMainFrame()); | 1095 DCHECK(navigation_handle->IsInMainFrame()); |
1090 DCHECK(!navigation_handle->HasCommitted() || | 1096 DCHECK(!navigation_handle->HasCommitted() || |
1091 !navigation_handle->IsSamePage()); | 1097 !navigation_handle->IsSamePage()); |
1092 | 1098 |
1093 return BrowserPageTrackDecider(embedder_interface_.get(), web_contents(), | 1099 return BrowserPageTrackDecider(embedder_interface_.get(), web_contents(), |
1094 navigation_handle).ShouldTrack(); | 1100 navigation_handle).ShouldTrack(); |
1095 } | 1101 } |
1096 | 1102 |
1097 } // namespace page_load_metrics | 1103 } // namespace page_load_metrics |
OLD | NEW |