| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/prerender/prerender_manager.h" | 5 #include "chrome/browser/prerender/prerender_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <functional> | 10 #include <functional> |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 | 313 |
| 314 PrerenderHandle* PrerenderManager::AddPrerenderForInstant( | 314 PrerenderHandle* PrerenderManager::AddPrerenderForInstant( |
| 315 const GURL& url, | 315 const GURL& url, |
| 316 content::SessionStorageNamespace* session_storage_namespace, | 316 content::SessionStorageNamespace* session_storage_namespace, |
| 317 const gfx::Size& size) { | 317 const gfx::Size& size) { |
| 318 DCHECK(search::ShouldPrefetchSearchResults()); | 318 DCHECK(search::ShouldPrefetchSearchResults()); |
| 319 return AddPrerender(ORIGIN_INSTANT, url, content::Referrer(), size, | 319 return AddPrerender(ORIGIN_INSTANT, url, content::Referrer(), size, |
| 320 session_storage_namespace); | 320 session_storage_namespace); |
| 321 } | 321 } |
| 322 | 322 |
| 323 PrerenderHandle* PrerenderManager::AddPrerenderForOffline( |
| 324 const GURL& url, |
| 325 content::SessionStorageNamespace* session_storage_namespace, |
| 326 const gfx::Size& size) { |
| 327 return AddPrerender(ORIGIN_OFFLINE, url, content::Referrer(), size, |
| 328 session_storage_namespace); |
| 329 } |
| 330 |
| 323 void PrerenderManager::CancelAllPrerenders() { | 331 void PrerenderManager::CancelAllPrerenders() { |
| 324 DCHECK(CalledOnValidThread()); | 332 DCHECK(CalledOnValidThread()); |
| 325 while (!active_prerenders_.empty()) { | 333 while (!active_prerenders_.empty()) { |
| 326 PrerenderContents* prerender_contents = | 334 PrerenderContents* prerender_contents = |
| 327 active_prerenders_.front()->contents(); | 335 active_prerenders_.front()->contents(); |
| 328 prerender_contents->Destroy(FINAL_STATUS_CANCELLED); | 336 prerender_contents->Destroy(FINAL_STATUS_CANCELLED); |
| 329 } | 337 } |
| 330 } | 338 } |
| 331 | 339 |
| 332 bool PrerenderManager::MaybeUsePrerenderedPage(const GURL& url, | 340 bool PrerenderManager::MaybeUsePrerenderedPage(const GURL& url, |
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 | 952 |
| 945 GURL url = url_arg; | 953 GURL url = url_arg; |
| 946 GURL alias_url; | 954 GURL alias_url; |
| 947 if (IsControlGroup() && MaybeGetQueryStringBasedAliasURL(url, &alias_url)) | 955 if (IsControlGroup() && MaybeGetQueryStringBasedAliasURL(url, &alias_url)) |
| 948 url = alias_url; | 956 url = alias_url; |
| 949 | 957 |
| 950 // From here on, we will record a FinalStatus so we need to register with the | 958 // From here on, we will record a FinalStatus so we need to register with the |
| 951 // histogram tracking. | 959 // histogram tracking. |
| 952 histograms_->RecordPrerender(origin, url_arg); | 960 histograms_->RecordPrerender(origin, url_arg); |
| 953 | 961 |
| 954 if (profile_->GetPrefs()->GetBoolean(prefs::kBlockThirdPartyCookies)) { | 962 if (profile_->GetPrefs()->GetBoolean(prefs::kBlockThirdPartyCookies) && |
| 963 origin != ORIGIN_OFFLINE) { |
| 955 RecordFinalStatusWithoutCreatingPrerenderContents( | 964 RecordFinalStatusWithoutCreatingPrerenderContents( |
| 956 url, origin, FINAL_STATUS_BLOCK_THIRD_PARTY_COOKIES); | 965 url, origin, FINAL_STATUS_BLOCK_THIRD_PARTY_COOKIES); |
| 957 return nullptr; | 966 return nullptr; |
| 958 } | 967 } |
| 959 | 968 |
| 960 NetworkPredictionStatus prerendering_status = | 969 NetworkPredictionStatus prerendering_status = |
| 961 GetPredictionStatusForOrigin(origin); | 970 GetPredictionStatusForOrigin(origin); |
| 962 if (prerendering_status != NetworkPredictionStatus::ENABLED) { | 971 if (prerendering_status != NetworkPredictionStatus::ENABLED) { |
| 963 FinalStatus final_status = | 972 FinalStatus final_status = |
| 964 prerendering_status == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK | 973 prerendering_status == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1140 void PrerenderManager::SortActivePrerenders() { | 1149 void PrerenderManager::SortActivePrerenders() { |
| 1141 std::sort(active_prerenders_.begin(), active_prerenders_.end(), | 1150 std::sort(active_prerenders_.begin(), active_prerenders_.end(), |
| 1142 PrerenderData::OrderByExpiryTime()); | 1151 PrerenderData::OrderByExpiryTime()); |
| 1143 } | 1152 } |
| 1144 | 1153 |
| 1145 PrerenderManager::PrerenderData* PrerenderManager::FindPrerenderData( | 1154 PrerenderManager::PrerenderData* PrerenderManager::FindPrerenderData( |
| 1146 const GURL& url, | 1155 const GURL& url, |
| 1147 const SessionStorageNamespace* session_storage_namespace) { | 1156 const SessionStorageNamespace* session_storage_namespace) { |
| 1148 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); | 1157 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); |
| 1149 it != active_prerenders_.end(); ++it) { | 1158 it != active_prerenders_.end(); ++it) { |
| 1150 if ((*it)->contents()->Matches(url, session_storage_namespace)) | 1159 PrerenderContents* contents = (*it)->contents(); |
| 1160 if (contents->Matches(url, session_storage_namespace)) { |
| 1161 if (contents->origin() == ORIGIN_OFFLINE) |
| 1162 return NULL; |
| 1151 return *it; | 1163 return *it; |
| 1164 } |
| 1152 } | 1165 } |
| 1153 return NULL; | 1166 return NULL; |
| 1154 } | 1167 } |
| 1155 | 1168 |
| 1156 ScopedVector<PrerenderManager::PrerenderData>::iterator | 1169 ScopedVector<PrerenderManager::PrerenderData>::iterator |
| 1157 PrerenderManager::FindIteratorForPrerenderContents( | 1170 PrerenderManager::FindIteratorForPrerenderContents( |
| 1158 PrerenderContents* prerender_contents) { | 1171 PrerenderContents* prerender_contents) { |
| 1159 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); | 1172 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); |
| 1160 it != active_prerenders_.end(); ++it) { | 1173 it != active_prerenders_.end(); ++it) { |
| 1161 if (prerender_contents == (*it)->contents()) | 1174 if (prerender_contents == (*it)->contents()) |
| 1162 return it; | 1175 return it; |
| 1163 } | 1176 } |
| 1164 return active_prerenders_.end(); | 1177 return active_prerenders_.end(); |
| 1165 } | 1178 } |
| 1166 | 1179 |
| 1167 bool PrerenderManager::DoesRateLimitAllowPrerender(Origin origin) const { | 1180 bool PrerenderManager::DoesRateLimitAllowPrerender(Origin origin) const { |
| 1168 DCHECK(CalledOnValidThread()); | 1181 DCHECK(CalledOnValidThread()); |
| 1169 base::TimeDelta elapsed_time = | 1182 base::TimeDelta elapsed_time = |
| 1170 GetCurrentTimeTicks() - last_prerender_start_time_; | 1183 GetCurrentTimeTicks() - last_prerender_start_time_; |
| 1171 histograms_->RecordTimeBetweenPrerenderRequests(origin, elapsed_time); | 1184 histograms_->RecordTimeBetweenPrerenderRequests(origin, elapsed_time); |
| 1185 // TODO(gabadie,pasko): Re-implement missing tests for |
| 1186 // FINAL_STATUS_RATE_LIMIT_EXCEEDED that where removed by: |
| 1187 // http://crrev.com/a2439eeab37f7cb7a118493fb55ec0cb07f93b49. |
| 1188 if (origin == ORIGIN_OFFLINE) |
| 1189 return true; |
| 1172 if (!config_.rate_limit_enabled) | 1190 if (!config_.rate_limit_enabled) |
| 1173 return true; | 1191 return true; |
| 1174 return elapsed_time >= | 1192 return elapsed_time >= |
| 1175 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); | 1193 base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); |
| 1176 } | 1194 } |
| 1177 | 1195 |
| 1178 void PrerenderManager::DeleteOldWebContents() { | 1196 void PrerenderManager::DeleteOldWebContents() { |
| 1179 while (!old_web_contents_list_.empty()) { | 1197 while (!old_web_contents_list_.empty()) { |
| 1180 WebContents* web_contents = old_web_contents_list_.front(); | 1198 WebContents* web_contents = old_web_contents_list_.front(); |
| 1181 old_web_contents_list_.pop_front(); | 1199 old_web_contents_list_.pop_front(); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1304 | 1322 |
| 1305 NetworkPredictionStatus PrerenderManager::GetPredictionStatus() const { | 1323 NetworkPredictionStatus PrerenderManager::GetPredictionStatus() const { |
| 1306 DCHECK(CalledOnValidThread()); | 1324 DCHECK(CalledOnValidThread()); |
| 1307 return CanPrefetchAndPrerenderUI(profile_->GetPrefs()); | 1325 return CanPrefetchAndPrerenderUI(profile_->GetPrefs()); |
| 1308 } | 1326 } |
| 1309 | 1327 |
| 1310 NetworkPredictionStatus PrerenderManager::GetPredictionStatusForOrigin( | 1328 NetworkPredictionStatus PrerenderManager::GetPredictionStatusForOrigin( |
| 1311 Origin origin) const { | 1329 Origin origin) const { |
| 1312 DCHECK(CalledOnValidThread()); | 1330 DCHECK(CalledOnValidThread()); |
| 1313 | 1331 |
| 1314 // LINK rel=prerender origins ignore the network state and the privacy | 1332 // <link rel=prerender> origins ignore the network state and the privacy |
| 1315 // settings. | 1333 // settings. Web developers should be able prefetch with all possible privacy |
| 1334 // settings and with all possible network types. This would avoid web devs |
| 1335 // coming up with creative ways to prefetch in cases they are not allowed to |
| 1336 // do so. |
| 1337 // |
| 1338 // Offline originated prerenders also ignore the network state and privacy |
| 1339 // settings because they are controlled by the offliner logic via |
| 1340 // PrerenderHandle. |
| 1316 if (origin == ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN || | 1341 if (origin == ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN || |
| 1317 origin == ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN) { | 1342 origin == ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN || |
| 1343 origin == ORIGIN_OFFLINE) { |
| 1318 return NetworkPredictionStatus::ENABLED; | 1344 return NetworkPredictionStatus::ENABLED; |
| 1319 } | 1345 } |
| 1320 | 1346 |
| 1321 // Prerendering forced for cellular networks still prevents navigation with | 1347 // Prerendering forced for cellular networks still prevents navigation with |
| 1322 // the DISABLED_ALWAYS selected via privacy settings. | 1348 // the DISABLED_ALWAYS selected via privacy settings. |
| 1323 NetworkPredictionStatus prediction_status = | 1349 NetworkPredictionStatus prediction_status = |
| 1324 CanPrefetchAndPrerenderUI(profile_->GetPrefs()); | 1350 CanPrefetchAndPrerenderUI(profile_->GetPrefs()); |
| 1325 if (origin == ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR && | 1351 if (origin == ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR && |
| 1326 prediction_status == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK) { | 1352 prediction_status == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK) { |
| 1327 return NetworkPredictionStatus::ENABLED; | 1353 return NetworkPredictionStatus::ENABLED; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1355 } | 1381 } |
| 1356 | 1382 |
| 1357 void PrerenderManager::RenderProcessHostDestroyed( | 1383 void PrerenderManager::RenderProcessHostDestroyed( |
| 1358 content::RenderProcessHost* host) { | 1384 content::RenderProcessHost* host) { |
| 1359 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1385 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1360 size_t erased = prerender_process_hosts_.erase(host); | 1386 size_t erased = prerender_process_hosts_.erase(host); |
| 1361 DCHECK_EQ(1u, erased); | 1387 DCHECK_EQ(1u, erased); |
| 1362 } | 1388 } |
| 1363 | 1389 |
| 1364 } // namespace prerender | 1390 } // namespace prerender |
| OLD | NEW |