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 // TODO(csharrison): Add this to the content public test API if we find that |
| 45 // this is useful in other places. |
| 46 // Delays WillProcessResponse until the caller tells it to cancel. |
| 47 class DelayWillProcessResponseThrottle : public content::NavigationThrottle { |
| 48 public: |
| 49 explicit DelayWillProcessResponseThrottle( |
| 50 content::NavigationHandle* navigation_handle) |
| 51 : NavigationThrottle(navigation_handle) {} |
| 52 |
| 53 // content::NavigationThrottle: |
| 54 ThrottleCheckResult WillProcessResponse() override { |
| 55 return NavigationThrottle::DEFER; |
| 56 } |
| 57 const char* GetNameForLogging() override { |
| 58 return "DelayWillProcessResponseThrottle"; |
| 59 } |
| 60 |
| 61 void CancelDeferredNavigation() { |
| 62 navigation_handle()->CancelDeferredNavigation(NavigationThrottle::CANCEL); |
| 63 } |
| 64 |
| 65 private: |
| 66 DISALLOW_COPY_AND_ASSIGN(DelayWillProcessResponseThrottle); |
| 67 }; |
| 68 |
| 69 // Adds a navigation throttle to the navigation which delays |
| 70 // WillProcessResponse. |
| 71 class DelayWillProcessResponseObserver : public content::WebContentsObserver { |
| 72 public: |
| 73 explicit DelayWillProcessResponseObserver(content::WebContents* contents) |
| 74 : content::WebContentsObserver(contents) {} |
| 75 |
| 76 // content::WebContentsObserver: |
| 77 void DidStartNavigation( |
| 78 content::NavigationHandle* navigation_handle) override { |
| 79 std::unique_ptr<content::NavigationThrottle> delay_throttle = |
| 80 base::MakeUnique<DelayWillProcessResponseThrottle>(navigation_handle); |
| 81 throttle_ = |
| 82 static_cast<DelayWillProcessResponseThrottle*>(delay_throttle.get()); |
| 83 navigation_handle->RegisterThrottleForTesting(std::move(delay_throttle)); |
| 84 } |
| 85 |
| 86 void LoadResourceForMainFrameAndResume( |
| 87 page_load_metrics::MetricsWebContentsObserver* observer) { |
| 88 DCHECK(throttle_); |
| 89 |
| 90 // Load a resource for the main frame before it commits. |
| 91 content::NavigationHandle* navigation_handle = |
| 92 throttle_->navigation_handle(); |
| 93 |
| 94 observer->OnRequestComplete( |
| 95 GURL(kNonAdUrl), |
| 96 navigation_handle->GetRenderFrameHost()->GetFrameTreeNodeId(), |
| 97 navigation_handle->GetGlobalRequestID(), |
| 98 content::RESOURCE_TYPE_MAIN_FRAME, false /* was_cached */, |
| 99 nullptr /* data_reduction_proxy */, 10 * 1024 /* raw_body_bytes */, |
| 100 0 /* original_network_content_length */, base::TimeTicks::Now()); |
| 101 |
| 102 throttle_->CancelDeferredNavigation(); |
| 103 } |
| 104 |
| 105 private: |
| 106 DelayWillProcessResponseThrottle* throttle_ = nullptr; |
| 107 content::GlobalRequestID global_request_id_; |
| 108 |
| 109 DISALLOW_COPY_AND_ASSIGN(DelayWillProcessResponseObserver); |
| 110 }; |
| 111 |
37 } // namespace | 112 } // namespace |
38 | 113 |
39 class AdsPageLoadMetricsObserverTest | 114 class AdsPageLoadMetricsObserverTest |
40 : public page_load_metrics::PageLoadMetricsObserverTestHarness { | 115 : public page_load_metrics::PageLoadMetricsObserverTestHarness { |
41 public: | 116 public: |
42 AdsPageLoadMetricsObserverTest() {} | 117 AdsPageLoadMetricsObserverTest() {} |
43 | 118 |
44 // Returns the final RenderFrameHost after navigation commits. | 119 // Returns the final RenderFrameHost after navigation commits. |
45 RenderFrameHost* NavigateFrame(const std::string& url, | 120 RenderFrameHost* NavigateFrame(const std::string& url, |
46 content::RenderFrameHost* frame) { | 121 content::RenderFrameHost* frame) { |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 | 673 |
599 // Test that a resource loaded into an unknown frame doesn't cause any | 674 // Test that a resource loaded into an unknown frame doesn't cause any |
600 // issues. | 675 // issues. |
601 histogram_tester().ExpectTotalCount( | 676 histogram_tester().ExpectTotalCount( |
602 "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", 0); | 677 "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", 0); |
603 LoadResource(child_of_subframe, ResourceCached::NOT_CACHED, 10); | 678 LoadResource(child_of_subframe, ResourceCached::NOT_CACHED, 10); |
604 histogram_tester().ExpectBucketCount( | 679 histogram_tester().ExpectBucketCount( |
605 "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", | 680 "PageLoad.Clients.Ads.Google.ResourceTypeWhenNoFrameFound", |
606 content::RESOURCE_TYPE_SUB_FRAME, 1); | 681 content::RESOURCE_TYPE_SUB_FRAME, 1); |
607 } | 682 } |
| 683 |
| 684 // Make sure that ads histograms aren't recorded if the tracker never commits |
| 685 // (see https://crbug.com/723219). |
| 686 TEST_F(AdsPageLoadMetricsObserverTest, NoHistogramWithoutCommit) { |
| 687 // Once the metrics observer has the GlobalRequestID, throttle. |
| 688 DelayWillProcessResponseObserver delay_observer(web_contents()); |
| 689 |
| 690 // Start main-frame navigation |
| 691 auto navigation_simulator = NavigationSimulator::CreateRendererInitiated( |
| 692 GURL(kNonAdUrl), web_contents()->GetMainFrame()); |
| 693 navigation_simulator->Start(); |
| 694 |
| 695 // This will be run once WillProcessResponse defers and the navigation |
| 696 // simulator runs the message loop waiting for the throttles to finish. |
| 697 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 698 FROM_HERE, |
| 699 base::Bind( |
| 700 &DelayWillProcessResponseObserver::LoadResourceForMainFrameAndResume, |
| 701 base::Unretained(&delay_observer), observer())); |
| 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 |