| 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 |