Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5327)

Unified Diff: chrome/browser/sessions/tab_restore_service.cc

Issue 14172: Makes the tab restore service contain any windows that were open at... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/sessions/tab_restore_service.cc
===================================================================
--- chrome/browser/sessions/tab_restore_service.cc (revision 7147)
+++ chrome/browser/sessions/tab_restore_service.cc (working copy)
@@ -12,6 +12,7 @@
#include "chrome/browser/navigation_entry.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/sessions/session_backend.h"
+#include "chrome/browser/sessions/session_service.h"
#include "chrome/common/scoped_vector.h"
#include "chrome/common/stl_util-inl.h"
@@ -28,8 +29,8 @@
// TabRestoreService ----------------------------------------------------------
-// Max number of entries we'll keep around.
-static const size_t kMaxEntries = 10;
+// static
+const size_t TabRestoreService::kMaxEntries = 10;
// Identifier for commands written to file.
// The ordering in the file is as follows:
@@ -64,7 +65,7 @@
int32 num_tabs;
};
-// Paylowed used for the start of a tab close.
+// Payload used for the start of a tab close.
struct SelectedNavigationInTabPayload {
SessionID::id_type id;
int32 index;
@@ -92,7 +93,7 @@
TabRestoreService::TabRestoreService(Profile* profile)
: BaseSessionService(BaseSessionService::TAB_RESTORE, profile,
std::wstring()),
- loaded_last_session_(false),
+ load_state_(NOT_LOADED),
restoring_(false),
reached_max_(false),
entries_to_write_(0),
@@ -105,6 +106,7 @@
FOR_EACH_OBSERVER(Observer, observer_list_, TabRestoreServiceDestroyed(this));
STLDeleteElements(&entries_);
+ STLDeleteElements(&staging_entries_);
}
void TabRestoreService::AddObserver(Observer* observer) {
@@ -242,15 +244,30 @@
}
void TabRestoreService::LoadTabsFromLastSession() {
- if (loaded_last_session_ || reached_max_)
+ if (load_state_ != NOT_LOADED || reached_max_)
return;
- loaded_last_session_ = true;
+ load_state_ = LOADING;
+ if (!profile()->restored_last_session() &&
+ !profile()->DidLastSessionExitCleanly() &&
+ profile()->GetSessionService()) {
+ // The previous session crashed and wasn't restored. Load the tabs/windows
+ // that were open at the point of crash from the session service.
+ profile()->GetSessionService()->GetLastSession(
+ &load_consumer_,
+ NewCallback(this, &TabRestoreService::OnGotPreviousSession));
+ } else {
+ load_state_ |= LOADED_LAST_SESSION;
+ }
+
+ // Request the tabs closed in the last session. If the last session crashed,
+ // this won't contain the tabs/window that were open at the point of the
+ // crash (the call to GetLastSession above requests those).
ScheduleGetLastSessionCommands(
new InternalGetCommandsRequest(
NewCallback(this, &TabRestoreService::OnGotLastSessionCommands)),
- &load_tabs_consumer_);
+ &load_consumer_);
}
void TabRestoreService::Save() {
@@ -466,6 +483,18 @@
void TabRestoreService::OnGotLastSessionCommands(
Handle handle,
scoped_refptr<InternalGetCommandsRequest> request) {
+ std::vector<Entry*> entries;
+ CreateEntriesFromCommands(request, &entries);
+ // Closed tabs always go to the end.
+ staging_entries_.insert(staging_entries_.end(), entries.begin(),
+ entries.end());
+ load_state_ |= LOADED_LAST_TABS;
+ LoadStateChanged();
+}
+
+void TabRestoreService::CreateEntriesFromCommands(
+ scoped_refptr<InternalGetCommandsRequest> request,
+ std::vector<Entry*>* loaded_entries) {
if (request->canceled() || entries_.size() == kMaxEntries)
return;
@@ -575,23 +604,7 @@
// entries with no navigations.
ValidateAndDeleteEmptyEntries(&(entries.get()));
- if (entries->empty())
- return;
-
- // And add them.
- for (size_t i = 0; i < entries->size(); ++i)
- AddEntry(entries[i], false, false);
-
- // AddEntry takes ownership of the entry, need to clear out entries so that
- // it doesn't delete them.
- entries->clear();
-
- // Make it so we rewrite all the tabs. We need to do this otherwise we won't
- // correctly write out the entries when Save is invoked (Save starts from
- // the front, not the end and we just added the entries to the end).
- entries_to_write_ = entries_.size();
-
- PruneAndNotify();
+ loaded_entries->swap(entries.get());
}
bool TabRestoreService::ValidateTab(Tab* tab) {
@@ -647,3 +660,90 @@
// Delete the remaining entries.
STLDeleteElements(&invalid_entries);
}
+
+void TabRestoreService::OnGotPreviousSession(
+ Handle handle,
+ std::vector<SessionWindow*>* windows) {
+ std::vector<Entry*> entries;
+ CreateEntriesFromWindows(windows, &entries);
+ // Previous session tabs go first.
+ staging_entries_.insert(staging_entries_.begin(), entries.begin(),
+ entries.end());
+ load_state_ |= LOADED_LAST_SESSION;
+ LoadStateChanged();
+}
+
+void TabRestoreService::CreateEntriesFromWindows(
+ std::vector<SessionWindow*>* windows,
+ std::vector<Entry*>* entries) {
+ for (size_t i = 0; i < windows->size(); ++i) {
+ scoped_ptr<Window> window(new Window());
+ if (ConvertSessionWindowToWindow((*windows)[i], window.get()))
+ entries->push_back(window.release());
+ }
+}
+
+bool TabRestoreService::ConvertSessionWindowToWindow(
+ SessionWindow* session_window,
+ Window* window) {
+ for (size_t i = 0; i < session_window->tabs.size(); ++i) {
+ if (!session_window->tabs[i]->navigations.empty()) {
+ window->tabs.resize(window->tabs.size() + 1);
+ Tab& tab = window->tabs.back();
+ tab.navigations.swap(session_window->tabs[i]->navigations);
+ tab.current_navigation_index =
+ session_window->tabs[i]->current_navigation_index;
+ }
+ }
+ if (window->tabs.empty())
+ return false;
+
+ window->selected_tab_index =
+ std::min(session_window->selected_tab_index,
+ static_cast<int>(window->tabs.size() - 1));
+ return true;
+}
+
+void TabRestoreService::LoadStateChanged() {
+ if ((load_state_ & (LOADED_LAST_TABS | LOADED_LAST_SESSION)) !=
+ (LOADED_LAST_TABS | LOADED_LAST_SESSION)) {
+ // Still waiting on previous session or previous tabs.
+ return;
+ }
+
+ // We're done loading.
+ load_state_ ^= LOADING;
+
+ if (staging_entries_.empty() || reached_max_) {
+ STLDeleteElements(&staging_entries_);
+ return;
+ }
+
+ if (staging_entries_.size() + entries_.size() > kMaxEntries) {
+ // If we add all the staged entries we'll end up with more than
+ // kMaxEntries. Delete entries such that we only end up with
+ // at most kMaxEntries.
+ DCHECK(entries_.size() < kMaxEntries);
+ STLDeleteContainerPointers(
+ staging_entries_.begin() + (kMaxEntries - entries_.size()),
+ staging_entries_.end());
+ staging_entries_.erase(
+ staging_entries_.begin() + (kMaxEntries - entries_.size()),
+ staging_entries_.end());
+ }
+
+ // And add them.
+ for (size_t i = 0; i < staging_entries_.size(); ++i)
+ AddEntry(staging_entries_[i], false, false);
+
+ // AddEntry takes ownership of the entry, need to clear out entries so that
+ // it doesn't delete them.
+ staging_entries_.clear();
+
+ // Make it so we rewrite all the tabs. We need to do this otherwise we won't
+ // correctly write out the entries when Save is invoked (Save starts from
+ // the front, not the end and we just added the entries to the end).
+ entries_to_write_ = staging_entries_.size();
+
+ PruneAndNotify();
+}
« no previous file with comments | « chrome/browser/sessions/tab_restore_service.h ('k') | chrome/browser/sessions/tab_restore_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698