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 "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" | 5 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 20 matching lines...) Expand all Loading... | |
31 namespace { | 31 namespace { |
32 | 32 |
33 const char kDefaultTestUrl[] = "https://google.com/"; | 33 const char kDefaultTestUrl[] = "https://google.com/"; |
34 const char kDefaultTestUrlAnchor[] = "https://google.com/#samedocument"; | 34 const char kDefaultTestUrlAnchor[] = "https://google.com/#samedocument"; |
35 const char kDefaultTestUrl2[] = "https://whatever.com/"; | 35 const char kDefaultTestUrl2[] = "https://whatever.com/"; |
36 const char kFilteredStartUrl[] = "https://whatever.com/ignore-on-start"; | 36 const char kFilteredStartUrl[] = "https://whatever.com/ignore-on-start"; |
37 const char kFilteredCommitUrl[] = "https://whatever.com/ignore-on-commit"; | 37 const char kFilteredCommitUrl[] = "https://whatever.com/ignore-on-commit"; |
38 | 38 |
39 // Simple PageLoadMetricsObserver that copies observed PageLoadTimings into the | 39 // Simple PageLoadMetricsObserver that copies observed PageLoadTimings into the |
40 // provided std::vector, so they can be analyzed by unit tests. | 40 // provided std::vector, so they can be analyzed by unit tests. |
41 class TestPageLoadMetricsObserver | 41 class TestPageLoadMetricsObserver : public PageLoadMetricsObserver { |
42 : public PageLoadMetricsObserver, | |
43 public MetricsWebContentsObserver::TestingObserver { | |
44 public: | 42 public: |
45 TestPageLoadMetricsObserver( | 43 TestPageLoadMetricsObserver( |
46 content::WebContents* web_contents, | |
47 std::vector<mojom::PageLoadTimingPtr>* updated_timings, | 44 std::vector<mojom::PageLoadTimingPtr>* updated_timings, |
48 std::vector<mojom::PageLoadTimingPtr>* updated_subframe_timings, | 45 std::vector<mojom::PageLoadTimingPtr>* updated_subframe_timings, |
49 std::vector<mojom::PageLoadTimingPtr>* complete_timings, | 46 std::vector<mojom::PageLoadTimingPtr>* complete_timings, |
50 std::vector<GURL>* observed_committed_urls) | 47 std::vector<GURL>* observed_committed_urls) |
51 : MetricsWebContentsObserver::TestingObserver(web_contents), | 48 : updated_timings_(updated_timings), |
52 updated_timings_(updated_timings), | |
53 updated_subframe_timings_(updated_subframe_timings), | 49 updated_subframe_timings_(updated_subframe_timings), |
54 complete_timings_(complete_timings), | 50 complete_timings_(complete_timings), |
55 observed_committed_urls_(observed_committed_urls) {} | 51 observed_committed_urls_(observed_committed_urls) {} |
56 | 52 |
57 ObservePolicy OnStart(content::NavigationHandle* navigation_handle, | 53 ObservePolicy OnStart(content::NavigationHandle* navigation_handle, |
58 const GURL& currently_committed_url, | 54 const GURL& currently_committed_url, |
59 bool started_in_foreground) override { | 55 bool started_in_foreground) override { |
60 observed_committed_urls_->push_back(currently_committed_url); | 56 observed_committed_urls_->push_back(currently_committed_url); |
61 return CONTINUE_OBSERVING; | 57 return CONTINUE_OBSERVING; |
62 } | 58 } |
63 | 59 |
64 void OnTimingUpdate(const mojom::PageLoadTiming& timing, | 60 void OnTimingUpdate(bool is_subframe, |
61 const mojom::PageLoadTiming& timing, | |
65 const PageLoadExtraInfo& extra_info) override { | 62 const PageLoadExtraInfo& extra_info) override { |
66 updated_timings_->push_back(timing.Clone()); | 63 if (is_subframe) |
67 } | |
68 | |
69 void OnTimingUpdated(bool is_main_frame, | |
70 const mojom::PageLoadTiming& timing, | |
71 const mojom::PageLoadMetadata& metadata) override { | |
72 if (!is_main_frame) { | |
73 updated_subframe_timings_->push_back(timing.Clone()); | 64 updated_subframe_timings_->push_back(timing.Clone()); |
74 } | 65 else |
66 updated_timings_->push_back(timing.Clone()); | |
75 } | 67 } |
76 | 68 |
77 void OnComplete(const mojom::PageLoadTiming& timing, | 69 void OnComplete(const mojom::PageLoadTiming& timing, |
78 const PageLoadExtraInfo& extra_info) override { | 70 const PageLoadExtraInfo& extra_info) override { |
79 complete_timings_->push_back(timing.Clone()); | 71 complete_timings_->push_back(timing.Clone()); |
80 } | 72 } |
81 | 73 |
82 ObservePolicy FlushMetricsOnAppEnterBackground( | 74 ObservePolicy FlushMetricsOnAppEnterBackground( |
83 const mojom::PageLoadTiming& timing, | 75 const mojom::PageLoadTiming& timing, |
84 const PageLoadExtraInfo& extra_info) override { | 76 const PageLoadExtraInfo& extra_info) override { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
119 completed_filtered_urls_->push_back(extra_info.url); | 111 completed_filtered_urls_->push_back(extra_info.url); |
120 } | 112 } |
121 | 113 |
122 private: | 114 private: |
123 std::vector<GURL>* const completed_filtered_urls_; | 115 std::vector<GURL>* const completed_filtered_urls_; |
124 }; | 116 }; |
125 | 117 |
126 class TestPageLoadMetricsEmbedderInterface | 118 class TestPageLoadMetricsEmbedderInterface |
127 : public PageLoadMetricsEmbedderInterface { | 119 : public PageLoadMetricsEmbedderInterface { |
128 public: | 120 public: |
129 explicit TestPageLoadMetricsEmbedderInterface( | 121 TestPageLoadMetricsEmbedderInterface() : is_ntp_(false) {} |
130 content::WebContents* web_contents) | |
131 : web_contents_(web_contents), is_ntp_(false) {} | |
132 | 122 |
133 bool IsNewTabPageUrl(const GURL& url) override { return is_ntp_; } | 123 bool IsNewTabPageUrl(const GURL& url) override { return is_ntp_; } |
134 void set_is_ntp(bool is_ntp) { is_ntp_ = is_ntp; } | 124 void set_is_ntp(bool is_ntp) { is_ntp_ = is_ntp; } |
135 void RegisterObservers(PageLoadTracker* tracker) override { | 125 void RegisterObservers(PageLoadTracker* tracker) override { |
136 tracker->AddObserver(base::MakeUnique<TestPageLoadMetricsObserver>( | 126 tracker->AddObserver(base::MakeUnique<TestPageLoadMetricsObserver>( |
137 web_contents_, &updated_timings_, &updated_subframe_timings_, | 127 &updated_timings_, &updated_subframe_timings_, &complete_timings_, |
138 &complete_timings_, &observed_committed_urls_)); | 128 &observed_committed_urls_)); |
139 tracker->AddObserver(base::MakeUnique<FilteringPageLoadMetricsObserver>( | 129 tracker->AddObserver(base::MakeUnique<FilteringPageLoadMetricsObserver>( |
140 &completed_filtered_urls_)); | 130 &completed_filtered_urls_)); |
141 } | 131 } |
142 const std::vector<mojom::PageLoadTimingPtr>& updated_timings() const { | 132 const std::vector<mojom::PageLoadTimingPtr>& updated_timings() const { |
143 return updated_timings_; | 133 return updated_timings_; |
144 } | 134 } |
145 const std::vector<mojom::PageLoadTimingPtr>& complete_timings() const { | 135 const std::vector<mojom::PageLoadTimingPtr>& complete_timings() const { |
146 return complete_timings_; | 136 return complete_timings_; |
147 } | 137 } |
148 const std::vector<mojom::PageLoadTimingPtr>& updated_subframe_timings() | 138 const std::vector<mojom::PageLoadTimingPtr>& updated_subframe_timings() |
(...skipping 10 matching lines...) Expand all Loading... | |
159 const std::vector<GURL>& completed_filtered_urls() const { | 149 const std::vector<GURL>& completed_filtered_urls() const { |
160 return completed_filtered_urls_; | 150 return completed_filtered_urls_; |
161 } | 151 } |
162 | 152 |
163 private: | 153 private: |
164 std::vector<mojom::PageLoadTimingPtr> updated_timings_; | 154 std::vector<mojom::PageLoadTimingPtr> updated_timings_; |
165 std::vector<mojom::PageLoadTimingPtr> updated_subframe_timings_; | 155 std::vector<mojom::PageLoadTimingPtr> updated_subframe_timings_; |
166 std::vector<mojom::PageLoadTimingPtr> complete_timings_; | 156 std::vector<mojom::PageLoadTimingPtr> complete_timings_; |
167 std::vector<GURL> observed_committed_urls_; | 157 std::vector<GURL> observed_committed_urls_; |
168 std::vector<GURL> completed_filtered_urls_; | 158 std::vector<GURL> completed_filtered_urls_; |
169 content::WebContents* web_contents_; | |
170 bool is_ntp_; | 159 bool is_ntp_; |
171 }; | 160 }; |
172 | 161 |
173 } // namespace | 162 } // namespace |
174 | 163 |
175 class MetricsWebContentsObserverTest : public ChromeRenderViewHostTestHarness { | 164 class MetricsWebContentsObserverTest : public ChromeRenderViewHostTestHarness { |
176 public: | 165 public: |
177 MetricsWebContentsObserverTest() : num_errors_(0) {} | 166 MetricsWebContentsObserverTest() : num_errors_(0) {} |
178 | 167 |
179 void SetUp() override { | 168 void SetUp() override { |
180 ChromeRenderViewHostTestHarness::SetUp(); | 169 ChromeRenderViewHostTestHarness::SetUp(); |
181 AttachObserver(); | 170 AttachObserver(); |
182 } | 171 } |
183 | 172 |
184 void NavigateToUntrackedUrl() { | 173 void NavigateToUntrackedUrl() { |
185 content::WebContentsTester::For(web_contents()) | 174 content::WebContentsTester::For(web_contents()) |
186 ->NavigateAndCommit(GURL(url::kAboutBlankURL)); | 175 ->NavigateAndCommit(GURL(url::kAboutBlankURL)); |
187 } | 176 } |
188 | 177 |
189 void SimulateTimingUpdate(const mojom::PageLoadTiming& timing) { | 178 void SimulateTimingUpdate(const mojom::PageLoadTiming& timing) { |
190 SimulateTimingUpdate(timing, web_contents()->GetMainFrame()); | 179 SimulateTimingUpdate(timing, web_contents()->GetMainFrame()); |
191 } | 180 } |
192 | 181 |
193 void SimulateTimingUpdate(const mojom::PageLoadTiming& timing, | 182 void SimulateTimingUpdate(const mojom::PageLoadTiming& timing, |
194 content::RenderFrameHost* render_frame_host) { | 183 content::RenderFrameHost* render_frame_host) { |
195 observer_->OnTimingUpdated(render_frame_host, timing, | 184 observer()->OnTimingUpdated(render_frame_host, timing, |
196 mojom::PageLoadMetadata()); | 185 mojom::PageLoadMetadata()); |
197 } | 186 } |
198 | 187 |
199 void AttachObserver() { | 188 void AttachObserver() { |
200 embedder_interface_ = | 189 embedder_interface_ = new TestPageLoadMetricsEmbedderInterface(); |
Charlie Harrison
2017/05/25 19:35:33
optional nit to avoid bare new (I know this is old
Bryan McQuade
2017/05/25 19:54:05
Good idea, this makes it clearer that we're holdin
| |
201 new TestPageLoadMetricsEmbedderInterface(web_contents()); | 190 MetricsWebContentsObserver* observer = |
202 // Owned by the web_contents. Tests must be careful not to call | 191 MetricsWebContentsObserver::CreateForWebContents( |
203 // SimulateTimingUpdate after they call DeleteContents() without also | 192 web_contents(), base::WrapUnique(embedder_interface_)); |
204 // calling AttachObserver() again. Otherwise they will use-after-free the | 193 observer->WasShown(); |
205 // observer_. | |
206 observer_ = MetricsWebContentsObserver::CreateForWebContents( | |
207 web_contents(), base::WrapUnique(embedder_interface_)); | |
208 observer_->WasShown(); | |
209 } | 194 } |
210 | 195 |
211 void CheckErrorEvent(InternalErrorLoadEvent error, int count) { | 196 void CheckErrorEvent(InternalErrorLoadEvent error, int count) { |
212 histogram_tester_.ExpectBucketCount(internal::kErrorEvents, error, count); | 197 histogram_tester_.ExpectBucketCount(internal::kErrorEvents, error, count); |
213 num_errors_ += count; | 198 num_errors_ += count; |
214 } | 199 } |
215 | 200 |
216 void CheckTotalErrorEvents() { | 201 void CheckTotalErrorEvents() { |
217 histogram_tester_.ExpectTotalCount(internal::kErrorEvents, num_errors_); | 202 histogram_tester_.ExpectTotalCount(internal::kErrorEvents, num_errors_); |
218 } | 203 } |
(...skipping 29 matching lines...) Expand all Loading... | |
248 | 233 |
249 const std::vector<GURL>& observed_committed_urls_from_on_start() const { | 234 const std::vector<GURL>& observed_committed_urls_from_on_start() const { |
250 return embedder_interface_->observed_committed_urls_from_on_start(); | 235 return embedder_interface_->observed_committed_urls_from_on_start(); |
251 } | 236 } |
252 | 237 |
253 const std::vector<GURL>& completed_filtered_urls() const { | 238 const std::vector<GURL>& completed_filtered_urls() const { |
254 return embedder_interface_->completed_filtered_urls(); | 239 return embedder_interface_->completed_filtered_urls(); |
255 } | 240 } |
256 | 241 |
257 protected: | 242 protected: |
243 MetricsWebContentsObserver* observer() { | |
244 return MetricsWebContentsObserver::FromWebContents(web_contents()); | |
245 } | |
246 | |
258 base::HistogramTester histogram_tester_; | 247 base::HistogramTester histogram_tester_; |
259 TestPageLoadMetricsEmbedderInterface* embedder_interface_; | 248 TestPageLoadMetricsEmbedderInterface* embedder_interface_; |
260 MetricsWebContentsObserver* observer_; | |
261 | 249 |
262 private: | 250 private: |
263 int num_errors_; | 251 int num_errors_; |
264 | 252 |
265 DISALLOW_COPY_AND_ASSIGN(MetricsWebContentsObserverTest); | 253 DISALLOW_COPY_AND_ASSIGN(MetricsWebContentsObserverTest); |
266 }; | 254 }; |
267 | 255 |
268 TEST_F(MetricsWebContentsObserverTest, SuccessfulMainFrameNavigation) { | 256 TEST_F(MetricsWebContentsObserverTest, SuccessfulMainFrameNavigation) { |
269 mojom::PageLoadTiming timing; | 257 mojom::PageLoadTiming timing; |
270 page_load_metrics::InitPageLoadTimingForTest(&timing); | 258 page_load_metrics::InitPageLoadTimingForTest(&timing); |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
641 } | 629 } |
642 | 630 |
643 TEST_F(MetricsWebContentsObserverTest, FlushMetricsOnAppEnterBackground) { | 631 TEST_F(MetricsWebContentsObserverTest, FlushMetricsOnAppEnterBackground) { |
644 content::WebContentsTester* web_contents_tester = | 632 content::WebContentsTester* web_contents_tester = |
645 content::WebContentsTester::For(web_contents()); | 633 content::WebContentsTester::For(web_contents()); |
646 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); | 634 web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); |
647 | 635 |
648 histogram_tester_.ExpectTotalCount( | 636 histogram_tester_.ExpectTotalCount( |
649 internal::kPageLoadCompletedAfterAppBackground, 0); | 637 internal::kPageLoadCompletedAfterAppBackground, 0); |
650 | 638 |
651 observer_->FlushMetricsOnAppEnterBackground(); | 639 observer()->FlushMetricsOnAppEnterBackground(); |
652 | 640 |
653 histogram_tester_.ExpectTotalCount( | 641 histogram_tester_.ExpectTotalCount( |
654 internal::kPageLoadCompletedAfterAppBackground, 1); | 642 internal::kPageLoadCompletedAfterAppBackground, 1); |
655 histogram_tester_.ExpectBucketCount( | 643 histogram_tester_.ExpectBucketCount( |
656 internal::kPageLoadCompletedAfterAppBackground, false, 1); | 644 internal::kPageLoadCompletedAfterAppBackground, false, 1); |
657 histogram_tester_.ExpectBucketCount( | 645 histogram_tester_.ExpectBucketCount( |
658 internal::kPageLoadCompletedAfterAppBackground, true, 0); | 646 internal::kPageLoadCompletedAfterAppBackground, true, 0); |
659 | 647 |
660 // Navigate again, which forces completion callbacks on the previous | 648 // Navigate again, which forces completion callbacks on the previous |
661 // navigation to be invoked. | 649 // navigation to be invoked. |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
801 ASSERT_EQ(2, CountUpdatedTimingReported()); | 789 ASSERT_EQ(2, CountUpdatedTimingReported()); |
802 ASSERT_EQ(0, CountEmptyCompleteTimingReported()); | 790 ASSERT_EQ(0, CountEmptyCompleteTimingReported()); |
803 | 791 |
804 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); | 792 ASSERT_EQ(1, CountUpdatedSubFrameTimingReported()); |
805 EXPECT_TRUE(subframe_timing.Equals(*updated_subframe_timings().back())); | 793 EXPECT_TRUE(subframe_timing.Equals(*updated_subframe_timings().back())); |
806 | 794 |
807 CheckNoErrorEvents(); | 795 CheckNoErrorEvents(); |
808 } | 796 } |
809 | 797 |
810 } // namespace page_load_metrics | 798 } // namespace page_load_metrics |
OLD | NEW |