OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "chrome/browser/prerender/prerender_link_manager.h" | |
6 | |
7 #include <limits> | |
8 #include <queue> | |
9 #include <utility> | |
10 | |
11 #include "chrome/browser/profiles/profile.h" | |
12 #include "chrome/browser/prerender/prerender_contents.h" | |
13 #include "chrome/browser/prerender/prerender_manager.h" | |
14 #include "chrome/browser/prerender/prerender_manager_factory.h" | |
15 #include "content/public/common/referrer.h" | |
16 #include "googleurl/src/gurl.h" | |
17 #include "googleurl/src/url_canon.h" | |
18 #include "ui/gfx/size.h" | |
19 | |
20 namespace { | |
21 | |
22 template<typename MapForwards, typename MapBackwards> | |
23 bool CheckMapsAreInverseOfEachOther(const MapForwards& map_forwards, | |
mmenke
2012/04/24 15:26:15
nit: Suggest you rename this "MapsAreInverseOfEac
cbentzel
2012/04/24 15:42:59
Nit: Perhaps AreMapsInverseOfEachOther? No actual
gavinp
2012/04/26 23:55:39
Done.
| |
24 const MapBackwards& map_backwards) { | |
25 if (map_forwards.size() != map_backwards.size()) | |
26 return false; | |
27 for (typename MapForwards::const_iterator i = map_forwards.begin(), | |
cbentzel
2012/04/24 15:42:59
This doesn't quite test inversion. For example, if
gavinp
2012/04/26 23:55:39
Done.
| |
28 e = map_forwards.end(); | |
29 i != e; ++i) { | |
30 if (map_backwards.find(i->second) == map_backwards.end()) | |
31 return false; | |
32 } | |
33 for (typename MapBackwards::const_iterator i = map_backwards.begin(), | |
34 e = map_backwards.end(); | |
mmenke
2012/04/24 15:26:15
Is this necessary? Given that the maps have the s
gavinp
2012/04/26 23:55:39
No it's not, especially now that I fixed the terri
| |
35 i != e; ++i) { | |
36 if (map_forwards.find(i->second) == map_forwards.end()) | |
37 return false; | |
38 } | |
39 return true; | |
40 } | |
41 | |
42 } | |
43 | |
44 namespace prerender { | |
45 | |
46 PrerenderLinkManager::PrerenderLinkManager( | |
47 PrerenderManager* manager) | |
48 : manager_(manager) { | |
49 } | |
50 | |
51 PrerenderLinkManager::~PrerenderLinkManager() { | |
52 } | |
53 | |
54 void PrerenderLinkManager::RemovePrerender( | |
cbentzel
2012/04/24 15:42:59
Nit: ordering of class definitions should match de
gavinp
2012/04/26 23:55:39
Done.
| |
55 const PrerenderIdToUrlMap::iterator& id_url_iter) { | |
56 DCHECK(CheckMapsAreInverseOfEachOther(id_map_, url_map_)); | |
57 const GURL url = id_url_iter->second; | |
58 const ChildAndPrerenderIdPair child_and_prerender_id = id_url_iter->first; | |
59 id_map_.erase(id_url_iter); | |
60 | |
61 for (UrlToPrerenderIdMap::iterator i = url_map_.lower_bound(url), | |
62 e = url_map_.upper_bound(url); | |
63 i != e; ++i) { | |
64 if (i->second == child_and_prerender_id) { | |
65 url_map_.erase(i); | |
66 DCHECK(CheckMapsAreInverseOfEachOther(id_map_, url_map_)); | |
67 return; | |
68 } | |
69 } | |
70 NOTREACHED(); | |
71 } | |
72 | |
73 void PrerenderLinkManager::OnAddPrerender(const int prerender_id, | |
cbentzel
2012/04/24 15:42:59
Curious - this doesn't match the signature in the
gavinp
2012/04/26 23:55:39
This does compile. You can always add "const" in
| |
74 const int child_id, | |
75 const GURL& orig_url, | |
76 const content::Referrer& referrer, | |
77 const gfx::Size& ALLOW_UNUSED size, | |
78 const int render_view_route_id) { | |
79 DVLOG(2) << "OnAddPrerender, child_id = " << child_id | |
80 << ", prerender_id = " << prerender_id | |
81 << ", url = " << orig_url.spec(); | |
82 DVLOG(3) << "... render_view_route_id = " << render_view_route_id | |
83 << ", referrer url = " << referrer.url.spec(); | |
84 DCHECK(CheckMapsAreInverseOfEachOther(id_map_, url_map_)); | |
85 // TODO(gavinp): Add tests to insure fragments work, then remove this fragment | |
cbentzel
2012/04/24 15:42:59
Nit: ensure
gavinp
2012/04/26 23:55:39
Done.
| |
86 // clearing code. | |
87 url_canon::Replacements<char> replacements; | |
88 replacements.ClearRef(); | |
89 const GURL url = orig_url.ReplaceComponents(replacements); | |
90 | |
91 manager_->AddPrerenderFromLinkRelPrerender( | |
92 child_id, render_view_route_id, url, referrer); | |
mmenke
2012/04/24 15:26:15
Random comment: When this fails, is there anythin
| |
93 const ChildAndPrerenderIdPair child_and_prerender_id(child_id, prerender_id); | |
94 DCHECK(id_map_.find(child_and_prerender_id) == id_map_.end()); | |
95 id_map_.insert(std::make_pair(child_and_prerender_id, url)); | |
cbentzel
2012/04/24 15:42:59
Should this be done prior to the AddPrerender case
gavinp
2012/04/26 23:55:39
See my reply to mmenke above...
| |
96 url_map_.insert(std::make_pair(url, child_and_prerender_id)); | |
97 DCHECK(CheckMapsAreInverseOfEachOther(id_map_, url_map_)); | |
98 } | |
99 | |
100 void PrerenderLinkManager::OnCancelPrerender(const int prerender_id, | |
101 const int child_id) { | |
102 DVLOG(2) << "OnCancelPrerender, child_id = " << child_id | |
103 << ", prerender_id = " << prerender_id; | |
104 const ChildAndPrerenderIdPair child_and_prerender_id(child_id, prerender_id); | |
105 PrerenderIdToUrlMap::iterator id_url_iter = | |
106 id_map_.find(child_and_prerender_id); | |
107 if (id_url_iter == id_map_.end()) { | |
108 NOTREACHED() << "Canceling a prerender that doesn't exist."; | |
109 return; | |
110 } | |
111 const GURL url = id_url_iter->second; | |
112 RemovePrerender(id_url_iter); | |
113 | |
114 if (url_map_.find(url) != url_map_.end()) | |
115 return; | |
116 | |
117 // TODO(gavinp): Track down the correct prerender and stop it, rather than | |
cbentzel
2012/04/24 15:42:59
Why not fix this now?
gavinp
2012/04/26 23:55:39
This here is advanced quite a lot from what was in
| |
118 // this nuclear option, which assumes that only one prerender at a time | |
119 // runs. | |
120 if (PrerenderContents* contents = manager_->GetEntry(url)) | |
121 contents->Destroy(FINAL_STATUS_CANCELLED); | |
cbentzel
2012/04/24 15:42:59
Yes, this seems like the appropriate FINAL_STATUS
| |
122 } | |
123 | |
124 void PrerenderLinkManager::OnAbandonPrerender( | |
125 int prerender_id, | |
cbentzel
2012/04/24 15:42:59
Nit: could this fit on the previous line?
gavinp
2012/04/26 23:55:39
Done. This removes the last sign of the horrible
| |
126 int child_id) { | |
127 DVLOG(2) << "OnAbandonPrerender, child_id = " << child_id | |
128 << ", prerender_id = " << prerender_id; | |
129 // TODO(gavinp,cbentzel): Implement reasonable behaviour for | |
130 // navigation away from launcher. | |
131 const ChildAndPrerenderIdPair child_and_prerender_id(child_id, prerender_id); | |
132 PrerenderIdToUrlMap::iterator id_url_iter = | |
133 id_map_.find(child_and_prerender_id); | |
134 if (id_url_iter == id_map_.end()) { | |
135 // FIXME(gavinp): Currently, canceled prerenders also get abandoned later. | |
136 // When the WebKit fix to stop this lands, add a NOTREACHED() here. | |
137 return; | |
138 } | |
139 RemovePrerender(id_url_iter); | |
140 } | |
141 | |
142 void PrerenderLinkManager::OnChannelClosing(int child_id) { | |
143 DVLOG(2) << "OnChannelClosing, child id = " << child_id; | |
144 const ChildAndPrerenderIdPair child_and_minimum_prerender_id( | |
145 child_id, std::numeric_limits<int>::min()); | |
146 const ChildAndPrerenderIdPair child_and_maximum_prerender_id( | |
147 child_id, std::numeric_limits<int>::max()); | |
148 std::queue<int> prerender_ids_to_abandon; | |
149 for (PrerenderIdToUrlMap::iterator | |
150 i = id_map_.lower_bound(child_and_minimum_prerender_id), | |
cbentzel
2012/04/24 15:42:59
Clever.
Just to be sure though - if id_map_ only
gavinp
2012/04/26 23:55:39
Yes. But we'd never run the loop body in that cas
| |
151 e = id_map_.upper_bound(child_and_maximum_prerender_id); | |
152 i != e; ++i) { | |
153 prerender_ids_to_abandon.push(i->first.second); | |
154 } | |
155 while (!prerender_ids_to_abandon.empty()) { | |
156 DVLOG(4) << "---> abandon prerender_id = " | |
157 << prerender_ids_to_abandon.front(); | |
158 OnAbandonPrerender(prerender_ids_to_abandon.front(), child_id); | |
cbentzel
2012/04/24 15:42:59
Why is this overloading OnAbandonPrerender, if we
gavinp
2012/04/26 23:55:39
What about the case of the user navigating away fr
| |
159 prerender_ids_to_abandon.pop(); | |
160 } | |
161 } | |
162 | |
163 } // namespace prerender | |
OLD | NEW |