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

Side by Side Diff: components/sessions/core/persistent_tab_restore_service.cc

Issue 2200993004: Make TabRestoreService::Entry noncopyable and fix up surrounding code. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@tab-test-cleanup
Patch Set: Get session ID from entries, take tabs' active status directly instead of an index Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 #include <string.h> 9 #include <string.h>
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/compiler_specific.h" 14 #include "base/compiler_specific.h"
15 #include "base/files/file_path.h" 15 #include "base/files/file_path.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/macros.h" 17 #include "base/macros.h"
18 #include "base/memory/ptr_util.h"
18 #include "base/memory/ref_counted.h" 19 #include "base/memory/ref_counted.h"
19 #include "base/memory/scoped_vector.h"
20 #include "base/stl_util.h" 20 #include "base/stl_util.h"
21 #include "base/task/cancelable_task_tracker.h" 21 #include "base/task/cancelable_task_tracker.h"
22 #include "base/time/time.h" 22 #include "base/time/time.h"
23 #include "components/sessions/core/base_session_service.h" 23 #include "components/sessions/core/base_session_service.h"
24 #include "components/sessions/core/base_session_service_commands.h" 24 #include "components/sessions/core/base_session_service_commands.h"
25 #include "components/sessions/core/base_session_service_delegate.h" 25 #include "components/sessions/core/base_session_service_delegate.h"
26 #include "components/sessions/core/session_command.h" 26 #include "components/sessions/core/session_command.h"
27 #include "components/sessions/core/session_constants.h" 27 #include "components/sessions/core/session_constants.h"
28 28
29 namespace sessions { 29 namespace sessions {
30 30
31 namespace { 31 namespace {
32 32
33 // Only written if the tab is pinned. 33 // Only written if the tab is pinned.
34 typedef bool PinnedStatePayload; 34 typedef bool PinnedStatePayload;
35 35
36 typedef int32_t RestoredEntryPayload; 36 typedef int32_t RestoredEntryPayload;
37 37
38 typedef std::map<SessionID::id_type, TabRestoreService::Entry*> IDToEntry;
39
40 // Payload used for the start of a tab close. This is the old struct that is 38 // Payload used for the start of a tab close. This is the old struct that is
41 // used for backwards compat when it comes to reading the session files. 39 // used for backwards compat when it comes to reading the session files.
42 struct SelectedNavigationInTabPayload { 40 struct SelectedNavigationInTabPayload {
43 SessionID::id_type id; 41 SessionID::id_type id;
44 int32_t index; 42 int32_t index;
45 }; 43 };
46 44
47 // Payload used for the start of a window close. This is the old struct that is 45 // Payload used for the start of a window close. This is the old struct that is
48 // used for backwards compat when it comes to reading the session files. This 46 // used for backwards compat when it comes to reading the session files. This
49 // struct must be POD, because we memset the contents. 47 // struct must be POD, because we memset the contents.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 const SessionCommand::id_type kCommandSetExtensionAppID = 6; 102 const SessionCommand::id_type kCommandSetExtensionAppID = 6;
105 const SessionCommand::id_type kCommandSetWindowAppName = 7; 103 const SessionCommand::id_type kCommandSetWindowAppName = 7;
106 const SessionCommand::id_type kCommandSetTabUserAgentOverride = 8; 104 const SessionCommand::id_type kCommandSetTabUserAgentOverride = 8;
107 105
108 // Number of entries (not commands) before we clobber the file and write 106 // Number of entries (not commands) before we clobber the file and write
109 // everything. 107 // everything.
110 const int kEntriesPerReset = 40; 108 const int kEntriesPerReset = 40;
111 109
112 const size_t kMaxEntries = TabRestoreServiceHelper::kMaxEntries; 110 const size_t kMaxEntries = TabRestoreServiceHelper::kMaxEntries;
113 111
112 void RemoveEntryByID(
113 SessionID::id_type id,
114 std::vector<std::unique_ptr<TabRestoreService::Entry>>* entries) {
115 // Look for the entry in the top-level collection.
116 for (auto it = entries->begin(); it != entries->end(); ++it) {
117 TabRestoreService::Entry& entry = **it;
118 // Erase it if it's our target.
119 if (entry.id == id) {
120 entries->erase(it);
121 return;
122 }
123 // If this entry is a window, look through its tabs.
124 if (entry.type == TabRestoreService::WINDOW) {
125 auto& window = static_cast<TabRestoreService::Window&>(entry);
126 for (auto it = window.tabs.begin(); it != window.tabs.end(); ++it) {
127 const TabRestoreService::Tab& tab = **it;
128 // Erase it if it's our target.
129 if (tab.id == id) {
130 window.tabs.erase(it);
131 return;
132 }
133 }
134 }
135 }
136 }
137
114 } // namespace 138 } // namespace
115 139
116 // PersistentTabRestoreService::Delegate --------------------------------------- 140 // PersistentTabRestoreService::Delegate ---------------------------------------
117 141
118 // This restore service will create and own a BaseSessionService and implement 142 // This restore service will create and own a BaseSessionService and implement
119 // the required BaseSessionServiceDelegate. 143 // the required BaseSessionServiceDelegate.
120 class PersistentTabRestoreService::Delegate 144 class PersistentTabRestoreService::Delegate
121 : public BaseSessionServiceDelegate, 145 : public BaseSessionServiceDelegate,
122 public TabRestoreServiceHelper::Observer { 146 public TabRestoreServiceHelper::Observer {
123 public: 147 public:
(...skipping 17 matching lines...) Expand all
141 tab_restore_service_helper_ = tab_restore_service_helper; 165 tab_restore_service_helper_ = tab_restore_service_helper;
142 } 166 }
143 167
144 void LoadTabsFromLastSession(); 168 void LoadTabsFromLastSession();
145 169
146 void DeleteLastSession(); 170 void DeleteLastSession();
147 171
148 bool IsLoaded() const; 172 bool IsLoaded() const;
149 173
150 // Creates and add entries to |entries| for each of the windows in |windows|. 174 // Creates and add entries to |entries| for each of the windows in |windows|.
151 static void CreateEntriesFromWindows(std::vector<SessionWindow*>* windows, 175 static void CreateEntriesFromWindows(
152 std::vector<Entry*>* entries); 176 std::vector<SessionWindow*>* windows,
177 std::vector<std::unique_ptr<Entry>>* entries);
153 178
154 void Shutdown(); 179 void Shutdown();
155 180
156 // Schedules the commands for a window close. 181 // Schedules the commands for a window close.
157 void ScheduleCommandsForWindow(const Window& window); 182 void ScheduleCommandsForWindow(const Window& window);
158 183
159 // Schedules the commands for a tab close. |selected_index| gives the index of 184 // Schedules the commands for a tab close. |selected_index| gives the index of
160 // the selected navigation. 185 // the selected navigation.
161 void ScheduleCommandsForTab(const Tab& tab, int selected_index); 186 void ScheduleCommandsForTab(const Tab& tab, int selected_index);
162 187
(...skipping 19 matching lines...) Expand all
182 // |tab.current_navigation_index| shouldn't be persisted. Returns -1 if no 207 // |tab.current_navigation_index| shouldn't be persisted. Returns -1 if no
183 // valid navigation to persist. 208 // valid navigation to persist.
184 int GetSelectedNavigationIndexToPersist(const Tab& tab); 209 int GetSelectedNavigationIndexToPersist(const Tab& tab);
185 210
186 // Invoked when we've loaded the session commands that identify the previously 211 // Invoked when we've loaded the session commands that identify the previously
187 // closed tabs. This creates entries, adds them to staging_entries_, and 212 // closed tabs. This creates entries, adds them to staging_entries_, and
188 // invokes LoadState. 213 // invokes LoadState.
189 void OnGotLastSessionCommands(ScopedVector<SessionCommand> commands); 214 void OnGotLastSessionCommands(ScopedVector<SessionCommand> commands);
190 215
191 // Populates |loaded_entries| with Entries from |commands|. 216 // Populates |loaded_entries| with Entries from |commands|.
192 void CreateEntriesFromCommands(const std::vector<SessionCommand*>& commands, 217 void CreateEntriesFromCommands(
193 std::vector<Entry*>* loaded_entries); 218 const std::vector<SessionCommand*>& commands,
219 std::vector<std::unique_ptr<Entry>>* loaded_entries);
194 220
195 // Validates all entries in |entries|, deleting any with no navigations. This 221 // Validates all entries in |entries|, deleting any with no navigations. This
196 // also deletes any entries beyond the max number of entries we can hold. 222 // also deletes any entries beyond the max number of entries we can hold.
197 static void ValidateAndDeleteEmptyEntries(std::vector<Entry*>* entries); 223 static void ValidateAndDeleteEmptyEntries(
224 std::vector<std::unique_ptr<Entry>>* entries);
198 225
199 // Callback from BaseSessionService when we've received the windows from the 226 // Callback from BaseSessionService when we've received the windows from the
200 // previous session. This creates and add entries to |staging_entries_| and 227 // previous session. This creates and add entries to |staging_entries_| and
201 // invokes LoadStateChanged. |ignored_active_window| is ignored because we 228 // invokes LoadStateChanged. |ignored_active_window| is ignored because we
202 // don't need to restore activation. 229 // don't need to restore activation.
203 void OnGotPreviousSession(ScopedVector<SessionWindow> windows, 230 void OnGotPreviousSession(ScopedVector<SessionWindow> windows,
204 SessionID::id_type ignored_active_window); 231 SessionID::id_type ignored_active_window);
205 232
206 // Converts a SessionWindow into a Window, returning true on success. We use 0 233 // Converts a SessionWindow into a Window, returning true on success. We use 0
207 // as the timestamp here since we do not know when the window/tab was closed. 234 // as the timestamp here since we do not know when the window/tab was closed.
208 static bool ConvertSessionWindowToWindow(SessionWindow* session_window, 235 static bool ConvertSessionWindowToWindow(SessionWindow* session_window,
209 Window* window); 236 Window* window);
210 237
211 // Invoked when previous tabs or session is loaded. If both have finished 238 // Invoked when previous tabs or session is loaded. If both have finished
212 // loading the entries in |staging_entries_| are added to entries and 239 // loading the entries in |staging_entries_| are added to entries and
213 // observers are notified. 240 // observers are notified.
214 void LoadStateChanged(); 241 void LoadStateChanged();
215 242
216 // If |id_to_entry| contains an entry for |id| the corresponding entry is
217 // deleted and removed from both |id_to_entry| and |entries|. This is used
218 // when creating entries from the backend file.
219 void RemoveEntryByID(SessionID::id_type id,
220 IDToEntry* id_to_entry,
221 std::vector<TabRestoreService::Entry*>* entries);
222
223 private: 243 private:
224 // The associated client. 244 // The associated client.
225 TabRestoreServiceClient* client_; 245 TabRestoreServiceClient* client_;
226 246
227 std::unique_ptr<BaseSessionService> base_session_service_; 247 std::unique_ptr<BaseSessionService> base_session_service_;
228 248
229 TabRestoreServiceHelper* tab_restore_service_helper_; 249 TabRestoreServiceHelper* tab_restore_service_helper_;
230 250
231 // The number of entries to write. 251 // The number of entries to write.
232 int entries_to_write_; 252 int entries_to_write_;
233 253
234 // Number of entries we've written. 254 // Number of entries we've written.
235 int entries_written_; 255 int entries_written_;
236 256
237 // Whether we've loaded the last session. 257 // Whether we've loaded the last session.
238 int load_state_; 258 int load_state_;
239 259
240 // Results from previously closed tabs/sessions is first added here. When the 260 // Results from previously closed tabs/sessions is first added here. When the
241 // results from both us and the session restore service have finished loading 261 // results from both us and the session restore service have finished loading
242 // LoadStateChanged is invoked, which adds these entries to entries_. 262 // LoadStateChanged is invoked, which adds these entries to entries_.
243 ScopedVector<Entry> staging_entries_; 263 std::vector<std::unique_ptr<Entry>> staging_entries_;
244 264
245 // Used when loading previous tabs/session and open tabs/session. 265 // Used when loading previous tabs/session and open tabs/session.
246 base::CancelableTaskTracker cancelable_task_tracker_; 266 base::CancelableTaskTracker cancelable_task_tracker_;
247 267
248 DISALLOW_COPY_AND_ASSIGN(Delegate); 268 DISALLOW_COPY_AND_ASSIGN(Delegate);
249 }; 269 };
250 270
251 PersistentTabRestoreService::Delegate::Delegate(TabRestoreServiceClient* client) 271 PersistentTabRestoreService::Delegate::Delegate(TabRestoreServiceClient* client)
252 : client_(client), 272 : client_(client),
253 base_session_service_( 273 base_session_service_(
(...skipping 26 matching lines...) Expand all
280 base_session_service_->set_pending_reset(true); 300 base_session_service_->set_pending_reset(true);
281 } 301 }
282 if (to_write_count) { 302 if (to_write_count) {
283 // Write the to_write_count most recently added entries out. The most 303 // Write the to_write_count most recently added entries out. The most
284 // recently added entry is at the front, so we use a reverse iterator to 304 // recently added entry is at the front, so we use a reverse iterator to
285 // write in the order the entries were added. 305 // write in the order the entries were added.
286 Entries::const_reverse_iterator i = entries.rbegin(); 306 Entries::const_reverse_iterator i = entries.rbegin();
287 DCHECK(static_cast<size_t>(to_write_count) <= entries.size()); 307 DCHECK(static_cast<size_t>(to_write_count) <= entries.size());
288 std::advance(i, entries.size() - static_cast<int>(to_write_count)); 308 std::advance(i, entries.size() - static_cast<int>(to_write_count));
289 for (; i != entries.rend(); ++i) { 309 for (; i != entries.rend(); ++i) {
290 Entry* entry = *i; 310 Entry& entry = **i;
291 if (entry->type == TAB) { 311 switch (entry.type) {
292 Tab* tab = static_cast<Tab*>(entry); 312 case TAB: {
293 int selected_index = GetSelectedNavigationIndexToPersist(*tab); 313 Tab& tab = static_cast<Tab&>(entry);
294 if (selected_index != -1) 314 int selected_index = GetSelectedNavigationIndexToPersist(tab);
295 ScheduleCommandsForTab(*tab, selected_index); 315 if (selected_index != -1)
296 } else { 316 ScheduleCommandsForTab(tab, selected_index);
297 ScheduleCommandsForWindow(*static_cast<Window*>(entry)); 317 break;
318 }
319 case WINDOW:
320 ScheduleCommandsForWindow(static_cast<Window&>(entry));
321 break;
298 } 322 }
299 entries_written_++; 323 entries_written_++;
300 } 324 }
301 } 325 }
302 if (base_session_service_->pending_reset()) 326 if (base_session_service_->pending_reset())
303 entries_written_ = 0; 327 entries_written_ = 0;
304 } 328 }
305 329
306 void PersistentTabRestoreService::Delegate::OnClearEntries() { 330 void PersistentTabRestoreService::Delegate::OnClearEntries() {
307 // Mark all the tabs as closed so that we don't attempt to restore them. 331 // Mark all the tabs as closed so that we don't attempt to restore them.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 base_session_service_->DeleteLastSession(); 397 base_session_service_->DeleteLastSession();
374 } 398 }
375 399
376 bool PersistentTabRestoreService::Delegate::IsLoaded() const { 400 bool PersistentTabRestoreService::Delegate::IsLoaded() const {
377 return !(load_state_ & (NOT_LOADED | LOADING)); 401 return !(load_state_ & (NOT_LOADED | LOADING));
378 } 402 }
379 403
380 // static 404 // static
381 void PersistentTabRestoreService::Delegate::CreateEntriesFromWindows( 405 void PersistentTabRestoreService::Delegate::CreateEntriesFromWindows(
382 std::vector<SessionWindow*>* windows, 406 std::vector<SessionWindow*>* windows,
383 std::vector<Entry*>* entries) { 407 std::vector<std::unique_ptr<Entry>>* entries) {
384 for (size_t i = 0; i < windows->size(); ++i) { 408 for (size_t i = 0; i < windows->size(); ++i) {
385 std::unique_ptr<Window> window(new Window()); 409 std::unique_ptr<Window> window(new Window());
386 if (ConvertSessionWindowToWindow((*windows)[i], window.get())) 410 if (ConvertSessionWindowToWindow((*windows)[i], window.get()))
387 entries->push_back(window.release()); 411 entries->push_back(std::move(window));
388 } 412 }
389 } 413 }
390 414
391 void PersistentTabRestoreService::Delegate::Shutdown() { 415 void PersistentTabRestoreService::Delegate::Shutdown() {
392 base_session_service_->Save(); 416 base_session_service_->Save();
393 } 417 }
394 418
395 void PersistentTabRestoreService::Delegate::ScheduleCommandsForWindow( 419 void PersistentTabRestoreService::Delegate::ScheduleCommandsForWindow(
396 const Window& window) { 420 const Window& window) {
397 DCHECK(!window.tabs.empty()); 421 DCHECK(!window.tabs.empty());
398 int selected_tab = window.selected_tab_index; 422 int selected_tab = window.selected_tab_index;
399 int valid_tab_count = 0; 423 int valid_tab_count = 0;
400 int real_selected_tab = selected_tab; 424 int real_selected_tab = selected_tab;
401 for (size_t i = 0; i < window.tabs.size(); ++i) { 425 for (size_t i = 0; i < window.tabs.size(); ++i) {
402 if (GetSelectedNavigationIndexToPersist(window.tabs[i]) != -1) { 426 if (GetSelectedNavigationIndexToPersist(*window.tabs[i]) != -1) {
403 valid_tab_count++; 427 valid_tab_count++;
404 } else if (static_cast<int>(i) < selected_tab) { 428 } else if (static_cast<int>(i) < selected_tab) {
405 real_selected_tab--; 429 real_selected_tab--;
406 } 430 }
407 } 431 }
408 if (valid_tab_count == 0) 432 if (valid_tab_count == 0)
409 return; // No tabs to persist. 433 return; // No tabs to persist.
410 434
411 base_session_service_->ScheduleCommand(CreateWindowCommand( 435 base_session_service_->ScheduleCommand(CreateWindowCommand(
412 window.id, std::min(real_selected_tab, valid_tab_count - 1), 436 window.id, std::min(real_selected_tab, valid_tab_count - 1),
413 valid_tab_count, window.timestamp)); 437 valid_tab_count, window.timestamp));
414 438
415 if (!window.app_name.empty()) { 439 if (!window.app_name.empty()) {
416 base_session_service_->ScheduleCommand(CreateSetWindowAppNameCommand( 440 base_session_service_->ScheduleCommand(CreateSetWindowAppNameCommand(
417 kCommandSetWindowAppName, window.id, window.app_name)); 441 kCommandSetWindowAppName, window.id, window.app_name));
418 } 442 }
419 443
420 for (size_t i = 0; i < window.tabs.size(); ++i) { 444 for (size_t i = 0; i < window.tabs.size(); ++i) {
421 int selected_index = GetSelectedNavigationIndexToPersist(window.tabs[i]); 445 int selected_index = GetSelectedNavigationIndexToPersist(*window.tabs[i]);
422 if (selected_index != -1) 446 if (selected_index != -1)
423 ScheduleCommandsForTab(window.tabs[i], selected_index); 447 ScheduleCommandsForTab(*window.tabs[i], selected_index);
424 } 448 }
425 } 449 }
426 450
427 void PersistentTabRestoreService::Delegate::ScheduleCommandsForTab( 451 void PersistentTabRestoreService::Delegate::ScheduleCommandsForTab(
428 const Tab& tab, 452 const Tab& tab,
429 int selected_index) { 453 int selected_index) {
430 const std::vector<SerializedNavigationEntry>& navigations = tab.navigations; 454 const std::vector<SerializedNavigationEntry>& navigations = tab.navigations;
431 int max_index = static_cast<int>(navigations.size()); 455 int max_index = static_cast<int>(navigations.size());
432 456
433 // Determine the first navigation we'll persist. 457 // Determine the first navigation we'll persist.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 !client_->ShouldTrackURLForRestore( 572 !client_->ShouldTrackURLForRestore(
549 navigations[selected_index].virtual_url())) { 573 navigations[selected_index].virtual_url())) {
550 selected_index++; 574 selected_index++;
551 } 575 }
552 576
553 return (selected_index == max_index) ? -1 : selected_index; 577 return (selected_index == max_index) ? -1 : selected_index;
554 } 578 }
555 579
556 void PersistentTabRestoreService::Delegate::OnGotLastSessionCommands( 580 void PersistentTabRestoreService::Delegate::OnGotLastSessionCommands(
557 ScopedVector<SessionCommand> commands) { 581 ScopedVector<SessionCommand> commands) {
558 std::vector<Entry*> entries; 582 std::vector<std::unique_ptr<TabRestoreService::Entry>> entries;
559 CreateEntriesFromCommands(commands.get(), &entries); 583 CreateEntriesFromCommands(commands.get(), &entries);
560 // Closed tabs always go to the end. 584 // Closed tabs always go to the end.
561 staging_entries_.insert(staging_entries_.end(), entries.begin(), 585 staging_entries_.insert(staging_entries_.end(),
562 entries.end()); 586 make_move_iterator(entries.begin()),
587 make_move_iterator(entries.end()));
563 load_state_ |= LOADED_LAST_TABS; 588 load_state_ |= LOADED_LAST_TABS;
564 LoadStateChanged(); 589 LoadStateChanged();
565 } 590 }
566 591
567 void PersistentTabRestoreService::Delegate::CreateEntriesFromCommands( 592 void PersistentTabRestoreService::Delegate::CreateEntriesFromCommands(
568 const std::vector<SessionCommand*>& commands, 593 const std::vector<SessionCommand*>& commands,
569 std::vector<Entry*>* loaded_entries) { 594 std::vector<std::unique_ptr<Entry>>* loaded_entries) {
570 if (tab_restore_service_helper_->entries().size() == kMaxEntries) 595 if (tab_restore_service_helper_->entries().size() == kMaxEntries)
571 return; 596 return;
572 597
573 // Iterate through the commands populating entries and id_to_entry. 598 // Iterate through the commands, populating |entries|.
574 ScopedVector<Entry> entries; 599 std::vector<std::unique_ptr<Entry>> entries;
575 IDToEntry id_to_entry;
576 // If non-null we're processing the navigations of this tab. 600 // If non-null we're processing the navigations of this tab.
577 Tab* current_tab = NULL; 601 Tab* current_tab = nullptr;
578 // If non-null we're processing the tabs of this window. 602 // If non-null we're processing the tabs of this window.
579 Window* current_window = NULL; 603 Window* current_window = nullptr;
580 // If > 0, we've gotten a window command but not all the tabs yet. 604 // If > 0, we've gotten a window command but not all the tabs yet.
581 int pending_window_tabs = 0; 605 int pending_window_tabs = 0;
582 for (std::vector<SessionCommand*>::const_iterator i = commands.begin(); 606 for (std::vector<SessionCommand*>::const_iterator i = commands.begin();
583 i != commands.end(); ++i) { 607 i != commands.end(); ++i) {
584 const SessionCommand& command = *(*i); 608 const SessionCommand& command = *(*i);
585 switch (command.id()) { 609 switch (command.id()) {
586 case kCommandRestoredEntry: { 610 case kCommandRestoredEntry: {
587 if (pending_window_tabs > 0) { 611 if (pending_window_tabs > 0) {
588 // Should never receive a restored command while waiting for all the 612 // Should never receive a restored command while waiting for all the
589 // tabs in a window. 613 // tabs in a window.
590 return; 614 return;
591 } 615 }
592 616
593 current_tab = NULL; 617 current_tab = nullptr;
594 current_window = NULL; 618 current_window = nullptr;
595 619
596 RestoredEntryPayload payload; 620 RestoredEntryPayload payload;
597 if (!command.GetPayload(&payload, sizeof(payload))) 621 if (!command.GetPayload(&payload, sizeof(payload)))
598 return; 622 return;
599 RemoveEntryByID(payload, &id_to_entry, &(entries.get())); 623 RemoveEntryByID(payload, &entries);
600 break; 624 break;
601 } 625 }
602 626
603 case kCommandWindow: { 627 case kCommandWindow: {
604 WindowPayload2 payload; 628 WindowPayload2 payload;
605 if (pending_window_tabs > 0) { 629 if (pending_window_tabs > 0) {
606 // Should never receive a window command while waiting for all the 630 // Should never receive a window command while waiting for all the
607 // tabs in a window. 631 // tabs in a window.
608 return; 632 return;
609 } 633 }
(...skipping 13 matching lines...) Expand all
623 // unknown timestamp. 647 // unknown timestamp.
624 payload.timestamp = 0; 648 payload.timestamp = 0;
625 } 649 }
626 650
627 pending_window_tabs = payload.num_tabs; 651 pending_window_tabs = payload.num_tabs;
628 if (pending_window_tabs <= 0) { 652 if (pending_window_tabs <= 0) {
629 // Should always have at least 1 tab. Likely indicates corruption. 653 // Should always have at least 1 tab. Likely indicates corruption.
630 return; 654 return;
631 } 655 }
632 656
633 RemoveEntryByID(payload.window_id, &id_to_entry, &(entries.get())); 657 RemoveEntryByID(payload.window_id, &entries);
634 658
635 current_window = new Window(); 659 entries.push_back(base::MakeUnique<Window>());
660 current_window = static_cast<Window*>(entries.back().get());
636 current_window->selected_tab_index = payload.selected_tab_index; 661 current_window->selected_tab_index = payload.selected_tab_index;
637 current_window->timestamp = 662 current_window->timestamp =
638 base::Time::FromInternalValue(payload.timestamp); 663 base::Time::FromInternalValue(payload.timestamp);
639 entries.push_back(current_window);
640 id_to_entry[payload.window_id] = current_window;
641 break; 664 break;
642 } 665 }
643 666
644 case kCommandSelectedNavigationInTab: { 667 case kCommandSelectedNavigationInTab: {
645 SelectedNavigationInTabPayload2 payload; 668 SelectedNavigationInTabPayload2 payload;
646 if (!command.GetPayload(&payload, sizeof(payload))) { 669 if (!command.GetPayload(&payload, sizeof(payload))) {
647 SelectedNavigationInTabPayload old_payload; 670 SelectedNavigationInTabPayload old_payload;
648 if (!command.GetPayload(&old_payload, sizeof(old_payload))) 671 if (!command.GetPayload(&old_payload, sizeof(old_payload)))
649 return; 672 return;
650 payload.id = old_payload.id; 673 payload.id = old_payload.id;
651 payload.index = old_payload.index; 674 payload.index = old_payload.index;
652 // Since we don't have a time use time 0 which is used to mark as an 675 // Since we don't have a time use time 0 which is used to mark as an
653 // unknown timestamp. 676 // unknown timestamp.
654 payload.timestamp = 0; 677 payload.timestamp = 0;
655 } 678 }
656 679
657 if (pending_window_tabs > 0) { 680 if (pending_window_tabs > 0) {
658 if (!current_window) { 681 if (!current_window) {
659 // We should have created a window already. 682 // We should have created a window already.
660 NOTREACHED(); 683 NOTREACHED();
661 return; 684 return;
662 } 685 }
663 current_window->tabs.resize(current_window->tabs.size() + 1); 686 current_window->tabs.push_back(base::MakeUnique<Tab>());
664 current_tab = &(current_window->tabs.back()); 687 current_tab = current_window->tabs.back().get();
665 if (--pending_window_tabs == 0) 688 if (--pending_window_tabs == 0)
666 current_window = NULL; 689 current_window = nullptr;
667 } else { 690 } else {
668 RemoveEntryByID(payload.id, &id_to_entry, &(entries.get())); 691 RemoveEntryByID(payload.id, &entries);
669 current_tab = new Tab(); 692 entries.push_back(base::MakeUnique<Tab>());
670 id_to_entry[payload.id] = current_tab; 693 current_tab = static_cast<Tab*>(entries.back().get());
671 current_tab->timestamp = 694 current_tab->timestamp =
672 base::Time::FromInternalValue(payload.timestamp); 695 base::Time::FromInternalValue(payload.timestamp);
673 entries.push_back(current_tab);
674 } 696 }
675 current_tab->current_navigation_index = payload.index; 697 current_tab->current_navigation_index = payload.index;
676 break; 698 break;
677 } 699 }
678 700
679 case kCommandUpdateTabNavigation: { 701 case kCommandUpdateTabNavigation: {
680 if (!current_tab) { 702 if (!current_tab) {
681 // Should be in a tab when we get this. 703 // Should be in a tab when we get this.
682 return; 704 return;
683 } 705 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 break; 772 break;
751 } 773 }
752 774
753 default: 775 default:
754 // Unknown type, usually indicates corruption of file. Ignore it. 776 // Unknown type, usually indicates corruption of file. Ignore it.
755 return; 777 return;
756 } 778 }
757 } 779 }
758 780
759 // If there was corruption some of the entries won't be valid. 781 // If there was corruption some of the entries won't be valid.
760 ValidateAndDeleteEmptyEntries(&(entries.get())); 782 ValidateAndDeleteEmptyEntries(&entries);
761 783
762 loaded_entries->swap(entries.get()); 784 loaded_entries->swap(entries);
763 } 785 }
764 786
765 // static 787 // static
766 void PersistentTabRestoreService::Delegate::ValidateAndDeleteEmptyEntries( 788 void PersistentTabRestoreService::Delegate::ValidateAndDeleteEmptyEntries(
767 std::vector<Entry*>* entries) { 789 std::vector<std::unique_ptr<Entry>>* entries) {
768 std::vector<Entry*> valid_entries; 790 std::vector<std::unique_ptr<Entry>> valid_entries;
769 std::vector<Entry*> invalid_entries;
770 791
771 // Iterate from the back so that we keep the most recently closed entries. 792 // Iterate from the back so that we keep the most recently closed entries.
772 for (std::vector<Entry*>::reverse_iterator i = entries->rbegin(); 793 for (auto i = entries->rbegin(); i != entries->rend(); ++i) {
773 i != entries->rend(); ++i) { 794 if (TabRestoreServiceHelper::ValidateEntry(**i))
774 if (TabRestoreServiceHelper::ValidateEntry(*i)) 795 valid_entries.push_back(std::move(*i));
775 valid_entries.push_back(*i);
776 else
777 invalid_entries.push_back(*i);
778 } 796 }
779 // NOTE: at this point the entries are ordered with newest at the front. 797 // NOTE: at this point the entries are ordered with newest at the front.
780 entries->swap(valid_entries); 798 entries->swap(valid_entries);
781
782 // Delete the remaining entries.
783 STLDeleteElements(&invalid_entries);
784 } 799 }
785 800
786 void PersistentTabRestoreService::Delegate::OnGotPreviousSession( 801 void PersistentTabRestoreService::Delegate::OnGotPreviousSession(
787 ScopedVector<SessionWindow> windows, 802 ScopedVector<SessionWindow> windows,
788 SessionID::id_type ignored_active_window) { 803 SessionID::id_type ignored_active_window) {
789 std::vector<Entry*> entries; 804 std::vector<std::unique_ptr<Entry>> entries;
790 CreateEntriesFromWindows(&windows.get(), &entries); 805 CreateEntriesFromWindows(&windows.get(), &entries);
791 // Previous session tabs go first. 806 // Previous session tabs go first.
792 staging_entries_.insert(staging_entries_.begin(), entries.begin(), 807 staging_entries_.insert(staging_entries_.begin(),
793 entries.end()); 808 make_move_iterator(entries.begin()),
809 make_move_iterator(entries.end()));
794 load_state_ |= LOADED_LAST_SESSION; 810 load_state_ |= LOADED_LAST_SESSION;
795 LoadStateChanged(); 811 LoadStateChanged();
796 } 812 }
797 813
798 bool PersistentTabRestoreService::Delegate::ConvertSessionWindowToWindow( 814 bool PersistentTabRestoreService::Delegate::ConvertSessionWindowToWindow(
799 SessionWindow* session_window, 815 SessionWindow* session_window,
800 Window* window) { 816 Window* window) {
801 for (size_t i = 0; i < session_window->tabs.size(); ++i) { 817 for (size_t i = 0; i < session_window->tabs.size(); ++i) {
802 if (!session_window->tabs[i]->navigations.empty()) { 818 if (!session_window->tabs[i]->navigations.empty()) {
803 window->tabs.resize(window->tabs.size() + 1); 819 window->tabs.push_back(base::MakeUnique<Tab>());
804 Tab& tab = window->tabs.back(); 820 Tab& tab = *window->tabs.back();
805 tab.pinned = session_window->tabs[i]->pinned; 821 tab.pinned = session_window->tabs[i]->pinned;
806 tab.navigations.swap(session_window->tabs[i]->navigations); 822 tab.navigations.swap(session_window->tabs[i]->navigations);
807 tab.current_navigation_index = 823 tab.current_navigation_index =
808 session_window->tabs[i]->current_navigation_index; 824 session_window->tabs[i]->current_navigation_index;
809 tab.extension_app_id = session_window->tabs[i]->extension_app_id; 825 tab.extension_app_id = session_window->tabs[i]->extension_app_id;
810 tab.timestamp = base::Time(); 826 tab.timestamp = base::Time();
811 } 827 }
812 } 828 }
813 if (window->tabs.empty()) 829 if (window->tabs.empty())
814 return false; 830 return false;
(...skipping 28 matching lines...) Expand all
843 // kMaxEntries. 859 // kMaxEntries.
844 int surplus = kMaxEntries - entries.size(); 860 int surplus = kMaxEntries - entries.size();
845 CHECK_LE(0, surplus); 861 CHECK_LE(0, surplus);
846 CHECK_GE(static_cast<int>(staging_entries_.size()), surplus); 862 CHECK_GE(static_cast<int>(staging_entries_.size()), surplus);
847 staging_entries_.erase( 863 staging_entries_.erase(
848 staging_entries_.begin() + (kMaxEntries - entries.size()), 864 staging_entries_.begin() + (kMaxEntries - entries.size()),
849 staging_entries_.end()); 865 staging_entries_.end());
850 } 866 }
851 867
852 // And add them. 868 // And add them.
853 for (size_t i = 0; i < staging_entries_.size(); ++i) { 869 for (auto& staging_entry : staging_entries_) {
854 staging_entries_[i]->from_last_session = true; 870 staging_entry->from_last_session = true;
855 tab_restore_service_helper_->AddEntry(staging_entries_[i], false, false); 871 tab_restore_service_helper_->AddEntry(std::move(staging_entry), false,
872 false);
856 } 873 }
857 874
858 // AddEntry takes ownership of the entry, need to clear out entries so that 875 staging_entries_.clear();
859 // it doesn't delete them. 876 entries_to_write_ = 0;
860 staging_entries_.weak_clear();
861
862 // Make it so we rewrite all the tabs. We need to do this otherwise we won't
863 // correctly write out the entries when Save is invoked (Save starts from
864 // the front, not the end and we just added the entries to the end).
865 entries_to_write_ = staging_entries_.size();
866 877
867 tab_restore_service_helper_->PruneEntries(); 878 tab_restore_service_helper_->PruneEntries();
868 tab_restore_service_helper_->NotifyTabsChanged(); 879 tab_restore_service_helper_->NotifyTabsChanged();
869 880
870 tab_restore_service_helper_->NotifyLoaded(); 881 tab_restore_service_helper_->NotifyLoaded();
871 } 882 }
872 883
873 void PersistentTabRestoreService::Delegate::RemoveEntryByID(
874 SessionID::id_type id,
875 IDToEntry* id_to_entry,
876 std::vector<TabRestoreService::Entry*>* entries) {
877 // Look for the entry in the map. If it is present, erase it from both
878 // collections and return.
879 IDToEntry::iterator i = id_to_entry->find(id);
880 if (i != id_to_entry->end()) {
881 entries->erase(std::find(entries->begin(), entries->end(), i->second));
882 delete i->second;
883 id_to_entry->erase(i);
884 return;
885 }
886
887 // Otherwise, loop over all items in the map and see if any of the Windows
888 // have Tabs with the |id|.
889 for (IDToEntry::iterator i = id_to_entry->begin(); i != id_to_entry->end();
890 ++i) {
891 if (i->second->type == TabRestoreService::WINDOW) {
892 TabRestoreService::Window* window =
893 static_cast<TabRestoreService::Window*>(i->second);
894 std::vector<TabRestoreService::Tab>::iterator j = window->tabs.begin();
895 for ( ; j != window->tabs.end(); ++j) {
896 // If the ID matches one of this window's tabs, remove it from the
897 // list.
898 if ((*j).id == id) {
899 window->tabs.erase(j);
900 return;
901 }
902 }
903 }
904 }
905 }
906
907 // PersistentTabRestoreService ------------------------------------------------- 884 // PersistentTabRestoreService -------------------------------------------------
908 885
909 PersistentTabRestoreService::PersistentTabRestoreService( 886 PersistentTabRestoreService::PersistentTabRestoreService(
910 std::unique_ptr<TabRestoreServiceClient> client, 887 std::unique_ptr<TabRestoreServiceClient> client,
911 TimeFactory* time_factory) 888 TimeFactory* time_factory)
912 : client_(std::move(client)), 889 : client_(std::move(client)),
913 delegate_(new Delegate(client_.get())), 890 delegate_(new Delegate(client_.get())),
914 helper_(this, delegate_.get(), client_.get(), time_factory) { 891 helper_(this, delegate_.get(), client_.get(), time_factory) {
915 delegate_->set_tab_restore_service_helper(&helper_); 892 delegate_->set_tab_restore_service_helper(&helper_);
916 } 893 }
(...skipping 29 matching lines...) Expand all
946 923
947 const TabRestoreService::Entries& PersistentTabRestoreService::entries() const { 924 const TabRestoreService::Entries& PersistentTabRestoreService::entries() const {
948 return helper_.entries(); 925 return helper_.entries();
949 } 926 }
950 927
951 std::vector<LiveTab*> PersistentTabRestoreService::RestoreMostRecentEntry( 928 std::vector<LiveTab*> PersistentTabRestoreService::RestoreMostRecentEntry(
952 LiveTabContext* context) { 929 LiveTabContext* context) {
953 return helper_.RestoreMostRecentEntry(context); 930 return helper_.RestoreMostRecentEntry(context);
954 } 931 }
955 932
956 TabRestoreService::Tab* PersistentTabRestoreService::RemoveTabEntryById( 933 std::unique_ptr<TabRestoreService::Tab>
957 SessionID::id_type id) { 934 PersistentTabRestoreService::RemoveTabEntryById(SessionID::id_type id) {
958 return helper_.RemoveTabEntryById(id); 935 return helper_.RemoveTabEntryById(id);
959 } 936 }
960 937
961 std::vector<LiveTab*> PersistentTabRestoreService::RestoreEntryById( 938 std::vector<LiveTab*> PersistentTabRestoreService::RestoreEntryById(
962 LiveTabContext* context, 939 LiveTabContext* context,
963 SessionID::id_type id, 940 SessionID::id_type id,
964 WindowOpenDisposition disposition) { 941 WindowOpenDisposition disposition) {
965 return helper_.RestoreEntryById(context, id, disposition); 942 return helper_.RestoreEntryById(context, id, disposition);
966 } 943 }
967 944
(...skipping 15 matching lines...) Expand all
983 960
984 TabRestoreService::Entries* PersistentTabRestoreService::mutable_entries() { 961 TabRestoreService::Entries* PersistentTabRestoreService::mutable_entries() {
985 return &helper_.entries_; 962 return &helper_.entries_;
986 } 963 }
987 964
988 void PersistentTabRestoreService::PruneEntries() { 965 void PersistentTabRestoreService::PruneEntries() {
989 helper_.PruneEntries(); 966 helper_.PruneEntries();
990 } 967 }
991 968
992 } // namespace sessions 969 } // namespace sessions
OLDNEW
« no previous file with comments | « components/sessions/core/persistent_tab_restore_service.h ('k') | components/sessions/core/tab_restore_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698