Chromium Code Reviews| Index: components/page_load_metrics/browser/metrics_web_contents_observer.cc |
| diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.cc b/components/page_load_metrics/browser/metrics_web_contents_observer.cc |
| index 0f40c4ba17a3c29ea60e852e49da36ff7a357de7..ad04b426914503705ea23e6656762d948583c32a 100644 |
| --- a/components/page_load_metrics/browser/metrics_web_contents_observer.cc |
| +++ b/components/page_load_metrics/browser/metrics_web_contents_observer.cc |
| @@ -16,6 +16,7 @@ |
| #include "components/page_load_metrics/browser/page_load_metrics_util.h" |
| #include "components/page_load_metrics/common/page_load_metrics_messages.h" |
| #include "components/page_load_metrics/common/page_load_timing.h" |
| +#include "content/browser/renderer_host/render_view_host_impl.h" |
|
Bryan McQuade
2016/05/25 21:32:29
My understanding is that you can't depend on conte
|
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/navigation_details.h" |
| #include "content/public/browser/navigation_handle.h" |
| @@ -30,6 +31,8 @@ |
| DEFINE_WEB_CONTENTS_USER_DATA_KEY( |
| page_load_metrics::MetricsWebContentsObserver); |
| +class RenderViewHost; |
| + |
| namespace page_load_metrics { |
| namespace internal { |
| @@ -365,6 +368,16 @@ void PageLoadTracker::Redirect(content::NavigationHandle* navigation_handle) { |
| } |
| } |
| +void PageLoadTracker::OnInputEvent(const blink::WebInputEvent& event) { |
| + // Only log the first user interaction in a given page load. |
| + if (user_interaction_time_.is_null()) |
| + user_interaction_time_ = base::TimeTicks::Now(); |
| + |
| + for (const auto& observer : observers_) { |
| + observer->OnUserInput(event); |
| + } |
| +} |
| + |
| bool PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing, |
| const PageLoadMetadata& new_metadata) { |
| // Throw away IPCs that are not relevant to the current navigation. |
| @@ -411,12 +424,15 @@ void PageLoadTracker::AddObserver( |
| PageLoadExtraInfo PageLoadTracker::GetPageLoadMetricsInfo() { |
| base::TimeDelta first_background_time; |
| base::TimeDelta first_foreground_time; |
| + base::TimeDelta first_user_interaction_time; |
| base::TimeDelta time_to_abort; |
| base::TimeDelta time_to_commit; |
| if (!background_time_.is_null()) |
| first_background_time = background_time_ - navigation_start_; |
| if (!foreground_time_.is_null()) |
| first_foreground_time = foreground_time_ - navigation_start_; |
| + if (!user_interaction_time_.is_null()) |
| + first_user_interaction_time = user_interaction_time_ - navigation_start_; |
| if (abort_type_ != ABORT_NONE) { |
| DCHECK_GT(abort_time_, navigation_start_); |
| time_to_abort = abort_time_ - navigation_start_; |
| @@ -431,9 +447,9 @@ PageLoadExtraInfo PageLoadTracker::GetPageLoadMetricsInfo() { |
| DCHECK(commit_time_.is_null()); |
| } |
| return PageLoadExtraInfo( |
| - first_background_time, first_foreground_time, started_in_foreground_, |
| - commit_time_.is_null() ? GURL() : url_, time_to_commit, abort_type_, |
| - time_to_abort, metadata_); |
| + first_background_time, first_foreground_time, first_user_interaction_time, |
| + started_in_foreground_, commit_time_.is_null() ? GURL() : url_, |
| + time_to_commit, abort_type_, time_to_abort, metadata_); |
| } |
| void PageLoadTracker::NotifyAbort(UserAbortType abort_type, |
| @@ -514,11 +530,20 @@ MetricsWebContentsObserver* MetricsWebContentsObserver::CreateForWebContents( |
| std::move(embedder_interface)); |
| web_contents->SetUserData(UserDataKey(), metrics); |
| } |
| + |
| + content::RenderWidgetHostImpl* rwhi = content::RenderWidgetHostImpl::From( |
|
Bryan McQuade
2016/05/25 20:47:04
since we're unlistening in the destructor, let's l
|
| + metrics->web_contents()->GetRenderViewHost()->GetWidget()); |
| + rwhi->latency_tracker()->AddInputEventCallback(base::Bind( |
| + &MetricsWebContentsObserver::OnInputEvent, base::Unretained(metrics))); |
| + |
| return metrics; |
| } |
| MetricsWebContentsObserver::~MetricsWebContentsObserver() { |
| - NotifyAbortAllLoads(ABORT_CLOSE); |
| + content::RenderWidgetHostImpl* rwhi = content::RenderWidgetHostImpl::From( |
| + web_contents()->GetRenderViewHost()->GetWidget()); |
|
Bryan McQuade
2016/05/25 19:02:47
My understanding is that a RenderViewHost's lifeti
Bryan McQuade
2016/05/25 20:47:04
I think you can address this issue by implementing
|
| + rwhi->latency_tracker()->RemoveInputEventCallback(base::Bind( |
| + &MetricsWebContentsObserver::OnInputEvent, base::Unretained(this))); |
| } |
| bool MetricsWebContentsObserver::OnMessageReceived( |
| @@ -656,6 +681,21 @@ void MetricsWebContentsObserver::NavigationStopped() { |
| NotifyAbortAllLoads(ABORT_STOP); |
| } |
| +bool MetricsWebContentsObserver::OnInputEvent( |
| + const blink::WebInputEvent& event) { |
| + // ignore browser navigation or reload which comes with type Undefined |
|
tdresser
2016/05/24 14:28:38
Capitalization and end with .
|
| + if (event.type != blink::WebInputEvent::Type::Undefined) { |
| + if (!committed_load_) { |
| + RecordInternalError(ERR_USER_INTERACTION_WITH_NO_RELEVANT_LOAD); |
| + return false; |
| + } |
| + committed_load_->OnInputEvent(event); |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| void MetricsWebContentsObserver::DidRedirectNavigation( |
| content::NavigationHandle* navigation_handle) { |
| if (!navigation_handle->IsInMainFrame()) |