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

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

Issue 2868983003: Ensure History > Recent Tabs restore preserves window disposition. (Closed)
Patch Set: Remove NOTREACHED(). Created 3 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>
(...skipping 27 matching lines...) Expand all
38 // 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
39 // 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.
40 struct SelectedNavigationInTabPayload { 40 struct SelectedNavigationInTabPayload {
41 SessionID::id_type id; 41 SessionID::id_type id;
42 int32_t index; 42 int32_t index;
43 }; 43 };
44 44
45 // 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
46 // 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
47 // struct must be POD, because we memset the contents. 47 // struct must be POD, because we memset the contents.
48 struct WindowPayload { 48 struct WindowPayloadObsolete {
49 SessionID::id_type window_id; 49 SessionID::id_type window_id;
50 int32_t selected_tab_index; 50 int32_t selected_tab_index;
51 int32_t num_tabs; 51 int32_t num_tabs;
52 }; 52 };
53 53
54 // Payload used for the start of a window close. This struct must be POD, 54 // Payload used for the start of a window close. This struct must be POD,
55 // because we memset the contents. 55 // because we memset the contents. This is an older version of the struct that
56 struct WindowPayload2 : WindowPayload { 56 // is used for backwards compat when it comes to reading the session files.
57 struct WindowPayloadObsolete2 : WindowPayloadObsolete {
57 int64_t timestamp; 58 int64_t timestamp;
58 }; 59 };
59 60
60 // Payload used for the start of a tab close. 61 // Payload used for the start of a tab close.
61 struct SelectedNavigationInTabPayload2 : SelectedNavigationInTabPayload { 62 struct SelectedNavigationInTabPayload2 : SelectedNavigationInTabPayload {
62 int64_t timestamp; 63 int64_t timestamp;
63 }; 64 };
64 65
65 // Used to indicate what has loaded. 66 // Used to indicate what has loaded.
66 enum LoadState { 67 enum LoadState {
(...skipping 22 matching lines...) Expand all
89 // the user agent override if it was using one. This is 90 // the user agent override if it was using one. This is
90 // followed by any number of kCommandUpdateTabNavigation commands (1 per 91 // followed by any number of kCommandUpdateTabNavigation commands (1 per
91 // navigation entry). 92 // navigation entry).
92 // . When the user closes a window a kCommandSelectedNavigationInTab command 93 // . When the user closes a window a kCommandSelectedNavigationInTab command
93 // is written out and followed by n tab closed sequences (as previoulsy 94 // is written out and followed by n tab closed sequences (as previoulsy
94 // described). 95 // described).
95 // . When the user restores an entry a command of type kCommandRestoredEntry 96 // . When the user restores an entry a command of type kCommandRestoredEntry
96 // is written. 97 // is written.
97 const SessionCommand::id_type kCommandUpdateTabNavigation = 1; 98 const SessionCommand::id_type kCommandUpdateTabNavigation = 1;
98 const SessionCommand::id_type kCommandRestoredEntry = 2; 99 const SessionCommand::id_type kCommandRestoredEntry = 2;
99 const SessionCommand::id_type kCommandWindow = 3; 100 const SessionCommand::id_type kCommandWindowDeprecated = 3;
100 const SessionCommand::id_type kCommandSelectedNavigationInTab = 4; 101 const SessionCommand::id_type kCommandSelectedNavigationInTab = 4;
101 const SessionCommand::id_type kCommandPinnedState = 5; 102 const SessionCommand::id_type kCommandPinnedState = 5;
102 const SessionCommand::id_type kCommandSetExtensionAppID = 6; 103 const SessionCommand::id_type kCommandSetExtensionAppID = 6;
103 const SessionCommand::id_type kCommandSetWindowAppName = 7; 104 const SessionCommand::id_type kCommandSetWindowAppName = 7;
104 const SessionCommand::id_type kCommandSetTabUserAgentOverride = 8; 105 const SessionCommand::id_type kCommandSetTabUserAgentOverride = 8;
106 const SessionCommand::id_type kCommandWindow = 9;
105 107
106 // Number of entries (not commands) before we clobber the file and write 108 // Number of entries (not commands) before we clobber the file and write
107 // everything. 109 // everything.
108 const int kEntriesPerReset = 40; 110 const int kEntriesPerReset = 40;
109 111
110 const size_t kMaxEntries = TabRestoreServiceHelper::kMaxEntries; 112 const size_t kMaxEntries = TabRestoreServiceHelper::kMaxEntries;
111 113
112 void RemoveEntryByID( 114 void RemoveEntryByID(
113 SessionID::id_type id, 115 SessionID::id_type id,
114 std::vector<std::unique_ptr<TabRestoreService::Entry>>* entries) { 116 std::vector<std::unique_ptr<TabRestoreService::Entry>>* entries) {
(...skipping 13 matching lines...) Expand all
128 // Erase it if it's our target. 130 // Erase it if it's our target.
129 if (tab.id == id) { 131 if (tab.id == id) {
130 window.tabs.erase(it); 132 window.tabs.erase(it);
131 return; 133 return;
132 } 134 }
133 } 135 }
134 } 136 }
135 } 137 }
136 } 138 }
137 139
140 // An enum that corresponds to ui::WindowShowStates. This needs to be kept in
141 // sync with that enum. Moreover, the integer values corresponding to each show
142 // state need to be stable in this enum (which is not necessarily true about the
143 // ui::WindowShowStates enum).
144 enum SerializedWindowShowState : int {
145 kSerializedShowStateInvalid = -1,
146 kSerializedShowStateDefault = 0,
147 kSerializedShowStateNormal = 1,
148 kSerializedShowStateMinimized = 2,
149 kSerializedShowStateMaximized = 3,
150 kSerializedShowStateInactive = 4,
151 kSerializedShowStateFullscreen = 5,
152 };
153
154 // Converts a window show state to an integer. This function needs to be kept
155 // up to date with the SerializedWindowShowState enum.
156 int SerializeWindowShowState(ui::WindowShowState show_state) {
157 switch (show_state) {
158 case ui::SHOW_STATE_DEFAULT:
159 return kSerializedShowStateDefault;
160 case ui::SHOW_STATE_NORMAL:
161 return kSerializedShowStateNormal;
162 case ui::SHOW_STATE_MINIMIZED:
163 return kSerializedShowStateMinimized;
164 case ui::SHOW_STATE_MAXIMIZED:
165 return kSerializedShowStateMaximized;
166 case ui::SHOW_STATE_INACTIVE:
167 return kSerializedShowStateInactive;
168 case ui::SHOW_STATE_FULLSCREEN:
169 return kSerializedShowStateFullscreen;
170 case ui::SHOW_STATE_END:
171 // This should never happen.
172 NOTREACHED();
173 }
174 return kSerializedShowStateInvalid;
175 }
176
177 // Converts an integer to a window show state. Returns true on success, false
178 // otherwise. This function needs to be kept up to date with the
179 // SerializedWindowShowState enum.
180 bool DeserializeWindowShowState(int show_state_int,
181 ui::WindowShowState* show_state) {
182 switch (static_cast<SerializedWindowShowState>(show_state_int)) {
183 case kSerializedShowStateDefault:
184 *show_state = ui::SHOW_STATE_DEFAULT;
185 return true;
186 case kSerializedShowStateNormal:
187 *show_state = ui::SHOW_STATE_NORMAL;
188 return true;
189 case kSerializedShowStateMinimized:
190 *show_state = ui::SHOW_STATE_MINIMIZED;
191 return true;
192 case kSerializedShowStateMaximized:
193 *show_state = ui::SHOW_STATE_MAXIMIZED;
194 return true;
195 case kSerializedShowStateInactive:
196 *show_state = ui::SHOW_STATE_INACTIVE;
197 return true;
198 case kSerializedShowStateFullscreen:
199 *show_state = ui::SHOW_STATE_FULLSCREEN;
200 return true;
201 case kSerializedShowStateInvalid:
202 default:
203 // Ignore unknown values. This could happen if the data is corrupt.
204 break;
205 }
206 return false;
207 }
208
209 // Superset of WindowPayloadObsolete/WindowPayloadObsolete2 and the other fields
210 // that can appear in the Pickle version of a Window command. This is used as a
211 // convenient destination for parsing the various fields in a WindowCommand.
212 struct WindowCommandFields {
213 // Fields in WindowPayloadObsolete/WindowPayloadObsolete2/Pickle:
214 int window_id = 0;
215 int selected_tab_index = 0;
216 int num_tabs = 0;
217
218 // Fields in WindowPayloadObsolete2/Pickle:
219 int64_t timestamp = 0;
220
221 // Fields in Pickle:
222 // Completely zeroed position/dimensions indicates that defaults should be
223 // used.
224 int window_x = 0;
225 int window_y = 0;
226 int window_width = 0;
227 int window_height = 0;
228 int window_show_state = 0;
229 std::string workspace;
230 };
231
232 std::unique_ptr<sessions::TabRestoreService::Window>
233 CreateWindowEntryFromCommand(const SessionCommand* command,
234 SessionID::id_type* window_id,
235 int32_t* num_tabs) {
236 WindowCommandFields fields;
237 ui::WindowShowState show_state = ui::SHOW_STATE_DEFAULT;
238
239 if (command->id() == kCommandWindow) {
240 std::unique_ptr<base::Pickle> pickle(command->PayloadAsPickle());
241 if (!pickle.get())
242 return nullptr;
243
244 base::PickleIterator it(*pickle);
245 WindowCommandFields parsed_fields;
246
247 // The first version of the pickle contains all of the following fields, so
248 // they should all successfully parse if the command is in fact a pickle.
249 if (!it.ReadInt(&parsed_fields.window_id) ||
250 !it.ReadInt(&parsed_fields.selected_tab_index) ||
251 !it.ReadInt(&parsed_fields.num_tabs) ||
252 !it.ReadInt64(&parsed_fields.timestamp) ||
253 !it.ReadInt(&parsed_fields.window_x) ||
254 !it.ReadInt(&parsed_fields.window_y) ||
255 !it.ReadInt(&parsed_fields.window_width) ||
256 !it.ReadInt(&parsed_fields.window_height) ||
257 !it.ReadInt(&parsed_fields.window_show_state) ||
258 !it.ReadString(&parsed_fields.workspace)) {
259 return nullptr;
260 }
261
262 // Validate the parameters. If the entire pickles parses but any of the
263 // validation fails assume corruption.
264 if (parsed_fields.window_width < 0 || parsed_fields.window_height < 0)
265 return nullptr;
266
267 // Deserialize the show state, validating it at the same time.
268 if (!DeserializeWindowShowState(parsed_fields.window_show_state,
269 &show_state)) {
270 return nullptr;
271 }
272
273 // New fields added to the pickle in later versions would be parsed and
274 // validated here.
275
276 // Copy the parsed data.
277 fields = parsed_fields;
278 } else if (command->id() == kCommandWindowDeprecated) {
279 // Old window commands can be in either of 2 formats. Try the newest first.
280 // These have distinct sizes so are easily distinguished.
281 bool parsed = false;
282
283 // Try to parse the command as a WindowPayloadObsolete2.
284 WindowPayloadObsolete2 payload2;
285 if (command->GetPayload(&payload2, sizeof(payload2))) {
286 fields.window_id = payload2.window_id;
287 fields.selected_tab_index = payload2.selected_tab_index;
288 fields.num_tabs = payload2.num_tabs;
289 fields.timestamp = payload2.timestamp;
290 parsed = true;
291 }
292
293 // Finally, try the oldest WindowPayloadObsolete type.
294 if (!parsed) {
295 WindowPayloadObsolete payload;
296 if (command->GetPayload(&payload, sizeof(payload))) {
297 fields.window_id = payload.window_id;
298 fields.selected_tab_index = payload.selected_tab_index;
299 fields.num_tabs = payload.num_tabs;
300 parsed = true;
301 }
302 }
303
304 // Fail if the old command wasn't able to be parsed in either of the
305 // deprecated formats.
306 if (!parsed)
307 return nullptr;
308 } else {
309 // This should never be called with anything other than a known window
310 // command ID.
311 NOTREACHED();
312 }
313
314 // Create the Window entry.
315 std::unique_ptr<sessions::TabRestoreService::Window> window =
316 base::MakeUnique<sessions::TabRestoreService::Window>();
317 window->selected_tab_index = fields.selected_tab_index;
318 window->timestamp = base::Time::FromInternalValue(fields.timestamp);
319 *window_id = static_cast<SessionID::id_type>(fields.window_id);
320 *num_tabs = fields.num_tabs;
321
322 // Set the bounds, show state and workspace if valid ones have been provided.
323 if (!(fields.window_x == 0 && fields.window_y == 0 &&
324 fields.window_width == 0 && fields.window_height == 0)) {
325 window->bounds.SetRect(fields.window_x, fields.window_y,
326 fields.window_width, fields.window_height);
327 // |show_state| was converted from window->show_state earlier during
328 // validation.
329 window->show_state = show_state;
330 window->workspace = std::move(fields.workspace);
331 }
332
333 return window;
334 }
335
138 } // namespace 336 } // namespace
139 337
140 // PersistentTabRestoreService::Delegate --------------------------------------- 338 // PersistentTabRestoreService::Delegate ---------------------------------------
141 339
142 // This restore service will create and own a BaseSessionService and implement 340 // This restore service will create and own a BaseSessionService and implement
143 // the required BaseSessionServiceDelegate. 341 // the required BaseSessionServiceDelegate.
144 class PersistentTabRestoreService::Delegate 342 class PersistentTabRestoreService::Delegate
145 : public BaseSessionServiceDelegate, 343 : public BaseSessionServiceDelegate,
146 public TabRestoreServiceHelper::Observer { 344 public TabRestoreServiceHelper::Observer {
147 public: 345 public:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 377
180 // Schedules the commands for a window close. 378 // Schedules the commands for a window close.
181 void ScheduleCommandsForWindow(const Window& window); 379 void ScheduleCommandsForWindow(const Window& window);
182 380
183 // Schedules the commands for a tab close. |selected_index| gives the index of 381 // Schedules the commands for a tab close. |selected_index| gives the index of
184 // the selected navigation. 382 // the selected navigation.
185 void ScheduleCommandsForTab(const Tab& tab, int selected_index); 383 void ScheduleCommandsForTab(const Tab& tab, int selected_index);
186 384
187 // Creates a window close command. 385 // Creates a window close command.
188 static std::unique_ptr<SessionCommand> CreateWindowCommand( 386 static std::unique_ptr<SessionCommand> CreateWindowCommand(
189 SessionID::id_type id, 387 SessionID::id_type window_id,
190 int selected_tab_index, 388 int selected_tab_index,
191 int num_tabs, 389 int num_tabs,
390 const gfx::Rect& bounds,
391 ui::WindowShowState show_state,
392 const std::string& workspace,
192 base::Time timestamp); 393 base::Time timestamp);
193 394
194 // Creates a tab close command. 395 // Creates a tab close command.
195 static std::unique_ptr<SessionCommand> CreateSelectedNavigationInTabCommand( 396 static std::unique_ptr<SessionCommand> CreateSelectedNavigationInTabCommand(
196 SessionID::id_type tab_id, 397 SessionID::id_type tab_id,
197 int32_t index, 398 int32_t index,
198 base::Time timestamp); 399 base::Time timestamp);
199 400
200 // Creates a restore command. 401 // Creates a restore command.
201 static std::unique_ptr<SessionCommand> CreateRestoredEntryCommand( 402 static std::unique_ptr<SessionCommand> CreateRestoredEntryCommand(
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 valid_tab_count++; 623 valid_tab_count++;
423 } else if (static_cast<int>(i) < selected_tab) { 624 } else if (static_cast<int>(i) < selected_tab) {
424 real_selected_tab--; 625 real_selected_tab--;
425 } 626 }
426 } 627 }
427 if (valid_tab_count == 0) 628 if (valid_tab_count == 0)
428 return; // No tabs to persist. 629 return; // No tabs to persist.
429 630
430 base_session_service_->ScheduleCommand(CreateWindowCommand( 631 base_session_service_->ScheduleCommand(CreateWindowCommand(
431 window.id, std::min(real_selected_tab, valid_tab_count - 1), 632 window.id, std::min(real_selected_tab, valid_tab_count - 1),
432 valid_tab_count, window.timestamp)); 633 valid_tab_count, window.bounds, window.show_state, window.workspace,
634 window.timestamp));
433 635
434 if (!window.app_name.empty()) { 636 if (!window.app_name.empty()) {
435 base_session_service_->ScheduleCommand(CreateSetWindowAppNameCommand( 637 base_session_service_->ScheduleCommand(CreateSetWindowAppNameCommand(
436 kCommandSetWindowAppName, window.id, window.app_name)); 638 kCommandSetWindowAppName, window.id, window.app_name));
437 } 639 }
438 640
439 for (size_t i = 0; i < window.tabs.size(); ++i) { 641 for (size_t i = 0; i < window.tabs.size(); ++i) {
440 int selected_index = GetSelectedNavigationIndexToPersist(*window.tabs[i]); 642 int selected_index = GetSelectedNavigationIndexToPersist(*window.tabs[i]);
441 if (selected_index != -1) 643 if (selected_index != -1)
442 ScheduleCommandsForTab(*window.tabs[i], selected_index); 644 ScheduleCommandsForTab(*window.tabs[i], selected_index);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation, 693 CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation,
492 tab.id, 694 tab.id,
493 navigations[i])); 695 navigations[i]));
494 } 696 }
495 } 697 }
496 } 698 }
497 699
498 // static 700 // static
499 std::unique_ptr<SessionCommand> 701 std::unique_ptr<SessionCommand>
500 PersistentTabRestoreService::Delegate::CreateWindowCommand( 702 PersistentTabRestoreService::Delegate::CreateWindowCommand(
501 SessionID::id_type id, 703 SessionID::id_type window_id,
502 int selected_tab_index, 704 int selected_tab_index,
503 int num_tabs, 705 int num_tabs,
706 const gfx::Rect& bounds,
707 ui::WindowShowState show_state,
708 const std::string& workspace,
504 base::Time timestamp) { 709 base::Time timestamp) {
505 WindowPayload2 payload; 710 static_assert(sizeof(SessionID::id_type) == sizeof(int),
506 // |timestamp| is aligned on a 16 byte boundary, leaving 4 bytes of 711 "SessionID::id_type has changed size.");
507 // uninitialized memory in the struct. 712
508 memset(&payload, 0, sizeof(payload)); 713 // Use a pickle to handle marshaling as this command contains variable-length
509 payload.window_id = id; 714 // content.
510 payload.selected_tab_index = selected_tab_index; 715 base::Pickle pickle;
511 payload.num_tabs = num_tabs; 716 pickle.WriteInt(static_cast<int>(window_id));
512 payload.timestamp = timestamp.ToInternalValue(); 717 pickle.WriteInt(selected_tab_index);
718 pickle.WriteInt(num_tabs);
719 pickle.WriteInt64(timestamp.ToInternalValue());
720 pickle.WriteInt(bounds.x());
721 pickle.WriteInt(bounds.y());
722 pickle.WriteInt(bounds.width());
723 pickle.WriteInt(bounds.height());
724 pickle.WriteInt(SerializeWindowShowState(show_state));
725
726 // Enforce a maximum length on workspace names. A common size is 32 bytes for
727 // GUIDs.
728 if (workspace.size() <= 128)
729 pickle.WriteString(workspace);
730 else
731 pickle.WriteString(std::string());
513 732
514 std::unique_ptr<SessionCommand> command( 733 std::unique_ptr<SessionCommand> command(
515 new SessionCommand(kCommandWindow, sizeof(payload))); 734 new SessionCommand(kCommandWindow, pickle));
516 memcpy(command->contents(), &payload, sizeof(payload));
517 return command; 735 return command;
518 } 736 }
519 737
520 // static 738 // static
521 std::unique_ptr<SessionCommand> 739 std::unique_ptr<SessionCommand>
522 PersistentTabRestoreService::Delegate::CreateSelectedNavigationInTabCommand( 740 PersistentTabRestoreService::Delegate::CreateSelectedNavigationInTabCommand(
523 SessionID::id_type tab_id, 741 SessionID::id_type tab_id,
524 int32_t index, 742 int32_t index,
525 base::Time timestamp) { 743 base::Time timestamp) {
526 SelectedNavigationInTabPayload2 payload; 744 SelectedNavigationInTabPayload2 payload;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 current_tab = nullptr; 829 current_tab = nullptr;
612 current_window = nullptr; 830 current_window = nullptr;
613 831
614 RestoredEntryPayload payload; 832 RestoredEntryPayload payload;
615 if (!command.GetPayload(&payload, sizeof(payload))) 833 if (!command.GetPayload(&payload, sizeof(payload)))
616 return; 834 return;
617 RemoveEntryByID(payload, &entries); 835 RemoveEntryByID(payload, &entries);
618 break; 836 break;
619 } 837 }
620 838
839 case kCommandWindowDeprecated:
621 case kCommandWindow: { 840 case kCommandWindow: {
622 WindowPayload2 payload; 841 // Should never receive a window command while waiting for all the
623 if (pending_window_tabs > 0) { 842 // tabs in a window.
624 // Should never receive a window command while waiting for all the 843 if (pending_window_tabs > 0)
625 // tabs in a window.
626 return; 844 return;
627 }
628 845
629 // Try the new payload first 846 // Try to parse the command, and silently skip if it fails.
630 if (!command.GetPayload(&payload, sizeof(payload))) { 847 int32_t num_tabs = 0;
631 // then the old payload 848 SessionID::id_type window_id = 0;
632 WindowPayload old_payload; 849 std::unique_ptr<Window> window =
633 if (!command.GetPayload(&old_payload, sizeof(old_payload))) 850 CreateWindowEntryFromCommand(&command, &window_id, &num_tabs);
634 return; 851 if (!window)
852 return;
635 853
636 // Copy the old payload data to the new payload. 854 // Should always have at least 1 tab. Likely indicates corruption.
637 payload.window_id = old_payload.window_id; 855 pending_window_tabs = num_tabs;
638 payload.selected_tab_index = old_payload.selected_tab_index; 856 if (pending_window_tabs <= 0)
639 payload.num_tabs = old_payload.num_tabs; 857 return;
640 // Since we don't have a time use time 0 which is used to mark as an
641 // unknown timestamp.
642 payload.timestamp = 0;
643 }
644 858
645 pending_window_tabs = payload.num_tabs; 859 RemoveEntryByID(window_id, &entries);
646 if (pending_window_tabs <= 0) { 860 current_window = window.get();
647 // Should always have at least 1 tab. Likely indicates corruption. 861 entries.push_back(std::move(window));
648 return;
649 }
650
651 RemoveEntryByID(payload.window_id, &entries);
652
653 entries.push_back(base::MakeUnique<Window>());
654 current_window = static_cast<Window*>(entries.back().get());
655 current_window->selected_tab_index = payload.selected_tab_index;
656 current_window->timestamp =
657 base::Time::FromInternalValue(payload.timestamp);
658 break; 862 break;
659 } 863 }
660 864
661 case kCommandSelectedNavigationInTab: { 865 case kCommandSelectedNavigationInTab: {
662 SelectedNavigationInTabPayload2 payload; 866 SelectedNavigationInTabPayload2 payload;
663 if (!command.GetPayload(&payload, sizeof(payload))) { 867 if (!command.GetPayload(&payload, sizeof(payload))) {
664 SelectedNavigationInTabPayload old_payload; 868 SelectedNavigationInTabPayload old_payload;
665 if (!command.GetPayload(&old_payload, sizeof(old_payload))) 869 if (!command.GetPayload(&old_payload, sizeof(old_payload)))
666 return; 870 return;
667 payload.id = old_payload.id; 871 payload.id = old_payload.id;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 } 971 }
768 972
769 default: 973 default:
770 // Unknown type, usually indicates corruption of file. Ignore it. 974 // Unknown type, usually indicates corruption of file. Ignore it.
771 return; 975 return;
772 } 976 }
773 } 977 }
774 978
775 // If there was corruption some of the entries won't be valid. 979 // If there was corruption some of the entries won't be valid.
776 ValidateAndDeleteEmptyEntries(&entries); 980 ValidateAndDeleteEmptyEntries(&entries);
777
778 loaded_entries->swap(entries); 981 loaded_entries->swap(entries);
779 } 982 }
780 983
781 // static 984 // static
782 void PersistentTabRestoreService::Delegate::ValidateAndDeleteEmptyEntries( 985 void PersistentTabRestoreService::Delegate::ValidateAndDeleteEmptyEntries(
783 std::vector<std::unique_ptr<Entry>>* entries) { 986 std::vector<std::unique_ptr<Entry>>* entries) {
784 std::vector<std::unique_ptr<Entry>> valid_entries; 987 std::vector<std::unique_ptr<Entry>> valid_entries;
785 988
786 // Iterate from the back so that we keep the most recently closed entries. 989 // Iterate from the back so that we keep the most recently closed entries.
787 for (auto i = entries->rbegin(); i != entries->rend(); ++i) { 990 for (auto i = entries->rbegin(); i != entries->rend(); ++i) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 tab.timestamp = base::Time(); 1023 tab.timestamp = base::Time();
821 } 1024 }
822 } 1025 }
823 if (window->tabs.empty()) 1026 if (window->tabs.empty())
824 return false; 1027 return false;
825 1028
826 window->selected_tab_index = 1029 window->selected_tab_index =
827 std::min(session_window->selected_tab_index, 1030 std::min(session_window->selected_tab_index,
828 static_cast<int>(window->tabs.size() - 1)); 1031 static_cast<int>(window->tabs.size() - 1));
829 window->timestamp = base::Time(); 1032 window->timestamp = base::Time();
1033 window->bounds = session_window->bounds;
1034 window->show_state = session_window->show_state;
1035 window->workspace = session_window->workspace;
830 return true; 1036 return true;
831 } 1037 }
832 1038
833 void PersistentTabRestoreService::Delegate::LoadStateChanged() { 1039 void PersistentTabRestoreService::Delegate::LoadStateChanged() {
834 if ((load_state_ & (LOADED_LAST_TABS | LOADED_LAST_SESSION)) != 1040 if ((load_state_ & (LOADED_LAST_TABS | LOADED_LAST_SESSION)) !=
835 (LOADED_LAST_TABS | LOADED_LAST_SESSION)) { 1041 (LOADED_LAST_TABS | LOADED_LAST_SESSION)) {
836 // Still waiting on previous session or previous tabs. 1042 // Still waiting on previous session or previous tabs.
837 return; 1043 return;
838 } 1044 }
839 1045
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 1164
959 TabRestoreService::Entries* PersistentTabRestoreService::mutable_entries() { 1165 TabRestoreService::Entries* PersistentTabRestoreService::mutable_entries() {
960 return &helper_.entries_; 1166 return &helper_.entries_;
961 } 1167 }
962 1168
963 void PersistentTabRestoreService::PruneEntries() { 1169 void PersistentTabRestoreService::PruneEntries() {
964 helper_.PruneEntries(); 1170 helper_.PruneEntries();
965 } 1171 }
966 1172
967 } // namespace sessions 1173 } // namespace sessions
OLDNEW
« no previous file with comments | « components/sessions/core/live_tab_context.h ('k') | components/sessions/core/tab_restore_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698