Chromium Code Reviews| 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 |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |