blob: a63cbbe0d03d058ecaffc63d63271cf9b50b5098 [file] [log] [blame]
[email protected]2736c032012-05-11 18:06:071// 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
3// found in the LICENSE file.
4
5#include "chrome/browser/prerender/prerender_link_manager.h"
6
[email protected]099d6722014-02-04 01:13:037#include <functional>
[email protected]2736c032012-05-11 18:06:078#include <limits>
dcheng4af48582016-04-19 00:29:359#include <memory>
[email protected]a2439eea2012-12-29 00:16:4510#include <set>
[email protected]1ee57dd72014-02-11 23:58:4011#include <string>
[email protected]2736c032012-05-11 18:06:0712#include <utility>
13
[email protected]1ee57dd72014-02-11 23:58:4014#include "base/metrics/field_trial.h"
[email protected]ea07cde2014-02-12 20:09:4715#include "base/metrics/histogram.h"
[email protected]2736c032012-05-11 18:06:0716#include "chrome/browser/prerender/prerender_contents.h"
[email protected]48055042012-07-14 21:12:1117#include "chrome/browser/prerender/prerender_handle.h"
[email protected]2736c032012-05-11 18:06:0718#include "chrome/browser/prerender/prerender_manager.h"
19#include "chrome/browser/prerender/prerender_manager_factory.h"
[email protected]26101702012-12-15 21:45:1820#include "chrome/common/prerender_messages.h"
[email protected]1ee57dd72014-02-11 23:58:4021#include "chrome/common/prerender_types.h"
[email protected]26101702012-12-15 21:45:1822#include "content/public/browser/render_process_host.h"
[email protected]2736c032012-05-11 18:06:0723#include "content/public/browser/render_view_host.h"
24#include "content/public/browser/session_storage_namespace.h"
25#include "content/public/common/referrer.h"
tfarinaebe974f02015-01-03 04:25:3226#include "ui/gfx/geometry/size.h"
[email protected]761fa4702013-07-02 15:25:1527#include "url/gurl.h"
[email protected]2736c032012-05-11 18:06:0728
[email protected]1df3d972014-06-11 04:55:1829#if defined(ENABLE_EXTENSIONS)
fsamuel8dfa19a2015-05-05 01:00:3930#include "components/guest_view/browser/guest_view_base.h"
[email protected]1df3d972014-06-11 04:55:1831#endif
32
[email protected]a2439eea2012-12-29 00:16:4533using base::TimeDelta;
34using base::TimeTicks;
[email protected]2736c032012-05-11 18:06:0735using content::RenderViewHost;
36using content::SessionStorageNamespace;
37
[email protected]1ee57dd72014-02-11 23:58:4038namespace prerender {
39
[email protected]26101702012-12-15 21:45:1840namespace {
41
[email protected]1ee57dd72014-02-11 23:58:4042bool ShouldStartRelNextPrerenders() {
43 const std::string experiment_name =
44 base::FieldTrialList::FindFullName("PrerenderRelNextTrial");
45
46 return experiment_name.find("Yes") != std::string::npos;
47}
48
avib896c712015-12-26 02:10:4349bool ShouldStartPrerender(const uint32_t rel_types) {
[email protected]1ee57dd72014-02-11 23:58:4050 const bool should_start_rel_next_prerenders =
51 ShouldStartRelNextPrerenders();
52
53 if (rel_types & PrerenderRelTypePrerender) {
54 return true;
55 } else if (should_start_rel_next_prerenders &&
56 (rel_types & PrerenderRelTypeNext) == PrerenderRelTypeNext) {
57 return true;
58 }
59 return false;
60}
61
mostynb3a46e0bf2014-12-23 09:02:4362static_assert(PrerenderRelTypePrerender == 0x1,
63 "RelTypeHistogrameEnum must match PrerenderRelType");
64static_assert(PrerenderRelTypeNext == 0x2,
65 "RelTypeHistogramEnum must match PrerenderRelType");
[email protected]ea07cde2014-02-12 20:09:4766enum RelTypeHistogramEnum {
67 RelTypeHistogramEnumNone = 0,
68 RelTypeHistogramEnumPrerender = PrerenderRelTypePrerender,
69 RelTypeHistogramEnumNext = PrerenderRelTypeNext,
70 RelTypeHistogramEnumPrerenderAndNext =
71 PrerenderRelTypePrerender | PrerenderRelTypeNext,
72 RelTypeHistogramEnumMax,
73};
74
avib896c712015-12-26 02:10:4375void RecordLinkManagerAdded(const uint32_t rel_types) {
76 const uint32_t enum_value = rel_types & (RelTypeHistogramEnumMax - 1);
[email protected]ea07cde2014-02-12 20:09:4777 UMA_HISTOGRAM_ENUMERATION("Prerender.RelTypesLinkAdded", enum_value,
78 RelTypeHistogramEnumMax);
79}
80
avib896c712015-12-26 02:10:4381void RecordLinkManagerStarting(const uint32_t rel_types) {
82 const uint32_t enum_value = rel_types & (RelTypeHistogramEnumMax - 1);
[email protected]ea07cde2014-02-12 20:09:4783 UMA_HISTOGRAM_ENUMERATION("Prerender.RelTypesLinkStarted", enum_value,
84 RelTypeHistogramEnumMax);
85}
86
[email protected]26101702012-12-15 21:45:1887void Send(int child_id, IPC::Message* raw_message) {
88 using content::RenderProcessHost;
dcheng4af48582016-04-19 00:29:3589 std::unique_ptr<IPC::Message> own_message(raw_message);
[email protected]26101702012-12-15 21:45:1890
91 RenderProcessHost* render_process_host = RenderProcessHost::FromID(child_id);
92 if (!render_process_host)
93 return;
94 render_process_host->Send(own_message.release());
95}
96
97} // namespace
98
[email protected]099d6722014-02-04 01:13:0399// Helper class to implement PrerenderContents::Observer and watch prerenders
100// which launch other prerenders.
101class PrerenderLinkManager::PendingPrerenderManager
102 : public PrerenderContents::Observer {
103 public:
104 explicit PendingPrerenderManager(PrerenderLinkManager* link_manager)
105 : link_manager_(link_manager) {}
106
dcheng2c9c80c52014-10-22 21:21:05107 ~PendingPrerenderManager() override {
[email protected]099d6722014-02-04 01:13:03108 DCHECK(observed_launchers_.empty());
109 for (std::set<PrerenderContents*>::iterator i = observed_launchers_.begin();
110 i != observed_launchers_.end(); ++i) {
111 (*i)->RemoveObserver(this);
112 }
113 }
114
115 void ObserveLauncher(PrerenderContents* launcher) {
116 DCHECK_EQ(FINAL_STATUS_MAX, launcher->final_status());
117 if (observed_launchers_.find(launcher) != observed_launchers_.end())
118 return;
119 observed_launchers_.insert(launcher);
120 launcher->AddObserver(this);
121 }
122
dcheng2c9c80c52014-10-22 21:21:05123 void OnPrerenderStart(PrerenderContents* launcher) override {}
[email protected]099d6722014-02-04 01:13:03124
dcheng2c9c80c52014-10-22 21:21:05125 void OnPrerenderStop(PrerenderContents* launcher) override {
[email protected]099d6722014-02-04 01:13:03126 observed_launchers_.erase(launcher);
127 if (launcher->final_status() == FINAL_STATUS_USED) {
128 link_manager_->StartPendingPrerendersForLauncher(launcher);
129 } else {
130 link_manager_->CancelPendingPrerendersForLauncher(launcher);
131 }
132 }
133
134 private:
135 // A pointer to the parent PrerenderLinkManager.
136 PrerenderLinkManager* link_manager_;
137
138 // The set of PrerenderContentses being observed. Lifetimes are managed by
139 // OnPrerenderStop.
140 std::set<PrerenderContents*> observed_launchers_;
141};
142
[email protected]2736c032012-05-11 18:06:07143PrerenderLinkManager::PrerenderLinkManager(PrerenderManager* manager)
[email protected]a2439eea2012-12-29 00:16:45144 : has_shutdown_(false),
[email protected]099d6722014-02-04 01:13:03145 manager_(manager),
146 pending_prerender_manager_(new PendingPrerenderManager(this)) {}
[email protected]2736c032012-05-11 18:06:07147
148PrerenderLinkManager::~PrerenderLinkManager() {
[email protected]a2439eea2012-12-29 00:16:45149 for (std::list<LinkPrerender>::iterator i = prerenders_.begin();
150 i != prerenders_.end(); ++i) {
151 if (i->handle) {
152 DCHECK(!i->handle->IsPrerendering())
153 << "All running prerenders should stop at the same time as the "
154 << "PrerenderManager.";
155 delete i->handle;
156 i->handle = 0;
157 }
[email protected]48055042012-07-14 21:12:11158 }
[email protected]2736c032012-05-11 18:06:07159}
160
[email protected]a2439eea2012-12-29 00:16:45161void PrerenderLinkManager::OnAddPrerender(int launcher_child_id,
[email protected]2736c032012-05-11 18:06:07162 int prerender_id,
[email protected]fa619802012-07-18 14:20:47163 const GURL& url,
avib896c712015-12-26 02:10:43164 uint32_t rel_types,
[email protected]2736c032012-05-11 18:06:07165 const content::Referrer& referrer,
166 const gfx::Size& size,
167 int render_view_route_id) {
[email protected]953ed812013-03-12 23:36:34168 DCHECK_EQ(static_cast<LinkPrerender*>(NULL),
169 FindByLauncherChildIdAndPrerenderId(launcher_child_id,
170 prerender_id));
[email protected]1df3d972014-06-11 04:55:18171
172#if defined(ENABLE_EXTENSIONS)
[email protected]a24efc22014-05-26 15:50:25173 content::RenderViewHost* rvh =
174 content::RenderViewHost::FromID(launcher_child_id, render_view_route_id);
175 content::WebContents* web_contents =
176 rvh ? content::WebContents::FromRenderViewHost(rvh) : NULL;
[email protected]c3ec4db2013-01-31 20:06:21177 // Guests inside <webview> do not support cross-process navigation and so we
178 // do not allow guests to prerender content.
fsamuel8dfa19a2015-05-05 01:00:39179 if (guest_view::GuestViewBase::IsGuest(web_contents))
[email protected]c3ec4db2013-01-31 20:06:21180 return;
[email protected]1df3d972014-06-11 04:55:18181#endif
[email protected]c3ec4db2013-01-31 20:06:21182
[email protected]099d6722014-02-04 01:13:03183 // Check if the launcher is itself an unswapped prerender.
184 PrerenderContents* prerender_contents =
185 manager_->GetPrerenderContentsForRoute(launcher_child_id,
186 render_view_route_id);
187 if (prerender_contents &&
188 prerender_contents->final_status() != FINAL_STATUS_MAX) {
189 // The launcher is a prerender about to be destroyed asynchronously, but
190 // its AddLinkRelPrerender message raced with shutdown. Ignore it.
191 DCHECK_NE(FINAL_STATUS_USED, prerender_contents->final_status());
192 return;
193 }
194
[email protected]a2439eea2012-12-29 00:16:45195 LinkPrerender
[email protected]1ee57dd72014-02-11 23:58:40196 prerender(launcher_child_id, prerender_id, url, rel_types, referrer, size,
[email protected]099d6722014-02-04 01:13:03197 render_view_route_id, manager_->GetCurrentTimeTicks(),
198 prerender_contents);
[email protected]a2439eea2012-12-29 00:16:45199 prerenders_.push_back(prerender);
[email protected]ea07cde2014-02-12 20:09:47200 RecordLinkManagerAdded(rel_types);
[email protected]099d6722014-02-04 01:13:03201 if (prerender_contents)
202 pending_prerender_manager_->ObserveLauncher(prerender_contents);
203 else
204 StartPrerenders();
[email protected]2736c032012-05-11 18:06:07205}
206
[email protected]2736c032012-05-11 18:06:07207void PrerenderLinkManager::OnCancelPrerender(int child_id, int prerender_id) {
[email protected]a2439eea2012-12-29 00:16:45208 LinkPrerender* prerender = FindByLauncherChildIdAndPrerenderId(child_id,
[email protected]197ea352013-01-04 18:37:29209 prerender_id);
[email protected]a2439eea2012-12-29 00:16:45210 if (!prerender)
[email protected]2736c032012-05-11 18:06:07211 return;
[email protected]762c7242012-12-18 02:23:52212
[email protected]1910aa02013-10-24 00:14:05213 CancelPrerender(prerender);
[email protected]a2439eea2012-12-29 00:16:45214 StartPrerenders();
[email protected]2736c032012-05-11 18:06:07215}
216
217void PrerenderLinkManager::OnAbandonPrerender(int child_id, int prerender_id) {
[email protected]a2439eea2012-12-29 00:16:45218 LinkPrerender* prerender = FindByLauncherChildIdAndPrerenderId(child_id,
[email protected]197ea352013-01-04 18:37:29219 prerender_id);
[email protected]a2439eea2012-12-29 00:16:45220 if (!prerender)
[email protected]48055042012-07-14 21:12:11221 return;
[email protected]a2439eea2012-12-29 00:16:45222
223 if (!prerender->handle) {
224 RemovePrerender(prerender);
225 return;
226 }
227
[email protected]1910aa02013-10-24 00:14:05228 prerender->has_been_abandoned = true;
[email protected]a2439eea2012-12-29 00:16:45229 prerender->handle->OnNavigateAway();
230 DCHECK(prerender->handle);
231
232 // If the prerender is not running, remove it from the list so it does not
233 // leak. If it is running, it will send a cancel event when it stops which
234 // will remove it.
235 if (!prerender->handle->IsPrerendering())
236 RemovePrerender(prerender);
[email protected]2736c032012-05-11 18:06:07237}
238
239void PrerenderLinkManager::OnChannelClosing(int child_id) {
[email protected]a2439eea2012-12-29 00:16:45240 std::list<LinkPrerender>::iterator next = prerenders_.begin();
241 while (next != prerenders_.end()) {
242 std::list<LinkPrerender>::iterator it = next;
[email protected]26101702012-12-15 21:45:18243 ++next;
244
[email protected]a2439eea2012-12-29 00:16:45245 if (child_id != it->launcher_child_id)
246 continue;
[email protected]26101702012-12-15 21:45:18247
[email protected]a2439eea2012-12-29 00:16:45248 const size_t running_prerender_count = CountRunningPrerenders();
249 OnAbandonPrerender(child_id, it->prerender_id);
250 DCHECK_EQ(running_prerender_count, CountRunningPrerenders());
[email protected]2736c032012-05-11 18:06:07251 }
252}
253
[email protected]a2439eea2012-12-29 00:16:45254PrerenderLinkManager::LinkPrerender::LinkPrerender(
255 int launcher_child_id,
256 int prerender_id,
257 const GURL& url,
avib896c712015-12-26 02:10:43258 uint32_t rel_types,
[email protected]a2439eea2012-12-29 00:16:45259 const content::Referrer& referrer,
260 const gfx::Size& size,
261 int render_view_route_id,
[email protected]099d6722014-02-04 01:13:03262 TimeTicks creation_time,
263 PrerenderContents* deferred_launcher)
264 : launcher_child_id(launcher_child_id),
265 prerender_id(prerender_id),
266 url(url),
[email protected]1ee57dd72014-02-11 23:58:40267 rel_types(rel_types),
[email protected]099d6722014-02-04 01:13:03268 referrer(referrer),
269 size(size),
270 render_view_route_id(render_view_route_id),
271 creation_time(creation_time),
272 deferred_launcher(deferred_launcher),
273 handle(NULL),
avib896c712015-12-26 02:10:43274 has_been_abandoned(false) {}
[email protected]a2439eea2012-12-29 00:16:45275
vmpstrb8aacbe2016-02-26 02:00:48276PrerenderLinkManager::LinkPrerender::LinkPrerender(const LinkPrerender& other) =
277 default;
278
[email protected]a2439eea2012-12-29 00:16:45279PrerenderLinkManager::LinkPrerender::~LinkPrerender() {
280 DCHECK_EQ(static_cast<PrerenderHandle*>(NULL), handle)
281 << "The PrerenderHandle should be destroyed before its Prerender.";
282}
283
[email protected]2736c032012-05-11 18:06:07284bool PrerenderLinkManager::IsEmpty() const {
[email protected]a2439eea2012-12-29 00:16:45285 return prerenders_.empty();
[email protected]48055042012-07-14 21:12:11286}
287
[email protected]a2439eea2012-12-29 00:16:45288size_t PrerenderLinkManager::CountRunningPrerenders() const {
289 size_t retval = 0;
290 for (std::list<LinkPrerender>::const_iterator i = prerenders_.begin();
291 i != prerenders_.end(); ++i) {
292 if (i->handle && i->handle->IsPrerendering())
293 ++retval;
[email protected]26101702012-12-15 21:45:18294 }
[email protected]a2439eea2012-12-29 00:16:45295 return retval;
296}
297
298void PrerenderLinkManager::StartPrerenders() {
299 if (has_shutdown_)
300 return;
301
302 size_t total_started_prerender_count = 0;
[email protected]1910aa02013-10-24 00:14:05303 std::list<LinkPrerender*> abandoned_prerenders;
304 std::list<std::list<LinkPrerender>::iterator> pending_prerenders;
[email protected]a2439eea2012-12-29 00:16:45305 std::multiset<std::pair<int, int> >
306 running_launcher_and_render_view_routes;
307
308 // Scan the list, counting how many prerenders have handles (and so were added
309 // to the PrerenderManager). The count is done for the system as a whole, and
310 // also per launcher.
311 for (std::list<LinkPrerender>::iterator i = prerenders_.begin();
312 i != prerenders_.end(); ++i) {
[email protected]099d6722014-02-04 01:13:03313 // Skip prerenders launched by a prerender.
314 if (i->deferred_launcher)
315 continue;
[email protected]1910aa02013-10-24 00:14:05316 if (!i->handle) {
317 pending_prerenders.push_back(i);
318 } else {
[email protected]a2439eea2012-12-29 00:16:45319 ++total_started_prerender_count;
[email protected]1910aa02013-10-24 00:14:05320 if (i->has_been_abandoned) {
321 abandoned_prerenders.push_back(&(*i));
322 } else {
323 // We do not count abandoned prerenders towards their launcher, since it
324 // has already navigated on to another page.
325 std::pair<int, int> launcher_and_render_view_route(
326 i->launcher_child_id, i->render_view_route_id);
327 running_launcher_and_render_view_routes.insert(
328 launcher_and_render_view_route);
329 DCHECK_GE(manager_->config().max_link_concurrency_per_launcher,
330 running_launcher_and_render_view_routes.count(
331 launcher_and_render_view_route));
332 }
[email protected]a2439eea2012-12-29 00:16:45333 }
334
335 DCHECK_EQ(&(*i), FindByLauncherChildIdAndPrerenderId(i->launcher_child_id,
336 i->prerender_id));
337 }
[email protected]1910aa02013-10-24 00:14:05338 DCHECK_LE(abandoned_prerenders.size(), total_started_prerender_count);
[email protected]a2439eea2012-12-29 00:16:45339 DCHECK_GE(manager_->config().max_link_concurrency,
340 total_started_prerender_count);
341 DCHECK_LE(CountRunningPrerenders(), total_started_prerender_count);
342
343 TimeTicks now = manager_->GetCurrentTimeTicks();
344
[email protected]1910aa02013-10-24 00:14:05345 // Scan the pending prerenders, starting prerenders as we can.
346 for (std::list<std::list<LinkPrerender>::iterator>::const_iterator
347 i = pending_prerenders.begin(), end = pending_prerenders.end();
348 i != end; ++i) {
349 TimeDelta prerender_age = now - (*i)->creation_time;
[email protected]a2439eea2012-12-29 00:16:45350 if (prerender_age >= manager_->config().max_wait_to_launch) {
351 // This prerender waited too long in the queue before launching.
[email protected]1910aa02013-10-24 00:14:05352 prerenders_.erase(*i);
[email protected]a2439eea2012-12-29 00:16:45353 continue;
354 }
355
356 std::pair<int, int> launcher_and_render_view_route(
[email protected]1910aa02013-10-24 00:14:05357 (*i)->launcher_child_id, (*i)->render_view_route_id);
[email protected]a2439eea2012-12-29 00:16:45358 if (manager_->config().max_link_concurrency_per_launcher <=
359 running_launcher_and_render_view_routes.count(
360 launcher_and_render_view_route)) {
361 // This prerender's launcher is already at its limit.
362 continue;
363 }
364
[email protected]1910aa02013-10-24 00:14:05365 if (total_started_prerender_count >=
366 manager_->config().max_link_concurrency ||
367 total_started_prerender_count >= prerenders_.size()) {
368 // The system is already at its prerender concurrency limit. Can we kill
369 // an abandoned prerender to make room?
370 if (!abandoned_prerenders.empty()) {
371 CancelPrerender(abandoned_prerenders.front());
372 --total_started_prerender_count;
373 abandoned_prerenders.pop_front();
374 } else {
375 return;
376 }
377 }
378
[email protected]1ee57dd72014-02-11 23:58:40379 if (!ShouldStartPrerender((*i)->rel_types)) {
380 prerenders_.erase(*i);
381 continue;
382 }
383
thestigc98161a2016-07-20 01:42:49384 std::unique_ptr<PrerenderHandle> handle =
385 manager_->AddPrerenderFromLinkRelPrerender(
386 (*i)->launcher_child_id, (*i)->render_view_route_id, (*i)->url,
387 (*i)->rel_types, (*i)->referrer, (*i)->size);
[email protected]a2439eea2012-12-29 00:16:45388 if (!handle) {
389 // This prerender couldn't be launched, it's gone.
[email protected]1910aa02013-10-24 00:14:05390 prerenders_.erase(*i);
[email protected]a2439eea2012-12-29 00:16:45391 continue;
392 }
393
394 // We have successfully started a new prerender.
thestigc98161a2016-07-20 01:42:49395 (*i)->handle = handle.release();
[email protected]a2439eea2012-12-29 00:16:45396 ++total_started_prerender_count;
thestigc98161a2016-07-20 01:42:49397 (*i)->handle->SetObserver(this);
398 if ((*i)->handle->IsPrerendering())
399 OnPrerenderStart((*i)->handle);
[email protected]ea07cde2014-02-12 20:09:47400 RecordLinkManagerStarting((*i)->rel_types);
[email protected]a2439eea2012-12-29 00:16:45401
402 running_launcher_and_render_view_routes.insert(
403 launcher_and_render_view_route);
404 }
405}
406
407PrerenderLinkManager::LinkPrerender*
408PrerenderLinkManager::FindByLauncherChildIdAndPrerenderId(int launcher_child_id,
409 int prerender_id) {
410 for (std::list<LinkPrerender>::iterator i = prerenders_.begin();
411 i != prerenders_.end(); ++i) {
412 if (launcher_child_id == i->launcher_child_id &&
413 prerender_id == i->prerender_id) {
414 return &(*i);
415 }
416 }
417 return NULL;
418}
419
420PrerenderLinkManager::LinkPrerender*
421PrerenderLinkManager::FindByPrerenderHandle(PrerenderHandle* prerender_handle) {
422 DCHECK(prerender_handle);
423 for (std::list<LinkPrerender>::iterator i = prerenders_.begin();
424 i != prerenders_.end(); ++i) {
425 if (prerender_handle == i->handle)
426 return &(*i);
427 }
428 return NULL;
429}
430
431void PrerenderLinkManager::RemovePrerender(LinkPrerender* prerender) {
432 for (std::list<LinkPrerender>::iterator i = prerenders_.begin();
433 i != prerenders_.end(); ++i) {
434 if (&(*i) == prerender) {
dcheng4af48582016-04-19 00:29:35435 std::unique_ptr<PrerenderHandle> own_handle(i->handle);
[email protected]a2439eea2012-12-29 00:16:45436 i->handle = NULL;
437 prerenders_.erase(i);
438 return;
439 }
440 }
441 NOTREACHED();
442}
443
[email protected]1910aa02013-10-24 00:14:05444void PrerenderLinkManager::CancelPrerender(LinkPrerender* prerender) {
445 for (std::list<LinkPrerender>::iterator i = prerenders_.begin();
446 i != prerenders_.end(); ++i) {
447 if (&(*i) == prerender) {
dcheng4af48582016-04-19 00:29:35448 std::unique_ptr<PrerenderHandle> own_handle(i->handle);
[email protected]1910aa02013-10-24 00:14:05449 i->handle = NULL;
450 prerenders_.erase(i);
451 if (own_handle)
452 own_handle->OnCancel();
453 return;
454 }
455 }
456 NOTREACHED();
457}
458
[email protected]099d6722014-02-04 01:13:03459void PrerenderLinkManager::StartPendingPrerendersForLauncher(
460 PrerenderContents* launcher) {
461 for (std::list<LinkPrerender>::iterator i = prerenders_.begin();
462 i != prerenders_.end(); ++i) {
463 if (i->deferred_launcher == launcher)
464 i->deferred_launcher = NULL;
465 }
466 StartPrerenders();
467}
468
469void PrerenderLinkManager::CancelPendingPrerendersForLauncher(
470 PrerenderContents* launcher) {
471 // Remove all pending prerenders for this launcher.
[email protected]099d6722014-02-04 01:13:03472 for (std::list<LinkPrerender>::iterator i = prerenders_.begin();
vmpstraed91af92015-11-02 21:59:24473 i != prerenders_.end();) {
[email protected]099d6722014-02-04 01:13:03474 if (i->deferred_launcher == launcher) {
475 DCHECK(!i->handle);
vmpstraed91af92015-11-02 21:59:24476 i = prerenders_.erase(i);
477 } else {
478 ++i;
[email protected]099d6722014-02-04 01:13:03479 }
480 }
[email protected]099d6722014-02-04 01:13:03481}
482
[email protected]a2439eea2012-12-29 00:16:45483void PrerenderLinkManager::Shutdown() {
484 has_shutdown_ = true;
[email protected]26101702012-12-15 21:45:18485}
486
[email protected]540125c2014-02-14 07:23:08487// In practice, this is always called from PrerenderLinkManager::OnAddPrerender.
[email protected]26101702012-12-15 21:45:18488void PrerenderLinkManager::OnPrerenderStart(
489 PrerenderHandle* prerender_handle) {
[email protected]a2439eea2012-12-29 00:16:45490 LinkPrerender* prerender = FindByPrerenderHandle(prerender_handle);
491 if (!prerender)
492 return;
493 Send(prerender->launcher_child_id,
494 new PrerenderMsg_OnPrerenderStart(prerender->prerender_id));
[email protected]26101702012-12-15 21:45:18495}
496
[email protected]49fc07b2013-01-03 21:05:22497void PrerenderLinkManager::OnPrerenderStopLoading(
498 PrerenderHandle* prerender_handle) {
[email protected]a2439eea2012-12-29 00:16:45499 LinkPrerender* prerender = FindByPrerenderHandle(prerender_handle);
500 if (!prerender)
[email protected]26101702012-12-15 21:45:18501 return;
[email protected]49fc07b2013-01-03 21:05:22502
[email protected]a2439eea2012-12-29 00:16:45503 Send(prerender->launcher_child_id,
[email protected]49fc07b2013-01-03 21:05:22504 new PrerenderMsg_OnPrerenderStopLoading(prerender->prerender_id));
[email protected]26101702012-12-15 21:45:18505}
506
[email protected]59000ecd2014-02-12 00:32:04507void PrerenderLinkManager::OnPrerenderDomContentLoaded(
508 PrerenderHandle* prerender_handle) {
509 LinkPrerender* prerender = FindByPrerenderHandle(prerender_handle);
510 if (!prerender)
511 return;
512
513 Send(prerender->launcher_child_id,
514 new PrerenderMsg_OnPrerenderDomContentLoaded(prerender->prerender_id));
515}
516
[email protected]26101702012-12-15 21:45:18517void PrerenderLinkManager::OnPrerenderStop(
518 PrerenderHandle* prerender_handle) {
[email protected]a2439eea2012-12-29 00:16:45519 LinkPrerender* prerender = FindByPrerenderHandle(prerender_handle);
520 if (!prerender)
[email protected]26101702012-12-15 21:45:18521 return;
[email protected]26101702012-12-15 21:45:18522
[email protected]0fd94d22013-10-10 09:03:57523 Send(prerender->launcher_child_id,
524 new PrerenderMsg_OnPrerenderStop(prerender->prerender_id));
pasko3e302bd52016-05-11 16:37:56525 RemovePrerender(prerender);
526 StartPrerenders();
[email protected]0fd94d22013-10-10 09:03:57527}
528
[email protected]2736c032012-05-11 18:06:07529} // namespace prerender