| 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 "content/browser/web_contents/navigation_controller_impl.h" | 5 #include "content/browser/web_contents/navigation_controller_impl.h" |
| 6 | 6 |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/string_number_conversions.h" // Temporary | 9 #include "base/string_number_conversions.h" // Temporary |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "base/time.h" | 11 #include "base/time.h" |
| 12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
| 13 #include "content/browser/browser_url_handler_impl.h" | 13 #include "content/browser/browser_url_handler_impl.h" |
| 14 #include "content/browser/child_process_security_policy_impl.h" | 14 #include "content/browser/child_process_security_policy_impl.h" |
| 15 #include "content/browser/dom_storage/dom_storage_context_impl.h" | 15 #include "content/browser/dom_storage/dom_storage_context_impl.h" |
| 16 #include "content/browser/dom_storage/session_storage_namespace_impl.h" | 16 #include "content/browser/dom_storage/session_storage_namespace_impl.h" |
| 17 #include "content/browser/renderer_host/render_view_host_impl.h" // Temporary | 17 #include "content/browser/renderer_host/render_view_host_impl.h" // Temporary |
| 18 #include "content/browser/site_instance_impl.h" | 18 #include "content/browser/site_instance_impl.h" |
| 19 #include "content/browser/web_contents/debug_urls.h" | 19 #include "content/browser/web_contents/debug_urls.h" |
| 20 #include "content/browser/web_contents/interstitial_page_impl.h" | 20 #include "content/browser/web_contents/interstitial_page_impl.h" |
| 21 #include "content/browser/web_contents/navigation_entry_impl.h" | 21 #include "content/browser/web_contents/navigation_entry_impl.h" |
| 22 #include "content/browser/web_contents/web_contents_impl.h" | 22 #include "content/browser/web_contents/web_contents_impl.h" |
| 23 #include "content/common/view_messages.h" | 23 #include "content/common/view_messages.h" |
| 24 #include "content/public/browser/browser_context.h" | 24 #include "content/public/browser/browser_context.h" |
| 25 #include "content/public/browser/content_browser_client.h" |
| 25 #include "content/public/browser/invalidate_type.h" | 26 #include "content/public/browser/invalidate_type.h" |
| 26 #include "content/public/browser/navigation_details.h" | 27 #include "content/public/browser/navigation_details.h" |
| 27 #include "content/public/browser/notification_service.h" | 28 #include "content/public/browser/notification_service.h" |
| 28 #include "content/public/browser/notification_types.h" | 29 #include "content/public/browser/notification_types.h" |
| 29 #include "content/public/browser/user_metrics.h" | 30 #include "content/public/browser/user_metrics.h" |
| 30 #include "content/public/browser/web_contents_delegate.h" | 31 #include "content/public/browser/web_contents_delegate.h" |
| 32 #include "content/public/common/content_client.h" |
| 31 #include "content/public/common/content_constants.h" | 33 #include "content/public/common/content_constants.h" |
| 32 #include "content/public/common/url_constants.h" | 34 #include "content/public/common/url_constants.h" |
| 33 #include "net/base/escape.h" | 35 #include "net/base/escape.h" |
| 34 #include "net/base/mime_util.h" | 36 #include "net/base/mime_util.h" |
| 35 #include "net/base/net_util.h" | 37 #include "net/base/net_util.h" |
| 36 #include "webkit/glue/webkit_glue.h" | 38 #include "webkit/glue/webkit_glue.h" |
| 37 | 39 |
| 38 using content::BrowserContext; | 40 using content::BrowserContext; |
| 39 using content::DOMStorageContext; | 41 using content::DOMStorageContext; |
| 42 using content::GetContentClient; |
| 40 using content::GlobalRequestID; | 43 using content::GlobalRequestID; |
| 41 using content::NavigationController; | 44 using content::NavigationController; |
| 42 using content::NavigationEntry; | 45 using content::NavigationEntry; |
| 43 using content::NavigationEntryImpl; | 46 using content::NavigationEntryImpl; |
| 44 using content::RenderViewHostImpl; | 47 using content::RenderViewHostImpl; |
| 45 using content::SessionStorageNamespace; | 48 using content::SessionStorageNamespace; |
| 49 using content::SessionStorageNamespaceMap; |
| 46 using content::SiteInstance; | 50 using content::SiteInstance; |
| 47 using content::UserMetricsAction; | 51 using content::UserMetricsAction; |
| 48 using content::WebContents; | 52 using content::WebContents; |
| 49 | 53 |
| 50 namespace { | 54 namespace { |
| 51 | 55 |
| 52 const int kInvalidateAll = 0xFFFFFFFF; | 56 const int kInvalidateAll = 0xFFFFFFFF; |
| 53 | 57 |
| 54 // Invoked when entries have been pruned, or removed. For example, if the | 58 // Invoked when entries have been pruned, or removed. For example, if the |
| 55 // current entries are [google, digg, yahoo], with the current entry google, | 59 // current entries are [google, digg, yahoo], with the current entry google, |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 | 175 |
| 172 // static | 176 // static |
| 173 void NavigationController::DisablePromptOnRepost() { | 177 void NavigationController::DisablePromptOnRepost() { |
| 174 g_check_for_repost = false; | 178 g_check_for_repost = false; |
| 175 } | 179 } |
| 176 | 180 |
| 177 } // namespace content | 181 } // namespace content |
| 178 | 182 |
| 179 NavigationControllerImpl::NavigationControllerImpl( | 183 NavigationControllerImpl::NavigationControllerImpl( |
| 180 WebContentsImpl* web_contents, | 184 WebContentsImpl* web_contents, |
| 181 BrowserContext* browser_context, | 185 BrowserContext* browser_context) |
| 182 SessionStorageNamespaceImpl* session_storage_namespace) | |
| 183 : browser_context_(browser_context), | 186 : browser_context_(browser_context), |
| 184 pending_entry_(NULL), | 187 pending_entry_(NULL), |
| 185 last_committed_entry_index_(-1), | 188 last_committed_entry_index_(-1), |
| 186 pending_entry_index_(-1), | 189 pending_entry_index_(-1), |
| 187 transient_entry_index_(-1), | 190 transient_entry_index_(-1), |
| 188 web_contents_(web_contents), | 191 web_contents_(web_contents), |
| 189 max_restored_page_id_(-1), | 192 max_restored_page_id_(-1), |
| 190 ALLOW_THIS_IN_INITIALIZER_LIST(ssl_manager_(this)), | 193 ALLOW_THIS_IN_INITIALIZER_LIST(ssl_manager_(this)), |
| 191 needs_reload_(false), | 194 needs_reload_(false), |
| 192 session_storage_namespace_(session_storage_namespace), | |
| 193 pending_reload_(NO_RELOAD) { | 195 pending_reload_(NO_RELOAD) { |
| 194 DCHECK(browser_context_); | 196 DCHECK(browser_context_); |
| 195 if (!session_storage_namespace_) { | |
| 196 session_storage_namespace_ = new SessionStorageNamespaceImpl( | |
| 197 static_cast<DOMStorageContextImpl*>( | |
| 198 BrowserContext::GetDefaultDOMStorageContext(browser_context_))); | |
| 199 } | |
| 200 } | 197 } |
| 201 | 198 |
| 202 NavigationControllerImpl::~NavigationControllerImpl() { | 199 NavigationControllerImpl::~NavigationControllerImpl() { |
| 203 DiscardNonCommittedEntriesInternal(); | 200 DiscardNonCommittedEntriesInternal(); |
| 204 } | 201 } |
| 205 | 202 |
| 206 WebContents* NavigationControllerImpl::GetWebContents() const { | 203 WebContents* NavigationControllerImpl::GetWebContents() const { |
| 207 return web_contents_; | 204 return web_contents_; |
| 208 } | 205 } |
| 209 | 206 |
| (...skipping 914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1124 static_cast<const NavigationControllerImpl&>(temp); | 1121 static_cast<const NavigationControllerImpl&>(temp); |
| 1125 // Verify that we look new. | 1122 // Verify that we look new. |
| 1126 DCHECK(GetEntryCount() == 0 && !GetPendingEntry()); | 1123 DCHECK(GetEntryCount() == 0 && !GetPendingEntry()); |
| 1127 | 1124 |
| 1128 if (source.GetEntryCount() == 0) | 1125 if (source.GetEntryCount() == 0) |
| 1129 return; // Nothing new to do. | 1126 return; // Nothing new to do. |
| 1130 | 1127 |
| 1131 needs_reload_ = true; | 1128 needs_reload_ = true; |
| 1132 InsertEntriesFrom(source, source.GetEntryCount()); | 1129 InsertEntriesFrom(source, source.GetEntryCount()); |
| 1133 | 1130 |
| 1134 session_storage_namespace_ = source.session_storage_namespace_->Clone(); | 1131 for (SessionStorageNamespaceMap::const_iterator it = |
| 1132 source.session_storage_namespace_map_.begin(); |
| 1133 it != source.session_storage_namespace_map_.end(); |
| 1134 ++it) { |
| 1135 SessionStorageNamespaceImpl* source_namespace = |
| 1136 static_cast<SessionStorageNamespaceImpl*>(it->second.get()); |
| 1137 session_storage_namespace_map_.insert( |
| 1138 make_pair(it->first, source_namespace->Clone())); |
| 1139 } |
| 1135 | 1140 |
| 1136 FinishRestore(source.last_committed_entry_index_, false); | 1141 FinishRestore(source.last_committed_entry_index_, false); |
| 1137 | 1142 |
| 1138 // Copy the max page id map from the old tab to the new tab. This ensures | 1143 // Copy the max page id map from the old tab to the new tab. This ensures |
| 1139 // that new and existing navigations in the tab's current SiteInstances | 1144 // that new and existing navigations in the tab's current SiteInstances |
| 1140 // are identified properly. | 1145 // are identified properly. |
| 1141 web_contents_->CopyMaxPageIDsFrom(source.web_contents()); | 1146 web_contents_->CopyMaxPageIDsFrom(source.web_contents()); |
| 1142 } | 1147 } |
| 1143 | 1148 |
| 1144 void NavigationControllerImpl::CopyStateFromAndPrune( | 1149 void NavigationControllerImpl::CopyStateFromAndPrune( |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1204 // that new and existing navigations in the tab's current SiteInstances | 1209 // that new and existing navigations in the tab's current SiteInstances |
| 1205 // are identified properly. | 1210 // are identified properly. |
| 1206 web_contents_->CopyMaxPageIDsFrom(source->web_contents()); | 1211 web_contents_->CopyMaxPageIDsFrom(source->web_contents()); |
| 1207 | 1212 |
| 1208 // If there is a last committed entry, be sure to include it in the new | 1213 // If there is a last committed entry, be sure to include it in the new |
| 1209 // max page ID map. | 1214 // max page ID map. |
| 1210 if (max_page_id > -1) { | 1215 if (max_page_id > -1) { |
| 1211 web_contents_->UpdateMaxPageIDForSiteInstance(site_instance.get(), | 1216 web_contents_->UpdateMaxPageIDForSiteInstance(site_instance.get(), |
| 1212 max_page_id); | 1217 max_page_id); |
| 1213 } | 1218 } |
| 1219 |
| 1220 // TODO(ajwong): Do we need to handle SessionStorage here? |
| 1214 } | 1221 } |
| 1215 | 1222 |
| 1216 void NavigationControllerImpl::PruneAllButActive() { | 1223 void NavigationControllerImpl::PruneAllButActive() { |
| 1217 if (transient_entry_index_ != -1) { | 1224 if (transient_entry_index_ != -1) { |
| 1218 // There is a transient entry. Prune up to it. | 1225 // There is a transient entry. Prune up to it. |
| 1219 DCHECK_EQ(GetEntryCount() - 1, transient_entry_index_); | 1226 DCHECK_EQ(GetEntryCount() - 1, transient_entry_index_); |
| 1220 entries_.erase(entries_.begin(), entries_.begin() + transient_entry_index_); | 1227 entries_.erase(entries_.begin(), entries_.begin() + transient_entry_index_); |
| 1221 transient_entry_index_ = 0; | 1228 transient_entry_index_ = 0; |
| 1222 last_committed_entry_index_ = -1; | 1229 last_committed_entry_index_ = -1; |
| 1223 pending_entry_index_ = -1; | 1230 pending_entry_index_ = -1; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1245 | 1252 |
| 1246 if (web_contents_->GetInterstitialPage()) { | 1253 if (web_contents_->GetInterstitialPage()) { |
| 1247 // Normally the interstitial page hides itself if the user doesn't proceeed. | 1254 // Normally the interstitial page hides itself if the user doesn't proceeed. |
| 1248 // This would result in showing a NavigationEntry we just removed. Set this | 1255 // This would result in showing a NavigationEntry we just removed. Set this |
| 1249 // so the interstitial triggers a reload if the user doesn't proceed. | 1256 // so the interstitial triggers a reload if the user doesn't proceed. |
| 1250 static_cast<InterstitialPageImpl*>(web_contents_->GetInterstitialPage())-> | 1257 static_cast<InterstitialPageImpl*>(web_contents_->GetInterstitialPage())-> |
| 1251 set_reload_on_dont_proceed(true); | 1258 set_reload_on_dont_proceed(true); |
| 1252 } | 1259 } |
| 1253 } | 1260 } |
| 1254 | 1261 |
| 1262 void NavigationControllerImpl::SetSessionStorageNamespace( |
| 1263 const std::string& partition_id, |
| 1264 content::SessionStorageNamespace* session_storage_namespace) { |
| 1265 if (!session_storage_namespace) { |
| 1266 return; |
| 1267 } |
| 1268 |
| 1269 // We can't overwrite an existing SessionStorage without violating spec. |
| 1270 // Attempts to do so may give a tab access to another tab's session storage |
| 1271 // so die hard on an error. |
| 1272 bool successful_insert = session_storage_namespace_map_.insert( |
| 1273 make_pair(partition_id, |
| 1274 static_cast<SessionStorageNamespaceImpl*>( |
| 1275 session_storage_namespace))) |
| 1276 .second; |
| 1277 CHECK(successful_insert) << "Cannot replace existing SessionStorageNamespace"; |
| 1278 } |
| 1279 |
| 1255 void NavigationControllerImpl::SetMaxRestoredPageID(int32 max_id) { | 1280 void NavigationControllerImpl::SetMaxRestoredPageID(int32 max_id) { |
| 1256 max_restored_page_id_ = max_id; | 1281 max_restored_page_id_ = max_id; |
| 1257 } | 1282 } |
| 1258 | 1283 |
| 1259 int32 NavigationControllerImpl::GetMaxRestoredPageID() const { | 1284 int32 NavigationControllerImpl::GetMaxRestoredPageID() const { |
| 1260 return max_restored_page_id_; | 1285 return max_restored_page_id_; |
| 1261 } | 1286 } |
| 1262 | 1287 |
| 1263 SessionStorageNamespace* | 1288 SessionStorageNamespace* |
| 1264 NavigationControllerImpl::GetSessionStorageNamespace() const { | 1289 NavigationControllerImpl::GetSessionStorageNamespace(int renderer_id) { |
| 1265 return session_storage_namespace_; | 1290 const std::string& partition_id = |
| 1291 GetContentClient()->browser()->GetStoragePartitionIdForChildProcess( |
| 1292 browser_context_, |
| 1293 renderer_id); |
| 1294 |
| 1295 SessionStorageNamespaceMap::const_iterator it = |
| 1296 session_storage_namespace_map_.find(partition_id); |
| 1297 if (it != session_storage_namespace_map_.end()) { |
| 1298 return it->second.get(); |
| 1299 } |
| 1300 |
| 1301 // Create one if no one has accessed session storage for this partition yet. |
| 1302 SessionStorageNamespaceImpl* session_storage_namespace = |
| 1303 new SessionStorageNamespaceImpl( |
| 1304 static_cast<DOMStorageContextImpl*>( |
| 1305 BrowserContext::GetDOMStorageContext(browser_context_, |
| 1306 renderer_id))); |
| 1307 session_storage_namespace_map_[partition_id] = session_storage_namespace; |
| 1308 |
| 1309 return session_storage_namespace; |
| 1310 } |
| 1311 |
| 1312 const SessionStorageNamespaceMap& |
| 1313 NavigationControllerImpl::GetSessionStorageNamespaceMap() const { |
| 1314 return session_storage_namespace_map_; |
| 1266 } | 1315 } |
| 1267 | 1316 |
| 1268 bool NavigationControllerImpl::NeedsReload() const { | 1317 bool NavigationControllerImpl::NeedsReload() const { |
| 1269 return needs_reload_; | 1318 return needs_reload_; |
| 1270 } | 1319 } |
| 1271 | 1320 |
| 1272 void NavigationControllerImpl::RemoveEntryAtIndexInternal(int index) { | 1321 void NavigationControllerImpl::RemoveEntryAtIndexInternal(int index) { |
| 1273 DCHECK(index < GetEntryCount()); | 1322 DCHECK(index < GetEntryCount()); |
| 1274 DCHECK(index != last_committed_entry_index_); | 1323 DCHECK(index != last_committed_entry_index_); |
| 1275 | 1324 |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1516 for (int i = 0; i < max_index; i++) { | 1565 for (int i = 0; i < max_index; i++) { |
| 1517 // When cloning a tab, copy all entries except interstitial pages | 1566 // When cloning a tab, copy all entries except interstitial pages |
| 1518 if (source.entries_[i].get()->GetPageType() != | 1567 if (source.entries_[i].get()->GetPageType() != |
| 1519 content::PAGE_TYPE_INTERSTITIAL) { | 1568 content::PAGE_TYPE_INTERSTITIAL) { |
| 1520 entries_.insert(entries_.begin() + insert_index++, | 1569 entries_.insert(entries_.begin() + insert_index++, |
| 1521 linked_ptr<NavigationEntryImpl>( | 1570 linked_ptr<NavigationEntryImpl>( |
| 1522 new NavigationEntryImpl(*source.entries_[i]))); | 1571 new NavigationEntryImpl(*source.entries_[i]))); |
| 1523 } | 1572 } |
| 1524 } | 1573 } |
| 1525 } | 1574 } |
| OLD | NEW |