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

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

Issue 1984173002: Log First User Interaction in Page Load Metrics (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove style change by formatter Created 4 years, 6 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 "components/page_load_metrics/browser/metrics_web_contents_observer.h" 5 #include "components/page_load_metrics/browser/metrics_web_contents_observer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/metrics/user_metrics.h" 15 #include "base/metrics/user_metrics.h"
16 #include "components/page_load_metrics/browser/page_load_metrics_util.h" 16 #include "components/page_load_metrics/browser/page_load_metrics_util.h"
17 #include "components/page_load_metrics/common/page_load_metrics_messages.h" 17 #include "components/page_load_metrics/common/page_load_metrics_messages.h"
18 #include "components/page_load_metrics/common/page_load_timing.h" 18 #include "components/page_load_metrics/common/page_load_timing.h"
19 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/navigation_details.h" 20 #include "content/public/browser/navigation_details.h"
21 #include "content/public/browser/navigation_handle.h" 21 #include "content/public/browser/navigation_handle.h"
22 #include "content/public/browser/render_frame_host.h" 22 #include "content/public/browser/render_frame_host.h"
23 #include "content/public/browser/render_view_host.h"
23 #include "content/public/browser/web_contents.h" 24 #include "content/public/browser/web_contents.h"
24 #include "content/public/browser/web_contents_observer.h" 25 #include "content/public/browser/web_contents_observer.h"
25 #include "content/public/browser/web_contents_user_data.h" 26 #include "content/public/browser/web_contents_user_data.h"
26 #include "ipc/ipc_message.h" 27 #include "ipc/ipc_message.h"
27 #include "ipc/ipc_message_macros.h" 28 #include "ipc/ipc_message_macros.h"
28 #include "ui/base/page_transition_types.h" 29 #include "ui/base/page_transition_types.h"
29 30
30 DEFINE_WEB_CONTENTS_USER_DATA_KEY( 31 DEFINE_WEB_CONTENTS_USER_DATA_KEY(
31 page_load_metrics::MetricsWebContentsObserver); 32 page_load_metrics::MetricsWebContentsObserver);
32 33
34 class RenderViewHost;
35
33 namespace page_load_metrics { 36 namespace page_load_metrics {
34 37
35 namespace internal { 38 namespace internal {
36 39
37 const char kErrorEvents[] = "PageLoad.Events.InternalError"; 40 const char kErrorEvents[] = "PageLoad.Events.InternalError";
38 const char kAbortChainSizeReload[] = 41 const char kAbortChainSizeReload[] =
39 "PageLoad.Internal.ProvisionalAbortChainSize.Reload"; 42 "PageLoad.Internal.ProvisionalAbortChainSize.Reload";
40 const char kAbortChainSizeForwardBack[] = 43 const char kAbortChainSizeForwardBack[] =
41 "PageLoad.Internal.ProvisionalAbortChainSize.ForwardBack"; 44 "PageLoad.Internal.ProvisionalAbortChainSize.ForwardBack";
42 const char kAbortChainSizeNewNavigation[] = 45 const char kAbortChainSizeNewNavigation[] =
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 observer->OnFailedProvisionalLoad(navigation_handle); 368 observer->OnFailedProvisionalLoad(navigation_handle);
366 } 369 }
367 } 370 }
368 371
369 void PageLoadTracker::Redirect(content::NavigationHandle* navigation_handle) { 372 void PageLoadTracker::Redirect(content::NavigationHandle* navigation_handle) {
370 for (const auto& observer : observers_) { 373 for (const auto& observer : observers_) {
371 observer->OnRedirect(navigation_handle); 374 observer->OnRedirect(navigation_handle);
372 } 375 }
373 } 376 }
374 377
378 void PageLoadTracker::OnInputEvent(const blink::WebInputEvent& event) {
379 for (const auto& observer : observers_) {
380 observer->OnUserInput(event, navigation_start_ - base::TimeTicks::Now());
381 }
382 }
383
375 bool PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing, 384 bool PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing,
376 const PageLoadMetadata& new_metadata) { 385 const PageLoadMetadata& new_metadata) {
377 // Throw away IPCs that are not relevant to the current navigation. 386 // Throw away IPCs that are not relevant to the current navigation.
378 // Two timing structures cannot refer to the same navigation if they indicate 387 // Two timing structures cannot refer to the same navigation if they indicate
379 // that a navigation started at different times, so a new timing struct with a 388 // that a navigation started at different times, so a new timing struct with a
380 // different start time from an earlier struct is considered invalid. 389 // different start time from an earlier struct is considered invalid.
381 bool valid_timing_descendent = 390 bool valid_timing_descendent =
382 timing_.navigation_start.is_null() || 391 timing_.navigation_start.is_null() ||
383 timing_.navigation_start == new_timing.navigation_start; 392 timing_.navigation_start == new_timing.navigation_start;
384 // Ensure flags sent previously are still present in the new metadata fields. 393 // Ensure flags sent previously are still present in the new metadata fields.
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 abort_time_ = timestamp; 510 abort_time_ = timestamp;
502 } 511 }
503 512
504 // static 513 // static
505 MetricsWebContentsObserver::MetricsWebContentsObserver( 514 MetricsWebContentsObserver::MetricsWebContentsObserver(
506 content::WebContents* web_contents, 515 content::WebContents* web_contents,
507 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface) 516 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface)
508 : content::WebContentsObserver(web_contents), 517 : content::WebContentsObserver(web_contents),
509 in_foreground_(false), 518 in_foreground_(false),
510 embedder_interface_(std::move(embedder_interface)), 519 embedder_interface_(std::move(embedder_interface)),
511 has_navigated_(false) {} 520 has_navigated_(false) {
521 this->RegisterInputEventObserver(web_contents->GetRenderViewHost());
522 }
512 523
513 MetricsWebContentsObserver* MetricsWebContentsObserver::CreateForWebContents( 524 MetricsWebContentsObserver* MetricsWebContentsObserver::CreateForWebContents(
514 content::WebContents* web_contents, 525 content::WebContents* web_contents,
515 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface) { 526 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface) {
516 DCHECK(web_contents); 527 DCHECK(web_contents);
517 528
518 MetricsWebContentsObserver* metrics = FromWebContents(web_contents); 529 MetricsWebContentsObserver* metrics = FromWebContents(web_contents);
519 if (!metrics) { 530 if (!metrics) {
520 metrics = new MetricsWebContentsObserver(web_contents, 531 metrics = new MetricsWebContentsObserver(web_contents,
521 std::move(embedder_interface)); 532 std::move(embedder_interface));
522 web_contents->SetUserData(UserDataKey(), metrics); 533 web_contents->SetUserData(UserDataKey(), metrics);
523 } 534 }
524 return metrics; 535 return metrics;
525 } 536 }
526 537
527 MetricsWebContentsObserver::~MetricsWebContentsObserver() { 538 MetricsWebContentsObserver::~MetricsWebContentsObserver() {
528 NotifyAbortAllLoads(ABORT_CLOSE); 539 NotifyAbortAllLoads(ABORT_CLOSE);
540 UnregisterInputEventObserver(web_contents()->GetRenderViewHost());
Charlie Harrison 2016/05/27 18:14:34 Hm this feels unsafe. I don't think we should be c
mushan1 2016/05/27 18:51:24 What do you think if we just remove this Unregiste
Charlie Harrison 2016/05/27 18:58:24 No, currently observers are scoped to the WebConte
mushan1 2016/05/27 19:38:11 refer to https://code.google.com/p/chromium/codese
541 }
542
543 void MetricsWebContentsObserver::RegisterInputEventObserver(
544 content::RenderViewHost* host) {
545 host->GetWidget()->AddInputEventObserver(this);
546 }
547
548 void MetricsWebContentsObserver::UnregisterInputEventObserver(
549 content::RenderViewHost* host) {
550 host->GetWidget()->RemoveInputEventObserver(this);
551 }
552
553 void MetricsWebContentsObserver::RenderViewHostChanged(
554 content::RenderViewHost* old_host,
555 content::RenderViewHost* new_host) {
556 UnregisterInputEventObserver(old_host);
557 RegisterInputEventObserver(new_host);
529 } 558 }
530 559
531 bool MetricsWebContentsObserver::OnMessageReceived( 560 bool MetricsWebContentsObserver::OnMessageReceived(
532 const IPC::Message& message, 561 const IPC::Message& message,
533 content::RenderFrameHost* render_frame_host) { 562 content::RenderFrameHost* render_frame_host) {
534 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 563 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
535 bool handled = true; 564 bool handled = true;
536 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(MetricsWebContentsObserver, message, 565 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(MetricsWebContentsObserver, message,
537 render_frame_host) 566 render_frame_host)
538 IPC_MESSAGE_HANDLER(PageLoadMetricsMsg_TimingUpdated, OnTimingUpdated) 567 IPC_MESSAGE_HANDLER(PageLoadMetricsMsg_TimingUpdated, OnTimingUpdated)
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 committed_load_->set_renderer_tracked( 685 committed_load_->set_renderer_tracked(
657 IsRelevantNavigation(navigation_handle, browser_url, mime_type)); 686 IsRelevantNavigation(navigation_handle, browser_url, mime_type));
658 687
659 committed_load_->Commit(navigation_handle); 688 committed_load_->Commit(navigation_handle);
660 } 689 }
661 690
662 void MetricsWebContentsObserver::NavigationStopped() { 691 void MetricsWebContentsObserver::NavigationStopped() {
663 NotifyAbortAllLoads(ABORT_STOP); 692 NotifyAbortAllLoads(ABORT_STOP);
664 } 693 }
665 694
695 bool MetricsWebContentsObserver::OnInputEvent(
696 const blink::WebInputEvent& event) {
697 // Ignore browser navigation or reload which comes with type Undefined.
698 if (event.type == blink::WebInputEvent::Type::Undefined)
699 return false;
700
701 if (!committed_load_) {
702 RecordInternalError(ERR_USER_INPUT_WITH_NO_RELEVANT_LOAD);
703 return false;
704 }
705
706 committed_load_->OnInputEvent(event);
707 return true;
708 }
709
666 void MetricsWebContentsObserver::DidRedirectNavigation( 710 void MetricsWebContentsObserver::DidRedirectNavigation(
667 content::NavigationHandle* navigation_handle) { 711 content::NavigationHandle* navigation_handle) {
668 if (!navigation_handle->IsInMainFrame()) 712 if (!navigation_handle->IsInMainFrame())
669 return; 713 return;
670 auto it = provisional_loads_.find(navigation_handle); 714 auto it = provisional_loads_.find(navigation_handle);
671 if (it == provisional_loads_.end()) 715 if (it == provisional_loads_.end())
672 return; 716 return;
673 it->second->Redirect(navigation_handle); 717 it->second->Redirect(navigation_handle);
674 } 718 }
675 719
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 832
789 if (!committed_load_->UpdateTiming(timing, metadata)) { 833 if (!committed_load_->UpdateTiming(timing, metadata)) {
790 // If the page load tracker cannot update its timing, something is wrong 834 // If the page load tracker cannot update its timing, something is wrong
791 // with the IPC (it's from another load, or it's invalid in some other way). 835 // with the IPC (it's from another load, or it's invalid in some other way).
792 // We expect this to be a rare occurrence. 836 // We expect this to be a rare occurrence.
793 RecordInternalError(ERR_BAD_TIMING_IPC); 837 RecordInternalError(ERR_BAD_TIMING_IPC);
794 } 838 }
795 } 839 }
796 840
797 } // namespace page_load_metrics 841 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698