| Index: chrome/browser/sessions/session_service.cc
|
| diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc
|
| index 8094054f7e50cb80d11a5cf5d9db32564045c1d4..5caf1a7708a39a2db255ba28e792b581b0a035d9 100644
|
| --- a/chrome/browser/sessions/session_service.cc
|
| +++ b/chrome/browser/sessions/session_service.cc
|
| @@ -58,154 +58,10 @@ using content::WebContents;
|
| using sessions::ContentSerializedNavigationBuilder;
|
| using sessions::SerializedNavigationEntry;
|
|
|
| -// Identifier for commands written to file.
|
| -static const SessionCommand::id_type kCommandSetTabWindow = 0;
|
| -// OBSOLETE Superseded by kCommandSetWindowBounds3.
|
| -// static const SessionCommand::id_type kCommandSetWindowBounds = 1;
|
| -static const SessionCommand::id_type kCommandSetTabIndexInWindow = 2;
|
| -// OBSOLETE Superseded kCommandTabClosed/kCommandWindowClosed commands.
|
| -// static const SessionCommand::id_type kCommandTabClosedObsolete = 3;
|
| -// static const SessionCommand::id_type kCommandWindowClosedObsolete = 4;
|
| -static const SessionCommand::id_type
|
| - kCommandTabNavigationPathPrunedFromBack = 5;
|
| -static const SessionCommand::id_type kCommandUpdateTabNavigation = 6;
|
| -static const SessionCommand::id_type kCommandSetSelectedNavigationIndex = 7;
|
| -static const SessionCommand::id_type kCommandSetSelectedTabInIndex = 8;
|
| -static const SessionCommand::id_type kCommandSetWindowType = 9;
|
| -// OBSOLETE Superseded by kCommandSetWindowBounds3. Except for data migration.
|
| -// static const SessionCommand::id_type kCommandSetWindowBounds2 = 10;
|
| -static const SessionCommand::id_type
|
| - kCommandTabNavigationPathPrunedFromFront = 11;
|
| -static const SessionCommand::id_type kCommandSetPinnedState = 12;
|
| -static const SessionCommand::id_type kCommandSetExtensionAppID = 13;
|
| -static const SessionCommand::id_type kCommandSetWindowBounds3 = 14;
|
| -static const SessionCommand::id_type kCommandSetWindowAppName = 15;
|
| -static const SessionCommand::id_type kCommandTabClosed = 16;
|
| -static const SessionCommand::id_type kCommandWindowClosed = 17;
|
| -static const SessionCommand::id_type kCommandSetTabUserAgentOverride = 18;
|
| -static const SessionCommand::id_type kCommandSessionStorageAssociated = 19;
|
| -static const SessionCommand::id_type kCommandSetActiveWindow = 20;
|
| -
|
| -// Every kWritesPerReset commands triggers recreating the file.
|
| -static const int kWritesPerReset = 250;
|
| -
|
| -namespace {
|
| -
|
| -// Various payload structures.
|
| -struct ClosedPayload {
|
| - SessionID::id_type id;
|
| - int64 close_time;
|
| -};
|
| -
|
| -struct WindowBoundsPayload2 {
|
| - SessionID::id_type window_id;
|
| - int32 x;
|
| - int32 y;
|
| - int32 w;
|
| - int32 h;
|
| - bool is_maximized;
|
| -};
|
| -
|
| -struct WindowBoundsPayload3 {
|
| - SessionID::id_type window_id;
|
| - int32 x;
|
| - int32 y;
|
| - int32 w;
|
| - int32 h;
|
| - int32 show_state;
|
| -};
|
| -
|
| -typedef SessionID::id_type ActiveWindowPayload;
|
| -
|
| -struct IDAndIndexPayload {
|
| - SessionID::id_type id;
|
| - int32 index;
|
| -};
|
| -
|
| -typedef IDAndIndexPayload TabIndexInWindowPayload;
|
| -
|
| -typedef IDAndIndexPayload TabNavigationPathPrunedFromBackPayload;
|
| -
|
| -typedef IDAndIndexPayload SelectedNavigationIndexPayload;
|
| -
|
| -typedef IDAndIndexPayload SelectedTabInIndexPayload;
|
| -
|
| -typedef IDAndIndexPayload WindowTypePayload;
|
| -
|
| -typedef IDAndIndexPayload TabNavigationPathPrunedFromFrontPayload;
|
| -
|
| -struct PinnedStatePayload {
|
| - SessionID::id_type tab_id;
|
| - bool pinned_state;
|
| -};
|
| -
|
| -// Persisted versions of ui::WindowShowState that are written to disk and can
|
| -// never change.
|
| -enum PersistedWindowShowState {
|
| - // SHOW_STATE_DEFAULT (0) never persisted.
|
| - PERSISTED_SHOW_STATE_NORMAL = 1,
|
| - PERSISTED_SHOW_STATE_MINIMIZED = 2,
|
| - PERSISTED_SHOW_STATE_MAXIMIZED = 3,
|
| - // SHOW_STATE_INACTIVE (4) never persisted.
|
| - PERSISTED_SHOW_STATE_FULLSCREEN = 5,
|
| - PERSISTED_SHOW_STATE_DETACHED_DEPRECATED = 6,
|
| - PERSISTED_SHOW_STATE_END = 6
|
| -};
|
| -
|
| -// Assert to ensure PersistedWindowShowState is updated if ui::WindowShowState
|
| -// is changed.
|
| -COMPILE_ASSERT(ui::SHOW_STATE_END ==
|
| - static_cast<ui::WindowShowState>(PERSISTED_SHOW_STATE_END),
|
| - persisted_show_state_mismatch);
|
| -
|
| -// Returns the show state to store to disk based |state|.
|
| -PersistedWindowShowState ShowStateToPersistedShowState(
|
| - ui::WindowShowState state) {
|
| - switch (state) {
|
| - case ui::SHOW_STATE_NORMAL:
|
| - return PERSISTED_SHOW_STATE_NORMAL;
|
| - case ui::SHOW_STATE_MINIMIZED:
|
| - return PERSISTED_SHOW_STATE_MINIMIZED;
|
| - case ui::SHOW_STATE_MAXIMIZED:
|
| - return PERSISTED_SHOW_STATE_MAXIMIZED;
|
| - case ui::SHOW_STATE_FULLSCREEN:
|
| - return PERSISTED_SHOW_STATE_FULLSCREEN;
|
| -
|
| - case ui::SHOW_STATE_DEFAULT:
|
| - case ui::SHOW_STATE_INACTIVE:
|
| - return PERSISTED_SHOW_STATE_NORMAL;
|
| -
|
| - case ui::SHOW_STATE_END:
|
| - break;
|
| - }
|
| - NOTREACHED();
|
| - return PERSISTED_SHOW_STATE_NORMAL;
|
| -}
|
| -
|
| -// Lints show state values when read back from persited disk.
|
| -ui::WindowShowState PersistedShowStateToShowState(int state) {
|
| - switch (state) {
|
| - case PERSISTED_SHOW_STATE_NORMAL:
|
| - return ui::SHOW_STATE_NORMAL;
|
| - case PERSISTED_SHOW_STATE_MINIMIZED:
|
| - return ui::SHOW_STATE_MINIMIZED;
|
| - case PERSISTED_SHOW_STATE_MAXIMIZED:
|
| - return ui::SHOW_STATE_MAXIMIZED;
|
| - case PERSISTED_SHOW_STATE_FULLSCREEN:
|
| - return ui::SHOW_STATE_FULLSCREEN;
|
| - case PERSISTED_SHOW_STATE_DETACHED_DEPRECATED:
|
| - return ui::SHOW_STATE_NORMAL;
|
| - }
|
| - NOTREACHED();
|
| - return ui::SHOW_STATE_NORMAL;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| // SessionService -------------------------------------------------------------
|
|
|
| SessionService::SessionService(Profile* profile)
|
| - : BaseSessionService(
|
| + : SessionServiceCommands(
|
| SESSION_RESTORE,
|
| profile->GetPath(),
|
| scoped_ptr<BaseSessionServiceDelegate>(
|
| @@ -216,15 +72,14 @@ SessionService::SessionService(Profile* profile)
|
| save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)),
|
| save_delay_in_mins_(base::TimeDelta::FromMinutes(10)),
|
| save_delay_in_hrs_(base::TimeDelta::FromHours(8)),
|
| - force_browser_not_alive_with_no_windows_(false),
|
| - weak_factory_(this) {
|
| + force_browser_not_alive_with_no_windows_(false) {
|
| // We should never be created when incognito.
|
| DCHECK(!profile->IsOffTheRecord());
|
| Init();
|
| }
|
|
|
| SessionService::SessionService(const base::FilePath& save_path)
|
| - : BaseSessionService(
|
| + : SessionServiceCommands(
|
| SESSION_RESTORE,
|
| save_path,
|
| scoped_ptr<BaseSessionServiceDelegate>(
|
| @@ -235,8 +90,7 @@ SessionService::SessionService(const base::FilePath& save_path)
|
| save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)),
|
| save_delay_in_mins_(base::TimeDelta::FromMinutes(10)),
|
| save_delay_in_hrs_(base::TimeDelta::FromHours(8)),
|
| - force_browser_not_alive_with_no_windows_(false),
|
| - weak_factory_(this) {
|
| + force_browser_not_alive_with_no_windows_(false) {
|
| Init();
|
| }
|
|
|
| @@ -252,7 +106,7 @@ bool SessionService::RestoreIfNecessary(const std::vector<GURL>& urls_to_open) {
|
| }
|
|
|
| void SessionService::ResetFromCurrentBrowsers() {
|
| - ScheduleReset();
|
| + ScheduleResetCommands();
|
| }
|
|
|
| void SessionService::MoveCurrentSessionToLastSession() {
|
| @@ -272,7 +126,7 @@ void SessionService::SetTabWindow(const SessionID& window_id,
|
| if (!ShouldTrackChangesToWindow(window_id))
|
| return;
|
|
|
| - ScheduleCommand(CreateSetTabWindowCommand(window_id, tab_id));
|
| + ScheduleCommand(CreateSetTabWindow(window_id, tab_id));
|
| }
|
|
|
| void SessionService::SetWindowBounds(const SessionID& window_id,
|
| @@ -281,7 +135,7 @@ void SessionService::SetWindowBounds(const SessionID& window_id,
|
| if (!ShouldTrackChangesToWindow(window_id))
|
| return;
|
|
|
| - ScheduleCommand(CreateSetWindowBoundsCommand(window_id, bounds, show_state));
|
| + ScheduleCommand(CreateSetWindowBounds(window_id, bounds, show_state));
|
| }
|
|
|
| void SessionService::SetTabIndexInWindow(const SessionID& window_id,
|
| @@ -290,7 +144,7 @@ void SessionService::SetTabIndexInWindow(const SessionID& window_id,
|
| if (!ShouldTrackChangesToWindow(window_id))
|
| return;
|
|
|
| - ScheduleCommand(CreateSetTabIndexInWindowCommand(tab_id, new_index));
|
| + ScheduleCommand(CreateSetTabIndexInWindow(tab_id, new_index));
|
| }
|
|
|
| void SessionService::SetPinnedState(const SessionID& window_id,
|
| @@ -299,7 +153,7 @@ void SessionService::SetPinnedState(const SessionID& window_id,
|
| if (!ShouldTrackChangesToWindow(window_id))
|
| return;
|
|
|
| - ScheduleCommand(CreatePinnedStateCommand(tab_id, is_pinned));
|
| + ScheduleCommand(CreatePinnedState(tab_id, is_pinned));
|
| }
|
|
|
| void SessionService::TabClosed(const SessionID& window_id,
|
| @@ -330,7 +184,7 @@ void SessionService::TabClosed(const SessionID& window_id,
|
| // . closing a tab and there are other windows/tabs open.
|
| // . closed by a user gesture.
|
| // In all cases we need to mark the tab as explicitly closed.
|
| - ScheduleCommand(CreateTabClosedCommand(tab_id.id()));
|
| + ScheduleCommand(CreateTabClosed(tab_id.id()));
|
| } else {
|
| // User closed the last tab in the last tabbed browser. Don't mark the
|
| // tab closed.
|
| @@ -343,7 +197,9 @@ void SessionService::WindowOpened(Browser* browser) {
|
| if (!ShouldTrackBrowser(browser))
|
| return;
|
|
|
| - AppType app_type = browser->is_app() ? TYPE_APP : TYPE_NORMAL;
|
| + SessionServiceCommands::AppType app_type =
|
| + browser->is_app() ? SessionServiceCommands::TYPE_APP :
|
| + SessionServiceCommands::TYPE_NORMAL;
|
| RestoreIfNecessary(std::vector<GURL>(), browser);
|
| SetWindowType(browser->session_id(), browser->type(), app_type);
|
| SetWindowAppName(browser->session_id(), browser->app_name());
|
| @@ -403,7 +259,7 @@ void SessionService::WindowClosed(const SessionID& window_id) {
|
|
|
| if (window_closing_ids_.find(window_id.id()) != window_closing_ids_.end()) {
|
| window_closing_ids_.erase(window_id.id());
|
| - ScheduleCommand(CreateWindowClosedCommand(window_id.id()));
|
| + ScheduleCommand(CreateWindowClosed(window_id.id()));
|
| } else if (pending_window_close_ids_.find(window_id.id()) ==
|
| pending_window_close_ids_.end()) {
|
| // We'll hit this if user closed the last tab in a window.
|
| @@ -411,15 +267,61 @@ void SessionService::WindowClosed(const SessionID& window_id) {
|
| if (!has_open_trackable_browsers_)
|
| pending_window_close_ids_.insert(window_id.id());
|
| else
|
| - ScheduleCommand(CreateWindowClosedCommand(window_id.id()));
|
| + ScheduleCommand(CreateWindowClosed(window_id.id()));
|
| }
|
| MaybeDeleteSessionOnlyData();
|
| }
|
|
|
| +void SessionService::TabInserted(WebContents* contents) {
|
| + SessionTabHelper* session_tab_helper =
|
| + SessionTabHelper::FromWebContents(contents);
|
| + if (!ShouldTrackChangesToWindow(session_tab_helper->window_id()))
|
| + return;
|
| + SetTabWindow(session_tab_helper->window_id(),
|
| + session_tab_helper->session_id());
|
| + extensions::TabHelper* extensions_tab_helper =
|
| + extensions::TabHelper::FromWebContents(contents);
|
| + if (extensions_tab_helper &&
|
| + extensions_tab_helper->extension_app()) {
|
| + SetTabExtensionAppID(
|
| + session_tab_helper->window_id(),
|
| + session_tab_helper->session_id(),
|
| + extensions_tab_helper->extension_app()->id());
|
| + }
|
| +
|
| + // Record the association between the SessionStorageNamespace and the
|
| + // tab.
|
| + //
|
| + // TODO(ajwong): This should be processing the whole map rather than
|
| + // just the default. This in particular will not work for tabs with only
|
| + // isolated apps which won't have a default partition.
|
| + content::SessionStorageNamespace* session_storage_namespace =
|
| + contents->GetController().GetDefaultSessionStorageNamespace();
|
| + ScheduleCommand(CreateSessionStorageAssociated(
|
| + session_tab_helper->session_id(),
|
| + session_storage_namespace->persistent_id()));
|
| + session_storage_namespace->SetShouldPersist(true);
|
| +}
|
| +
|
| +void SessionService::TabClosing(WebContents* contents) {
|
| + // Allow the associated sessionStorage to get deleted; it won't be needed
|
| + // in the session restore.
|
| + content::SessionStorageNamespace* session_storage_namespace =
|
| + contents->GetController().GetDefaultSessionStorageNamespace();
|
| + session_storage_namespace->SetShouldPersist(false);
|
| + SessionTabHelper* session_tab_helper =
|
| + SessionTabHelper::FromWebContents(contents);
|
| + TabClosed(session_tab_helper->window_id(),
|
| + session_tab_helper->session_id(),
|
| + contents->GetClosedByUserGesture());
|
| + RecordSessionUpdateHistogramData(content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
|
| + &last_updated_tab_closed_time_);
|
| +}
|
| +
|
| void SessionService::SetWindowType(const SessionID& window_id,
|
| Browser::Type type,
|
| - AppType app_type) {
|
| - if (!should_track_changes_for_browser_type(type, app_type))
|
| + SessionServiceCommands::AppType app_type) {
|
| + if (!ShouldTrackChangesOfWindowType(WindowTypeForBrowserType(type), app_type))
|
| return;
|
|
|
| windows_tracking_.insert(window_id.id());
|
| @@ -432,7 +334,7 @@ void SessionService::SetWindowType(const SessionID& window_id,
|
| move_on_new_browser_ = true;
|
|
|
| ScheduleCommand(
|
| - CreateSetWindowTypeCommand(window_id, WindowTypeForBrowserType(type)));
|
| + CreateSetWindowType(window_id, WindowTypeForBrowserType(type)));
|
| }
|
|
|
| void SessionService::SetWindowAppName(
|
| @@ -441,10 +343,7 @@ void SessionService::SetWindowAppName(
|
| if (!ShouldTrackChangesToWindow(window_id))
|
| return;
|
|
|
| - ScheduleCommand(CreateSetTabExtensionAppIDCommand(
|
| - kCommandSetWindowAppName,
|
| - window_id.id(),
|
| - app_name));
|
| + ScheduleCommand(CreateSetWindowAppName(window_id, app_name));
|
| }
|
|
|
| void SessionService::TabNavigationPathPrunedFromBack(const SessionID& window_id,
|
| @@ -453,14 +352,7 @@ void SessionService::TabNavigationPathPrunedFromBack(const SessionID& window_id,
|
| if (!ShouldTrackChangesToWindow(window_id))
|
| return;
|
|
|
| - TabNavigationPathPrunedFromBackPayload payload = { 0 };
|
| - payload.id = tab_id.id();
|
| - payload.index = count;
|
| - SessionCommand* command =
|
| - new SessionCommand(kCommandTabNavigationPathPrunedFromBack,
|
| - sizeof(payload));
|
| - memcpy(command->contents(), &payload, sizeof(payload));
|
| - ScheduleCommand(command);
|
| + ScheduleCommand(CreateTabNavigationPathPrunedFromBack(tab_id, count));
|
| }
|
|
|
| void SessionService::TabNavigationPathPrunedFromFront(
|
| @@ -478,14 +370,7 @@ void SessionService::TabNavigationPathPrunedFromFront(
|
| range.second = std::max(0, range.second - count);
|
| }
|
|
|
| - TabNavigationPathPrunedFromFrontPayload payload = { 0 };
|
| - payload.id = tab_id.id();
|
| - payload.index = count;
|
| - SessionCommand* command =
|
| - new SessionCommand(kCommandTabNavigationPathPrunedFromFront,
|
| - sizeof(payload));
|
| - memcpy(command->contents(), &payload, sizeof(payload));
|
| - ScheduleCommand(command);
|
| + ScheduleCommand(CreateTabNavigationPathPrunedFromFront(tab_id, count));
|
| }
|
|
|
| void SessionService::UpdateTabNavigation(
|
| @@ -503,8 +388,7 @@ void SessionService::UpdateTabNavigation(
|
| range.first = std::min(navigation.index(), range.first);
|
| range.second = std::max(navigation.index(), range.second);
|
| }
|
| - ScheduleCommand(CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation,
|
| - tab_id.id(), navigation));
|
| + ScheduleCommand(CreateUpdateTabNavigation(tab_id, navigation));
|
| }
|
|
|
| void SessionService::TabRestored(WebContents* tab, bool pinned) {
|
| @@ -533,7 +417,7 @@ void SessionService::SetSelectedNavigationIndex(const SessionID& window_id,
|
| return;
|
| }
|
| }
|
| - ScheduleCommand(CreateSetSelectedNavigationIndexCommand(tab_id, index));
|
| + ScheduleCommand(CreateSetSelectedNavigationIndex(tab_id, index));
|
| }
|
|
|
| void SessionService::SetSelectedTabInWindow(const SessionID& window_id,
|
| @@ -551,24 +435,34 @@ void SessionService::SetTabUserAgentOverride(
|
| if (!ShouldTrackChangesToWindow(window_id))
|
| return;
|
|
|
| - ScheduleCommand(CreateSetTabUserAgentOverrideCommand(
|
| - kCommandSetTabUserAgentOverride, tab_id.id(), user_agent_override));
|
| + ScheduleCommand(CreateSetTabUserAgentOverride(tab_id, user_agent_override));
|
| +}
|
| +
|
| +void SessionService::SetTabExtensionAppID(
|
| + const SessionID& window_id,
|
| + const SessionID& tab_id,
|
| + const std::string& extension_app_id) {
|
| + if (!ShouldTrackChangesToWindow(window_id))
|
| + return;
|
| +
|
| + ScheduleCommand(CreateSetTabExtensionAppID(tab_id, extension_app_id));
|
| }
|
|
|
| -base::CancelableTaskTracker::TaskId SessionService::GetLastSession(
|
| - const SessionCallback& callback,
|
| - base::CancelableTaskTracker* tracker) {
|
| - // OnGotSessionCommands maps the SessionCommands to browser state, then run
|
| - // the callback.
|
| - return ScheduleGetLastSessionCommands(
|
| - base::Bind(&SessionService::OnGotSessionCommands,
|
| - weak_factory_.GetWeakPtr(), callback),
|
| - tracker);
|
| +bool SessionService::ShouldTrackChangesOfWindowType(
|
| + SessionWindow::WindowType type,
|
| + SessionServiceCommands::AppType app_type) const {
|
| +#if defined(OS_CHROMEOS)
|
| + // Restore app popups for ChromeOS alone.
|
| + if (type == SessionWindow::TYPE_POPUP && app_type == TYPE_APP)
|
| + return true;
|
| +#endif
|
| +
|
| + return type == SessionWindow::TYPE_TABBED;
|
| }
|
|
|
| void SessionService::Save() {
|
| bool had_commands = !pending_commands().empty();
|
| - BaseSessionService::Save();
|
| + SessionServiceCommands::Save();
|
| if (had_commands) {
|
| RecordSessionUpdateHistogramData(chrome::NOTIFICATION_SESSION_SERVICE_SAVED,
|
| &last_updated_save_time_);
|
| @@ -749,572 +643,7 @@ void SessionService::Observe(int type,
|
|
|
| void SessionService::OnBrowserSetLastActive(Browser* browser) {
|
| if (ShouldTrackBrowser(browser))
|
| - ScheduleCommand(CreateSetActiveWindowCommand(browser->session_id()));
|
| -}
|
| -
|
| -void SessionService::SetTabExtensionAppID(
|
| - const SessionID& window_id,
|
| - const SessionID& tab_id,
|
| - const std::string& extension_app_id) {
|
| - if (!ShouldTrackChangesToWindow(window_id))
|
| - return;
|
| -
|
| - ScheduleCommand(CreateSetTabExtensionAppIDCommand(kCommandSetExtensionAppID,
|
| - tab_id.id(), extension_app_id));
|
| -}
|
| -
|
| -SessionCommand* SessionService::CreateSetSelectedTabInWindow(
|
| - const SessionID& window_id,
|
| - int index) {
|
| - SelectedTabInIndexPayload payload = { 0 };
|
| - payload.id = window_id.id();
|
| - payload.index = index;
|
| - SessionCommand* command = new SessionCommand(kCommandSetSelectedTabInIndex,
|
| - sizeof(payload));
|
| - memcpy(command->contents(), &payload, sizeof(payload));
|
| - return command;
|
| -}
|
| -
|
| -SessionCommand* SessionService::CreateSetTabWindowCommand(
|
| - const SessionID& window_id,
|
| - const SessionID& tab_id) {
|
| - SessionID::id_type payload[] = { window_id.id(), tab_id.id() };
|
| - SessionCommand* command =
|
| - new SessionCommand(kCommandSetTabWindow, sizeof(payload));
|
| - memcpy(command->contents(), payload, sizeof(payload));
|
| - return command;
|
| -}
|
| -
|
| -SessionCommand* SessionService::CreateSetWindowBoundsCommand(
|
| - const SessionID& window_id,
|
| - const gfx::Rect& bounds,
|
| - ui::WindowShowState show_state) {
|
| - WindowBoundsPayload3 payload = { 0 };
|
| - payload.window_id = window_id.id();
|
| - payload.x = bounds.x();
|
| - payload.y = bounds.y();
|
| - payload.w = bounds.width();
|
| - payload.h = bounds.height();
|
| - payload.show_state = ShowStateToPersistedShowState(show_state);
|
| - SessionCommand* command = new SessionCommand(kCommandSetWindowBounds3,
|
| - sizeof(payload));
|
| - memcpy(command->contents(), &payload, sizeof(payload));
|
| - return command;
|
| -}
|
| -
|
| -SessionCommand* SessionService::CreateSetTabIndexInWindowCommand(
|
| - const SessionID& tab_id,
|
| - int new_index) {
|
| - TabIndexInWindowPayload payload = { 0 };
|
| - payload.id = tab_id.id();
|
| - payload.index = new_index;
|
| - SessionCommand* command =
|
| - new SessionCommand(kCommandSetTabIndexInWindow, sizeof(payload));
|
| - memcpy(command->contents(), &payload, sizeof(payload));
|
| - return command;
|
| -}
|
| -
|
| -SessionCommand* SessionService::CreateTabClosedCommand(
|
| - const SessionID::id_type tab_id) {
|
| - ClosedPayload payload;
|
| - // Because of what appears to be a compiler bug setting payload to {0} doesn't
|
| - // set the padding to 0, resulting in Purify reporting an UMR when we write
|
| - // the structure to disk. To avoid this we explicitly memset the struct.
|
| - memset(&payload, 0, sizeof(payload));
|
| - payload.id = tab_id;
|
| - payload.close_time = Time::Now().ToInternalValue();
|
| - SessionCommand* command =
|
| - new SessionCommand(kCommandTabClosed, sizeof(payload));
|
| - memcpy(command->contents(), &payload, sizeof(payload));
|
| - return command;
|
| -}
|
| -
|
| -SessionCommand* SessionService::CreateWindowClosedCommand(
|
| - const SessionID::id_type window_id) {
|
| - ClosedPayload payload;
|
| - // See comment in CreateTabClosedCommand as to why we do this.
|
| - memset(&payload, 0, sizeof(payload));
|
| - payload.id = window_id;
|
| - payload.close_time = Time::Now().ToInternalValue();
|
| - SessionCommand* command =
|
| - new SessionCommand(kCommandWindowClosed, sizeof(payload));
|
| - memcpy(command->contents(), &payload, sizeof(payload));
|
| - return command;
|
| -}
|
| -
|
| -SessionCommand* SessionService::CreateSetSelectedNavigationIndexCommand(
|
| - const SessionID& tab_id,
|
| - int index) {
|
| - SelectedNavigationIndexPayload payload = { 0 };
|
| - payload.id = tab_id.id();
|
| - payload.index = index;
|
| - SessionCommand* command = new SessionCommand(
|
| - kCommandSetSelectedNavigationIndex, sizeof(payload));
|
| - memcpy(command->contents(), &payload, sizeof(payload));
|
| - return command;
|
| -}
|
| -
|
| -SessionCommand* SessionService::CreateSetWindowTypeCommand(
|
| - const SessionID& window_id,
|
| - WindowType type) {
|
| - WindowTypePayload payload = { 0 };
|
| - payload.id = window_id.id();
|
| - payload.index = static_cast<int32>(type);
|
| - SessionCommand* command = new SessionCommand(
|
| - kCommandSetWindowType, sizeof(payload));
|
| - memcpy(command->contents(), &payload, sizeof(payload));
|
| - return command;
|
| -}
|
| -
|
| -SessionCommand* SessionService::CreatePinnedStateCommand(
|
| - const SessionID& tab_id,
|
| - bool is_pinned) {
|
| - PinnedStatePayload payload = { 0 };
|
| - payload.tab_id = tab_id.id();
|
| - payload.pinned_state = is_pinned;
|
| - SessionCommand* command =
|
| - new SessionCommand(kCommandSetPinnedState, sizeof(payload));
|
| - memcpy(command->contents(), &payload, sizeof(payload));
|
| - return command;
|
| -}
|
| -
|
| -SessionCommand* SessionService::CreateSessionStorageAssociatedCommand(
|
| - const SessionID& tab_id,
|
| - const std::string& session_storage_persistent_id) {
|
| - Pickle pickle;
|
| - pickle.WriteInt(tab_id.id());
|
| - pickle.WriteString(session_storage_persistent_id);
|
| - return new SessionCommand(kCommandSessionStorageAssociated, pickle);
|
| -}
|
| -
|
| -SessionCommand* SessionService::CreateSetActiveWindowCommand(
|
| - const SessionID& window_id) {
|
| - ActiveWindowPayload payload = 0;
|
| - payload = window_id.id();
|
| - SessionCommand* command =
|
| - new SessionCommand(kCommandSetActiveWindow, sizeof(payload));
|
| - memcpy(command->contents(), &payload, sizeof(payload));
|
| - return command;
|
| -}
|
| -
|
| -void SessionService::OnGotSessionCommands(
|
| - const SessionCallback& callback,
|
| - ScopedVector<SessionCommand> commands) {
|
| - ScopedVector<SessionWindow> valid_windows;
|
| - SessionID::id_type active_window_id = 0;
|
| -
|
| - RestoreSessionFromCommands(
|
| - commands.get(), &valid_windows.get(), &active_window_id);
|
| - callback.Run(valid_windows.Pass(), active_window_id);
|
| -}
|
| -
|
| -void SessionService::RestoreSessionFromCommands(
|
| - const std::vector<SessionCommand*>& commands,
|
| - std::vector<SessionWindow*>* valid_windows,
|
| - SessionID::id_type* active_window_id) {
|
| - std::map<int, SessionTab*> tabs;
|
| - std::map<int, SessionWindow*> windows;
|
| -
|
| - VLOG(1) << "RestoreSessionFromCommands " << commands.size();
|
| - if (CreateTabsAndWindows(commands, &tabs, &windows, active_window_id)) {
|
| - AddTabsToWindows(&tabs, &windows);
|
| - SortTabsBasedOnVisualOrderAndPrune(&windows, valid_windows);
|
| - UpdateSelectedTabIndex(valid_windows);
|
| - }
|
| - STLDeleteValues(&tabs);
|
| - // Don't delete conents of windows, that is done by the caller as all
|
| - // valid windows are added to valid_windows.
|
| -}
|
| -
|
| -void SessionService::UpdateSelectedTabIndex(
|
| - std::vector<SessionWindow*>* windows) {
|
| - for (std::vector<SessionWindow*>::const_iterator i = windows->begin();
|
| - i != windows->end(); ++i) {
|
| - // See note in SessionWindow as to why we do this.
|
| - int new_index = 0;
|
| - for (std::vector<SessionTab*>::const_iterator j = (*i)->tabs.begin();
|
| - j != (*i)->tabs.end(); ++j) {
|
| - if ((*j)->tab_visual_index == (*i)->selected_tab_index) {
|
| - new_index = static_cast<int>(j - (*i)->tabs.begin());
|
| - break;
|
| - }
|
| - }
|
| - (*i)->selected_tab_index = new_index;
|
| - }
|
| -}
|
| -
|
| -SessionWindow* SessionService::GetWindow(
|
| - SessionID::id_type window_id,
|
| - IdToSessionWindow* windows) {
|
| - std::map<int, SessionWindow*>::iterator i = windows->find(window_id);
|
| - if (i == windows->end()) {
|
| - SessionWindow* window = new SessionWindow();
|
| - window->window_id.set_id(window_id);
|
| - (*windows)[window_id] = window;
|
| - return window;
|
| - }
|
| - return i->second;
|
| -}
|
| -
|
| -SessionTab* SessionService::GetTab(
|
| - SessionID::id_type tab_id,
|
| - IdToSessionTab* tabs) {
|
| - DCHECK(tabs);
|
| - std::map<int, SessionTab*>::iterator i = tabs->find(tab_id);
|
| - if (i == tabs->end()) {
|
| - SessionTab* tab = new SessionTab();
|
| - tab->tab_id.set_id(tab_id);
|
| - (*tabs)[tab_id] = tab;
|
| - return tab;
|
| - }
|
| - return i->second;
|
| -}
|
| -
|
| -std::vector<SerializedNavigationEntry>::iterator
|
| - SessionService::FindClosestNavigationWithIndex(
|
| - std::vector<SerializedNavigationEntry>* navigations,
|
| - int index) {
|
| - DCHECK(navigations);
|
| - for (std::vector<SerializedNavigationEntry>::iterator
|
| - i = navigations->begin(); i != navigations->end(); ++i) {
|
| - if (i->index() >= index)
|
| - return i;
|
| - }
|
| - return navigations->end();
|
| -}
|
| -
|
| -// Function used in sorting windows. Sorting is done based on window id. As
|
| -// window ids increment for each new window, this effectively sorts by creation
|
| -// time.
|
| -static bool WindowOrderSortFunction(const SessionWindow* w1,
|
| - const SessionWindow* w2) {
|
| - return w1->window_id.id() < w2->window_id.id();
|
| -}
|
| -
|
| -// Compares the two tabs based on visual index.
|
| -static bool TabVisualIndexSortFunction(const SessionTab* t1,
|
| - const SessionTab* t2) {
|
| - const int delta = t1->tab_visual_index - t2->tab_visual_index;
|
| - return delta == 0 ? (t1->tab_id.id() < t2->tab_id.id()) : (delta < 0);
|
| -}
|
| -
|
| -void SessionService::SortTabsBasedOnVisualOrderAndPrune(
|
| - std::map<int, SessionWindow*>* windows,
|
| - std::vector<SessionWindow*>* valid_windows) {
|
| - std::map<int, SessionWindow*>::iterator i = windows->begin();
|
| - while (i != windows->end()) {
|
| - SessionWindow* window = i->second;
|
| - AppType app_type = window->app_name.empty() ? TYPE_NORMAL : TYPE_APP;
|
| - if (window->tabs.empty() || window->is_constrained ||
|
| - !should_track_changes_for_browser_type(
|
| - static_cast<Browser::Type>(window->type),
|
| - app_type)) {
|
| - delete window;
|
| - windows->erase(i++);
|
| - } else {
|
| - // Valid window; sort the tabs and add it to the list of valid windows.
|
| - std::sort(window->tabs.begin(), window->tabs.end(),
|
| - &TabVisualIndexSortFunction);
|
| - // Otherwise, add the window such that older windows appear first.
|
| - if (valid_windows->empty()) {
|
| - valid_windows->push_back(window);
|
| - } else {
|
| - valid_windows->insert(
|
| - std::upper_bound(valid_windows->begin(), valid_windows->end(),
|
| - window, &WindowOrderSortFunction),
|
| - window);
|
| - }
|
| - ++i;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void SessionService::AddTabsToWindows(std::map<int, SessionTab*>* tabs,
|
| - std::map<int, SessionWindow*>* windows) {
|
| - VLOG(1) << "AddTabsToWindws";
|
| - VLOG(1) << "Tabs " << tabs->size() << ", windows " << windows->size();
|
| - std::map<int, SessionTab*>::iterator i = tabs->begin();
|
| - while (i != tabs->end()) {
|
| - SessionTab* tab = i->second;
|
| - if (tab->window_id.id() && !tab->navigations.empty()) {
|
| - SessionWindow* window = GetWindow(tab->window_id.id(), windows);
|
| - window->tabs.push_back(tab);
|
| - tabs->erase(i++);
|
| -
|
| - // See note in SessionTab as to why we do this.
|
| - std::vector<SerializedNavigationEntry>::iterator j =
|
| - FindClosestNavigationWithIndex(&(tab->navigations),
|
| - tab->current_navigation_index);
|
| - if (j == tab->navigations.end()) {
|
| - tab->current_navigation_index =
|
| - static_cast<int>(tab->navigations.size() - 1);
|
| - } else {
|
| - tab->current_navigation_index =
|
| - static_cast<int>(j - tab->navigations.begin());
|
| - }
|
| - } else {
|
| - // Never got a set tab index in window, or tabs are empty, nothing
|
| - // to do.
|
| - ++i;
|
| - }
|
| - }
|
| -}
|
| -
|
| -bool SessionService::CreateTabsAndWindows(
|
| - const std::vector<SessionCommand*>& data,
|
| - std::map<int, SessionTab*>* tabs,
|
| - std::map<int, SessionWindow*>* windows,
|
| - SessionID::id_type* active_window_id) {
|
| - // If the file is corrupt (command with wrong size, or unknown command), we
|
| - // still return true and attempt to restore what we we can.
|
| - VLOG(1) << "CreateTabsAndWindows";
|
| -
|
| - startup_metric_utils::ScopedSlowStartupUMA
|
| - scoped_timer("Startup.SlowStartupSessionServiceCreateTabsAndWindows");
|
| -
|
| - for (std::vector<SessionCommand*>::const_iterator i = data.begin();
|
| - i != data.end(); ++i) {
|
| - const SessionCommand::id_type kCommandSetWindowBounds2 = 10;
|
| - const SessionCommand* command = *i;
|
| -
|
| - VLOG(1) << "Read command " << (int) command->id();
|
| - switch (command->id()) {
|
| - case kCommandSetTabWindow: {
|
| - SessionID::id_type payload[2];
|
| - if (!command->GetPayload(payload, sizeof(payload))) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| - GetTab(payload[1], tabs)->window_id.set_id(payload[0]);
|
| - break;
|
| - }
|
| -
|
| - // This is here for forward migration only. New data is saved with
|
| - // |kCommandSetWindowBounds3|.
|
| - case kCommandSetWindowBounds2: {
|
| - WindowBoundsPayload2 payload;
|
| - if (!command->GetPayload(&payload, sizeof(payload))) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| - GetWindow(payload.window_id, windows)->bounds.SetRect(payload.x,
|
| - payload.y,
|
| - payload.w,
|
| - payload.h);
|
| - GetWindow(payload.window_id, windows)->show_state =
|
| - payload.is_maximized ?
|
| - ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL;
|
| - break;
|
| - }
|
| -
|
| - case kCommandSetWindowBounds3: {
|
| - WindowBoundsPayload3 payload;
|
| - if (!command->GetPayload(&payload, sizeof(payload))) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| - GetWindow(payload.window_id, windows)->bounds.SetRect(payload.x,
|
| - payload.y,
|
| - payload.w,
|
| - payload.h);
|
| - GetWindow(payload.window_id, windows)->show_state =
|
| - PersistedShowStateToShowState(payload.show_state);
|
| - break;
|
| - }
|
| -
|
| - case kCommandSetTabIndexInWindow: {
|
| - TabIndexInWindowPayload payload;
|
| - if (!command->GetPayload(&payload, sizeof(payload))) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| - GetTab(payload.id, tabs)->tab_visual_index = payload.index;
|
| - break;
|
| - }
|
| -
|
| - case kCommandTabClosed:
|
| - case kCommandWindowClosed: {
|
| - ClosedPayload payload;
|
| - if (!command->GetPayload(&payload, sizeof(payload))) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| - if (command->id() == kCommandTabClosed) {
|
| - delete GetTab(payload.id, tabs);
|
| - tabs->erase(payload.id);
|
| - } else {
|
| - delete GetWindow(payload.id, windows);
|
| - windows->erase(payload.id);
|
| - }
|
| - break;
|
| - }
|
| -
|
| - case kCommandTabNavigationPathPrunedFromBack: {
|
| - TabNavigationPathPrunedFromBackPayload payload;
|
| - if (!command->GetPayload(&payload, sizeof(payload))) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| - SessionTab* tab = GetTab(payload.id, tabs);
|
| - tab->navigations.erase(
|
| - FindClosestNavigationWithIndex(&(tab->navigations), payload.index),
|
| - tab->navigations.end());
|
| - break;
|
| - }
|
| -
|
| - case kCommandTabNavigationPathPrunedFromFront: {
|
| - TabNavigationPathPrunedFromFrontPayload payload;
|
| - if (!command->GetPayload(&payload, sizeof(payload)) ||
|
| - payload.index <= 0) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| - SessionTab* tab = GetTab(payload.id, tabs);
|
| -
|
| - // Update the selected navigation index.
|
| - tab->current_navigation_index =
|
| - std::max(-1, tab->current_navigation_index - payload.index);
|
| -
|
| - // And update the index of existing navigations.
|
| - for (std::vector<SerializedNavigationEntry>::iterator
|
| - i = tab->navigations.begin();
|
| - i != tab->navigations.end();) {
|
| - i->set_index(i->index() - payload.index);
|
| - if (i->index() < 0)
|
| - i = tab->navigations.erase(i);
|
| - else
|
| - ++i;
|
| - }
|
| - break;
|
| - }
|
| -
|
| - case kCommandUpdateTabNavigation: {
|
| - SerializedNavigationEntry navigation;
|
| - SessionID::id_type tab_id;
|
| - if (!RestoreUpdateTabNavigationCommand(
|
| - *command, &navigation, &tab_id)) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| - SessionTab* tab = GetTab(tab_id, tabs);
|
| - std::vector<SerializedNavigationEntry>::iterator i =
|
| - FindClosestNavigationWithIndex(&(tab->navigations),
|
| - navigation.index());
|
| - if (i != tab->navigations.end() && i->index() == navigation.index())
|
| - *i = navigation;
|
| - else
|
| - tab->navigations.insert(i, navigation);
|
| - break;
|
| - }
|
| -
|
| - case kCommandSetSelectedNavigationIndex: {
|
| - SelectedNavigationIndexPayload payload;
|
| - if (!command->GetPayload(&payload, sizeof(payload))) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| - GetTab(payload.id, tabs)->current_navigation_index = payload.index;
|
| - break;
|
| - }
|
| -
|
| - case kCommandSetSelectedTabInIndex: {
|
| - SelectedTabInIndexPayload payload;
|
| - if (!command->GetPayload(&payload, sizeof(payload))) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| - GetWindow(payload.id, windows)->selected_tab_index = payload.index;
|
| - break;
|
| - }
|
| -
|
| - case kCommandSetWindowType: {
|
| - WindowTypePayload payload;
|
| - if (!command->GetPayload(&payload, sizeof(payload))) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| - GetWindow(payload.id, windows)->is_constrained = false;
|
| - GetWindow(payload.id, windows)->type =
|
| - BrowserTypeForWindowType(
|
| - static_cast<WindowType>(payload.index));
|
| - break;
|
| - }
|
| -
|
| - case kCommandSetPinnedState: {
|
| - PinnedStatePayload payload;
|
| - if (!command->GetPayload(&payload, sizeof(payload))) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| - GetTab(payload.tab_id, tabs)->pinned = payload.pinned_state;
|
| - break;
|
| - }
|
| -
|
| - case kCommandSetWindowAppName: {
|
| - SessionID::id_type window_id;
|
| - std::string app_name;
|
| - if (!RestoreSetWindowAppNameCommand(*command, &window_id, &app_name))
|
| - return true;
|
| -
|
| - GetWindow(window_id, windows)->app_name.swap(app_name);
|
| - break;
|
| - }
|
| -
|
| - case kCommandSetExtensionAppID: {
|
| - SessionID::id_type tab_id;
|
| - std::string extension_app_id;
|
| - if (!RestoreSetTabExtensionAppIDCommand(
|
| - *command, &tab_id, &extension_app_id)) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| -
|
| - GetTab(tab_id, tabs)->extension_app_id.swap(extension_app_id);
|
| - break;
|
| - }
|
| -
|
| - case kCommandSetTabUserAgentOverride: {
|
| - SessionID::id_type tab_id;
|
| - std::string user_agent_override;
|
| - if (!RestoreSetTabUserAgentOverrideCommand(
|
| - *command, &tab_id, &user_agent_override)) {
|
| - return true;
|
| - }
|
| -
|
| - GetTab(tab_id, tabs)->user_agent_override.swap(user_agent_override);
|
| - break;
|
| - }
|
| -
|
| - case kCommandSessionStorageAssociated: {
|
| - scoped_ptr<Pickle> command_pickle(command->PayloadAsPickle());
|
| - SessionID::id_type command_tab_id;
|
| - std::string session_storage_persistent_id;
|
| - PickleIterator iter(*command_pickle.get());
|
| - if (!command_pickle->ReadInt(&iter, &command_tab_id) ||
|
| - !command_pickle->ReadString(&iter, &session_storage_persistent_id))
|
| - return true;
|
| - // Associate the session storage back.
|
| - GetTab(command_tab_id, tabs)->session_storage_persistent_id =
|
| - session_storage_persistent_id;
|
| - break;
|
| - }
|
| -
|
| - case kCommandSetActiveWindow: {
|
| - ActiveWindowPayload payload;
|
| - if (!command->GetPayload(&payload, sizeof(payload))) {
|
| - VLOG(1) << "Failed reading command " << command->id();
|
| - return true;
|
| - }
|
| - *active_window_id = payload;
|
| - break;
|
| - }
|
| -
|
| - default:
|
| - VLOG(1) << "Failed reading an unknown command " << command->id();
|
| - return true;
|
| - }
|
| - }
|
| - return true;
|
| + ScheduleCommand(CreateSetActiveWindow(browser->session_id()));
|
| }
|
|
|
| void SessionService::BuildCommandsForTab(const SessionID& window_id,
|
| @@ -1326,7 +655,7 @@ void SessionService::BuildCommandsForTab(const SessionID& window_id,
|
| DCHECK(tab && commands && window_id.id());
|
| SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab);
|
| const SessionID& session_id(session_tab_helper->session_id());
|
| - commands->push_back(CreateSetTabWindowCommand(window_id, session_id));
|
| + commands->push_back(CreateSetTabWindow(window_id, session_id));
|
|
|
| const int current_index = tab->GetController().GetCurrentEntryIndex();
|
| const int min_index = std::max(0,
|
| @@ -1340,24 +669,20 @@ void SessionService::BuildCommandsForTab(const SessionID& window_id,
|
| std::pair<int, int>(min_index, max_index);
|
| }
|
|
|
| - if (is_pinned) {
|
| - commands->push_back(CreatePinnedStateCommand(session_id, true));
|
| - }
|
| + if (is_pinned)
|
| + commands->push_back(CreatePinnedState(session_id, true));
|
|
|
| extensions::TabHelper* extensions_tab_helper =
|
| extensions::TabHelper::FromWebContents(tab);
|
| if (extensions_tab_helper->extension_app()) {
|
| - commands->push_back(
|
| - CreateSetTabExtensionAppIDCommand(
|
| - kCommandSetExtensionAppID, session_id.id(),
|
| - extensions_tab_helper->extension_app()->id()));
|
| + commands->push_back(CreateSetTabExtensionAppID(
|
| + session_id,
|
| + extensions_tab_helper->extension_app()->id()));
|
| }
|
|
|
| const std::string& ua_override = tab->GetUserAgentOverride();
|
| if (!ua_override.empty()) {
|
| - commands->push_back(
|
| - CreateSetTabUserAgentOverrideCommand(
|
| - kCommandSetTabUserAgentOverride, session_id.id(), ua_override));
|
| + commands->push_back(CreateSetTabUserAgentOverride(session_id, ua_override));
|
| }
|
|
|
| for (int i = min_index; i < max_index; ++i) {
|
| @@ -1369,22 +694,21 @@ void SessionService::BuildCommandsForTab(const SessionID& window_id,
|
| const SerializedNavigationEntry navigation =
|
| ContentSerializedNavigationBuilder::FromNavigationEntry(i, *entry);
|
| commands->push_back(
|
| - CreateUpdateTabNavigationCommand(
|
| - kCommandUpdateTabNavigation, session_id.id(), navigation));
|
| + CreateUpdateTabNavigation(session_id, navigation));
|
| }
|
| }
|
| commands->push_back(
|
| - CreateSetSelectedNavigationIndexCommand(session_id, current_index));
|
| + CreateSetSelectedNavigationIndex(session_id, current_index));
|
|
|
| if (index_in_window != -1) {
|
| commands->push_back(
|
| - CreateSetTabIndexInWindowCommand(session_id, index_in_window));
|
| + CreateSetTabIndexInWindow(session_id, index_in_window));
|
| }
|
|
|
| // Record the association between the sessionStorage namespace and the tab.
|
| content::SessionStorageNamespace* session_storage_namespace =
|
| tab->GetController().GetDefaultSessionStorageNamespace();
|
| - ScheduleCommand(CreateSessionStorageAssociatedCommand(
|
| + ScheduleCommand(CreateSessionStorageAssociated(
|
| session_tab_helper->session_id(),
|
| session_storage_namespace->persistent_id()));
|
| }
|
| @@ -1398,18 +722,16 @@ void SessionService::BuildCommandsForBrowser(
|
| DCHECK(browser->session_id().id());
|
|
|
| commands->push_back(
|
| - CreateSetWindowBoundsCommand(browser->session_id(),
|
| - browser->window()->GetRestoredBounds(),
|
| - browser->window()->GetRestoredState()));
|
| + CreateSetWindowBounds(browser->session_id(),
|
| + browser->window()->GetRestoredBounds(),
|
| + browser->window()->GetRestoredState()));
|
|
|
| - commands->push_back(CreateSetWindowTypeCommand(
|
| + commands->push_back(CreateSetWindowType(
|
| browser->session_id(), WindowTypeForBrowserType(browser->type())));
|
|
|
| if (!browser->app_name().empty()) {
|
| - commands->push_back(CreateSetWindowAppNameCommand(
|
| - kCommandSetWindowAppName,
|
| - browser->session_id().id(),
|
| - browser->app_name()));
|
| + commands->push_back(CreateSetWindowAppName(browser->session_id(),
|
| + browser->app_name()));
|
| }
|
|
|
| windows_to_track->insert(browser->session_id().id());
|
| @@ -1448,102 +770,16 @@ void SessionService::BuildCommandsFromBrowsers(
|
| }
|
| }
|
|
|
| -void SessionService::ScheduleReset() {
|
| - set_pending_reset(true);
|
| - STLDeleteElements(&pending_commands());
|
| - tab_to_available_range_.clear();
|
| - windows_tracking_.clear();
|
| - BuildCommandsFromBrowsers(&pending_commands(), &tab_to_available_range_,
|
| - &windows_tracking_);
|
| - if (!windows_tracking_.empty()) {
|
| - // We're lazily created on startup and won't get an initial batch of
|
| - // SetWindowType messages. Set these here to make sure our state is correct.
|
| - has_open_trackable_browsers_ = true;
|
| - move_on_new_browser_ = true;
|
| - }
|
| - StartSaveTimer();
|
| -}
|
| -
|
| -bool SessionService::ReplacePendingCommand(SessionCommand* command) {
|
| - // We optimize page navigations, which can happen quite frequently and
|
| - // are expensive. And activation is like Highlander, there can only be one!
|
| - if (command->id() != kCommandUpdateTabNavigation &&
|
| - command->id() != kCommandSetActiveWindow) {
|
| - return false;
|
| - }
|
| - for (std::vector<SessionCommand*>::reverse_iterator i =
|
| - pending_commands().rbegin(); i != pending_commands().rend(); ++i) {
|
| - SessionCommand* existing_command = *i;
|
| - if (command->id() == kCommandUpdateTabNavigation &&
|
| - existing_command->id() == kCommandUpdateTabNavigation) {
|
| - scoped_ptr<Pickle> command_pickle(command->PayloadAsPickle());
|
| - PickleIterator iterator(*command_pickle);
|
| - SessionID::id_type command_tab_id;
|
| - int command_nav_index;
|
| - if (!command_pickle->ReadInt(&iterator, &command_tab_id) ||
|
| - !command_pickle->ReadInt(&iterator, &command_nav_index)) {
|
| - return false;
|
| - }
|
| - SessionID::id_type existing_tab_id;
|
| - int existing_nav_index;
|
| - {
|
| - // Creating a pickle like this means the Pickle references the data from
|
| - // the command. Make sure we delete the pickle before the command, else
|
| - // the pickle references deleted memory.
|
| - scoped_ptr<Pickle> existing_pickle(existing_command->PayloadAsPickle());
|
| - iterator = PickleIterator(*existing_pickle);
|
| - if (!existing_pickle->ReadInt(&iterator, &existing_tab_id) ||
|
| - !existing_pickle->ReadInt(&iterator, &existing_nav_index)) {
|
| - return false;
|
| - }
|
| - }
|
| - if (existing_tab_id == command_tab_id &&
|
| - existing_nav_index == command_nav_index) {
|
| - // existing_command is an update for the same tab/index pair. Replace
|
| - // it with the new one. We need to add to the end of the list just in
|
| - // case there is a prune command after the update command.
|
| - delete existing_command;
|
| - pending_commands().erase(i.base() - 1);
|
| - pending_commands().push_back(command);
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| - if (command->id() == kCommandSetActiveWindow &&
|
| - existing_command->id() == kCommandSetActiveWindow) {
|
| - *i = command;
|
| - delete existing_command;
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -void SessionService::ScheduleCommand(SessionCommand* command) {
|
| - DCHECK(command);
|
| - if (ReplacePendingCommand(command))
|
| - return;
|
| - BaseSessionService::ScheduleCommand(command);
|
| - // Don't schedule a reset on tab closed/window closed. Otherwise we may
|
| - // lose tabs/windows we want to restore from if we exit right after this.
|
| - if (!pending_reset() && pending_window_close_ids_.empty() &&
|
| - commands_since_reset() >= kWritesPerReset &&
|
| - (command->id() != kCommandTabClosed &&
|
| - command->id() != kCommandWindowClosed)) {
|
| - ScheduleReset();
|
| - }
|
| -}
|
| -
|
| void SessionService::CommitPendingCloses() {
|
| for (PendingTabCloseIDs::iterator i = pending_tab_close_ids_.begin();
|
| i != pending_tab_close_ids_.end(); ++i) {
|
| - ScheduleCommand(CreateTabClosedCommand(*i));
|
| + ScheduleCommand(CreateTabClosed(*i));
|
| }
|
| pending_tab_close_ids_.clear();
|
|
|
| for (PendingWindowCloseIDs::iterator i = pending_window_close_ids_.begin();
|
| i != pending_window_close_ids_.end(); ++i) {
|
| - ScheduleCommand(CreateWindowClosedCommand(*i));
|
| + ScheduleCommand(CreateWindowClosed(*i));
|
| }
|
| pending_window_close_ids_.clear();
|
| }
|
| @@ -1595,6 +831,24 @@ bool SessionService::ShouldTrackChangesToWindow(
|
| return windows_tracking_.find(window_id.id()) != windows_tracking_.end();
|
| }
|
|
|
| +void SessionService::ScheduleResetCommands() {
|
| + if (pending_reset() || !pending_window_close_ids_.empty())
|
| + return;
|
| + set_pending_reset(true);
|
| + STLDeleteElements(&pending_commands());
|
| + tab_to_available_range_.clear();
|
| + windows_tracking_.clear();
|
| + BuildCommandsFromBrowsers(&pending_commands(), &tab_to_available_range_,
|
| + &windows_tracking_);
|
| + if (!windows_tracking_.empty()) {
|
| + // We're lazily created on startup and won't get an initial batch of
|
| + // SetWindowType messages. Set these here to make sure our state is correct.
|
| + has_open_trackable_browsers_ = true;
|
| + move_on_new_browser_ = true;
|
| + }
|
| + StartSaveTimer();
|
| +}
|
| +
|
| bool SessionService::ShouldTrackBrowser(Browser* browser) const {
|
| if (browser->profile() != profile())
|
| return false;
|
| @@ -1605,39 +859,33 @@ bool SessionService::ShouldTrackBrowser(Browser* browser) const {
|
| !browser->is_trusted_source()) {
|
| return false;
|
| }
|
| - AppType app_type = browser->is_app() ? TYPE_APP : TYPE_NORMAL;
|
| - return should_track_changes_for_browser_type(browser->type(), app_type);
|
| + SessionServiceCommands::AppType app_type =
|
| + browser->is_app() ? SessionServiceCommands::TYPE_APP :
|
| + SessionServiceCommands::TYPE_NORMAL;
|
| + return ShouldTrackChangesOfWindowType(
|
| + WindowTypeForBrowserType(browser->type()),
|
| + app_type);
|
| }
|
|
|
| -bool SessionService::should_track_changes_for_browser_type(Browser::Type type,
|
| - AppType app_type) {
|
| -#if defined(OS_CHROMEOS)
|
| - // Restore app popups for chromeos alone.
|
| - if (type == Browser::TYPE_POPUP && app_type == TYPE_APP)
|
| - return true;
|
| -#endif
|
| -
|
| - return type == Browser::TYPE_TABBED;
|
| -}
|
| -
|
| -SessionService::WindowType SessionService::WindowTypeForBrowserType(
|
| +SessionWindow::WindowType SessionService::WindowTypeForBrowserType(
|
| Browser::Type type) {
|
| switch (type) {
|
| case Browser::TYPE_POPUP:
|
| - return TYPE_POPUP;
|
| + return SessionWindow::TYPE_POPUP;
|
| case Browser::TYPE_TABBED:
|
| - return TYPE_TABBED;
|
| + return SessionWindow::TYPE_TABBED;
|
| default:
|
| DCHECK(false);
|
| - return TYPE_TABBED;
|
| + return SessionWindow::TYPE_TABBED;
|
| }
|
| }
|
|
|
| -Browser::Type SessionService::BrowserTypeForWindowType(WindowType type) {
|
| +Browser::Type SessionService::BrowserTypeForWindowType(
|
| + SessionWindow::WindowType type) {
|
| switch (type) {
|
| - case TYPE_POPUP:
|
| + case SessionWindow::TYPE_POPUP:
|
| return Browser::TYPE_POPUP;
|
| - case TYPE_TABBED:
|
| + case SessionWindow::TYPE_TABBED:
|
| default:
|
| return Browser::TYPE_TABBED;
|
| }
|
| @@ -1773,52 +1021,6 @@ void SessionService::RecordUpdatedSaveTime(base::TimeDelta delta,
|
| }
|
| }
|
|
|
| -void SessionService::TabInserted(WebContents* contents) {
|
| - SessionTabHelper* session_tab_helper =
|
| - SessionTabHelper::FromWebContents(contents);
|
| - if (!ShouldTrackChangesToWindow(session_tab_helper->window_id()))
|
| - return;
|
| - SetTabWindow(session_tab_helper->window_id(),
|
| - session_tab_helper->session_id());
|
| - extensions::TabHelper* extensions_tab_helper =
|
| - extensions::TabHelper::FromWebContents(contents);
|
| - if (extensions_tab_helper &&
|
| - extensions_tab_helper->extension_app()) {
|
| - SetTabExtensionAppID(
|
| - session_tab_helper->window_id(),
|
| - session_tab_helper->session_id(),
|
| - extensions_tab_helper->extension_app()->id());
|
| - }
|
| -
|
| - // Record the association between the SessionStorageNamespace and the
|
| - // tab.
|
| - //
|
| - // TODO(ajwong): This should be processing the whole map rather than
|
| - // just the default. This in particular will not work for tabs with only
|
| - // isolated apps which won't have a default partition.
|
| - content::SessionStorageNamespace* session_storage_namespace =
|
| - contents->GetController().GetDefaultSessionStorageNamespace();
|
| - ScheduleCommand(CreateSessionStorageAssociatedCommand(
|
| - session_tab_helper->session_id(),
|
| - session_storage_namespace->persistent_id()));
|
| - session_storage_namespace->SetShouldPersist(true);
|
| -}
|
| -
|
| -void SessionService::TabClosing(WebContents* contents) {
|
| - // Allow the associated sessionStorage to get deleted; it won't be needed
|
| - // in the session restore.
|
| - content::SessionStorageNamespace* session_storage_namespace =
|
| - contents->GetController().GetDefaultSessionStorageNamespace();
|
| - session_storage_namespace->SetShouldPersist(false);
|
| - SessionTabHelper* session_tab_helper =
|
| - SessionTabHelper::FromWebContents(contents);
|
| - TabClosed(session_tab_helper->window_id(),
|
| - session_tab_helper->session_id(),
|
| - contents->GetClosedByUserGesture());
|
| - RecordSessionUpdateHistogramData(content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
|
| - &last_updated_tab_closed_time_);
|
| -}
|
| -
|
| void SessionService::MaybeDeleteSessionOnlyData() {
|
| // Don't try anything if we're testing. The browser_process is not fully
|
| // created and DeleteSession will crash if we actually attempt it.
|
|
|