Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Side by Side Diff: chrome/browser/predictors/loading_data_collector.cc

Issue 2937623007: predictors: Move more methods from ResourcePrefetchPredictor into LoadingDataCollector. (Closed)
Patch Set: Make InitializationState type public. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <string> 5 #include <string>
6 6
7 #include "chrome/browser/predictors/loading_data_collector.h" 7 #include "chrome/browser/predictors/loading_data_collector.h"
8 #include "chrome/browser/predictors/loading_stats_collector.h"
8 #include "chrome/browser/profiles/profile.h" 9 #include "chrome/browser/profiles/profile.h"
10 #include "components/history/core/browser/history_service.h"
9 #include "components/mime_util/mime_util.h" 11 #include "components/mime_util/mime_util.h"
10 #include "content/public/browser/resource_request_info.h" 12 #include "content/public/browser/resource_request_info.h"
11 #include "content/public/common/resource_type.h" 13 #include "content/public/common/resource_type.h"
12 #include "net/url_request/url_request.h" 14 #include "net/url_request/url_request.h"
13 15
16 using content::BrowserThread;
17
14 namespace predictors { 18 namespace predictors {
15 19
16 namespace { 20 namespace {
17 21
22 using PageRequestSummary =
23 predictors::ResourcePrefetchPredictor::PageRequestSummary;
trevordixon 2017/06/14 08:04:34 Might make sense to move PageRequestSummary into l
alexilin 2017/06/14 11:41:54 I'd suggest you to move all of OriginRequestSummar
trevordixon 2017/06/16 05:11:28 Done.
24
18 bool g_allow_port_in_urls = false; 25 bool g_allow_port_in_urls = false;
19 26
27 void UpdateOrAddToOrigins(
28 std::map<GURL, ResourcePrefetchPredictor::OriginRequestSummary>* summaries,
29 const ResourcePrefetchPredictor::URLRequestSummary& request_summary) {
30 const GURL& request_url = request_summary.request_url;
31 DCHECK(request_url.is_valid());
32 if (!request_url.is_valid())
33 return;
34
35 GURL origin = request_url.GetOrigin();
36 auto it = summaries->find(origin);
37 if (it == summaries->end()) {
38 ResourcePrefetchPredictor::OriginRequestSummary summary;
39 summary.origin = origin;
40 summary.first_occurrence = summaries->size();
41 it = summaries->insert({origin, summary}).first;
42 }
43
44 it->second.always_access_network |=
45 request_summary.always_revalidate || request_summary.is_no_store;
46 it->second.accessed_network |= request_summary.network_accessed;
47 }
48
20 } // namespace 49 } // namespace
21 50
22 // static 51 // static
23 bool LoadingDataCollector::ShouldRecordRequest( 52 bool LoadingDataCollector::ShouldRecordRequest(
24 net::URLRequest* request, 53 net::URLRequest* request,
25 content::ResourceType resource_type) { 54 content::ResourceType resource_type) {
26 const content::ResourceRequestInfo* request_info = 55 const content::ResourceRequestInfo* request_info =
27 content::ResourceRequestInfo::ForRequest(request); 56 content::ResourceRequestInfo::ForRequest(request);
28 if (!request_info) 57 if (!request_info)
29 return false; 58 return false;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 actual_resource_type == content::RESOURCE_TYPE_SCRIPT || 132 actual_resource_type == content::RESOURCE_TYPE_SCRIPT ||
104 actual_resource_type == content::RESOURCE_TYPE_IMAGE || 133 actual_resource_type == content::RESOURCE_TYPE_IMAGE ||
105 actual_resource_type == content::RESOURCE_TYPE_FONT_RESOURCE; 134 actual_resource_type == content::RESOURCE_TYPE_FONT_RESOURCE;
106 } 135 }
107 136
108 // static 137 // static
109 void LoadingDataCollector::SetAllowPortInUrlsForTesting(bool state) { 138 void LoadingDataCollector::SetAllowPortInUrlsForTesting(bool state) {
110 g_allow_port_in_urls = state; 139 g_allow_port_in_urls = state;
111 } 140 }
112 141
113 LoadingDataCollector::LoadingDataCollector(ResourcePrefetchPredictor* predictor) 142 LoadingDataCollector::LoadingDataCollector(
114 : predictor_(predictor) {} 143 ResourcePrefetchPredictor* predictor,
144 predictors::LoadingStatsCollector* stats_collector,
145 const LoadingPredictorConfig& config)
146 : predictor_(predictor),
147 stats_collector_(stats_collector),
148 config_(config) {}
115 149
116 LoadingDataCollector::~LoadingDataCollector() {} 150 LoadingDataCollector::~LoadingDataCollector() {}
117 151
118 void LoadingDataCollector::RecordURLRequest( 152 void LoadingDataCollector::RecordURLRequest(
119 const ResourcePrefetchPredictor::URLRequestSummary& request) { 153 const ResourcePrefetchPredictor::URLRequestSummary& request) {
120 predictor_->RecordURLRequest(request); 154 DCHECK_CURRENTLY_ON(BrowserThread::UI);
155 if (predictor_->initialization_state() !=
156 ResourcePrefetchPredictor::INITIALIZED)
trevordixon 2017/06/14 08:04:34 I copied all of the initialization_state checks ov
alexilin 2017/06/14 11:41:54 Yeah, initialization is only needed for ResourcePr
trevordixon 2017/06/16 05:11:28 Done.
157 return;
158
159 CHECK_EQ(request.resource_type, content::RESOURCE_TYPE_MAIN_FRAME);
160 OnMainFrameRequest(request);
121 } 161 }
122 162
123 void LoadingDataCollector::RecordURLResponse( 163 void LoadingDataCollector::RecordURLResponse(
124 const ResourcePrefetchPredictor::URLRequestSummary& response) { 164 const ResourcePrefetchPredictor::URLRequestSummary& response) {
125 predictor_->RecordURLResponse(response); 165 DCHECK_CURRENTLY_ON(BrowserThread::UI);
166 if (predictor_->initialization_state() !=
167 ResourcePrefetchPredictor::INITIALIZED)
168 return;
169
170 if (response.resource_type != content::RESOURCE_TYPE_MAIN_FRAME)
171 OnSubresourceResponse(response);
126 } 172 }
127 173
128 void LoadingDataCollector::RecordURLRedirect( 174 void LoadingDataCollector::RecordURLRedirect(
129 const ResourcePrefetchPredictor::URLRequestSummary& response) { 175 const ResourcePrefetchPredictor::URLRequestSummary& response) {
130 predictor_->RecordURLRedirect(response); 176 DCHECK_CURRENTLY_ON(BrowserThread::UI);
177 if (predictor_->initialization_state() !=
178 ResourcePrefetchPredictor::INITIALIZED)
179 return;
180
181 if (response.resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
182 OnMainFrameRedirect(response);
183 else
184 OnSubresourceRedirect(response);
131 } 185 }
132 186
133 void LoadingDataCollector::RecordMainFrameLoadComplete( 187 void LoadingDataCollector::RecordMainFrameLoadComplete(
134 const NavigationID& navigation_id) { 188 const NavigationID& navigation_id) {
135 predictor_->RecordMainFrameLoadComplete(navigation_id); 189 switch (predictor_->initialization_state()) {
190 case ResourcePrefetchPredictor::NOT_INITIALIZED:
191 predictor_->StartInitialization();
192 break;
193 case ResourcePrefetchPredictor::INITIALIZING:
194 break;
195 case ResourcePrefetchPredictor::INITIALIZED:
196 // WebContents can return an empty URL if the navigation entry
197 // corresponding to the navigation has not been created yet.
198 if (!navigation_id.main_frame_url.is_empty())
199 OnNavigationComplete(navigation_id);
200 break;
201 default:
202 NOTREACHED() << "Unexpected initialization_state_: "
203 << predictor_->initialization_state();
204 }
136 } 205 }
137 206
138 void LoadingDataCollector::RecordFirstContentfulPaint( 207 void LoadingDataCollector::RecordFirstContentfulPaint(
139 const NavigationID& navigation_id, 208 const NavigationID& navigation_id,
140 const base::TimeTicks& first_contentful_paint) { 209 const base::TimeTicks& first_contentful_paint) {
141 predictor_->RecordFirstContentfulPaint(navigation_id, first_contentful_paint); 210 DCHECK_CURRENTLY_ON(BrowserThread::UI);
211 if (predictor_->initialization_state() !=
212 ResourcePrefetchPredictor::INITIALIZED)
213 return;
214
215 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id);
216 if (nav_it != inflight_navigations_.end())
217 nav_it->second->first_contentful_paint = first_contentful_paint;
218 }
219
220 void LoadingDataCollector::OnMainFrameRequest(
221 const ResourcePrefetchPredictor::URLRequestSummary& request) {
222 DCHECK_CURRENTLY_ON(BrowserThread::UI);
223 DCHECK_EQ(ResourcePrefetchPredictor::INITIALIZED,
224 predictor_->initialization_state());
225
226 CleanupAbandonedNavigations(request.navigation_id);
227
228 // New empty navigation entry.
229 const GURL& main_frame_url = request.navigation_id.main_frame_url;
230 inflight_navigations_.emplace(
231 request.navigation_id,
232 base::MakeUnique<PageRequestSummary>(main_frame_url));
233 }
234
235 void LoadingDataCollector::OnMainFrameRedirect(
236 const ResourcePrefetchPredictor::URLRequestSummary& response) {
237 DCHECK_CURRENTLY_ON(BrowserThread::UI);
238 DCHECK_EQ(ResourcePrefetchPredictor::INITIALIZED,
239 predictor_->initialization_state());
240
241 const GURL& main_frame_url = response.navigation_id.main_frame_url;
242 std::unique_ptr<PageRequestSummary> summary;
243 NavigationMap::iterator nav_it =
244 inflight_navigations_.find(response.navigation_id);
245 if (nav_it != inflight_navigations_.end()) {
246 summary = std::move(nav_it->second);
247 inflight_navigations_.erase(nav_it);
248 }
249
250 // The redirect url may be empty if the URL was invalid.
251 if (response.redirect_url.is_empty())
252 return;
253
254 // If we lost the information about the first hop for some reason.
255 if (!summary) {
256 summary = base::MakeUnique<PageRequestSummary>(main_frame_url);
257 }
258
259 // A redirect will not lead to another OnMainFrameRequest call, so record the
260 // redirect url as a new navigation id and save the initial url.
261 NavigationID navigation_id(response.navigation_id);
262 navigation_id.main_frame_url = response.redirect_url;
263 summary->main_frame_url = response.redirect_url;
264 inflight_navigations_.emplace(navigation_id, std::move(summary));
265 }
266
267 void LoadingDataCollector::OnSubresourceResponse(
268 const ResourcePrefetchPredictor::URLRequestSummary& response) {
269 DCHECK_CURRENTLY_ON(BrowserThread::UI);
270 DCHECK_EQ(ResourcePrefetchPredictor::INITIALIZED,
271 predictor_->initialization_state());
272
273 NavigationMap::const_iterator nav_it =
274 inflight_navigations_.find(response.navigation_id);
275 if (nav_it == inflight_navigations_.end())
276 return;
277 auto& page_request_summary = *nav_it->second;
278
279 if (!response.is_no_store)
280 page_request_summary.subresource_requests.push_back(response);
281
282 if (config_.is_origin_learning_enabled)
283 UpdateOrAddToOrigins(&page_request_summary.origins, response);
284 }
285
286 void LoadingDataCollector::OnSubresourceRedirect(
287 const ResourcePrefetchPredictor::URLRequestSummary& response) {
288 DCHECK_CURRENTLY_ON(BrowserThread::UI);
289 DCHECK_EQ(ResourcePrefetchPredictor::INITIALIZED,
290 predictor_->initialization_state());
291
292 if (!config_.is_origin_learning_enabled)
293 return;
294
295 NavigationMap::const_iterator nav_it =
296 inflight_navigations_.find(response.navigation_id);
297 if (nav_it == inflight_navigations_.end())
298 return;
299 auto& page_request_summary = *nav_it->second;
300 UpdateOrAddToOrigins(&page_request_summary.origins, response);
301 }
302
303 void LoadingDataCollector::OnNavigationComplete(
304 const NavigationID& nav_id_without_timing_info) {
305 DCHECK_CURRENTLY_ON(BrowserThread::UI);
306 DCHECK_EQ(ResourcePrefetchPredictor::INITIALIZED,
307 predictor_->initialization_state());
308
309 NavigationMap::iterator nav_it =
310 inflight_navigations_.find(nav_id_without_timing_info);
311 if (nav_it == inflight_navigations_.end())
312 return;
313
314 // Remove the navigation from the inflight navigations.
315 std::unique_ptr<PageRequestSummary> summary = std::move(nav_it->second);
316 inflight_navigations_.erase(nav_it);
317
318 // Set before_first_contentful paint for each resource.
319 for (auto& request_summary : summary->subresource_requests) {
320 request_summary.before_first_contentful_paint =
321 request_summary.response_time < summary->first_contentful_paint;
322 }
323
324 if (stats_collector_)
325 stats_collector_->RecordPageRequestSummary(*summary);
326
327 predictor_->HandlePageRequestSummary(std::move(summary));
328 }
329
330 void LoadingDataCollector::CleanupAbandonedNavigations(
331 const NavigationID& navigation_id) {
332 if (stats_collector_)
333 stats_collector_->CleanupAbandonedStats();
334
335 static const base::TimeDelta max_navigation_age =
336 base::TimeDelta::FromSeconds(config_.max_navigation_lifetime_seconds);
337
338 base::TimeTicks time_now = base::TimeTicks::Now();
339 for (NavigationMap::iterator it = inflight_navigations_.begin();
340 it != inflight_navigations_.end();) {
341 if ((it->first.tab_id == navigation_id.tab_id) ||
342 (time_now - it->first.creation_time > max_navigation_age)) {
343 inflight_navigations_.erase(it++);
344 } else {
345 ++it;
346 }
347 }
142 } 348 }
143 349
144 } // namespace predictors 350 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698