Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/extensions/api/web_navigation/frame_navigation_state.h" | 5 #include "chrome/browser/extensions/api/web_navigation/frame_navigation_state.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "chrome/common/url_constants.h" | 8 #include "chrome/common/url_constants.h" |
| 9 #include "content/public/browser/render_frame_host.h" | |
| 9 #include "extensions/common/constants.h" | 10 #include "extensions/common/constants.h" |
| 10 | 11 |
| 11 namespace extensions { | 12 namespace extensions { |
| 12 | 13 |
| 13 namespace { | 14 namespace { |
| 14 | 15 |
| 15 // URL schemes for which we'll send events. | 16 // URL schemes for which we'll send events. |
| 16 const char* kValidSchemes[] = { | 17 const char* kValidSchemes[] = { |
| 17 content::kChromeUIScheme, | 18 content::kChromeUIScheme, |
| 18 url::kHttpScheme, | 19 url::kHttpScheme, |
| 19 url::kHttpsScheme, | 20 url::kHttpsScheme, |
| 20 url::kFileScheme, | 21 url::kFileScheme, |
| 21 url::kFtpScheme, | 22 url::kFtpScheme, |
| 22 url::kJavaScriptScheme, | 23 url::kJavaScriptScheme, |
| 23 url::kDataScheme, | 24 url::kDataScheme, |
| 24 url::kFileSystemScheme, | 25 url::kFileSystemScheme, |
| 25 }; | 26 }; |
| 26 | 27 |
| 27 } // namespace | 28 } // namespace |
| 28 | 29 |
| 29 FrameNavigationState::FrameID::FrameID() | |
| 30 : frame_num(-1), | |
| 31 render_view_host(NULL) { | |
| 32 } | |
| 33 | |
| 34 FrameNavigationState::FrameID::FrameID( | |
| 35 int64 frame_num, | |
| 36 content::RenderViewHost* render_view_host) | |
| 37 : frame_num(frame_num), | |
| 38 render_view_host(render_view_host) { | |
| 39 } | |
| 40 | |
| 41 bool FrameNavigationState::FrameID::operator<( | |
| 42 const FrameNavigationState::FrameID& other) const { | |
| 43 return frame_num < other.frame_num || | |
| 44 (frame_num == other.frame_num && | |
| 45 render_view_host < other.render_view_host); | |
| 46 } | |
| 47 | |
| 48 bool FrameNavigationState::FrameID::operator==( | |
| 49 const FrameNavigationState::FrameID& other) const { | |
| 50 return frame_num == other.frame_num && | |
| 51 render_view_host == other.render_view_host; | |
| 52 } | |
| 53 | |
| 54 bool FrameNavigationState::FrameID::operator!=( | |
| 55 const FrameNavigationState::FrameID& other) const { | |
| 56 return !(*this == other); | |
| 57 } | |
| 58 | |
| 59 FrameNavigationState::FrameState::FrameState() {} | 30 FrameNavigationState::FrameState::FrameState() {} |
| 60 | 31 |
| 61 // static | 32 // static |
| 62 bool FrameNavigationState::allow_extension_scheme_ = false; | 33 bool FrameNavigationState::allow_extension_scheme_ = false; |
| 63 | 34 |
| 64 FrameNavigationState::FrameNavigationState() {} | 35 FrameNavigationState::FrameNavigationState() : main_frame_host_(NULL) { |
| 36 } | |
| 65 | 37 |
| 66 FrameNavigationState::~FrameNavigationState() {} | 38 FrameNavigationState::~FrameNavigationState() {} |
| 67 | 39 |
| 68 bool FrameNavigationState::CanSendEvents(FrameID frame_id) const { | 40 bool FrameNavigationState::CanSendEvents( |
| 69 FrameIdToStateMap::const_iterator frame_state = | 41 content::RenderFrameHost* frame_host) const { |
| 70 frame_state_map_.find(frame_id); | 42 FrameHostToStateMap::const_iterator it = |
| 71 if (frame_state == frame_state_map_.end() || | 43 frame_host_state_map_.find(frame_host); |
| 72 frame_state->second.error_occurred) { | 44 if (it == frame_host_state_map_.end() || it->second.error_occurred) { |
| 73 return false; | 45 return false; |
| 74 } | 46 } |
| 75 return IsValidUrl(frame_state->second.url); | 47 return IsValidUrl(it->second.url); |
| 76 } | 48 } |
| 77 | 49 |
| 78 bool FrameNavigationState::IsValidUrl(const GURL& url) const { | 50 bool FrameNavigationState::IsValidUrl(const GURL& url) const { |
| 79 for (unsigned i = 0; i < arraysize(kValidSchemes); ++i) { | 51 for (unsigned i = 0; i < arraysize(kValidSchemes); ++i) { |
| 80 if (url.scheme() == kValidSchemes[i]) | 52 if (url.scheme() == kValidSchemes[i]) |
| 81 return true; | 53 return true; |
| 82 } | 54 } |
| 83 // Allow about:blank and about:srcdoc. | 55 // Allow about:blank and about:srcdoc. |
| 84 if (url.spec() == url::kAboutBlankURL || | 56 if (url.spec() == url::kAboutBlankURL || |
| 85 url.spec() == content::kAboutSrcDocURL) { | 57 url.spec() == content::kAboutSrcDocURL) { |
| 86 return true; | 58 return true; |
| 87 } | 59 } |
| 88 return allow_extension_scheme_ && url.scheme() == kExtensionScheme; | 60 return allow_extension_scheme_ && url.scheme() == kExtensionScheme; |
| 89 } | 61 } |
| 90 | 62 |
| 91 void FrameNavigationState::TrackFrame(FrameID frame_id, | 63 void FrameNavigationState::TrackFrame(content::RenderFrameHost* frame_host, |
| 92 FrameID parent_frame_id, | |
| 93 const GURL& url, | 64 const GURL& url, |
| 94 bool is_main_frame, | |
| 95 bool is_error_page, | 65 bool is_error_page, |
| 96 bool is_iframe_srcdoc) { | 66 bool is_iframe_srcdoc) { |
| 97 FrameState& frame_state = frame_state_map_[frame_id]; | 67 FrameState& frame_state = frame_host_state_map_[frame_host]; |
| 98 frame_state.error_occurred = is_error_page; | 68 frame_state.error_occurred = is_error_page; |
| 99 frame_state.url = url; | 69 frame_state.url = url; |
| 100 frame_state.is_main_frame = is_main_frame; | |
| 101 frame_state.is_iframe_srcdoc = is_iframe_srcdoc; | 70 frame_state.is_iframe_srcdoc = is_iframe_srcdoc; |
| 102 DCHECK(!is_iframe_srcdoc || url == GURL(url::kAboutBlankURL)); | 71 DCHECK(!is_iframe_srcdoc || url == GURL(url::kAboutBlankURL)); |
| 103 frame_state.is_navigating = true; | 72 frame_state.is_navigating = true; |
| 104 frame_state.is_committed = false; | 73 frame_state.is_committed = false; |
| 105 frame_state.is_server_redirected = false; | 74 frame_state.is_server_redirected = false; |
| 106 frame_state.is_parsing = true; | 75 frame_state.is_parsing = true; |
| 107 if (!is_main_frame) { | 76 frame_hosts_.insert(frame_host); |
| 108 frame_state.parent_frame_num = parent_frame_id.frame_num; | |
| 109 } else { | |
| 110 DCHECK_EQ(-1, parent_frame_id.frame_num); | |
| 111 frame_state.parent_frame_num = -1; | |
| 112 } | |
| 113 frame_ids_.insert(frame_id); | |
| 114 } | 77 } |
| 115 | 78 |
| 116 void FrameNavigationState::FrameDetached(FrameID frame_id) { | 79 void FrameNavigationState::FrameDetached(content::RenderFrameHost* frame_host) { |
| 117 FrameIdToStateMap::const_iterator frame_state = | 80 if (frame_host == main_frame_host_) |
| 118 frame_state_map_.find(frame_id); | 81 main_frame_host_ = NULL; |
| 119 if (frame_state == frame_state_map_.end()) | 82 frame_host_state_map_.erase(frame_host); |
|
jochen (gone - plz use gerrit)
2014/07/14 09:38:36
can we add at least DCHECK()s (or even CHECKs()) t
jochen (gone - plz use gerrit)
2014/07/14 09:38:36
can we add at least DCHECK()s (or even CHECKs()) t
dcheng
2014/07/14 20:12:55
Done.
dcheng
2014/07/14 20:12:55
Done.
| |
| 120 return; | 83 frame_hosts_.erase(frame_host); |
| 121 if (frame_id == main_frame_id_) | |
| 122 main_frame_id_ = FrameID(); | |
| 123 frame_state_map_.erase(frame_id); | |
| 124 frame_ids_.erase(frame_id); | |
| 125 #ifndef NDEBUG | |
| 126 // Check that the deleted frame was not the parent of any other frame. WebKit | |
| 127 // should always detach frames starting with the children. | |
| 128 for (FrameIdToStateMap::const_iterator frame = frame_state_map_.begin(); | |
| 129 frame != frame_state_map_.end(); ++frame) { | |
| 130 if (frame->first.render_view_host != frame_id.render_view_host) | |
| 131 continue; | |
| 132 if (frame->second.parent_frame_num != frame_id.frame_num) | |
| 133 continue; | |
| 134 NOTREACHED(); | |
| 135 } | |
| 136 #endif | |
| 137 } | 84 } |
| 138 | 85 |
| 139 void FrameNavigationState::StopTrackingFramesInRVH( | 86 void FrameNavigationState::StopTrackingFramesInRVH( |
| 140 content::RenderViewHost* render_view_host, | 87 content::RenderViewHost* render_view_host, |
| 141 FrameID id_to_skip) { | 88 content::RenderFrameHost* frame_host_to_skip) { |
| 142 for (std::set<FrameID>::iterator frame = frame_ids_.begin(); | 89 for (std::set<content::RenderFrameHost*>::iterator it = frame_hosts_.begin(); |
| 143 frame != frame_ids_.end();) { | 90 it != frame_hosts_.end();) { |
| 144 if (frame->render_view_host != render_view_host || *frame == id_to_skip) { | 91 if ((*it)->GetRenderViewHost() != render_view_host || |
| 145 ++frame; | 92 *it == frame_host_to_skip) { |
| 93 ++it; | |
| 146 continue; | 94 continue; |
| 147 } | 95 } |
| 148 FrameID frame_id = *frame; | 96 if (*it == main_frame_host_) |
| 149 ++frame; | 97 main_frame_host_ = NULL; |
| 150 if (frame_id == main_frame_id_) | 98 frame_host_state_map_.erase(*it); |
| 151 main_frame_id_ = FrameID(); | 99 frame_hosts_.erase(it++); |
| 152 frame_state_map_.erase(frame_id); | |
| 153 frame_ids_.erase(frame_id); | |
| 154 } | 100 } |
| 155 } | 101 } |
| 156 | 102 |
| 157 void FrameNavigationState::UpdateFrame(FrameID frame_id, const GURL& url) { | 103 void FrameNavigationState::UpdateFrame(content::RenderFrameHost* frame_host, |
| 158 FrameIdToStateMap::iterator frame_state = frame_state_map_.find(frame_id); | 104 const GURL& url) { |
| 159 if (frame_state == frame_state_map_.end()) { | 105 FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host); |
| 106 if (it == frame_host_state_map_.end()) { | |
| 160 NOTREACHED(); | 107 NOTREACHED(); |
|
jochen (gone - plz use gerrit)
2014/07/14 09:38:36
if you decided to go for a CHECK() above, this sho
dcheng
2014/07/14 20:12:55
I've opted for DCHECKs/NOTREACHED.
| |
| 161 return; | 108 return; |
| 162 } | 109 } |
| 163 frame_state->second.url = url; | 110 it->second.url = url; |
| 164 } | 111 } |
| 165 | 112 |
| 166 bool FrameNavigationState::IsValidFrame(FrameID frame_id) const { | 113 bool FrameNavigationState::IsValidFrame( |
| 167 FrameIdToStateMap::const_iterator frame_state = | 114 content::RenderFrameHost* frame_host) const { |
| 168 frame_state_map_.find(frame_id); | 115 return frame_host_state_map_.find(frame_host) != frame_host_state_map_.end(); |
| 169 return (frame_state != frame_state_map_.end()); | |
| 170 } | 116 } |
| 171 | 117 |
| 172 GURL FrameNavigationState::GetUrl(FrameID frame_id) const { | 118 GURL FrameNavigationState::GetUrl(content::RenderFrameHost* frame_host) const { |
| 173 FrameIdToStateMap::const_iterator frame_state = | 119 FrameHostToStateMap::const_iterator it = |
| 174 frame_state_map_.find(frame_id); | 120 frame_host_state_map_.find(frame_host); |
| 175 if (frame_state == frame_state_map_.end()) { | 121 if (it == frame_host_state_map_.end()) { |
| 176 NOTREACHED(); | 122 NOTREACHED(); |
| 177 return GURL(); | 123 return GURL(); |
| 178 } | 124 } |
| 179 if (frame_state->second.is_iframe_srcdoc) | 125 if (it->second.is_iframe_srcdoc) |
| 180 return GURL(content::kAboutSrcDocURL); | 126 return GURL(content::kAboutSrcDocURL); |
| 181 return frame_state->second.url; | 127 return it->second.url; |
| 182 } | 128 } |
| 183 | 129 |
| 184 bool FrameNavigationState::IsMainFrame(FrameID frame_id) const { | 130 content::RenderFrameHost* FrameNavigationState::GetLastCommittedMainFrameHost() |
| 185 FrameIdToStateMap::const_iterator frame_state = | 131 const { |
| 186 frame_state_map_.find(frame_id); | 132 return main_frame_host_; |
| 187 return (frame_state != frame_state_map_.end() && | |
| 188 frame_state->second.is_main_frame); | |
| 189 } | 133 } |
| 190 | 134 |
| 191 FrameNavigationState::FrameID FrameNavigationState::GetMainFrameID() const { | 135 void FrameNavigationState::SetErrorOccurredInFrame( |
| 192 return main_frame_id_; | 136 content::RenderFrameHost* frame_host) { |
| 137 FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host); | |
| 138 if (it == frame_host_state_map_.end()) { | |
| 139 NOTREACHED(); | |
| 140 return; | |
| 141 } | |
| 142 it->second.error_occurred = true; | |
| 193 } | 143 } |
| 194 | 144 |
| 195 FrameNavigationState::FrameID FrameNavigationState::GetParentFrameID( | 145 bool FrameNavigationState::GetErrorOccurredInFrame( |
| 196 FrameID frame_id) const { | 146 content::RenderFrameHost* frame_host) const { |
| 197 FrameIdToStateMap::const_iterator frame_state = | 147 FrameHostToStateMap::const_iterator it = |
| 198 frame_state_map_.find(frame_id); | 148 frame_host_state_map_.find(frame_host); |
| 199 if (frame_state == frame_state_map_.end()) { | 149 return it == frame_host_state_map_.end() || it->second.error_occurred; |
|
jochen (gone - plz use gerrit)
2014/07/14 09:38:36
it == end() should be NOTREACHED()
dcheng
2014/07/14 20:12:55
Done.
| |
| 200 NOTREACHED(); | |
| 201 return FrameID(); | |
| 202 } | |
| 203 return FrameID(frame_state->second.parent_frame_num, | |
| 204 frame_id.render_view_host); | |
| 205 } | 150 } |
| 206 | 151 |
| 207 void FrameNavigationState::SetErrorOccurredInFrame(FrameID frame_id) { | 152 void FrameNavigationState::SetNavigationCompleted( |
| 208 DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end()); | 153 content::RenderFrameHost* frame_host) { |
| 209 frame_state_map_[frame_id].error_occurred = true; | 154 FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host); |
| 155 if (it == frame_host_state_map_.end()) { | |
| 156 NOTREACHED(); | |
| 157 return; | |
| 158 } | |
| 159 it->second.is_navigating = false; | |
| 210 } | 160 } |
| 211 | 161 |
| 212 bool FrameNavigationState::GetErrorOccurredInFrame(FrameID frame_id) const { | 162 bool FrameNavigationState::GetNavigationCompleted( |
| 213 FrameIdToStateMap::const_iterator frame_state = | 163 content::RenderFrameHost* frame_host) const { |
| 214 frame_state_map_.find(frame_id); | 164 FrameHostToStateMap::const_iterator it = |
| 215 return (frame_state == frame_state_map_.end() || | 165 frame_host_state_map_.find(frame_host); |
| 216 frame_state->second.error_occurred); | 166 return it == frame_host_state_map_.end() || !it->second.is_navigating; |
|
jochen (gone - plz use gerrit)
2014/07/14 09:38:36
same here
dcheng
2014/07/14 20:12:55
Done.
| |
| 217 } | 167 } |
| 218 | 168 |
| 219 void FrameNavigationState::SetNavigationCompleted(FrameID frame_id) { | 169 void FrameNavigationState::SetParsingFinished( |
| 220 DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end()); | 170 content::RenderFrameHost* frame_host) { |
| 221 frame_state_map_[frame_id].is_navigating = false; | 171 FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host); |
| 172 if (it == frame_host_state_map_.end()) { | |
| 173 NOTREACHED(); | |
| 174 return; | |
| 175 } | |
| 176 it->second.is_parsing = false; | |
| 222 } | 177 } |
| 223 | 178 |
| 224 bool FrameNavigationState::GetNavigationCompleted(FrameID frame_id) const { | 179 bool FrameNavigationState::GetParsingFinished( |
| 225 FrameIdToStateMap::const_iterator frame_state = | 180 content::RenderFrameHost* frame_host) const { |
| 226 frame_state_map_.find(frame_id); | 181 FrameHostToStateMap::const_iterator it = |
| 227 return (frame_state == frame_state_map_.end() || | 182 frame_host_state_map_.find(frame_host); |
| 228 !frame_state->second.is_navigating); | 183 return it == frame_host_state_map_.end() || !it->second.is_parsing; |
|
jochen (gone - plz use gerrit)
2014/07/14 09:38:36
and here
dcheng
2014/07/14 20:12:55
Done.
| |
| 229 } | 184 } |
| 230 | 185 |
| 231 void FrameNavigationState::SetParsingFinished(FrameID frame_id) { | 186 void FrameNavigationState::SetNavigationCommitted( |
| 232 DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end()); | 187 content::RenderFrameHost* frame_host) { |
| 233 frame_state_map_[frame_id].is_parsing = false; | 188 FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host); |
| 189 if (it == frame_host_state_map_.end()) { | |
| 190 NOTREACHED(); | |
| 191 return; | |
| 192 } | |
| 193 it->second.is_committed = true; | |
| 194 if (!frame_host->GetParent()) | |
| 195 main_frame_host_ = frame_host; | |
| 234 } | 196 } |
| 235 | 197 |
| 236 bool FrameNavigationState::GetParsingFinished(FrameID frame_id) const { | 198 bool FrameNavigationState::GetNavigationCommitted( |
| 237 FrameIdToStateMap::const_iterator frame_state = | 199 content::RenderFrameHost* frame_host) const { |
| 238 frame_state_map_.find(frame_id); | 200 FrameHostToStateMap::const_iterator it = |
| 239 return (frame_state == frame_state_map_.end() || | 201 frame_host_state_map_.find(frame_host); |
| 240 !frame_state->second.is_parsing); | 202 return it != frame_host_state_map_.end() && it->second.is_committed; |
|
jochen (gone - plz use gerrit)
2014/07/14 09:38:36
and here
dcheng
2014/07/14 20:12:55
Done.
| |
| 241 } | 203 } |
| 242 | 204 |
| 243 void FrameNavigationState::SetNavigationCommitted(FrameID frame_id) { | 205 void FrameNavigationState::SetIsServerRedirected( |
| 244 DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end()); | 206 content::RenderFrameHost* frame_host) { |
| 245 frame_state_map_[frame_id].is_committed = true; | 207 FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host); |
| 246 if (frame_state_map_[frame_id].is_main_frame) | 208 if (it == frame_host_state_map_.end()) { |
| 247 main_frame_id_ = frame_id; | 209 NOTREACHED(); |
| 210 return; | |
| 211 } | |
| 212 it->second.is_server_redirected = true; | |
| 248 } | 213 } |
| 249 | 214 |
| 250 bool FrameNavigationState::GetNavigationCommitted(FrameID frame_id) const { | 215 bool FrameNavigationState::GetIsServerRedirected( |
| 251 FrameIdToStateMap::const_iterator frame_state = | 216 content::RenderFrameHost* frame_host) const { |
| 252 frame_state_map_.find(frame_id); | 217 FrameHostToStateMap::const_iterator it = |
| 253 return (frame_state != frame_state_map_.end() && | 218 frame_host_state_map_.find(frame_host); |
| 254 frame_state->second.is_committed); | 219 return it != frame_host_state_map_.end() && it->second.is_server_redirected; |
|
jochen (gone - plz use gerrit)
2014/07/14 09:38:36
...and here :)
dcheng
2014/07/14 20:12:55
Done.
| |
| 255 } | |
| 256 | |
| 257 void FrameNavigationState::SetIsServerRedirected(FrameID frame_id) { | |
| 258 DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end()); | |
| 259 frame_state_map_[frame_id].is_server_redirected = true; | |
| 260 } | |
| 261 | |
| 262 bool FrameNavigationState::GetIsServerRedirected(FrameID frame_id) const { | |
| 263 FrameIdToStateMap::const_iterator frame_state = | |
| 264 frame_state_map_.find(frame_id); | |
| 265 return (frame_state != frame_state_map_.end() && | |
| 266 frame_state->second.is_server_redirected); | |
| 267 } | 220 } |
| 268 | 221 |
| 269 } // namespace extensions | 222 } // namespace extensions |
| OLD | NEW |