OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <string> | 7 #include <string> |
8 | 8 |
| 9 #include "base/command_line.h" |
9 #include "base/logging.h" | 10 #include "base/logging.h" |
10 #include "base/metrics/field_trial.h" | 11 #include "base/metrics/field_trial.h" |
11 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
12 #include "base/time.h" | 13 #include "base/time.h" |
13 #include "base/values.h" | 14 #include "base/values.h" |
14 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
15 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
16 #include "chrome/browser/favicon/favicon_tab_helper.h" | 17 #include "chrome/browser/favicon/favicon_tab_helper.h" |
17 #include "chrome/browser/prerender/prerender_contents.h" | 18 #include "chrome/browser/prerender/prerender_contents.h" |
18 #include "chrome/browser/prerender/prerender_final_status.h" | 19 #include "chrome/browser/prerender/prerender_final_status.h" |
19 #include "chrome/browser/prerender/prerender_history.h" | 20 #include "chrome/browser/prerender/prerender_history.h" |
20 #include "chrome/browser/prerender/prerender_observer.h" | 21 #include "chrome/browser/prerender/prerender_observer.h" |
21 #include "chrome/browser/prerender/prerender_tracker.h" | 22 #include "chrome/browser/prerender/prerender_tracker.h" |
22 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
23 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 24 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
24 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h" | 25 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h" |
| 26 #include "chrome/common/chrome_switches.h" |
25 #include "chrome/common/render_messages.h" | 27 #include "chrome/common/render_messages.h" |
26 #include "content/browser/browser_thread.h" | 28 #include "content/browser/browser_thread.h" |
27 #include "content/browser/renderer_host/render_process_host.h" | 29 #include "content/browser/renderer_host/render_process_host.h" |
28 #include "content/browser/renderer_host/render_view_host.h" | 30 #include "content/browser/renderer_host/render_view_host.h" |
29 #include "content/browser/renderer_host/resource_dispatcher_host.h" | 31 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
30 #include "content/browser/tab_contents/render_view_host_manager.h" | 32 #include "content/browser/tab_contents/render_view_host_manager.h" |
31 #include "content/browser/tab_contents/tab_contents.h" | 33 #include "content/browser/tab_contents/tab_contents.h" |
32 #include "content/browser/tab_contents/tab_contents_delegate.h" | 34 #include "content/browser/tab_contents/tab_contents_delegate.h" |
33 #include "content/common/notification_service.h" | 35 #include "content/common/notification_service.h" |
34 #include "googleurl/src/url_canon.h" | 36 #include "googleurl/src/url_canon.h" |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 GURL url_; | 200 GURL url_; |
199 base::TimeTicks time_; | 201 base::TimeTicks time_; |
200 NavigationRecord(const GURL& url, base::TimeTicks time) | 202 NavigationRecord(const GURL& url, base::TimeTicks time) |
201 : url_(url), | 203 : url_(url), |
202 time_(time) { | 204 time_(time) { |
203 } | 205 } |
204 }; | 206 }; |
205 | 207 |
206 struct PrerenderManager::PendingContentsData { | 208 struct PrerenderManager::PendingContentsData { |
207 PendingContentsData(const GURL& url, | 209 PendingContentsData(const GURL& url, |
208 const GURL& referrer) | 210 const GURL& referrer, |
209 : url_(url), referrer_(referrer) { } | 211 Origin origin) |
| 212 : url_(url), referrer_(referrer), origin_(origin) { } |
210 ~PendingContentsData() {} | 213 ~PendingContentsData() {} |
211 GURL url_; | 214 GURL url_; |
212 GURL referrer_; | 215 GURL referrer_; |
| 216 Origin origin_; |
213 }; | 217 }; |
214 | 218 |
215 void HandleTag( | 219 void HandleTag( |
216 const base::WeakPtr<PrerenderManager>& prerender_manager_weak_ptr, | 220 const base::WeakPtr<PrerenderManager>& prerender_manager_weak_ptr, |
217 int render_process_id, | 221 int render_process_id, |
218 int render_view_id, | 222 int render_view_id, |
219 const GURL& url, | 223 const GURL& url, |
220 const GURL& referrer) { | 224 const GURL& referrer) { |
221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
222 PrerenderManager* prerender_manager = prerender_manager_weak_ptr.get(); | 226 PrerenderManager* prerender_manager = prerender_manager_weak_ptr.get(); |
223 if (!prerender_manager || !prerender_manager->is_enabled()) | 227 if (!prerender_manager || !prerender_manager->is_enabled()) |
224 return; | 228 return; |
225 prerender_manager->RecordTagObserved(); | 229 prerender_manager->RecordTagObserved(); |
226 | 230 |
227 std::pair<int, int> child_route_id_pair = std::make_pair(render_process_id, | 231 std::pair<int, int> child_route_id_pair = std::make_pair(render_process_id, |
228 render_view_id); | 232 render_view_id); |
229 | 233 |
230 prerender_manager->AddPreload(child_route_id_pair, url, referrer); | 234 prerender_manager->AddPrerenderFromPage(ORIGIN_LINK_REL_PRERENDER, |
| 235 child_route_id_pair, url, referrer); |
231 } | 236 } |
232 | 237 |
233 void DestroyPreloadForRenderView( | 238 void DestroyPrerenderForRenderView( |
234 const base::WeakPtr<PrerenderManager>& prerender_manager_weak_ptr, | 239 const base::WeakPtr<PrerenderManager>& prerender_manager_weak_ptr, |
235 int render_process_id, | 240 int render_process_id, |
236 int render_view_id, | 241 int render_view_id, |
237 FinalStatus final_status) { | 242 FinalStatus final_status) { |
238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
239 PrerenderManager* prerender_manager = prerender_manager_weak_ptr.get(); | 244 PrerenderManager* prerender_manager = prerender_manager_weak_ptr.get(); |
240 if (!prerender_manager) | 245 if (!prerender_manager) |
241 return; | 246 return; |
242 | 247 |
243 prerender_manager->DestroyPreloadForChildRouteIdPair( | 248 prerender_manager->DestroyPrerenderForChildRouteIdPair( |
244 std::make_pair(render_process_id, render_view_id), | 249 std::make_pair(render_process_id, render_view_id), |
245 final_status); | 250 final_status); |
246 } | 251 } |
247 | 252 |
248 PrerenderManager::PrerenderManager(Profile* profile, | 253 PrerenderManager::PrerenderManager(Profile* profile, |
249 PrerenderTracker* prerender_tracker) | 254 PrerenderTracker* prerender_tracker) |
250 : rate_limit_enabled_(true), | 255 : rate_limit_enabled_(true), |
251 enabled_(true), | 256 enabled_(true), |
252 profile_(profile), | 257 profile_(profile), |
253 prerender_tracker_(prerender_tracker), | 258 prerender_tracker_(prerender_tracker), |
(...skipping 15 matching lines...) Expand all Loading... |
269 PrerenderManager::~PrerenderManager() { | 274 PrerenderManager::~PrerenderManager() { |
270 DestroyAllContents(FINAL_STATUS_MANAGER_SHUTDOWN); | 275 DestroyAllContents(FINAL_STATUS_MANAGER_SHUTDOWN); |
271 } | 276 } |
272 | 277 |
273 void PrerenderManager::SetPrerenderContentsFactory( | 278 void PrerenderManager::SetPrerenderContentsFactory( |
274 PrerenderContents::Factory* prerender_contents_factory) { | 279 PrerenderContents::Factory* prerender_contents_factory) { |
275 DCHECK(CalledOnValidThread()); | 280 DCHECK(CalledOnValidThread()); |
276 prerender_contents_factory_.reset(prerender_contents_factory); | 281 prerender_contents_factory_.reset(prerender_contents_factory); |
277 } | 282 } |
278 | 283 |
279 bool PrerenderManager::AddPreload( | 284 bool PrerenderManager::AddPrerenderFromPage( |
| 285 Origin origin, |
280 const std::pair<int, int>& child_route_id_pair, | 286 const std::pair<int, int>& child_route_id_pair, |
281 const GURL& url_arg, | 287 const GURL& url_arg, |
282 const GURL& referrer) { | 288 const GURL& referrer) { |
283 DCHECK(CalledOnValidThread()); | 289 DCHECK(CalledOnValidThread()); |
284 | 290 |
285 // If the referring page is prerendering, defer the prerender. | 291 // If the referring page is prerendering, defer the prerender. |
286 if (FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != | 292 if (FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != |
287 prerender_list_.end()) { | 293 prerender_list_.end()) { |
288 AddPendingPreload(child_route_id_pair, url_arg, referrer); | 294 AddPendingPrerender(origin, child_route_id_pair, url_arg, referrer); |
289 return true; | 295 return true; |
290 } | 296 } |
291 | 297 |
292 DeleteOldEntries(); | 298 DeleteOldEntries(); |
293 DeletePendingDeleteEntries(); | 299 DeletePendingDeleteEntries(); |
294 | 300 |
295 GURL url = url_arg; | 301 GURL url = url_arg; |
296 GURL alias_url; | 302 GURL alias_url; |
297 if (IsControlGroup() && | 303 if (IsControlGroup() && |
298 PrerenderManager::MaybeGetQueryStringBasedAliasURL( | 304 PrerenderManager::MaybeGetQueryStringBasedAliasURL( |
299 url, &alias_url)) { | 305 url, &alias_url)) { |
300 url = alias_url; | 306 url = alias_url; |
301 } | 307 } |
302 | 308 |
303 if (FindEntry(url)) | 309 if (FindEntry(url)) |
304 return false; | 310 return false; |
305 | 311 |
306 // Do not prerender if there are too many render processes, and we would | 312 // Do not prerender if there are too many render processes, and we would |
307 // have to use an existing one. We do not want prerendering to happen in | 313 // have to use an existing one. We do not want prerendering to happen in |
308 // a shared process, so that we can always reliably lower the CPU | 314 // a shared process, so that we can always reliably lower the CPU |
309 // priority for prerendering. | 315 // priority for prerendering. |
310 // In single-process mode, ShouldTryToUseExistingProcessHost() always returns | 316 // In single-process mode, ShouldTryToUseExistingProcessHost() always returns |
311 // true, so that case needs to be explicitly checked for. | 317 // true, so that case needs to be explicitly checked for. |
312 // TODO(tburkard): Figure out how to cancel prerendering in the opposite | 318 // TODO(tburkard): Figure out how to cancel prerendering in the opposite |
313 // case, when a new tab is added to a process used for prerendering. | 319 // case, when a new tab is added to a process used for prerendering. |
314 if (RenderProcessHost::ShouldTryToUseExistingProcessHost() && | 320 if (RenderProcessHost::ShouldTryToUseExistingProcessHost() && |
315 !RenderProcessHost::run_renderer_in_process()) { | 321 !RenderProcessHost::run_renderer_in_process()) { |
316 RecordFinalStatus(FINAL_STATUS_TOO_MANY_PROCESSES); | 322 RecordFinalStatus(origin, FINAL_STATUS_TOO_MANY_PROCESSES); |
317 return false; | 323 return false; |
318 } | 324 } |
319 | 325 |
320 // Check if enough time has passed since the last prerender. | 326 // Check if enough time has passed since the last prerender. |
321 if (!DoesRateLimitAllowPrerender()) { | 327 if (!DoesRateLimitAllowPrerender()) { |
322 // Cancel the prerender. We could add it to the pending prerender list but | 328 // Cancel the prerender. We could add it to the pending prerender list but |
323 // this doesn't make sense as the next prerender request will be triggered | 329 // this doesn't make sense as the next prerender request will be triggered |
324 // by a navigation and is unlikely to be the same site. | 330 // by a navigation and is unlikely to be the same site. |
325 RecordFinalStatus(FINAL_STATUS_RATE_LIMIT_EXCEEDED); | 331 RecordFinalStatus(origin, FINAL_STATUS_RATE_LIMIT_EXCEEDED); |
326 return false; | 332 return false; |
327 } | 333 } |
328 | 334 |
329 RenderViewHost* source_render_view_host = NULL; | 335 RenderViewHost* source_render_view_host = NULL; |
330 // This test should fail only during unit tests. | 336 // This test should fail only during unit tests. |
331 if (child_route_id_pair.first != -1) { | 337 if (child_route_id_pair.first != -1) { |
332 source_render_view_host = | 338 source_render_view_host = |
333 RenderViewHost::FromID(child_route_id_pair.first, | 339 RenderViewHost::FromID(child_route_id_pair.first, |
334 child_route_id_pair.second); | 340 child_route_id_pair.second); |
335 // Don't prerender page if parent RenderViewHost no longer exists, or it has | 341 // Don't prerender page if parent RenderViewHost no longer exists, or it has |
336 // no view. The latter should only happen when the RenderView has closed. | 342 // no view. The latter should only happen when the RenderView has closed. |
337 if (!source_render_view_host || !source_render_view_host->view()) { | 343 if (!source_render_view_host || !source_render_view_host->view()) { |
338 RecordFinalStatus(FINAL_STATUS_SOURCE_RENDER_VIEW_CLOSED); | 344 RecordFinalStatus(origin, FINAL_STATUS_SOURCE_RENDER_VIEW_CLOSED); |
339 return false; | 345 return false; |
340 } | 346 } |
341 } | 347 } |
342 | 348 |
343 PrerenderContents* prerender_contents = | 349 PrerenderContents* prerender_contents = |
344 CreatePrerenderContents(url, referrer); | 350 CreatePrerenderContents(url, referrer, origin); |
345 if (!prerender_contents || !prerender_contents->Init()) | 351 if (!prerender_contents || !prerender_contents->Init()) |
346 return false; | 352 return false; |
347 | 353 |
348 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents? | 354 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents? |
349 PrerenderContentsData data(prerender_contents, GetCurrentTime()); | 355 PrerenderContentsData data(prerender_contents, GetCurrentTime()); |
350 | 356 |
351 prerender_list_.push_back(data); | 357 prerender_list_.push_back(data); |
| 358 |
352 if (IsControlGroup()) { | 359 if (IsControlGroup()) { |
353 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP); | 360 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP); |
354 } else { | 361 } else { |
355 last_prerender_start_time_ = GetCurrentTimeTicks(); | 362 last_prerender_start_time_ = GetCurrentTimeTicks(); |
356 data.contents_->StartPrerendering(source_render_view_host); | 363 data.contents_->StartPrerendering(source_render_view_host); |
357 } | 364 } |
358 while (prerender_list_.size() > max_elements_) { | 365 while (prerender_list_.size() > max_elements_) { |
359 data = prerender_list_.front(); | 366 data = prerender_list_.front(); |
360 prerender_list_.pop_front(); | 367 prerender_list_.pop_front(); |
361 data.contents_->Destroy(FINAL_STATUS_EVICTED); | 368 data.contents_->Destroy(FINAL_STATUS_EVICTED); |
362 } | 369 } |
363 StartSchedulingPeriodicCleanups(); | 370 StartSchedulingPeriodicCleanups(); |
364 return true; | 371 return true; |
365 } | 372 } |
366 | 373 |
367 void PrerenderManager::AddPendingPreload( | 374 bool PrerenderManager::AddPrerender(Origin origin, const GURL& url) { |
| 375 bool should_prerender = true; |
| 376 if (origin == ORIGIN_OMNIBOX) { |
| 377 CommandLine* cl = CommandLine::ForCurrentProcess(); |
| 378 should_prerender = cl->HasSwitch(switches::kPrerenderFromOmnibox); |
| 379 } |
| 380 |
| 381 if (!should_prerender) |
| 382 return false; |
| 383 |
| 384 return AddPrerenderFromPage(origin, std::make_pair(-1, -1), url, GURL()); |
| 385 } |
| 386 |
| 387 void PrerenderManager::AddPendingPrerender( |
| 388 Origin origin, |
368 const std::pair<int, int>& child_route_id_pair, | 389 const std::pair<int, int>& child_route_id_pair, |
369 const GURL& url, | 390 const GURL& url, |
370 const GURL& referrer) { | 391 const GURL& referrer) { |
371 DCHECK(FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != | 392 DCHECK(FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != |
372 prerender_list_.end()); | 393 prerender_list_.end()); |
373 PendingPrerenderList::iterator it = | 394 PendingPrerenderList::iterator it = |
374 pending_prerender_list_.find(child_route_id_pair); | 395 pending_prerender_list_.find(child_route_id_pair); |
375 if (it == pending_prerender_list_.end()) { | 396 if (it == pending_prerender_list_.end()) { |
376 PendingPrerenderList::value_type el = std::make_pair(child_route_id_pair, | 397 PendingPrerenderList::value_type el = std::make_pair(child_route_id_pair, |
377 std::vector<PendingContentsData>()); | 398 std::vector<PendingContentsData>()); |
378 it = pending_prerender_list_.insert(el).first; | 399 it = pending_prerender_list_.insert(el).first; |
379 } | 400 } |
380 | 401 |
381 it->second.push_back(PendingContentsData(url, referrer)); | 402 it->second.push_back(PendingContentsData(url, referrer, origin)); |
382 } | 403 } |
383 | 404 |
384 std::list<PrerenderManager::PrerenderContentsData>::iterator | 405 std::list<PrerenderManager::PrerenderContentsData>::iterator |
385 PrerenderManager::FindPrerenderContentsForChildRouteIdPair( | 406 PrerenderManager::FindPrerenderContentsForChildRouteIdPair( |
386 const std::pair<int, int>& child_route_id_pair) { | 407 const std::pair<int, int>& child_route_id_pair) { |
387 std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); | 408 std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); |
388 for (; it != prerender_list_.end(); ++it) { | 409 for (; it != prerender_list_.end(); ++it) { |
389 PrerenderContents* prerender_contents = it->contents_; | 410 PrerenderContents* prerender_contents = it->contents_; |
390 | 411 |
391 int child_id; | 412 int child_id; |
392 int route_id; | 413 int route_id; |
393 bool has_child_id = prerender_contents->GetChildId(&child_id); | 414 bool has_child_id = prerender_contents->GetChildId(&child_id); |
394 bool has_route_id = has_child_id && | 415 bool has_route_id = has_child_id && |
395 prerender_contents->GetRouteId(&route_id); | 416 prerender_contents->GetRouteId(&route_id); |
396 | 417 |
397 if (has_child_id && has_route_id && | 418 if (has_child_id && has_route_id && |
398 child_id == child_route_id_pair.first && | 419 child_id == child_route_id_pair.first && |
399 route_id == child_route_id_pair.second) { | 420 route_id == child_route_id_pair.second) { |
400 break; | 421 break; |
401 } | 422 } |
402 } | 423 } |
403 return it; | 424 return it; |
404 } | 425 } |
405 | 426 |
406 void PrerenderManager::DestroyPreloadForChildRouteIdPair( | 427 void PrerenderManager::DestroyPrerenderForChildRouteIdPair( |
407 const std::pair<int, int>& child_route_id_pair, | 428 const std::pair<int, int>& child_route_id_pair, |
408 FinalStatus final_status) { | 429 FinalStatus final_status) { |
409 DCHECK(CalledOnValidThread()); | 430 DCHECK(CalledOnValidThread()); |
410 std::list<PrerenderContentsData>::iterator it = | 431 std::list<PrerenderContentsData>::iterator it = |
411 FindPrerenderContentsForChildRouteIdPair(child_route_id_pair); | 432 FindPrerenderContentsForChildRouteIdPair(child_route_id_pair); |
412 if (it != prerender_list_.end()) { | 433 if (it != prerender_list_.end()) { |
413 PrerenderContents* prerender_contents = it->contents_; | 434 PrerenderContents* prerender_contents = it->contents_; |
414 prerender_contents->Destroy(final_status); | 435 prerender_contents->Destroy(final_status); |
415 } | 436 } |
416 } | 437 } |
(...skipping 29 matching lines...) Expand all Loading... |
446 } | 467 } |
447 } | 468 } |
448 // Entry not found. | 469 // Entry not found. |
449 return NULL; | 470 return NULL; |
450 } | 471 } |
451 | 472 |
452 PrerenderContents* PrerenderManager::GetEntry(const GURL& url) { | 473 PrerenderContents* PrerenderManager::GetEntry(const GURL& url) { |
453 return GetEntryButNotSpecifiedTC(url, NULL); | 474 return GetEntryButNotSpecifiedTC(url, NULL); |
454 } | 475 } |
455 | 476 |
456 bool PrerenderManager::MaybeUsePreloadedPage(TabContents* tab_contents, | 477 bool PrerenderManager::MaybeUsePrerenderedPage(TabContents* tab_contents, |
457 const GURL& url, | 478 const GURL& url, |
458 bool has_opener_set) { | 479 bool has_opener_set) { |
459 DCHECK(CalledOnValidThread()); | 480 DCHECK(CalledOnValidThread()); |
460 scoped_ptr<PrerenderContents> prerender_contents( | 481 scoped_ptr<PrerenderContents> prerender_contents( |
461 GetEntryButNotSpecifiedTC(url, tab_contents)); | 482 GetEntryButNotSpecifiedTC(url, tab_contents)); |
462 if (prerender_contents.get() == NULL) | 483 if (prerender_contents.get() == NULL) |
463 return false; | 484 return false; |
464 | 485 |
465 // Do not use the prerendered version if the opener window.property was | 486 // Do not use the prerendered version if the opener window.property was |
466 // supposed to be set. | 487 // supposed to be set. |
467 if (has_opener_set) { | 488 if (has_opener_set) { |
468 prerender_contents.release()->Destroy(FINAL_STATUS_WINDOW_OPENER); | 489 prerender_contents.release()->Destroy(FINAL_STATUS_WINDOW_OPENER); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 | 574 |
554 // See if we have any pending prerender requests for this routing id and start | 575 // See if we have any pending prerender requests for this routing id and start |
555 // the preload if we do. | 576 // the preload if we do. |
556 std::pair<int, int> child_route_pair = std::make_pair(child_id, route_id); | 577 std::pair<int, int> child_route_pair = std::make_pair(child_id, route_id); |
557 PendingPrerenderList::iterator pending_it = | 578 PendingPrerenderList::iterator pending_it = |
558 pending_prerender_list_.find(child_route_pair); | 579 pending_prerender_list_.find(child_route_pair); |
559 if (pending_it != pending_prerender_list_.end()) { | 580 if (pending_it != pending_prerender_list_.end()) { |
560 for (std::vector<PendingContentsData>::iterator content_it = | 581 for (std::vector<PendingContentsData>::iterator content_it = |
561 pending_it->second.begin(); | 582 pending_it->second.begin(); |
562 content_it != pending_it->second.end(); ++content_it) { | 583 content_it != pending_it->second.end(); ++content_it) { |
563 AddPreload(pending_it->first, content_it->url_, content_it->referrer_); | 584 AddPrerenderFromPage(content_it->origin_, pending_it->first, |
| 585 content_it->url_, content_it->referrer_); |
564 } | 586 } |
565 pending_prerender_list_.erase(pending_it); | 587 pending_prerender_list_.erase(pending_it); |
566 } | 588 } |
567 | 589 |
568 if (old_tab_contents->tab_contents()->NeedToFireBeforeUnload()) { | 590 if (old_tab_contents->tab_contents()->NeedToFireBeforeUnload()) { |
569 // Schedule the delete to occur after the tab has run its unload handlers. | 591 // Schedule the delete to occur after the tab has run its unload handlers. |
570 on_close_tab_contents_deleters_.push_back( | 592 on_close_tab_contents_deleters_.push_back( |
571 new OnCloseTabContentsDeleter(this, old_tab_contents)); | 593 new OnCloseTabContentsDeleter(this, old_tab_contents)); |
572 old_tab_contents->render_view_host()->FirePageBeforeUnload(false); | 594 old_tab_contents->render_view_host()->FirePageBeforeUnload(false); |
573 } else { | 595 } else { |
574 // No unload handler to run, so delete asap. | 596 // No unload handler to run, so delete asap. |
575 ScheduleDeleteOldTabContents(old_tab_contents, NULL); | 597 ScheduleDeleteOldTabContents(old_tab_contents, NULL); |
576 } | 598 } |
577 | 599 |
578 // TODO(cbentzel): Should prerender_contents move to the pending delete | 600 // TODO(cbentzel): Should prerender_contents move to the pending delete |
579 // list, instead of deleting directly here? | 601 // list, instead of deleting directly here? |
580 AddToHistory(prerender_contents.get()); | 602 AddToHistory(prerender_contents.get()); |
581 return true; | 603 return true; |
582 } | 604 } |
583 | 605 |
584 void PrerenderManager::MoveEntryToPendingDelete(PrerenderContents* entry) { | 606 void PrerenderManager::MoveEntryToPendingDelete(PrerenderContents* entry) { |
585 DCHECK(CalledOnValidThread()); | 607 DCHECK(CalledOnValidThread()); |
586 DCHECK(!IsPendingDelete(entry)); | 608 DCHECK(!IsPendingDelete(entry)); |
587 for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); | 609 for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); |
588 it != prerender_list_.end(); | 610 it != prerender_list_.end(); |
589 ++it) { | 611 ++it) { |
590 if (it->contents_ == entry) { | 612 if (it->contents_ == entry) { |
591 RemovePendingPreload(entry); | 613 RemovePendingPrerender(entry); |
592 prerender_list_.erase(it); | 614 prerender_list_.erase(it); |
593 break; | 615 break; |
594 } | 616 } |
595 } | 617 } |
596 pending_delete_list_.push_back(entry); | 618 pending_delete_list_.push_back(entry); |
597 | 619 |
598 // Destroy the old TabContents relatively promptly to reduce resource usage, | 620 // Destroy the old TabContents relatively promptly to reduce resource usage, |
599 // and in the case of HTML5 media, reduce the change of playing any sound. | 621 // and in the case of HTML5 media, reduce the change of playing any sound. |
600 PostCleanupTask(); | 622 PostCleanupTask(); |
601 } | 623 } |
(...skipping 20 matching lines...) Expand all Loading... |
622 } | 644 } |
623 | 645 |
624 bool PrerenderManager::IsPrerenderElementFresh(const base::Time start) const { | 646 bool PrerenderManager::IsPrerenderElementFresh(const base::Time start) const { |
625 DCHECK(CalledOnValidThread()); | 647 DCHECK(CalledOnValidThread()); |
626 base::Time now = GetCurrentTime(); | 648 base::Time now = GetCurrentTime(); |
627 return (now - start < max_prerender_age_); | 649 return (now - start < max_prerender_age_); |
628 } | 650 } |
629 | 651 |
630 PrerenderContents* PrerenderManager::CreatePrerenderContents( | 652 PrerenderContents* PrerenderManager::CreatePrerenderContents( |
631 const GURL& url, | 653 const GURL& url, |
632 const GURL& referrer) { | 654 const GURL& referrer, |
| 655 Origin origin) { |
633 DCHECK(CalledOnValidThread()); | 656 DCHECK(CalledOnValidThread()); |
634 return prerender_contents_factory_->CreatePrerenderContents( | 657 return prerender_contents_factory_->CreatePrerenderContents( |
635 this, prerender_tracker_, profile_, url, referrer); | 658 this, prerender_tracker_, profile_, url, referrer, origin); |
636 } | 659 } |
637 | 660 |
638 void PrerenderManager::DeletePendingDeleteEntries() { | 661 void PrerenderManager::DeletePendingDeleteEntries() { |
639 while (!pending_delete_list_.empty()) { | 662 while (!pending_delete_list_.empty()) { |
640 PrerenderContents* contents = pending_delete_list_.front(); | 663 PrerenderContents* contents = pending_delete_list_.front(); |
641 pending_delete_list_.pop_front(); | 664 pending_delete_list_.pop_front(); |
642 AddToHistory(contents); | 665 AddToHistory(contents); |
643 delete contents; | 666 delete contents; |
644 } | 667 } |
645 } | 668 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 | 788 |
766 void PrerenderManager::RecordTagObserved() { | 789 void PrerenderManager::RecordTagObserved() { |
767 DCHECK(CalledOnValidThread()); | 790 DCHECK(CalledOnValidThread()); |
768 | 791 |
769 // If we observe multiple tags within the 30 second window, we will still | 792 // If we observe multiple tags within the 30 second window, we will still |
770 // reset the window to begin at the most recent occurrence, so that we will | 793 // reset the window to begin at the most recent occurrence, so that we will |
771 // always be in a window in the 30 seconds from each occurrence. | 794 // always be in a window in the 30 seconds from each occurrence. |
772 last_prerender_seen_time_ = base::TimeTicks::Now(); | 795 last_prerender_seen_time_ = base::TimeTicks::Now(); |
773 } | 796 } |
774 | 797 |
775 void PrerenderManager::RemovePendingPreload(PrerenderContents* entry) { | 798 void PrerenderManager::RemovePendingPrerender(PrerenderContents* entry) { |
776 DCHECK(CalledOnValidThread()); | 799 DCHECK(CalledOnValidThread()); |
777 int child_id; | 800 int child_id; |
778 int route_id; | 801 int route_id; |
779 bool has_child_id = entry->GetChildId(&child_id); | 802 bool has_child_id = entry->GetChildId(&child_id); |
780 bool has_route_id = has_child_id && entry->GetRouteId(&route_id); | 803 bool has_route_id = has_child_id && entry->GetRouteId(&route_id); |
781 | 804 |
782 // If the entry doesn't have a RenderViewHost then it didn't start | 805 // If the entry doesn't have a RenderViewHost then it didn't start |
783 // prerendering and there shouldn't be any pending preloads to remove. | 806 // prerendering and there shouldn't be any pending preloads to remove. |
784 if (has_child_id && has_route_id) { | 807 if (has_child_id && has_route_id) { |
785 std::pair<int, int> child_route_pair = std::make_pair(child_id, route_id); | 808 std::pair<int, int> child_route_pair = std::make_pair(child_id, route_id); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 DeleteOldTabContents(); | 1055 DeleteOldTabContents(); |
1033 while (!prerender_list_.empty()) { | 1056 while (!prerender_list_.empty()) { |
1034 PrerenderContentsData data = prerender_list_.front(); | 1057 PrerenderContentsData data = prerender_list_.front(); |
1035 prerender_list_.pop_front(); | 1058 prerender_list_.pop_front(); |
1036 data.contents_->Destroy(final_status); | 1059 data.contents_->Destroy(final_status); |
1037 } | 1060 } |
1038 DeletePendingDeleteEntries(); | 1061 DeletePendingDeleteEntries(); |
1039 } | 1062 } |
1040 | 1063 |
1041 } // namespace prerender | 1064 } // namespace prerender |
OLD | NEW |