| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "components/sessions/core/persistent_tab_restore_service.h" | 5 #include "components/sessions/core/persistent_tab_restore_service.h" |
| 6 | 6 |
| 7 #include <cstring> // memcpy | 7 #include <cstring> // memcpy |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
| 16 #include "base/memory/scoped_vector.h" | 16 #include "base/memory/scoped_vector.h" |
| 17 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 18 #include "base/task/cancelable_task_tracker.h" | 18 #include "base/task/cancelable_task_tracker.h" |
| 19 #include "base/time/time.h" | 19 #include "base/time/time.h" |
| 20 #include "components/sessions/base_session_service.h" | 20 #include "components/sessions/base_session_service.h" |
| 21 #include "components/sessions/base_session_service_commands.h" | 21 #include "components/sessions/base_session_service_commands.h" |
| 22 #include "components/sessions/base_session_service_delegate.h" | 22 #include "components/sessions/base_session_service_delegate.h" |
| 23 #include "components/sessions/core/session_constants.h" | 23 #include "components/sessions/core/session_constants.h" |
| 24 #include "components/sessions/session_command.h" | 24 #include "components/sessions/session_command.h" |
| 25 | 25 |
| 26 using sessions::LiveTab; | 26 namespace sessions { |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 // Only written if the tab is pinned. | 30 // Only written if the tab is pinned. |
| 31 typedef bool PinnedStatePayload; | 31 typedef bool PinnedStatePayload; |
| 32 | 32 |
| 33 typedef int32 RestoredEntryPayload; | 33 typedef int32 RestoredEntryPayload; |
| 34 | 34 |
| 35 typedef std::map<SessionID::id_type, TabRestoreService::Entry*> IDToEntry; | 35 typedef std::map<SessionID::id_type, TabRestoreService::Entry*> IDToEntry; |
| 36 | 36 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 // the selected index, then a kCommandPinnedState command if the tab was | 86 // the selected index, then a kCommandPinnedState command if the tab was |
| 87 // pinned and kCommandSetExtensionAppID if the tab has an app id and | 87 // pinned and kCommandSetExtensionAppID if the tab has an app id and |
| 88 // the user agent override if it was using one. This is | 88 // the user agent override if it was using one. This is |
| 89 // followed by any number of kCommandUpdateTabNavigation commands (1 per | 89 // followed by any number of kCommandUpdateTabNavigation commands (1 per |
| 90 // navigation entry). | 90 // navigation entry). |
| 91 // . When the user closes a window a kCommandSelectedNavigationInTab command | 91 // . When the user closes a window a kCommandSelectedNavigationInTab command |
| 92 // is written out and followed by n tab closed sequences (as previoulsy | 92 // is written out and followed by n tab closed sequences (as previoulsy |
| 93 // described). | 93 // described). |
| 94 // . When the user restores an entry a command of type kCommandRestoredEntry | 94 // . When the user restores an entry a command of type kCommandRestoredEntry |
| 95 // is written. | 95 // is written. |
| 96 const sessions::SessionCommand::id_type kCommandUpdateTabNavigation = 1; | 96 const SessionCommand::id_type kCommandUpdateTabNavigation = 1; |
| 97 const sessions::SessionCommand::id_type kCommandRestoredEntry = 2; | 97 const SessionCommand::id_type kCommandRestoredEntry = 2; |
| 98 const sessions::SessionCommand::id_type kCommandWindow = 3; | 98 const SessionCommand::id_type kCommandWindow = 3; |
| 99 const sessions::SessionCommand::id_type kCommandSelectedNavigationInTab = 4; | 99 const SessionCommand::id_type kCommandSelectedNavigationInTab = 4; |
| 100 const sessions::SessionCommand::id_type kCommandPinnedState = 5; | 100 const SessionCommand::id_type kCommandPinnedState = 5; |
| 101 const sessions::SessionCommand::id_type kCommandSetExtensionAppID = 6; | 101 const SessionCommand::id_type kCommandSetExtensionAppID = 6; |
| 102 const sessions::SessionCommand::id_type kCommandSetWindowAppName = 7; | 102 const SessionCommand::id_type kCommandSetWindowAppName = 7; |
| 103 const sessions::SessionCommand::id_type kCommandSetTabUserAgentOverride = 8; | 103 const SessionCommand::id_type kCommandSetTabUserAgentOverride = 8; |
| 104 | 104 |
| 105 // Number of entries (not commands) before we clobber the file and write | 105 // Number of entries (not commands) before we clobber the file and write |
| 106 // everything. | 106 // everything. |
| 107 const int kEntriesPerReset = 40; | 107 const int kEntriesPerReset = 40; |
| 108 | 108 |
| 109 const size_t kMaxEntries = TabRestoreServiceHelper::kMaxEntries; | 109 const size_t kMaxEntries = TabRestoreServiceHelper::kMaxEntries; |
| 110 | 110 |
| 111 } // namespace | 111 } // namespace |
| 112 | 112 |
| 113 // PersistentTabRestoreService::Delegate --------------------------------------- | 113 // PersistentTabRestoreService::Delegate --------------------------------------- |
| 114 | 114 |
| 115 // This restore service will create and own a BaseSessionService and implement | 115 // This restore service will create and own a BaseSessionService and implement |
| 116 // the required sessions::BaseSessionServiceDelegate. | 116 // the required BaseSessionServiceDelegate. |
| 117 class PersistentTabRestoreService::Delegate | 117 class PersistentTabRestoreService::Delegate |
| 118 : public sessions::BaseSessionServiceDelegate, | 118 : public BaseSessionServiceDelegate, |
| 119 public TabRestoreServiceHelper::Observer { | 119 public TabRestoreServiceHelper::Observer { |
| 120 public: | 120 public: |
| 121 explicit Delegate(sessions::TabRestoreServiceClient* client); | 121 explicit Delegate(TabRestoreServiceClient* client); |
| 122 | 122 |
| 123 ~Delegate() override; | 123 ~Delegate() override; |
| 124 | 124 |
| 125 // sessions::BaseSessionServiceDelegate: | 125 // BaseSessionServiceDelegate: |
| 126 base::SequencedWorkerPool* GetBlockingPool() override; | 126 base::SequencedWorkerPool* GetBlockingPool() override; |
| 127 bool ShouldUseDelayedSave() override; | 127 bool ShouldUseDelayedSave() override; |
| 128 void OnWillSaveCommands() override; | 128 void OnWillSaveCommands() override; |
| 129 | 129 |
| 130 // TabRestoreServiceHelper::Observer: | 130 // TabRestoreServiceHelper::Observer: |
| 131 void OnClearEntries() override; | 131 void OnClearEntries() override; |
| 132 void OnRestoreEntryById(SessionID::id_type id, | 132 void OnRestoreEntryById(SessionID::id_type id, |
| 133 Entries::const_iterator entry_iterator) override; | 133 Entries::const_iterator entry_iterator) override; |
| 134 void OnAddEntry() override; | 134 void OnAddEntry() override; |
| 135 | 135 |
| 136 void set_tab_restore_service_helper( | 136 void set_tab_restore_service_helper( |
| 137 TabRestoreServiceHelper* tab_restore_service_helper) { | 137 TabRestoreServiceHelper* tab_restore_service_helper) { |
| 138 tab_restore_service_helper_ = tab_restore_service_helper; | 138 tab_restore_service_helper_ = tab_restore_service_helper; |
| 139 } | 139 } |
| 140 | 140 |
| 141 void LoadTabsFromLastSession(); | 141 void LoadTabsFromLastSession(); |
| 142 | 142 |
| 143 void DeleteLastSession(); | 143 void DeleteLastSession(); |
| 144 | 144 |
| 145 bool IsLoaded() const; | 145 bool IsLoaded() const; |
| 146 | 146 |
| 147 // Creates and add entries to |entries| for each of the windows in |windows|. | 147 // Creates and add entries to |entries| for each of the windows in |windows|. |
| 148 static void CreateEntriesFromWindows( | 148 static void CreateEntriesFromWindows(std::vector<SessionWindow*>* windows, |
| 149 std::vector<sessions::SessionWindow*>* windows, | 149 std::vector<Entry*>* entries); |
| 150 std::vector<Entry*>* entries); | |
| 151 | 150 |
| 152 void Shutdown(); | 151 void Shutdown(); |
| 153 | 152 |
| 154 // Schedules the commands for a window close. | 153 // Schedules the commands for a window close. |
| 155 void ScheduleCommandsForWindow(const Window& window); | 154 void ScheduleCommandsForWindow(const Window& window); |
| 156 | 155 |
| 157 // Schedules the commands for a tab close. |selected_index| gives the index of | 156 // Schedules the commands for a tab close. |selected_index| gives the index of |
| 158 // the selected navigation. | 157 // the selected navigation. |
| 159 void ScheduleCommandsForTab(const Tab& tab, int selected_index); | 158 void ScheduleCommandsForTab(const Tab& tab, int selected_index); |
| 160 | 159 |
| 161 // Creates a window close command. | 160 // Creates a window close command. |
| 162 static scoped_ptr<sessions::SessionCommand> CreateWindowCommand( | 161 static scoped_ptr<SessionCommand> CreateWindowCommand(SessionID::id_type id, |
| 163 SessionID::id_type id, | 162 int selected_tab_index, |
| 164 int selected_tab_index, | 163 int num_tabs, |
| 165 int num_tabs, | 164 base::Time timestamp); |
| 166 base::Time timestamp); | |
| 167 | 165 |
| 168 // Creates a tab close command. | 166 // Creates a tab close command. |
| 169 static scoped_ptr<sessions::SessionCommand> | 167 static scoped_ptr<SessionCommand> CreateSelectedNavigationInTabCommand( |
| 170 CreateSelectedNavigationInTabCommand( | |
| 171 SessionID::id_type tab_id, | 168 SessionID::id_type tab_id, |
| 172 int32 index, | 169 int32 index, |
| 173 base::Time timestamp); | 170 base::Time timestamp); |
| 174 | 171 |
| 175 // Creates a restore command. | 172 // Creates a restore command. |
| 176 static scoped_ptr<sessions::SessionCommand> CreateRestoredEntryCommand( | 173 static scoped_ptr<SessionCommand> CreateRestoredEntryCommand( |
| 177 SessionID::id_type entry_id); | 174 SessionID::id_type entry_id); |
| 178 | 175 |
| 179 // Returns the index to persist as the selected index. This is the same as | 176 // Returns the index to persist as the selected index. This is the same as |
| 180 // |tab.current_navigation_index| unless the entry at | 177 // |tab.current_navigation_index| unless the entry at |
| 181 // |tab.current_navigation_index| shouldn't be persisted. Returns -1 if no | 178 // |tab.current_navigation_index| shouldn't be persisted. Returns -1 if no |
| 182 // valid navigation to persist. | 179 // valid navigation to persist. |
| 183 int GetSelectedNavigationIndexToPersist(const Tab& tab); | 180 int GetSelectedNavigationIndexToPersist(const Tab& tab); |
| 184 | 181 |
| 185 // Invoked when we've loaded the session commands that identify the previously | 182 // Invoked when we've loaded the session commands that identify the previously |
| 186 // closed tabs. This creates entries, adds them to staging_entries_, and | 183 // closed tabs. This creates entries, adds them to staging_entries_, and |
| 187 // invokes LoadState. | 184 // invokes LoadState. |
| 188 void OnGotLastSessionCommands( | 185 void OnGotLastSessionCommands(ScopedVector<SessionCommand> commands); |
| 189 ScopedVector<sessions::SessionCommand> commands); | |
| 190 | 186 |
| 191 // Populates |loaded_entries| with Entries from |commands|. | 187 // Populates |loaded_entries| with Entries from |commands|. |
| 192 void CreateEntriesFromCommands( | 188 void CreateEntriesFromCommands(const std::vector<SessionCommand*>& commands, |
| 193 const std::vector<sessions::SessionCommand*>& commands, | 189 std::vector<Entry*>* loaded_entries); |
| 194 std::vector<Entry*>* loaded_entries); | |
| 195 | 190 |
| 196 // Validates all entries in |entries|, deleting any with no navigations. This | 191 // Validates all entries in |entries|, deleting any with no navigations. This |
| 197 // also deletes any entries beyond the max number of entries we can hold. | 192 // also deletes any entries beyond the max number of entries we can hold. |
| 198 static void ValidateAndDeleteEmptyEntries(std::vector<Entry*>* entries); | 193 static void ValidateAndDeleteEmptyEntries(std::vector<Entry*>* entries); |
| 199 | 194 |
| 200 // Callback from BaseSessionService when we've received the windows from the | 195 // Callback from BaseSessionService when we've received the windows from the |
| 201 // previous session. This creates and add entries to |staging_entries_| and | 196 // previous session. This creates and add entries to |staging_entries_| and |
| 202 // invokes LoadStateChanged. |ignored_active_window| is ignored because we | 197 // invokes LoadStateChanged. |ignored_active_window| is ignored because we |
| 203 // don't need to restore activation. | 198 // don't need to restore activation. |
| 204 void OnGotPreviousSession(ScopedVector<sessions::SessionWindow> windows, | 199 void OnGotPreviousSession(ScopedVector<SessionWindow> windows, |
| 205 SessionID::id_type ignored_active_window); | 200 SessionID::id_type ignored_active_window); |
| 206 | 201 |
| 207 // Converts a SessionWindow into a Window, returning true on success. We use 0 | 202 // Converts a SessionWindow into a Window, returning true on success. We use 0 |
| 208 // as the timestamp here since we do not know when the window/tab was closed. | 203 // as the timestamp here since we do not know when the window/tab was closed. |
| 209 static bool ConvertSessionWindowToWindow( | 204 static bool ConvertSessionWindowToWindow(SessionWindow* session_window, |
| 210 sessions::SessionWindow* session_window, | 205 Window* window); |
| 211 Window* window); | |
| 212 | 206 |
| 213 // Invoked when previous tabs or session is loaded. If both have finished | 207 // Invoked when previous tabs or session is loaded. If both have finished |
| 214 // loading the entries in |staging_entries_| are added to entries and | 208 // loading the entries in |staging_entries_| are added to entries and |
| 215 // observers are notified. | 209 // observers are notified. |
| 216 void LoadStateChanged(); | 210 void LoadStateChanged(); |
| 217 | 211 |
| 218 // If |id_to_entry| contains an entry for |id| the corresponding entry is | 212 // If |id_to_entry| contains an entry for |id| the corresponding entry is |
| 219 // deleted and removed from both |id_to_entry| and |entries|. This is used | 213 // deleted and removed from both |id_to_entry| and |entries|. This is used |
| 220 // when creating entries from the backend file. | 214 // when creating entries from the backend file. |
| 221 void RemoveEntryByID(SessionID::id_type id, | 215 void RemoveEntryByID(SessionID::id_type id, |
| 222 IDToEntry* id_to_entry, | 216 IDToEntry* id_to_entry, |
| 223 std::vector<TabRestoreService::Entry*>* entries); | 217 std::vector<TabRestoreService::Entry*>* entries); |
| 224 | 218 |
| 225 private: | 219 private: |
| 226 // The associated client. | 220 // The associated client. |
| 227 sessions::TabRestoreServiceClient* client_; | 221 TabRestoreServiceClient* client_; |
| 228 | 222 |
| 229 scoped_ptr<sessions::BaseSessionService> base_session_service_; | 223 scoped_ptr<BaseSessionService> base_session_service_; |
| 230 | 224 |
| 231 TabRestoreServiceHelper* tab_restore_service_helper_; | 225 TabRestoreServiceHelper* tab_restore_service_helper_; |
| 232 | 226 |
| 233 // The number of entries to write. | 227 // The number of entries to write. |
| 234 int entries_to_write_; | 228 int entries_to_write_; |
| 235 | 229 |
| 236 // Number of entries we've written. | 230 // Number of entries we've written. |
| 237 int entries_written_; | 231 int entries_written_; |
| 238 | 232 |
| 239 // Whether we've loaded the last session. | 233 // Whether we've loaded the last session. |
| 240 int load_state_; | 234 int load_state_; |
| 241 | 235 |
| 242 // Results from previously closed tabs/sessions is first added here. When the | 236 // Results from previously closed tabs/sessions is first added here. When the |
| 243 // results from both us and the session restore service have finished loading | 237 // results from both us and the session restore service have finished loading |
| 244 // LoadStateChanged is invoked, which adds these entries to entries_. | 238 // LoadStateChanged is invoked, which adds these entries to entries_. |
| 245 ScopedVector<Entry> staging_entries_; | 239 ScopedVector<Entry> staging_entries_; |
| 246 | 240 |
| 247 // Used when loading previous tabs/session and open tabs/session. | 241 // Used when loading previous tabs/session and open tabs/session. |
| 248 base::CancelableTaskTracker cancelable_task_tracker_; | 242 base::CancelableTaskTracker cancelable_task_tracker_; |
| 249 | 243 |
| 250 DISALLOW_COPY_AND_ASSIGN(Delegate); | 244 DISALLOW_COPY_AND_ASSIGN(Delegate); |
| 251 }; | 245 }; |
| 252 | 246 |
| 253 PersistentTabRestoreService::Delegate::Delegate( | 247 PersistentTabRestoreService::Delegate::Delegate(TabRestoreServiceClient* client) |
| 254 sessions::TabRestoreServiceClient* client) | |
| 255 : client_(client), | 248 : client_(client), |
| 256 base_session_service_(new sessions::BaseSessionService( | 249 base_session_service_( |
| 257 sessions::BaseSessionService::TAB_RESTORE, | 250 new BaseSessionService(BaseSessionService::TAB_RESTORE, |
| 258 client_->GetPathToSaveTo(), | 251 client_->GetPathToSaveTo(), |
| 259 this)), | 252 this)), |
| 260 tab_restore_service_helper_(NULL), | 253 tab_restore_service_helper_(NULL), |
| 261 entries_to_write_(0), | 254 entries_to_write_(0), |
| 262 entries_written_(0), | 255 entries_written_(0), |
| 263 load_state_(NOT_LOADED) {} | 256 load_state_(NOT_LOADED) {} |
| 264 | 257 |
| 265 PersistentTabRestoreService::Delegate::~Delegate() {} | 258 PersistentTabRestoreService::Delegate::~Delegate() {} |
| 266 | 259 |
| 267 base::SequencedWorkerPool* | 260 base::SequencedWorkerPool* |
| 268 PersistentTabRestoreService::Delegate::GetBlockingPool() { | 261 PersistentTabRestoreService::Delegate::GetBlockingPool() { |
| 269 return client_->GetBlockingPool(); | 262 return client_->GetBlockingPool(); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 void PersistentTabRestoreService::Delegate::DeleteLastSession() { | 368 void PersistentTabRestoreService::Delegate::DeleteLastSession() { |
| 376 base_session_service_->DeleteLastSession(); | 369 base_session_service_->DeleteLastSession(); |
| 377 } | 370 } |
| 378 | 371 |
| 379 bool PersistentTabRestoreService::Delegate::IsLoaded() const { | 372 bool PersistentTabRestoreService::Delegate::IsLoaded() const { |
| 380 return !(load_state_ & (NOT_LOADED | LOADING)); | 373 return !(load_state_ & (NOT_LOADED | LOADING)); |
| 381 } | 374 } |
| 382 | 375 |
| 383 // static | 376 // static |
| 384 void PersistentTabRestoreService::Delegate::CreateEntriesFromWindows( | 377 void PersistentTabRestoreService::Delegate::CreateEntriesFromWindows( |
| 385 std::vector<sessions::SessionWindow*>* windows, | 378 std::vector<SessionWindow*>* windows, |
| 386 std::vector<Entry*>* entries) { | 379 std::vector<Entry*>* entries) { |
| 387 for (size_t i = 0; i < windows->size(); ++i) { | 380 for (size_t i = 0; i < windows->size(); ++i) { |
| 388 scoped_ptr<Window> window(new Window()); | 381 scoped_ptr<Window> window(new Window()); |
| 389 if (ConvertSessionWindowToWindow((*windows)[i], window.get())) | 382 if (ConvertSessionWindowToWindow((*windows)[i], window.get())) |
| 390 entries->push_back(window.release()); | 383 entries->push_back(window.release()); |
| 391 } | 384 } |
| 392 } | 385 } |
| 393 | 386 |
| 394 void PersistentTabRestoreService::Delegate::Shutdown() { | 387 void PersistentTabRestoreService::Delegate::Shutdown() { |
| 395 base_session_service_->Save(); | 388 base_session_service_->Save(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 412 return; // No tabs to persist. | 405 return; // No tabs to persist. |
| 413 | 406 |
| 414 base_session_service_->ScheduleCommand( | 407 base_session_service_->ScheduleCommand( |
| 415 CreateWindowCommand(window.id, | 408 CreateWindowCommand(window.id, |
| 416 std::min(real_selected_tab, valid_tab_count - 1), | 409 std::min(real_selected_tab, valid_tab_count - 1), |
| 417 valid_tab_count, | 410 valid_tab_count, |
| 418 window.timestamp).Pass()); | 411 window.timestamp).Pass()); |
| 419 | 412 |
| 420 if (!window.app_name.empty()) { | 413 if (!window.app_name.empty()) { |
| 421 base_session_service_->ScheduleCommand( | 414 base_session_service_->ScheduleCommand( |
| 422 sessions::CreateSetWindowAppNameCommand(kCommandSetWindowAppName, | 415 CreateSetWindowAppNameCommand(kCommandSetWindowAppName, window.id, |
| 423 window.id, | 416 window.app_name) |
| 424 window.app_name).Pass()); | 417 .Pass()); |
| 425 } | 418 } |
| 426 | 419 |
| 427 for (size_t i = 0; i < window.tabs.size(); ++i) { | 420 for (size_t i = 0; i < window.tabs.size(); ++i) { |
| 428 int selected_index = GetSelectedNavigationIndexToPersist(window.tabs[i]); | 421 int selected_index = GetSelectedNavigationIndexToPersist(window.tabs[i]); |
| 429 if (selected_index != -1) | 422 if (selected_index != -1) |
| 430 ScheduleCommandsForTab(window.tabs[i], selected_index); | 423 ScheduleCommandsForTab(window.tabs[i], selected_index); |
| 431 } | 424 } |
| 432 } | 425 } |
| 433 | 426 |
| 434 void PersistentTabRestoreService::Delegate::ScheduleCommandsForTab( | 427 void PersistentTabRestoreService::Delegate::ScheduleCommandsForTab( |
| 435 const Tab& tab, | 428 const Tab& tab, |
| 436 int selected_index) { | 429 int selected_index) { |
| 437 const std::vector<sessions::SerializedNavigationEntry>& navigations = | 430 const std::vector<SerializedNavigationEntry>& navigations = tab.navigations; |
| 438 tab.navigations; | |
| 439 int max_index = static_cast<int>(navigations.size()); | 431 int max_index = static_cast<int>(navigations.size()); |
| 440 | 432 |
| 441 // Determine the first navigation we'll persist. | 433 // Determine the first navigation we'll persist. |
| 442 int valid_count_before_selected = 0; | 434 int valid_count_before_selected = 0; |
| 443 int first_index_to_persist = selected_index; | 435 int first_index_to_persist = selected_index; |
| 444 for (int i = selected_index - 1; | 436 for (int i = selected_index - 1; |
| 445 i >= 0 && | 437 i >= 0 && valid_count_before_selected < gMaxPersistNavigationCount; |
| 446 valid_count_before_selected < sessions::gMaxPersistNavigationCount; | |
| 447 --i) { | 438 --i) { |
| 448 if (client_->ShouldTrackURLForRestore(navigations[i].virtual_url())) { | 439 if (client_->ShouldTrackURLForRestore(navigations[i].virtual_url())) { |
| 449 first_index_to_persist = i; | 440 first_index_to_persist = i; |
| 450 valid_count_before_selected++; | 441 valid_count_before_selected++; |
| 451 } | 442 } |
| 452 } | 443 } |
| 453 | 444 |
| 454 // Write the command that identifies the selected tab. | 445 // Write the command that identifies the selected tab. |
| 455 base_session_service_->ScheduleCommand( | 446 base_session_service_->ScheduleCommand( |
| 456 CreateSelectedNavigationInTabCommand(tab.id, | 447 CreateSelectedNavigationInTabCommand(tab.id, |
| 457 valid_count_before_selected, | 448 valid_count_before_selected, |
| 458 tab.timestamp).Pass()); | 449 tab.timestamp).Pass()); |
| 459 | 450 |
| 460 if (tab.pinned) { | 451 if (tab.pinned) { |
| 461 PinnedStatePayload payload = true; | 452 PinnedStatePayload payload = true; |
| 462 scoped_ptr<sessions::SessionCommand> command( | 453 scoped_ptr<SessionCommand> command( |
| 463 new sessions::SessionCommand(kCommandPinnedState, sizeof(payload))); | 454 new SessionCommand(kCommandPinnedState, sizeof(payload))); |
| 464 memcpy(command->contents(), &payload, sizeof(payload)); | 455 memcpy(command->contents(), &payload, sizeof(payload)); |
| 465 base_session_service_->ScheduleCommand(command.Pass()); | 456 base_session_service_->ScheduleCommand(command.Pass()); |
| 466 } | 457 } |
| 467 | 458 |
| 468 if (!tab.extension_app_id.empty()) { | 459 if (!tab.extension_app_id.empty()) { |
| 469 base_session_service_->ScheduleCommand( | 460 base_session_service_->ScheduleCommand( |
| 470 sessions::CreateSetTabExtensionAppIDCommand( | 461 CreateSetTabExtensionAppIDCommand(kCommandSetExtensionAppID, tab.id, |
| 471 kCommandSetExtensionAppID, | 462 tab.extension_app_id) |
| 472 tab.id, | 463 .Pass()); |
| 473 tab.extension_app_id).Pass()); | |
| 474 } | 464 } |
| 475 | 465 |
| 476 if (!tab.user_agent_override.empty()) { | 466 if (!tab.user_agent_override.empty()) { |
| 477 base_session_service_->ScheduleCommand( | 467 base_session_service_->ScheduleCommand( |
| 478 sessions::CreateSetTabUserAgentOverrideCommand( | 468 CreateSetTabUserAgentOverrideCommand(kCommandSetTabUserAgentOverride, |
| 479 kCommandSetTabUserAgentOverride, | 469 tab.id, tab.user_agent_override) |
| 480 tab.id, | 470 .Pass()); |
| 481 tab.user_agent_override).Pass()); | |
| 482 } | 471 } |
| 483 | 472 |
| 484 // Then write the navigations. | 473 // Then write the navigations. |
| 485 for (int i = first_index_to_persist, wrote_count = 0; | 474 for (int i = first_index_to_persist, wrote_count = 0; |
| 486 wrote_count < 2 * sessions::gMaxPersistNavigationCount && i < max_index; | 475 wrote_count < 2 * gMaxPersistNavigationCount && i < max_index; ++i) { |
| 487 ++i) { | |
| 488 if (client_->ShouldTrackURLForRestore(navigations[i].virtual_url())) { | 476 if (client_->ShouldTrackURLForRestore(navigations[i].virtual_url())) { |
| 489 base_session_service_->ScheduleCommand( | 477 base_session_service_->ScheduleCommand( |
| 490 CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation, | 478 CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation, |
| 491 tab.id, | 479 tab.id, |
| 492 navigations[i])); | 480 navigations[i])); |
| 493 } | 481 } |
| 494 } | 482 } |
| 495 } | 483 } |
| 496 | 484 |
| 497 // static | 485 // static |
| 498 scoped_ptr<sessions::SessionCommand> | 486 scoped_ptr<SessionCommand> |
| 499 PersistentTabRestoreService::Delegate::CreateWindowCommand( | 487 PersistentTabRestoreService::Delegate::CreateWindowCommand( |
| 500 SessionID::id_type id, | 488 SessionID::id_type id, |
| 501 int selected_tab_index, | 489 int selected_tab_index, |
| 502 int num_tabs, | 490 int num_tabs, |
| 503 base::Time timestamp) { | 491 base::Time timestamp) { |
| 504 WindowPayload2 payload; | 492 WindowPayload2 payload; |
| 505 // |timestamp| is aligned on a 16 byte boundary, leaving 4 bytes of | 493 // |timestamp| is aligned on a 16 byte boundary, leaving 4 bytes of |
| 506 // uninitialized memory in the struct. | 494 // uninitialized memory in the struct. |
| 507 memset(&payload, 0, sizeof(payload)); | 495 memset(&payload, 0, sizeof(payload)); |
| 508 payload.window_id = id; | 496 payload.window_id = id; |
| 509 payload.selected_tab_index = selected_tab_index; | 497 payload.selected_tab_index = selected_tab_index; |
| 510 payload.num_tabs = num_tabs; | 498 payload.num_tabs = num_tabs; |
| 511 payload.timestamp = timestamp.ToInternalValue(); | 499 payload.timestamp = timestamp.ToInternalValue(); |
| 512 | 500 |
| 513 scoped_ptr<sessions::SessionCommand> command( | 501 scoped_ptr<SessionCommand> command( |
| 514 new sessions::SessionCommand(kCommandWindow, sizeof(payload))); | 502 new SessionCommand(kCommandWindow, sizeof(payload))); |
| 515 memcpy(command->contents(), &payload, sizeof(payload)); | 503 memcpy(command->contents(), &payload, sizeof(payload)); |
| 516 return command; | 504 return command; |
| 517 } | 505 } |
| 518 | 506 |
| 519 // static | 507 // static |
| 520 scoped_ptr<sessions::SessionCommand> | 508 scoped_ptr<SessionCommand> |
| 521 PersistentTabRestoreService::Delegate::CreateSelectedNavigationInTabCommand( | 509 PersistentTabRestoreService::Delegate::CreateSelectedNavigationInTabCommand( |
| 522 SessionID::id_type tab_id, | 510 SessionID::id_type tab_id, |
| 523 int32 index, | 511 int32 index, |
| 524 base::Time timestamp) { | 512 base::Time timestamp) { |
| 525 SelectedNavigationInTabPayload2 payload; | 513 SelectedNavigationInTabPayload2 payload; |
| 526 payload.id = tab_id; | 514 payload.id = tab_id; |
| 527 payload.index = index; | 515 payload.index = index; |
| 528 payload.timestamp = timestamp.ToInternalValue(); | 516 payload.timestamp = timestamp.ToInternalValue(); |
| 529 scoped_ptr<sessions::SessionCommand> command( | 517 scoped_ptr<SessionCommand> command( |
| 530 new sessions::SessionCommand( | 518 new SessionCommand(kCommandSelectedNavigationInTab, sizeof(payload))); |
| 531 kCommandSelectedNavigationInTab, sizeof(payload))); | |
| 532 memcpy(command->contents(), &payload, sizeof(payload)); | 519 memcpy(command->contents(), &payload, sizeof(payload)); |
| 533 return command; | 520 return command; |
| 534 } | 521 } |
| 535 | 522 |
| 536 // static | 523 // static |
| 537 scoped_ptr<sessions::SessionCommand> | 524 scoped_ptr<SessionCommand> |
| 538 PersistentTabRestoreService::Delegate::CreateRestoredEntryCommand( | 525 PersistentTabRestoreService::Delegate::CreateRestoredEntryCommand( |
| 539 SessionID::id_type entry_id) { | 526 SessionID::id_type entry_id) { |
| 540 RestoredEntryPayload payload = entry_id; | 527 RestoredEntryPayload payload = entry_id; |
| 541 scoped_ptr<sessions::SessionCommand> command( | 528 scoped_ptr<SessionCommand> command( |
| 542 new sessions::SessionCommand(kCommandRestoredEntry, sizeof(payload))); | 529 new SessionCommand(kCommandRestoredEntry, sizeof(payload))); |
| 543 memcpy(command->contents(), &payload, sizeof(payload)); | 530 memcpy(command->contents(), &payload, sizeof(payload)); |
| 544 return command; | 531 return command; |
| 545 } | 532 } |
| 546 | 533 |
| 547 int PersistentTabRestoreService::Delegate::GetSelectedNavigationIndexToPersist( | 534 int PersistentTabRestoreService::Delegate::GetSelectedNavigationIndexToPersist( |
| 548 const Tab& tab) { | 535 const Tab& tab) { |
| 549 const std::vector<sessions::SerializedNavigationEntry>& navigations = | 536 const std::vector<SerializedNavigationEntry>& navigations = tab.navigations; |
| 550 tab.navigations; | |
| 551 int selected_index = tab.current_navigation_index; | 537 int selected_index = tab.current_navigation_index; |
| 552 int max_index = static_cast<int>(navigations.size()); | 538 int max_index = static_cast<int>(navigations.size()); |
| 553 | 539 |
| 554 // Find the first navigation to persist. We won't persist the selected | 540 // Find the first navigation to persist. We won't persist the selected |
| 555 // navigation if client_->ShouldTrackURLForRestore returns false. | 541 // navigation if client_->ShouldTrackURLForRestore returns false. |
| 556 while (selected_index >= 0 && | 542 while (selected_index >= 0 && |
| 557 !client_->ShouldTrackURLForRestore( | 543 !client_->ShouldTrackURLForRestore( |
| 558 navigations[selected_index].virtual_url())) { | 544 navigations[selected_index].virtual_url())) { |
| 559 selected_index--; | 545 selected_index--; |
| 560 } | 546 } |
| 561 | 547 |
| 562 if (selected_index != -1) | 548 if (selected_index != -1) |
| 563 return selected_index; | 549 return selected_index; |
| 564 | 550 |
| 565 // Couldn't find a navigation to persist going back, go forward. | 551 // Couldn't find a navigation to persist going back, go forward. |
| 566 selected_index = tab.current_navigation_index + 1; | 552 selected_index = tab.current_navigation_index + 1; |
| 567 while (selected_index < max_index && | 553 while (selected_index < max_index && |
| 568 !client_->ShouldTrackURLForRestore( | 554 !client_->ShouldTrackURLForRestore( |
| 569 navigations[selected_index].virtual_url())) { | 555 navigations[selected_index].virtual_url())) { |
| 570 selected_index++; | 556 selected_index++; |
| 571 } | 557 } |
| 572 | 558 |
| 573 return (selected_index == max_index) ? -1 : selected_index; | 559 return (selected_index == max_index) ? -1 : selected_index; |
| 574 } | 560 } |
| 575 | 561 |
| 576 void PersistentTabRestoreService::Delegate::OnGotLastSessionCommands( | 562 void PersistentTabRestoreService::Delegate::OnGotLastSessionCommands( |
| 577 ScopedVector<sessions::SessionCommand> commands) { | 563 ScopedVector<SessionCommand> commands) { |
| 578 std::vector<Entry*> entries; | 564 std::vector<Entry*> entries; |
| 579 CreateEntriesFromCommands(commands.get(), &entries); | 565 CreateEntriesFromCommands(commands.get(), &entries); |
| 580 // Closed tabs always go to the end. | 566 // Closed tabs always go to the end. |
| 581 staging_entries_.insert(staging_entries_.end(), entries.begin(), | 567 staging_entries_.insert(staging_entries_.end(), entries.begin(), |
| 582 entries.end()); | 568 entries.end()); |
| 583 load_state_ |= LOADED_LAST_TABS; | 569 load_state_ |= LOADED_LAST_TABS; |
| 584 LoadStateChanged(); | 570 LoadStateChanged(); |
| 585 } | 571 } |
| 586 | 572 |
| 587 void PersistentTabRestoreService::Delegate::CreateEntriesFromCommands( | 573 void PersistentTabRestoreService::Delegate::CreateEntriesFromCommands( |
| 588 const std::vector<sessions::SessionCommand*>& commands, | 574 const std::vector<SessionCommand*>& commands, |
| 589 std::vector<Entry*>* loaded_entries) { | 575 std::vector<Entry*>* loaded_entries) { |
| 590 if (tab_restore_service_helper_->entries().size() == kMaxEntries) | 576 if (tab_restore_service_helper_->entries().size() == kMaxEntries) |
| 591 return; | 577 return; |
| 592 | 578 |
| 593 // Iterate through the commands populating entries and id_to_entry. | 579 // Iterate through the commands populating entries and id_to_entry. |
| 594 ScopedVector<Entry> entries; | 580 ScopedVector<Entry> entries; |
| 595 IDToEntry id_to_entry; | 581 IDToEntry id_to_entry; |
| 596 // If non-null we're processing the navigations of this tab. | 582 // If non-null we're processing the navigations of this tab. |
| 597 Tab* current_tab = NULL; | 583 Tab* current_tab = NULL; |
| 598 // If non-null we're processing the tabs of this window. | 584 // If non-null we're processing the tabs of this window. |
| 599 Window* current_window = NULL; | 585 Window* current_window = NULL; |
| 600 // If > 0, we've gotten a window command but not all the tabs yet. | 586 // If > 0, we've gotten a window command but not all the tabs yet. |
| 601 int pending_window_tabs = 0; | 587 int pending_window_tabs = 0; |
| 602 for (std::vector<sessions::SessionCommand*>::const_iterator i = | 588 for (std::vector<SessionCommand*>::const_iterator i = commands.begin(); |
| 603 commands.begin(); i != commands.end(); ++i) { | 589 i != commands.end(); ++i) { |
| 604 const sessions::SessionCommand& command = *(*i); | 590 const SessionCommand& command = *(*i); |
| 605 switch (command.id()) { | 591 switch (command.id()) { |
| 606 case kCommandRestoredEntry: { | 592 case kCommandRestoredEntry: { |
| 607 if (pending_window_tabs > 0) { | 593 if (pending_window_tabs > 0) { |
| 608 // Should never receive a restored command while waiting for all the | 594 // Should never receive a restored command while waiting for all the |
| 609 // tabs in a window. | 595 // tabs in a window. |
| 610 return; | 596 return; |
| 611 } | 597 } |
| 612 | 598 |
| 613 current_tab = NULL; | 599 current_tab = NULL; |
| 614 current_window = NULL; | 600 current_window = NULL; |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 invalid_entries.push_back(*i); | 783 invalid_entries.push_back(*i); |
| 798 } | 784 } |
| 799 // NOTE: at this point the entries are ordered with newest at the front. | 785 // NOTE: at this point the entries are ordered with newest at the front. |
| 800 entries->swap(valid_entries); | 786 entries->swap(valid_entries); |
| 801 | 787 |
| 802 // Delete the remaining entries. | 788 // Delete the remaining entries. |
| 803 STLDeleteElements(&invalid_entries); | 789 STLDeleteElements(&invalid_entries); |
| 804 } | 790 } |
| 805 | 791 |
| 806 void PersistentTabRestoreService::Delegate::OnGotPreviousSession( | 792 void PersistentTabRestoreService::Delegate::OnGotPreviousSession( |
| 807 ScopedVector<sessions::SessionWindow> windows, | 793 ScopedVector<SessionWindow> windows, |
| 808 SessionID::id_type ignored_active_window) { | 794 SessionID::id_type ignored_active_window) { |
| 809 std::vector<Entry*> entries; | 795 std::vector<Entry*> entries; |
| 810 CreateEntriesFromWindows(&windows.get(), &entries); | 796 CreateEntriesFromWindows(&windows.get(), &entries); |
| 811 // Previous session tabs go first. | 797 // Previous session tabs go first. |
| 812 staging_entries_.insert(staging_entries_.begin(), entries.begin(), | 798 staging_entries_.insert(staging_entries_.begin(), entries.begin(), |
| 813 entries.end()); | 799 entries.end()); |
| 814 load_state_ |= LOADED_LAST_SESSION; | 800 load_state_ |= LOADED_LAST_SESSION; |
| 815 LoadStateChanged(); | 801 LoadStateChanged(); |
| 816 } | 802 } |
| 817 | 803 |
| 818 bool PersistentTabRestoreService::Delegate::ConvertSessionWindowToWindow( | 804 bool PersistentTabRestoreService::Delegate::ConvertSessionWindowToWindow( |
| 819 sessions::SessionWindow* session_window, | 805 SessionWindow* session_window, |
| 820 Window* window) { | 806 Window* window) { |
| 821 for (size_t i = 0; i < session_window->tabs.size(); ++i) { | 807 for (size_t i = 0; i < session_window->tabs.size(); ++i) { |
| 822 if (!session_window->tabs[i]->navigations.empty()) { | 808 if (!session_window->tabs[i]->navigations.empty()) { |
| 823 window->tabs.resize(window->tabs.size() + 1); | 809 window->tabs.resize(window->tabs.size() + 1); |
| 824 Tab& tab = window->tabs.back(); | 810 Tab& tab = window->tabs.back(); |
| 825 tab.pinned = session_window->tabs[i]->pinned; | 811 tab.pinned = session_window->tabs[i]->pinned; |
| 826 tab.navigations.swap(session_window->tabs[i]->navigations); | 812 tab.navigations.swap(session_window->tabs[i]->navigations); |
| 827 tab.current_navigation_index = | 813 tab.current_navigation_index = |
| 828 session_window->tabs[i]->current_navigation_index; | 814 session_window->tabs[i]->current_navigation_index; |
| 829 tab.extension_app_id = session_window->tabs[i]->extension_app_id; | 815 tab.extension_app_id = session_window->tabs[i]->extension_app_id; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 return; | 906 return; |
| 921 } | 907 } |
| 922 } | 908 } |
| 923 } | 909 } |
| 924 } | 910 } |
| 925 } | 911 } |
| 926 | 912 |
| 927 // PersistentTabRestoreService ------------------------------------------------- | 913 // PersistentTabRestoreService ------------------------------------------------- |
| 928 | 914 |
| 929 PersistentTabRestoreService::PersistentTabRestoreService( | 915 PersistentTabRestoreService::PersistentTabRestoreService( |
| 930 scoped_ptr<sessions::TabRestoreServiceClient> client, | 916 scoped_ptr<TabRestoreServiceClient> client, |
| 931 TimeFactory* time_factory) | 917 TimeFactory* time_factory) |
| 932 : client_(client.Pass()), | 918 : client_(client.Pass()), |
| 933 delegate_(new Delegate(client_.get())), | 919 delegate_(new Delegate(client_.get())), |
| 934 helper_(this, delegate_.get(), client_.get(), time_factory) { | 920 helper_(this, delegate_.get(), client_.get(), time_factory) { |
| 935 delegate_->set_tab_restore_service_helper(&helper_); | 921 delegate_->set_tab_restore_service_helper(&helper_); |
| 936 } | 922 } |
| 937 | 923 |
| 938 PersistentTabRestoreService::~PersistentTabRestoreService() {} | 924 PersistentTabRestoreService::~PersistentTabRestoreService() {} |
| 939 | 925 |
| 940 void PersistentTabRestoreService::AddObserver( | 926 void PersistentTabRestoreService::AddObserver( |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 delegate_->LoadTabsFromLastSession(); | 991 delegate_->LoadTabsFromLastSession(); |
| 1006 } | 992 } |
| 1007 | 993 |
| 1008 TabRestoreService::Entries* PersistentTabRestoreService::mutable_entries() { | 994 TabRestoreService::Entries* PersistentTabRestoreService::mutable_entries() { |
| 1009 return &helper_.entries_; | 995 return &helper_.entries_; |
| 1010 } | 996 } |
| 1011 | 997 |
| 1012 void PersistentTabRestoreService::PruneEntries() { | 998 void PersistentTabRestoreService::PruneEntries() { |
| 1013 helper_.PruneEntries(); | 999 helper_.PruneEntries(); |
| 1014 } | 1000 } |
| 1001 |
| 1002 } // namespace sessions |
| OLD | NEW |