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
3 // found in the LICENSE file.
5 #include "chrome/renderer/prerender/prerender_dispatcher.h"
7 #include "base/logging.h"
8 #include "chrome/common/prerender_messages.h"
9 #include "chrome/renderer/prerender/prerender_extra_data.h"
10 #include "content/public/common/referrer.h"
11 #include "content/public/renderer/render_thread.h"
12 #include "content/public/renderer/render_view.h"
13 #include "third_party/WebKit/public/platform/WebPrerenderingSupport.h"
14 #include "third_party/WebKit/public/platform/WebString.h"
15 #include "third_party/WebKit/public/platform/WebURL.h"
20 using WebKit::WebPrerender
;
21 using WebKit::WebPrerenderingSupport
;
23 PrerenderDispatcher::PrerenderDispatcher() {
24 WebPrerenderingSupport::initialize(this);
27 PrerenderDispatcher::~PrerenderDispatcher() {
28 WebPrerenderingSupport::shutdown();
31 bool PrerenderDispatcher::IsPrerenderURL(const GURL
& url
) const {
32 return running_prerender_urls_
.count(url
) >= 1;
35 void PrerenderDispatcher::OnPrerenderStart(int prerender_id
) {
36 DCHECK_NE(0u, prerenders_
.count(prerender_id
));
37 std::map
<int, WebPrerender
>::iterator it
= prerenders_
.find(prerender_id
);
39 WebPrerender
& prerender
= it
->second
;
41 // The prerender should only be null in unit tests.
42 if (prerender
.isNull())
45 prerender
.didStartPrerender();
48 void PrerenderDispatcher::OnPrerenderStopLoading(int prerender_id
) {
49 DCHECK_NE(0u, prerenders_
.count(prerender_id
));
50 std::map
<int, WebPrerender
>::iterator it
= prerenders_
.find(prerender_id
);
52 WebPrerender
& prerender
= it
->second
;
53 DCHECK(!prerender
.isNull())
54 << "OnPrerenderStopLoading shouldn't be called from a unit test, the only"
55 << "context in which a WebPrerender in the dispatcher can be null.";
57 prerender
.didSendLoadForPrerender();
60 void PrerenderDispatcher::OnPrerenderAddAlias(const GURL
& alias
) {
61 running_prerender_urls_
.insert(alias
);
64 void PrerenderDispatcher::OnPrerenderRemoveAliases(
65 const std::vector
<GURL
>& aliases
) {
66 for (size_t i
= 0; i
< aliases
.size(); ++i
) {
67 std::multiset
<GURL
>::iterator it
= running_prerender_urls_
.find(aliases
[i
]);
68 if (it
!= running_prerender_urls_
.end()) {
69 running_prerender_urls_
.erase(it
);
74 void PrerenderDispatcher::OnPrerenderStop(int prerender_id
) {
75 DCHECK_NE(0u, prerenders_
.count(prerender_id
));
76 WebPrerender
& prerender
= prerenders_
[prerender_id
];
78 // The prerender should only be null in unit tests.
79 if (!prerender
.isNull())
80 prerender
.didStopPrerender();
82 // TODO(cbentzel): We'd also want to send the map of active prerenders when
83 // creating a new render process, so the Add/Remove go relative to that.
84 // This may not be that big of a deal in practice, since the newly created tab
85 // is unlikely to go to the prerendered page.
86 prerenders_
.erase(prerender_id
);
89 bool PrerenderDispatcher::OnControlMessageReceived(
90 const IPC::Message
& message
) {
92 IPC_BEGIN_MESSAGE_MAP(PrerenderDispatcher
, message
)
93 IPC_MESSAGE_HANDLER(PrerenderMsg_OnPrerenderStart
, OnPrerenderStart
)
94 IPC_MESSAGE_HANDLER(PrerenderMsg_OnPrerenderStopLoading
,
95 OnPrerenderStopLoading
)
96 IPC_MESSAGE_HANDLER(PrerenderMsg_OnPrerenderAddAlias
, OnPrerenderAddAlias
)
97 IPC_MESSAGE_HANDLER(PrerenderMsg_OnPrerenderRemoveAliases
,
98 OnPrerenderRemoveAliases
)
99 IPC_MESSAGE_HANDLER(PrerenderMsg_OnPrerenderStop
, OnPrerenderStop
)
100 IPC_MESSAGE_UNHANDLED(handled
= false)
101 IPC_END_MESSAGE_MAP()
106 void PrerenderDispatcher::add(const WebPrerender
& prerender
) {
107 const PrerenderExtraData
& extra_data
=
108 PrerenderExtraData::FromPrerender(prerender
);
109 if (prerenders_
.count(extra_data
.prerender_id()) != 0) {
110 // TODO(gavinp): Determine why these apparently duplicate adds occur.
114 prerenders_
[extra_data
.prerender_id()] = prerender
;
116 content::RenderThread::Get()->Send(new PrerenderHostMsg_AddLinkRelPrerender(
117 extra_data
.prerender_id(), GURL(prerender
.url()),
118 content::Referrer(GURL(prerender
.referrer()),
119 prerender
.referrerPolicy()),
120 extra_data
.size(), extra_data
.render_view_route_id()));
123 void PrerenderDispatcher::cancel(const WebPrerender
& prerender
) {
124 const PrerenderExtraData
& extra_data
=
125 PrerenderExtraData::FromPrerender(prerender
);
126 content::RenderThread::Get()->Send(
127 new PrerenderHostMsg_CancelLinkRelPrerender(extra_data
.prerender_id()));
130 void PrerenderDispatcher::abandon(const WebPrerender
& prerender
) {
131 const PrerenderExtraData
& extra_data
=
132 PrerenderExtraData::FromPrerender(prerender
);
133 content::RenderThread::Get()->Send(
134 new PrerenderHostMsg_AbandonLinkRelPrerender(extra_data
.prerender_id()));
137 } // namespace prerender