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 "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 |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 observer->OnFailedProvisionalLoad(navigation_handle); | 366 observer->OnFailedProvisionalLoad(navigation_handle); |
366 } | 367 } |
367 } | 368 } |
368 | 369 |
369 void PageLoadTracker::Redirect(content::NavigationHandle* navigation_handle) { | 370 void PageLoadTracker::Redirect(content::NavigationHandle* navigation_handle) { |
370 for (const auto& observer : observers_) { | 371 for (const auto& observer : observers_) { |
371 observer->OnRedirect(navigation_handle); | 372 observer->OnRedirect(navigation_handle); |
372 } | 373 } |
373 } | 374 } |
374 | 375 |
| 376 void PageLoadTracker::OnInputEvent(const blink::WebInputEvent& event) { |
| 377 for (const auto& observer : observers_) { |
| 378 observer->OnUserInput(event); |
| 379 } |
| 380 } |
| 381 |
375 bool PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing, | 382 bool PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing, |
376 const PageLoadMetadata& new_metadata) { | 383 const PageLoadMetadata& new_metadata) { |
377 // Throw away IPCs that are not relevant to the current navigation. | 384 // Throw away IPCs that are not relevant to the current navigation. |
378 // Two timing structures cannot refer to the same navigation if they indicate | 385 // 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 | 386 // 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. | 387 // different start time from an earlier struct is considered invalid. |
381 bool valid_timing_descendent = | 388 bool valid_timing_descendent = |
382 timing_.navigation_start.is_null() || | 389 timing_.navigation_start.is_null() || |
383 timing_.navigation_start == new_timing.navigation_start; | 390 timing_.navigation_start == new_timing.navigation_start; |
384 // Ensure flags sent previously are still present in the new metadata fields. | 391 // Ensure flags sent previously are still present in the new metadata fields. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 abort_time_ = timestamp; | 508 abort_time_ = timestamp; |
502 } | 509 } |
503 | 510 |
504 // static | 511 // static |
505 MetricsWebContentsObserver::MetricsWebContentsObserver( | 512 MetricsWebContentsObserver::MetricsWebContentsObserver( |
506 content::WebContents* web_contents, | 513 content::WebContents* web_contents, |
507 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface) | 514 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface) |
508 : content::WebContentsObserver(web_contents), | 515 : content::WebContentsObserver(web_contents), |
509 in_foreground_(false), | 516 in_foreground_(false), |
510 embedder_interface_(std::move(embedder_interface)), | 517 embedder_interface_(std::move(embedder_interface)), |
511 has_navigated_(false) {} | 518 has_navigated_(false) { |
| 519 RegisterInputEventObserver(web_contents->GetRenderViewHost()); |
| 520 } |
512 | 521 |
513 MetricsWebContentsObserver* MetricsWebContentsObserver::CreateForWebContents( | 522 MetricsWebContentsObserver* MetricsWebContentsObserver::CreateForWebContents( |
514 content::WebContents* web_contents, | 523 content::WebContents* web_contents, |
515 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface) { | 524 std::unique_ptr<PageLoadMetricsEmbedderInterface> embedder_interface) { |
516 DCHECK(web_contents); | 525 DCHECK(web_contents); |
517 | 526 |
518 MetricsWebContentsObserver* metrics = FromWebContents(web_contents); | 527 MetricsWebContentsObserver* metrics = FromWebContents(web_contents); |
519 if (!metrics) { | 528 if (!metrics) { |
520 metrics = new MetricsWebContentsObserver(web_contents, | 529 metrics = new MetricsWebContentsObserver(web_contents, |
521 std::move(embedder_interface)); | 530 std::move(embedder_interface)); |
522 web_contents->SetUserData(UserDataKey(), metrics); | 531 web_contents->SetUserData(UserDataKey(), metrics); |
523 } | 532 } |
524 return metrics; | 533 return metrics; |
525 } | 534 } |
526 | 535 |
527 MetricsWebContentsObserver::~MetricsWebContentsObserver() { | 536 MetricsWebContentsObserver::~MetricsWebContentsObserver() { |
528 NotifyAbortAllLoads(ABORT_CLOSE); | 537 NotifyAbortAllLoads(ABORT_CLOSE); |
529 } | 538 } |
530 | 539 |
| 540 void MetricsWebContentsObserver::RegisterInputEventObserver( |
| 541 content::RenderViewHost* host) { |
| 542 if (host != nullptr) |
| 543 host->GetWidget()->AddInputEventObserver(this); |
| 544 } |
| 545 |
| 546 void MetricsWebContentsObserver::UnregisterInputEventObserver( |
| 547 content::RenderViewHost* host) { |
| 548 if (host != nullptr) |
| 549 host->GetWidget()->RemoveInputEventObserver(this); |
| 550 } |
| 551 |
| 552 void MetricsWebContentsObserver::RenderViewHostChanged( |
| 553 content::RenderViewHost* old_host, |
| 554 content::RenderViewHost* new_host) { |
| 555 UnregisterInputEventObserver(old_host); |
| 556 RegisterInputEventObserver(new_host); |
| 557 } |
| 558 |
531 bool MetricsWebContentsObserver::OnMessageReceived( | 559 bool MetricsWebContentsObserver::OnMessageReceived( |
532 const IPC::Message& message, | 560 const IPC::Message& message, |
533 content::RenderFrameHost* render_frame_host) { | 561 content::RenderFrameHost* render_frame_host) { |
534 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 562 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
535 bool handled = true; | 563 bool handled = true; |
536 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(MetricsWebContentsObserver, message, | 564 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(MetricsWebContentsObserver, message, |
537 render_frame_host) | 565 render_frame_host) |
538 IPC_MESSAGE_HANDLER(PageLoadMetricsMsg_TimingUpdated, OnTimingUpdated) | 566 IPC_MESSAGE_HANDLER(PageLoadMetricsMsg_TimingUpdated, OnTimingUpdated) |
539 IPC_MESSAGE_UNHANDLED(handled = false) | 567 IPC_MESSAGE_UNHANDLED(handled = false) |
540 IPC_END_MESSAGE_MAP() | 568 IPC_END_MESSAGE_MAP() |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 committed_load_->set_renderer_tracked( | 684 committed_load_->set_renderer_tracked( |
657 IsRelevantNavigation(navigation_handle, browser_url, mime_type)); | 685 IsRelevantNavigation(navigation_handle, browser_url, mime_type)); |
658 | 686 |
659 committed_load_->Commit(navigation_handle); | 687 committed_load_->Commit(navigation_handle); |
660 } | 688 } |
661 | 689 |
662 void MetricsWebContentsObserver::NavigationStopped() { | 690 void MetricsWebContentsObserver::NavigationStopped() { |
663 NotifyAbortAllLoads(ABORT_STOP); | 691 NotifyAbortAllLoads(ABORT_STOP); |
664 } | 692 } |
665 | 693 |
| 694 void MetricsWebContentsObserver::OnInputEvent( |
| 695 const blink::WebInputEvent& event) { |
| 696 // Ignore browser navigation or reload which comes with type Undefined. |
| 697 if (event.type == blink::WebInputEvent::Type::Undefined) |
| 698 return; |
| 699 |
| 700 if (!committed_load_) { |
| 701 RecordInternalError(ERR_USER_INPUT_WITH_NO_RELEVANT_LOAD); |
| 702 return; |
| 703 } |
| 704 |
| 705 committed_load_->OnInputEvent(event); |
| 706 } |
| 707 |
666 void MetricsWebContentsObserver::DidRedirectNavigation( | 708 void MetricsWebContentsObserver::DidRedirectNavigation( |
667 content::NavigationHandle* navigation_handle) { | 709 content::NavigationHandle* navigation_handle) { |
668 if (!navigation_handle->IsInMainFrame()) | 710 if (!navigation_handle->IsInMainFrame()) |
669 return; | 711 return; |
670 auto it = provisional_loads_.find(navigation_handle); | 712 auto it = provisional_loads_.find(navigation_handle); |
671 if (it == provisional_loads_.end()) | 713 if (it == provisional_loads_.end()) |
672 return; | 714 return; |
673 it->second->Redirect(navigation_handle); | 715 it->second->Redirect(navigation_handle); |
674 } | 716 } |
675 | 717 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 | 830 |
789 if (!committed_load_->UpdateTiming(timing, metadata)) { | 831 if (!committed_load_->UpdateTiming(timing, metadata)) { |
790 // If the page load tracker cannot update its timing, something is wrong | 832 // 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). | 833 // 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. | 834 // We expect this to be a rare occurrence. |
793 RecordInternalError(ERR_BAD_TIMING_IPC); | 835 RecordInternalError(ERR_BAD_TIMING_IPC); |
794 } | 836 } |
795 } | 837 } |
796 | 838 |
797 } // namespace page_load_metrics | 839 } // namespace page_load_metrics |
OLD | NEW |