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

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: Address sky's comments on PS15. 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 SERIALIZED_SHOW_STATE_INVALID = -1,
sky 2017/08/14 16:43:52 Latest style is kCamelCase.
chrisha 2017/08/14 17:22:33 Done.
146 SERIALIZED_SHOW_STATE_DEFAULT = 0,
147 SERIALIZED_SHOW_STATE_NORMAL = 1,
148 SERIALIZED_SHOW_STATE_MINIMIZED = 2,
149 SERIALIZED_SHOW_STATE_MAXIMIZED = 3,
150 SERIALIZED_SHOW_STATE_INACTIVE = 4,
151 SERIALIZED_SHOW_STATE_FULLSCREEN = 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 SERIALIZED_SHOW_STATE_DEFAULT;
160 case ui::SHOW_STATE_NORMAL:
161 return SERIALIZED_SHOW_STATE_NORMAL;
162 case ui::SHOW_STATE_MINIMIZED:
163 return SERIALIZED_SHOW_STATE_MINIMIZED;
164 case ui::SHOW_STATE_MAXIMIZED:
165 return SERIALIZED_SHOW_STATE_MAXIMIZED;
166 case ui::SHOW_STATE_INACTIVE:
167 return SERIALIZED_SHOW_STATE_INACTIVE;
168 case ui::SHOW_STATE_FULLSCREEN:
169 return SERIALIZED_SHOW_STATE_FULLSCREEN;
170 case ui::SHOW_STATE_END:
171 // This should never happen.
172 NOTREACHED();
173 return SERIALIZED_SHOW_STATE_INVALID;
174 ;
sky 2017/08/14 16:43:52 remove this.
chrisha 2017/08/14 17:22:34 Done.
175 }
176 }
177
178 // Converts an integer to a window show state. Returns true on success, false
179 // otherwise. This function needs to be kept up to date with the
180 // SerializedWindowShowState enum.
181 bool DeserializeWindowShowState(int show_state_int,
182 ui::WindowShowState* show_state) {
183 switch (static_cast<SerializedWindowShowState>(show_state_int)) {
184 case SERIALIZED_SHOW_STATE_DEFAULT:
185 *show_state = ui::SHOW_STATE_DEFAULT;
186 return true;
187 case SERIALIZED_SHOW_STATE_NORMAL:
188 *show_state = ui::SHOW_STATE_NORMAL;
189 return true;
190 case SERIALIZED_SHOW_STATE_MINIMIZED:
191 *show_state = ui::SHOW_STATE_MINIMIZED;
192 return true;
193 case SERIALIZED_SHOW_STATE_MAXIMIZED:
194 *show_state = ui::SHOW_STATE_MAXIMIZED;
195 return true;
196 case SERIALIZED_SHOW_STATE_INACTIVE:
197 *show_state = ui::SHOW_STATE_INACTIVE;
198 return true;
199 case SERIALIZED_SHOW_STATE_FULLSCREEN:
200 *show_state = ui::SHOW_STATE_FULLSCREEN;
201 return true;
202 case SERIALIZED_SHOW_STATE_INVALID:
203 default:
204 // Ignore unknown values. This could happen if the data is corrupt.
205 break;
206 }
207 return false;
208 }
209
210 // Superset of WindowPayloadObsolete/WindowPayloadObsolete2 and the other fields
211 // that can appear in the Pickle version of a Window command. This is used as a
212 // convenient destination for parsing the various fields in a WindowCommand.
213 struct WindowCommandFields {
214 // Fields in WindowPayloadObsolete/WindowPayloadObsolete2/Pickle:
215 int window_id = 0;
216 int selected_tab_index = 0;
217 int num_tabs = 0;
218
219 // Fields in WindowPayloadObsolete2/Pickle:
220 int64_t timestamp = 0;
221
222 // Fields in Pickle:
223 // Completely zeroed position/dimensions indicates that defaults should be
224 // used.
225 int window_x = 0;
226 int window_y = 0;
227 int window_width = 0;
228 int window_height = 0;
229 int window_show_state = 0;
230 std::string workspace;
231 };
232
233 std::unique_ptr<sessions::TabRestoreService::Window>
234 CreateWindowEntryFromCommand(const SessionCommand* command,
235 SessionID::id_type* window_id,
236 int32_t* num_tabs) {
237 WindowCommandFields fields;
238 ui::WindowShowState show_state = ui::SHOW_STATE_DEFAULT;
239
240 if (command->id() == kCommandWindow) {
241 std::unique_ptr<base::Pickle> pickle(command->PayloadAsPickle());
242 if (!pickle.get())
243 return nullptr;
244
245 base::PickleIterator it(*pickle);
246 WindowCommandFields parsed_fields;
247
248 // The first version of the pickle contains all of the following fields, so
249 // they should all successfully parse if the command is in fact a pickle.
250 if (!it.ReadInt(&parsed_fields.window_id) ||
251 !it.ReadInt(&parsed_fields.selected_tab_index) ||
252 !it.ReadInt(&parsed_fields.num_tabs) ||
253 !it.ReadInt64(&parsed_fields.timestamp) ||
254 !it.ReadInt(&parsed_fields.window_x) ||
255 !it.ReadInt(&parsed_fields.window_y) ||
256 !it.ReadInt(&parsed_fields.window_width) ||
257 !it.ReadInt(&parsed_fields.window_height) ||
258 !it.ReadInt(&parsed_fields.window_show_state) ||
259 !it.ReadString(&parsed_fields.workspace)) {
260 return nullptr;
261 }
262
263 // Validate the parameters. If the entire pickles parses but any of the
264 // validation fails assume corruption.
265 if (parsed_fields.window_width < 0 || parsed_fields.window_height < 0)
266 return nullptr;
267
268 // Deserialize the show state, validating it at the same time.
269 if (!DeserializeWindowShowState(parsed_fields.window_show_state,
270 &show_state)) {
271 return nullptr;
272 }
273
274 // New fields added to the pickle in later versions would be parsed and
275 // validated here.
276
277 // Copy the parsed data.
278 fields = parsed_fields;
279 } else if (command->id() == kCommandWindowDeprecated) {
280 // Old window commands can be in either of 2 formats. Try the newest first.
281 // These have distinct sizes so are easily distinguished.
282 bool parsed = false;
283
284 // Try to parse the command as a WindowPayloadObsolete2.
285 WindowPayloadObsolete2 payload2;
286 if (command->GetPayload(&payload2, sizeof(payload2))) {
287 fields.window_id = payload2.window_id;
288 fields.selected_tab_index = payload2.selected_tab_index;
289 fields.num_tabs = payload2.num_tabs;
290 fields.timestamp = payload2.timestamp;
291 parsed = true;
292 }
293
294 // Finally, try the oldest WindowPayloadObsolete type.
295 if (!parsed) {
296 WindowPayloadObsolete payload;
297 if (command->GetPayload(&payload, sizeof(payload))) {
298 fields.window_id = payload.window_id;
299 fields.selected_tab_index = payload.selected_tab_index;
300 fields.num_tabs = payload.num_tabs;
301 parsed = true;
302 }
303 }
304
305 // Fail if the old command wasn't able to be parsed in either of the
306 // deprecated formats.
307 if (!parsed)
308 return nullptr;
309 } else {
310 // This should never be called with anything other than a known window
311 // command ID.
312 NOTREACHED();
313 }
314
315 // Create the Window entry.
316 std::unique_ptr<sessions::TabRestoreService::Window> window =
317 base::MakeUnique<sessions::TabRestoreService::Window>();
318 window->selected_tab_index = fields.selected_tab_index;
319 window->timestamp =
320 base::Time::FromInternalValue(fields.timestamp);
321 *window_id = static_cast<SessionID::id_type>(fields.window_id);
322 *num_tabs = fields.num_tabs;
323
324 // Set the bounds, show state and workspace if valid ones have been provided.
325 if (!(fields.window_x == 0 && fields.window_y == 0 &&
326 fields.window_width == 0 && fields.window_height == 0)) {
327 window->bounds.SetRect(fields.window_x, fields.window_y,
328 fields.window_width, fields.window_height);
329 // |show_state| was converted from window->show_state earlier during
330 // validation.
331 window->show_state = show_state;
332 window->workspace = std::move(fields.workspace);
333 }
334
335 return window;
336 }
337
138 } // namespace 338 } // namespace
139 339
140 // PersistentTabRestoreService::Delegate --------------------------------------- 340 // PersistentTabRestoreService::Delegate ---------------------------------------
141 341
142 // This restore service will create and own a BaseSessionService and implement 342 // This restore service will create and own a BaseSessionService and implement
143 // the required BaseSessionServiceDelegate. 343 // the required BaseSessionServiceDelegate.
144 class PersistentTabRestoreService::Delegate 344 class PersistentTabRestoreService::Delegate
145 : public BaseSessionServiceDelegate, 345 : public BaseSessionServiceDelegate,
146 public TabRestoreServiceHelper::Observer { 346 public TabRestoreServiceHelper::Observer {
147 public: 347 public:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 379
180 // Schedules the commands for a window close. 380 // Schedules the commands for a window close.
181 void ScheduleCommandsForWindow(const Window& window); 381 void ScheduleCommandsForWindow(const Window& window);
182 382
183 // Schedules the commands for a tab close. |selected_index| gives the index of 383 // Schedules the commands for a tab close. |selected_index| gives the index of
184 // the selected navigation. 384 // the selected navigation.
185 void ScheduleCommandsForTab(const Tab& tab, int selected_index); 385 void ScheduleCommandsForTab(const Tab& tab, int selected_index);
186 386
187 // Creates a window close command. 387 // Creates a window close command.
188 static std::unique_ptr<SessionCommand> CreateWindowCommand( 388 static std::unique_ptr<SessionCommand> CreateWindowCommand(
189 SessionID::id_type id, 389 SessionID::id_type window_id,
190 int selected_tab_index, 390 int selected_tab_index,
191 int num_tabs, 391 int num_tabs,
392 const gfx::Rect& bounds,
393 ui::WindowShowState show_state,
394 const std::string& workspace,
192 base::Time timestamp); 395 base::Time timestamp);
193 396
194 // Creates a tab close command. 397 // Creates a tab close command.
195 static std::unique_ptr<SessionCommand> CreateSelectedNavigationInTabCommand( 398 static std::unique_ptr<SessionCommand> CreateSelectedNavigationInTabCommand(
196 SessionID::id_type tab_id, 399 SessionID::id_type tab_id,
197 int32_t index, 400 int32_t index,
198 base::Time timestamp); 401 base::Time timestamp);
199 402
200 // Creates a restore command. 403 // Creates a restore command.
201 static std::unique_ptr<SessionCommand> CreateRestoredEntryCommand( 404 static std::unique_ptr<SessionCommand> CreateRestoredEntryCommand(
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 valid_tab_count++; 625 valid_tab_count++;
423 } else if (static_cast<int>(i) < selected_tab) { 626 } else if (static_cast<int>(i) < selected_tab) {
424 real_selected_tab--; 627 real_selected_tab--;
425 } 628 }
426 } 629 }
427 if (valid_tab_count == 0) 630 if (valid_tab_count == 0)
428 return; // No tabs to persist. 631 return; // No tabs to persist.
429 632
430 base_session_service_->ScheduleCommand(CreateWindowCommand( 633 base_session_service_->ScheduleCommand(CreateWindowCommand(
431 window.id, std::min(real_selected_tab, valid_tab_count - 1), 634 window.id, std::min(real_selected_tab, valid_tab_count - 1),
432 valid_tab_count, window.timestamp)); 635 valid_tab_count, window.bounds, window.show_state, window.workspace,
636 window.timestamp));
433 637
434 if (!window.app_name.empty()) { 638 if (!window.app_name.empty()) {
435 base_session_service_->ScheduleCommand(CreateSetWindowAppNameCommand( 639 base_session_service_->ScheduleCommand(CreateSetWindowAppNameCommand(
436 kCommandSetWindowAppName, window.id, window.app_name)); 640 kCommandSetWindowAppName, window.id, window.app_name));
437 } 641 }
438 642
439 for (size_t i = 0; i < window.tabs.size(); ++i) { 643 for (size_t i = 0; i < window.tabs.size(); ++i) {
440 int selected_index = GetSelectedNavigationIndexToPersist(*window.tabs[i]); 644 int selected_index = GetSelectedNavigationIndexToPersist(*window.tabs[i]);
441 if (selected_index != -1) 645 if (selected_index != -1)
442 ScheduleCommandsForTab(*window.tabs[i], selected_index); 646 ScheduleCommandsForTab(*window.tabs[i], selected_index);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation, 695 CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation,
492 tab.id, 696 tab.id,
493 navigations[i])); 697 navigations[i]));
494 } 698 }
495 } 699 }
496 } 700 }
497 701
498 // static 702 // static
499 std::unique_ptr<SessionCommand> 703 std::unique_ptr<SessionCommand>
500 PersistentTabRestoreService::Delegate::CreateWindowCommand( 704 PersistentTabRestoreService::Delegate::CreateWindowCommand(
501 SessionID::id_type id, 705 SessionID::id_type window_id,
502 int selected_tab_index, 706 int selected_tab_index,
503 int num_tabs, 707 int num_tabs,
708 const gfx::Rect& bounds,
709 ui::WindowShowState show_state,
710 const std::string& workspace,
504 base::Time timestamp) { 711 base::Time timestamp) {
505 WindowPayload2 payload; 712 static_assert(sizeof(SessionID::id_type) == sizeof(int),
506 // |timestamp| is aligned on a 16 byte boundary, leaving 4 bytes of 713 "SessionID::id_type has changed size.");
507 // uninitialized memory in the struct. 714
508 memset(&payload, 0, sizeof(payload)); 715 // Use a pickle to handle marshaling as this command contains variable-length
509 payload.window_id = id; 716 // content.
510 payload.selected_tab_index = selected_tab_index; 717 base::Pickle pickle;
511 payload.num_tabs = num_tabs; 718 pickle.WriteInt(static_cast<int>(window_id));
512 payload.timestamp = timestamp.ToInternalValue(); 719 pickle.WriteInt(selected_tab_index);
720 pickle.WriteInt(num_tabs);
721 pickle.WriteInt64(timestamp.ToInternalValue());
722 pickle.WriteInt(bounds.x());
723 pickle.WriteInt(bounds.y());
724 pickle.WriteInt(bounds.width());
725 pickle.WriteInt(bounds.height());
726 pickle.WriteInt(SerializeWindowShowState(show_state));
727
728 // Enforce a maximum length on workspace names. A common size is 32 bytes for
729 // GUIDs.
730 if (workspace.size() <= 128)
731 pickle.WriteString(workspace);
732 else
733 pickle.WriteString(std::string());
513 734
514 std::unique_ptr<SessionCommand> command( 735 std::unique_ptr<SessionCommand> command(
515 new SessionCommand(kCommandWindow, sizeof(payload))); 736 new SessionCommand(kCommandWindow, pickle));
516 memcpy(command->contents(), &payload, sizeof(payload));
517 return command; 737 return command;
518 } 738 }
519 739
520 // static 740 // static
521 std::unique_ptr<SessionCommand> 741 std::unique_ptr<SessionCommand>
522 PersistentTabRestoreService::Delegate::CreateSelectedNavigationInTabCommand( 742 PersistentTabRestoreService::Delegate::CreateSelectedNavigationInTabCommand(
523 SessionID::id_type tab_id, 743 SessionID::id_type tab_id,
524 int32_t index, 744 int32_t index,
525 base::Time timestamp) { 745 base::Time timestamp) {
526 SelectedNavigationInTabPayload2 payload; 746 SelectedNavigationInTabPayload2 payload;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 current_tab = nullptr; 831 current_tab = nullptr;
612 current_window = nullptr; 832 current_window = nullptr;
613 833
614 RestoredEntryPayload payload; 834 RestoredEntryPayload payload;
615 if (!command.GetPayload(&payload, sizeof(payload))) 835 if (!command.GetPayload(&payload, sizeof(payload)))
616 return; 836 return;
617 RemoveEntryByID(payload, &entries); 837 RemoveEntryByID(payload, &entries);
618 break; 838 break;
619 } 839 }
620 840
841 case kCommandWindowDeprecated:
621 case kCommandWindow: { 842 case kCommandWindow: {
622 WindowPayload2 payload; 843 // Should never receive a window command while waiting for all the
623 if (pending_window_tabs > 0) { 844 // tabs in a window.
624 // Should never receive a window command while waiting for all the 845 if (pending_window_tabs > 0)
625 // tabs in a window.
626 return; 846 return;
627 }
628 847
629 // Try the new payload first 848 // Try to parse the command, and silently skip if it fails.
630 if (!command.GetPayload(&payload, sizeof(payload))) { 849 int32_t num_tabs = 0;
631 // then the old payload 850 SessionID::id_type window_id = 0;
632 WindowPayload old_payload; 851 std::unique_ptr<Window> window =
633 if (!command.GetPayload(&old_payload, sizeof(old_payload))) 852 CreateWindowEntryFromCommand(&command, &window_id, &num_tabs);
634 return; 853 if (!window)
854 return;
635 855
636 // Copy the old payload data to the new payload. 856 // Should always have at least 1 tab. Likely indicates corruption.
637 payload.window_id = old_payload.window_id; 857 pending_window_tabs = num_tabs;
638 payload.selected_tab_index = old_payload.selected_tab_index; 858 if (pending_window_tabs <= 0)
639 payload.num_tabs = old_payload.num_tabs; 859 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 860
645 pending_window_tabs = payload.num_tabs; 861 RemoveEntryByID(window_id, &entries);
646 if (pending_window_tabs <= 0) { 862 current_window = window.get();
647 // Should always have at least 1 tab. Likely indicates corruption. 863 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; 864 break;
659 } 865 }
660 866
661 case kCommandSelectedNavigationInTab: { 867 case kCommandSelectedNavigationInTab: {
662 SelectedNavigationInTabPayload2 payload; 868 SelectedNavigationInTabPayload2 payload;
663 if (!command.GetPayload(&payload, sizeof(payload))) { 869 if (!command.GetPayload(&payload, sizeof(payload))) {
664 SelectedNavigationInTabPayload old_payload; 870 SelectedNavigationInTabPayload old_payload;
665 if (!command.GetPayload(&old_payload, sizeof(old_payload))) 871 if (!command.GetPayload(&old_payload, sizeof(old_payload)))
666 return; 872 return;
667 payload.id = old_payload.id; 873 payload.id = old_payload.id;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 } 973 }
768 974
769 default: 975 default:
770 // Unknown type, usually indicates corruption of file. Ignore it. 976 // Unknown type, usually indicates corruption of file. Ignore it.
771 return; 977 return;
772 } 978 }
773 } 979 }
774 980
775 // If there was corruption some of the entries won't be valid. 981 // If there was corruption some of the entries won't be valid.
776 ValidateAndDeleteEmptyEntries(&entries); 982 ValidateAndDeleteEmptyEntries(&entries);
777
778 loaded_entries->swap(entries); 983 loaded_entries->swap(entries);
779 } 984 }
780 985
781 // static 986 // static
782 void PersistentTabRestoreService::Delegate::ValidateAndDeleteEmptyEntries( 987 void PersistentTabRestoreService::Delegate::ValidateAndDeleteEmptyEntries(
783 std::vector<std::unique_ptr<Entry>>* entries) { 988 std::vector<std::unique_ptr<Entry>>* entries) {
784 std::vector<std::unique_ptr<Entry>> valid_entries; 989 std::vector<std::unique_ptr<Entry>> valid_entries;
785 990
786 // Iterate from the back so that we keep the most recently closed entries. 991 // Iterate from the back so that we keep the most recently closed entries.
787 for (auto i = entries->rbegin(); i != entries->rend(); ++i) { 992 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(); 1025 tab.timestamp = base::Time();
821 } 1026 }
822 } 1027 }
823 if (window->tabs.empty()) 1028 if (window->tabs.empty())
824 return false; 1029 return false;
825 1030
826 window->selected_tab_index = 1031 window->selected_tab_index =
827 std::min(session_window->selected_tab_index, 1032 std::min(session_window->selected_tab_index,
828 static_cast<int>(window->tabs.size() - 1)); 1033 static_cast<int>(window->tabs.size() - 1));
829 window->timestamp = base::Time(); 1034 window->timestamp = base::Time();
1035 window->bounds = session_window->bounds;
1036 window->show_state = session_window->show_state;
1037 window->workspace = session_window->workspace;
830 return true; 1038 return true;
831 } 1039 }
832 1040
833 void PersistentTabRestoreService::Delegate::LoadStateChanged() { 1041 void PersistentTabRestoreService::Delegate::LoadStateChanged() {
834 if ((load_state_ & (LOADED_LAST_TABS | LOADED_LAST_SESSION)) != 1042 if ((load_state_ & (LOADED_LAST_TABS | LOADED_LAST_SESSION)) !=
835 (LOADED_LAST_TABS | LOADED_LAST_SESSION)) { 1043 (LOADED_LAST_TABS | LOADED_LAST_SESSION)) {
836 // Still waiting on previous session or previous tabs. 1044 // Still waiting on previous session or previous tabs.
837 return; 1045 return;
838 } 1046 }
839 1047
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 1166
959 TabRestoreService::Entries* PersistentTabRestoreService::mutable_entries() { 1167 TabRestoreService::Entries* PersistentTabRestoreService::mutable_entries() {
960 return &helper_.entries_; 1168 return &helper_.entries_;
961 } 1169 }
962 1170
963 void PersistentTabRestoreService::PruneEntries() { 1171 void PersistentTabRestoreService::PruneEntries() {
964 helper_.PruneEntries(); 1172 helper_.PruneEntries();
965 } 1173 }
966 1174
967 } // namespace sessions 1175 } // 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