OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/frame_host/navigation_controller_impl.h" | 5 #include "content/browser/frame_host/navigation_controller_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 1299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1310 } | 1310 } |
1311 | 1311 |
1312 void NavigationControllerImpl::CopyStateFromAndPrune( | 1312 void NavigationControllerImpl::CopyStateFromAndPrune( |
1313 NavigationController* temp, | 1313 NavigationController* temp, |
1314 bool replace_entry) { | 1314 bool replace_entry) { |
1315 // It is up to callers to check the invariants before calling this. | 1315 // It is up to callers to check the invariants before calling this. |
1316 CHECK(CanPruneAllButLastCommitted()); | 1316 CHECK(CanPruneAllButLastCommitted()); |
1317 | 1317 |
1318 NavigationControllerImpl* source = | 1318 NavigationControllerImpl* source = |
1319 static_cast<NavigationControllerImpl*>(temp); | 1319 static_cast<NavigationControllerImpl*>(temp); |
1320 // The SiteInstance and page_id of the last committed entry needs to be | |
1321 // remembered at this point, in case there is only one committed entry | |
1322 // and it is pruned. We use a scoped_refptr to ensure the SiteInstance | |
1323 // can't be freed during this time period. | |
1324 NavigationEntryImpl* last_committed = | |
1325 NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry()); | |
1326 scoped_refptr<SiteInstance> site_instance( | |
1327 last_committed->site_instance()); | |
1328 int32 minimum_page_id = last_committed->GetPageID(); | |
1329 int32 max_page_id = | |
1330 delegate_->GetMaxPageIDForSiteInstance(site_instance.get()); | |
1331 | 1320 |
1332 // Remove all the entries leaving the active entry. | 1321 // Remove all the entries leaving the last committed entry. |
1333 PruneAllButLastCommittedInternal(); | 1322 PruneAllButLastCommittedInternal(); |
1334 | 1323 |
1335 // We now have one entry, possibly with a new pending entry. Ensure that | 1324 // We now have one entry, possibly with a new pending entry. Ensure that |
1336 // adding the entries from source won't put us over the limit. | 1325 // adding the entries from source won't put us over the limit. |
1337 DCHECK_EQ(1, GetEntryCount()); | 1326 DCHECK_EQ(1, GetEntryCount()); |
1338 if (!replace_entry) | 1327 if (!replace_entry) |
1339 source->PruneOldestEntryIfFull(); | 1328 source->PruneOldestEntryIfFull(); |
1340 | 1329 |
1341 // Insert the entries from source. Don't use source->GetCurrentEntryIndex as | 1330 // Insert the entries from source. Don't use source->GetCurrentEntryIndex as |
1342 // we don't want to copy over the transient entry. Ignore any pending entry, | 1331 // we don't want to copy over the transient entry. Ignore any pending entry, |
1343 // since it has not committed in source. | 1332 // since it has not committed in source. |
1344 int max_source_index = source->last_committed_entry_index_; | 1333 int max_source_index = source->last_committed_entry_index_; |
1345 if (max_source_index == -1) | 1334 if (max_source_index == -1) |
1346 max_source_index = source->GetEntryCount(); | 1335 max_source_index = source->GetEntryCount(); |
1347 else | 1336 else |
1348 max_source_index++; | 1337 max_source_index++; |
1349 | 1338 |
1350 // Ignore the source's current entry if merging with replacement. | 1339 // Ignore the source's current entry if merging with replacement. |
1351 // TODO(davidben): This should preserve entries forward of the current | 1340 // TODO(davidben): This should preserve entries forward of the current |
1352 // too. http://crbug.com/317872 | 1341 // too. http://crbug.com/317872 |
1353 if (replace_entry && max_source_index > 0) | 1342 if (replace_entry && max_source_index > 0) |
1354 max_source_index--; | 1343 max_source_index--; |
1355 | 1344 |
1356 InsertEntriesFrom(*source, max_source_index); | 1345 InsertEntriesFrom(*source, max_source_index); |
1357 | 1346 |
1358 // Adjust indices such that the last entry and pending are at the end now. | 1347 // Adjust indices such that the last entry and pending are at the end now. |
1359 last_committed_entry_index_ = GetEntryCount() - 1; | 1348 last_committed_entry_index_ = GetEntryCount() - 1; |
1360 | 1349 |
1361 delegate_->SetHistoryLengthAndPrune(site_instance.get(), | 1350 delegate_->SetHistoryOffsetAndLength(last_committed_entry_index_, |
1362 max_source_index, | 1351 GetEntryCount()); |
1363 minimum_page_id); | |
1364 | 1352 |
1365 // Copy the max page id map from the old tab to the new tab. This ensures | 1353 // Copy the max page id map from the old tab to the new tab. This ensures that |
1366 // that new and existing navigations in the tab's current SiteInstances | 1354 // new and existing navigations in the tab's current SiteInstances are |
1367 // are identified properly. | 1355 // identified properly. |
| 1356 NavigationEntryImpl* last_committed = |
| 1357 NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry()); |
| 1358 int32 site_max_page_id = |
| 1359 delegate_->GetMaxPageIDForSiteInstance(last_committed->site_instance()); |
1368 delegate_->CopyMaxPageIDsFrom(source->delegate()->GetWebContents()); | 1360 delegate_->CopyMaxPageIDsFrom(source->delegate()->GetWebContents()); |
| 1361 delegate_->UpdateMaxPageIDForSiteInstance(last_committed->site_instance(), |
| 1362 site_max_page_id); |
1369 max_restored_page_id_ = source->max_restored_page_id_; | 1363 max_restored_page_id_ = source->max_restored_page_id_; |
1370 | |
1371 // If there is a last committed entry, be sure to include it in the new | |
1372 // max page ID map. | |
1373 if (max_page_id > -1) { | |
1374 delegate_->UpdateMaxPageIDForSiteInstance(site_instance.get(), | |
1375 max_page_id); | |
1376 } | |
1377 } | 1364 } |
1378 | 1365 |
1379 bool NavigationControllerImpl::CanPruneAllButLastCommitted() { | 1366 bool NavigationControllerImpl::CanPruneAllButLastCommitted() { |
1380 // If there is no last committed entry, we cannot prune. Even if there is a | 1367 // If there is no last committed entry, we cannot prune. Even if there is a |
1381 // pending entry, it may not commit, leaving this WebContents blank, despite | 1368 // pending entry, it may not commit, leaving this WebContents blank, despite |
1382 // possibly giving it new entries via CopyStateFromAndPrune. | 1369 // possibly giving it new entries via CopyStateFromAndPrune. |
1383 if (last_committed_entry_index_ == -1) | 1370 if (last_committed_entry_index_ == -1) |
1384 return false; | 1371 return false; |
1385 | 1372 |
1386 // We cannot prune if there is a pending entry at an existing entry index. | 1373 // We cannot prune if there is a pending entry at an existing entry index. |
1387 // It may not commit, so we have to keep the last committed entry, and thus | 1374 // It may not commit, so we have to keep the last committed entry, and thus |
1388 // there is no sensible place to keep the pending entry. It is ok to have | 1375 // there is no sensible place to keep the pending entry. It is ok to have |
1389 // a new pending entry, which can optionally commit as a new navigation. | 1376 // a new pending entry, which can optionally commit as a new navigation. |
1390 if (pending_entry_index_ != -1) | 1377 if (pending_entry_index_ != -1) |
1391 return false; | 1378 return false; |
1392 | 1379 |
1393 // We should not prune if we are currently showing a transient entry. | 1380 // We should not prune if we are currently showing a transient entry. |
1394 if (transient_entry_index_ != -1) | 1381 if (transient_entry_index_ != -1) |
1395 return false; | 1382 return false; |
1396 | 1383 |
1397 return true; | 1384 return true; |
1398 } | 1385 } |
1399 | 1386 |
1400 void NavigationControllerImpl::PruneAllButLastCommitted() { | 1387 void NavigationControllerImpl::PruneAllButLastCommitted() { |
1401 PruneAllButLastCommittedInternal(); | 1388 PruneAllButLastCommittedInternal(); |
1402 | 1389 |
1403 // We should still have a last committed entry. | 1390 DCHECK_EQ(0, last_committed_entry_index_); |
1404 DCHECK_NE(-1, last_committed_entry_index_); | 1391 DCHECK_EQ(1, GetEntryCount()); |
1405 | 1392 |
1406 // We pass 0 instead of GetEntryCount() for the history_length parameter of | 1393 delegate_->SetHistoryOffsetAndLength(last_committed_entry_index_, |
1407 // SetHistoryLengthAndPrune, because it will create history_length additional | 1394 GetEntryCount()); |
1408 // history entries. | |
1409 // TODO(jochen): This API is confusing and we should clean it up. | |
1410 // http://crbug.com/178491 | |
1411 NavigationEntryImpl* entry = | |
1412 NavigationEntryImpl::FromNavigationEntry(GetVisibleEntry()); | |
1413 delegate_->SetHistoryLengthAndPrune( | |
1414 entry->site_instance(), 0, entry->GetPageID()); | |
1415 } | 1395 } |
1416 | 1396 |
1417 void NavigationControllerImpl::PruneAllButLastCommittedInternal() { | 1397 void NavigationControllerImpl::PruneAllButLastCommittedInternal() { |
1418 // It is up to callers to check the invariants before calling this. | 1398 // It is up to callers to check the invariants before calling this. |
1419 CHECK(CanPruneAllButLastCommitted()); | 1399 CHECK(CanPruneAllButLastCommitted()); |
1420 | 1400 |
1421 // Erase all entries but the last committed entry. There may still be a | 1401 // Erase all entries but the last committed entry. There may still be a |
1422 // new pending entry after this. | 1402 // new pending entry after this. |
1423 entries_.erase(entries_.begin(), | 1403 entries_.erase(entries_.begin(), |
1424 entries_.begin() + last_committed_entry_index_); | 1404 entries_.begin() + last_committed_entry_index_); |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1790 } | 1770 } |
1791 } | 1771 } |
1792 } | 1772 } |
1793 | 1773 |
1794 void NavigationControllerImpl::SetGetTimestampCallbackForTest( | 1774 void NavigationControllerImpl::SetGetTimestampCallbackForTest( |
1795 const base::Callback<base::Time()>& get_timestamp_callback) { | 1775 const base::Callback<base::Time()>& get_timestamp_callback) { |
1796 get_timestamp_callback_ = get_timestamp_callback; | 1776 get_timestamp_callback_ = get_timestamp_callback; |
1797 } | 1777 } |
1798 | 1778 |
1799 } // namespace content | 1779 } // namespace content |
OLD | NEW |