Chromium Code Reviews| 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 |