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 |