Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/observers/ads_page_load_metrics_obser ver.h" | 5 #include "chrome/browser/page_load_metrics/observers/ads_page_load_metrics_obser ver.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "base/test/histogram_tester.h" | 10 #include "base/test/histogram_tester.h" |
| 11 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" | |
| 11 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_ test_harness.h" | 12 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_ test_harness.h" |
| 12 #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" | 13 #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" |
| 13 #include "chrome/browser/page_load_metrics/page_load_tracker.h" | 14 #include "chrome/browser/page_load_metrics/page_load_tracker.h" |
| 15 #include "content/public/browser/global_request_id.h" | |
| 16 #include "content/public/browser/navigation_handle.h" | |
| 17 #include "content/public/browser/navigation_throttle.h" | |
| 14 #include "content/public/browser/render_frame_host.h" | 18 #include "content/public/browser/render_frame_host.h" |
| 15 #include "content/public/browser/web_contents.h" | 19 #include "content/public/browser/web_contents.h" |
| 20 #include "content/public/browser/web_contents_observer.h" | |
| 16 #include "content/public/common/resource_type.h" | 21 #include "content/public/common/resource_type.h" |
| 17 #include "content/public/test/navigation_simulator.h" | 22 #include "content/public/test/navigation_simulator.h" |
| 18 #include "content/public/test/test_renderer_host.h" | 23 #include "content/public/test/test_renderer_host.h" |
| 19 #include "url/gurl.h" | 24 #include "url/gurl.h" |
| 20 | 25 |
| 21 using content::RenderFrameHost; | 26 using content::RenderFrameHost; |
| 22 using content::RenderFrameHostTester; | 27 using content::RenderFrameHostTester; |
| 23 using content::NavigationSimulator; | 28 using content::NavigationSimulator; |
| 24 | 29 |
| 25 namespace { | 30 namespace { |
| 26 | 31 |
| 27 enum class ResourceCached { NOT_CACHED, CACHED }; | 32 enum class ResourceCached { NOT_CACHED, CACHED }; |
| 28 enum class FrameType { AD = 0, NON_AD }; | 33 enum class FrameType { AD = 0, NON_AD }; |
| 29 | 34 |
| 30 const char kAdUrl[] = "https://tpc.googlesyndication.com/safeframe/1"; | 35 const char kAdUrl[] = "https://tpc.googlesyndication.com/safeframe/1"; |
| 31 const char kNonAdUrl[] = "https://foo.com/"; | 36 const char kNonAdUrl[] = "https://foo.com/"; |
| 32 const char kNonAdUrl2[] = "https://bar.com/"; | 37 const char kNonAdUrl2[] = "https://bar.com/"; |
| 33 | 38 |
| 34 const char kAdName[] = "google_ads_iframe_1"; | 39 const char kAdName[] = "google_ads_iframe_1"; |
| 35 const char kNonAdName[] = "foo"; | 40 const char kNonAdName[] = "foo"; |
| 36 | 41 |
| 42 class DelayWillProcessResponseObserver; | |
| 43 | |
| 44 // Delays WillProcessResponse until the caller tells it to cancel. | |
|
Charlie Harrison
2017/05/17 18:54:51
Would you add a TODO(csharrison) to add this to th
jkarlin
2017/05/18 13:50:13
Done.
| |
| 45 class DelayWillProcessResponseThrottle : public content::NavigationThrottle { | |
| 46 public: | |
| 47 explicit DelayWillProcessResponseThrottle( | |
| 48 content::NavigationHandle* navigation_handle) | |
| 49 : NavigationThrottle(navigation_handle) {} | |
| 50 | |
| 51 // NavigationThrottle overrides | |
|
Charlie Harrison
2017/05/17 18:54:50
// content::NavigationThrottle:
jkarlin
2017/05/18 13:50:13
Done.
| |
| 52 ThrottleCheckResult WillProcessResponse() override { | |
| 53 return NavigationThrottle::DEFER; | |
| 54 } | |
| 55 const char* GetNameForLogging() override { | |
| 56 return "DelayWillProcessResponseThrottle"; | |
| 57 } | |
| 58 | |
| 59 void CancelDeferredNavigation() { | |
| 60 navigation_handle()->CancelDeferredNavigation(NavigationThrottle::CANCEL); | |
| 61 } | |
| 62 | |
| 63 content::GlobalRequestID GetGlobalRequestID() const { | |
| 64 return navigation_handle()->GetGlobalRequestID(); | |
| 65 } | |
| 66 | |
| 67 private: | |
| 68 DISALLOW_COPY_AND_ASSIGN(DelayWillProcessResponseThrottle); | |
| 69 }; | |
| 70 | |
| 71 // Adds a navigation throttle to the navigation which delays | |
| 72 // WillProcessResponse. | |
| 73 class DelayWillProcessResponseObserver : public content::WebContentsObserver { | |
| 74 public: | |
| 75 explicit DelayWillProcessResponseObserver(content::WebContents* contents) | |
| 76 : WebContentsObserver(contents), throttle_(nullptr) {} | |
|
Charlie Harrison
2017/05/17 18:54:50
Hm why don't you need content:: prefix to WebConte
Charlie Harrison
2017/05/17 18:54:50
Don't need to set throttle_ to nullptr here since
jkarlin
2017/05/18 13:50:13
Done.
jkarlin
2017/05/18 13:50:13
I have no idea. Added for clarity.
| |
| 77 | |
| 78 // WebContentsObserver override | |
|
Charlie Harrison
2017/05/17 18:54:50
// content::WebContentsObserver:
jkarlin
2017/05/18 13:50:13
Done.
| |
| 79 void DidStartNavigation( | |
| 80 content::NavigationHandle* navigation_handle) override { | |
| 81 std::unique_ptr<content::NavigationThrottle> delay_throttle = | |
| 82 base::MakeUnique<DelayWillProcessResponseThrottle>(navigation_handle); | |
| 83 throttle_ = | |
| 84 static_cast<DelayWillProcessResponseThrottle*>(delay_throttle.get()); | |
| 85 navigation_handle->RegisterThrottleForTesting(std::move(delay_throttle)); | |
| 86 } | |
| 87 | |
| 88 DelayWillProcessResponseThrottle* throttle() const { return throttle_; } | |
| 89 | |
| 90 private: | |
| 91 DelayWillProcessResponseThrottle* throttle_ = nullptr; | |
| 92 content::GlobalRequestID global_request_id_; | |
| 93 | |
| 94 DISALLOW_COPY_AND_ASSIGN(DelayWillProcessResponseObserver); | |
| 95 }; | |
| 96 | |
| 97 void LoadResourceForMainFrameAndResume( | |
|
Charlie Harrison
2017/05/17 18:54:50
Why not include this as a method in the delay obse
jkarlin
2017/05/18 13:50:13
Done.
| |
| 98 page_load_metrics::MetricsWebContentsObserver* observer, | |
| 99 DelayWillProcessResponseThrottle* throttle) { | |
| 100 // Load a resource for the main frame before it commits. | |
| 101 content::NavigationHandle* navigation_handle = throttle->navigation_handle(); | |
| 102 | |
| 103 observer->OnRequestComplete( | |
| 104 GURL(kNonAdUrl), | |
| 105 navigation_handle->GetRenderFrameHost()->GetFrameTreeNodeId(), | |
| 106 navigation_handle->GetGlobalRequestID(), | |
| 107 content::RESOURCE_TYPE_MAIN_FRAME, false /* was_cached */, | |
| 108 nullptr /* data_reduction_proxy */, 10 * 1024 /* raw_body_bytes */, | |
| 109 0 /* original_network_content_length */, base::TimeTicks::Now()); | |
| 110 | |
| 111 throttle->CancelDeferredNavigation(); | |
| 112 } | |
| 113 | |
| 37 } // namespace | 114 } // namespace |
| 38 | 115 |
| 39 class AdsPageLoadMetricsObserverTest | 116 class AdsPageLoadMetricsObserverTest |
| 40 : public page_load_metrics::PageLoadMetricsObserverTestHarness { | 117 : public page_load_metrics::PageLoadMetricsObserverTestHarness { |
| 41 public: | 118 public: |
| 42 AdsPageLoadMetricsObserverTest() {} | 119 AdsPageLoadMetricsObserverTest() {} |
| 43 | 120 |
| 44 // Returns the final RenderFrameHost after navigation commits. | 121 // Returns the final RenderFrameHost after navigation commits. |
| 45 RenderFrameHost* NavigateFrame(const std::string& url, | 122 RenderFrameHost* NavigateFrame(const std::string& url, |
| 46 content::RenderFrameHost* frame) { | 123 content::RenderFrameHost* frame) { |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 598 | 675 |
| 599 // Test that a resource loaded into an unknown frame doesn't cause any | 676 // Test that a resource loaded into an unknown frame doesn't cause any |
| 600 // issues. | 677 // issues. |
| 601 histogram_tester().ExpectTotalCount( | 678 histogram_tester().ExpectTotalCount( |
| 602 "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", 0); | 679 "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", 0); |
| 603 LoadResource(child_of_subframe, ResourceCached::NOT_CACHED, 10); | 680 LoadResource(child_of_subframe, ResourceCached::NOT_CACHED, 10); |
| 604 histogram_tester().ExpectBucketCount( | 681 histogram_tester().ExpectBucketCount( |
| 605 "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", | 682 "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", |
| 606 content::RESOURCE_TYPE_SUB_FRAME, 1); | 683 content::RESOURCE_TYPE_SUB_FRAME, 1); |
| 607 } | 684 } |
| 685 | |
| 686 // Make sure that ads histograms aren't recorded if the tracker never commits | |
| 687 // (see https://crbug.com/723219). | |
| 688 TEST_F(AdsPageLoadMetricsObserverTest, NoHistogramWithoutCommit) { | |
| 689 // Once the metrics observer has the GlobalRequestID, throttle. | |
| 690 DelayWillProcessResponseObserver delay_observer(web_contents()); | |
| 691 | |
| 692 // Start main-frame navigation | |
| 693 auto navigation_simulator = NavigationSimulator::CreateRendererInitiated( | |
| 694 GURL(kNonAdUrl), web_contents()->GetMainFrame()); | |
| 695 navigation_simulator->Start(); | |
| 696 | |
| 697 // This will be run once WillProcessResponse defers and the navigation | |
| 698 // simulator runs the message loop waiting for the throttles to finish. | |
| 699 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 700 FROM_HERE, base::Bind(&LoadResourceForMainFrameAndResume, observer(), | |
| 701 delay_observer.throttle())); | |
| 702 | |
| 703 // The commit will defer after calling WillProcessNavigationResponse, it | |
| 704 // will load a resource, and then the throttle will cancel the commit. | |
| 705 navigation_simulator->Commit(); | |
| 706 | |
| 707 // There shouldn't be any histograms for an aborted main frame. | |
| 708 EXPECT_EQ(0u, histogram_tester() | |
| 709 .GetTotalCountsForPrefix("PageLoad.Clients.Ads.") | |
| 710 .size()); | |
| 711 } | |
| OLD | NEW |