Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/sessions/core/persistent_tab_restore_service.h" | 5 #include "components/sessions/core/persistent_tab_restore_service.h" |
| 6 | 6 |
| 7 #include <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 Loading... | |
| 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 // Erase it if it's our target. | 129 // Erase it if it's our target. |
| 129 if (tab.id == id) { | 130 if (tab.id == id) { |
| 130 window.tabs.erase(it); | 131 window.tabs.erase(it); |
| 131 return; | 132 return; |
| 132 } | 133 } |
| 133 } | 134 } |
| 134 } | 135 } |
| 135 } | 136 } |
| 136 } | 137 } |
| 137 | 138 |
| 139 // Converts a window show state to an integer. This function needs to be kept in | |
| 140 // sync with IntToWindowShowState below. | |
| 141 int WindowShowStateToInt(ui::WindowShowState show_state) { | |
|
sky
2017/07/11 20:28:09
optional: Maybe WindowShowStateToSerializedValue a
chrisha
2017/08/14 14:43:21
Done.
| |
| 142 switch (show_state) { | |
| 143 case ui::SHOW_STATE_DEFAULT: | |
| 144 return 0; | |
|
sky
2017/07/11 20:28:09
Use a local enum with explicit values and a warnin
chrisha
2017/08/14 14:43:21
Done.
| |
| 145 case ui::SHOW_STATE_NORMAL: | |
| 146 return 1; | |
| 147 case ui::SHOW_STATE_MINIMIZED: | |
| 148 return 2; | |
| 149 case ui::SHOW_STATE_MAXIMIZED: | |
| 150 return 3; | |
| 151 case ui::SHOW_STATE_INACTIVE: | |
| 152 return 4; | |
| 153 case ui::SHOW_STATE_FULLSCREEN: | |
| 154 return 5; | |
| 155 case ui::SHOW_STATE_END: | |
| 156 // This should never happen. | |
| 157 NOTREACHED(); | |
| 158 return 6; | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 // Converts an integer to a window show state. Returns true on success, false | |
| 163 // otherwise. | |
| 164 bool IntToWindowShowState(int show_state_int, ui::WindowShowState* show_state) { | |
| 165 switch (show_state_int) { | |
| 166 case 0: | |
| 167 *show_state = ui::SHOW_STATE_DEFAULT; | |
| 168 return true; | |
| 169 case 1: | |
| 170 *show_state = ui::SHOW_STATE_NORMAL; | |
| 171 return true; | |
| 172 case 2: | |
| 173 *show_state = ui::SHOW_STATE_MINIMIZED; | |
| 174 return true; | |
| 175 case 3: | |
| 176 *show_state = ui::SHOW_STATE_MAXIMIZED; | |
| 177 return true; | |
| 178 case 4: | |
| 179 *show_state = ui::SHOW_STATE_INACTIVE; | |
| 180 return true; | |
| 181 case 5: | |
| 182 *show_state = ui::SHOW_STATE_FULLSCREEN; | |
| 183 return true; | |
| 184 default: | |
| 185 break; | |
| 186 } | |
| 187 return false; | |
| 188 } | |
| 189 | |
| 190 // Superset of WindowPayloadObsolete/WindowPayloadObsolete2 and the other fields | |
| 191 // that can appear in the Pickle version of a Window command. This is used as a | |
| 192 // convenient destination for parsing the various fields in a WindowCommand. | |
| 193 struct WindowCommandFields { | |
| 194 // Fields in WindowPayloadObsolete/WindowPayloadObsolete2/Pickle: | |
| 195 int window_id = 0; | |
| 196 int selected_tab_index = 0; | |
| 197 int num_tabs = 0; | |
| 198 | |
| 199 // Fields in WindowPayloadObsolete2/Pickle: | |
| 200 int64_t timestamp = 0; | |
| 201 | |
| 202 // Fields in Pickle: | |
| 203 // Completely zeroed position/dimensions indicates that defaults should be | |
| 204 // used. | |
| 205 int window_x = 0; | |
| 206 int window_y = 0; | |
| 207 int window_width = 0; | |
| 208 int window_height = 0; | |
| 209 int window_show_state = 0; | |
| 210 std::string workspace; | |
| 211 }; | |
| 212 | |
| 213 std::unique_ptr<sessions::TabRestoreService::Window> | |
| 214 CreateWindowEntryFromCommand(const SessionCommand* command, | |
| 215 SessionID::id_type* window_id, | |
| 216 int32_t* num_tabs) { | |
| 217 bool parsed = false; | |
| 218 | |
| 219 WindowCommandFields fields; | |
| 220 ui::WindowShowState show_state = ui::SHOW_STATE_DEFAULT; | |
| 221 | |
| 222 // First try to parse the command as a pickle (the most modern version). | |
| 223 std::unique_ptr<base::Pickle> pickle(command->PayloadAsPickle()); | |
|
sky
2017/07/11 20:28:09
I think this code would be less error prone if you
chrisha
2017/08/14 14:43:21
That's a good point. Done.
| |
| 224 if (pickle.get()) { | |
| 225 base::PickleIterator it(*pickle); | |
| 226 WindowCommandFields parsed_fields; | |
| 227 | |
| 228 // The first version of the pickle contains all of the following fields, so | |
| 229 // they should all successfully parse if the command is in fact a pickle. | |
| 230 if (it.ReadInt(&parsed_fields.window_id) && | |
| 231 it.ReadInt(&parsed_fields.selected_tab_index) && | |
| 232 it.ReadInt(&parsed_fields.num_tabs) && | |
| 233 it.ReadInt64(&parsed_fields.timestamp) && | |
| 234 it.ReadInt(&parsed_fields.window_x) && | |
| 235 it.ReadInt(&parsed_fields.window_y) && | |
| 236 it.ReadInt(&parsed_fields.window_width) && | |
|
sky
2017/07/11 20:28:09
Make sure width/height are non-negative.
chrisha
2017/08/14 14:43:21
Done.
| |
| 237 it.ReadInt(&parsed_fields.window_height) && | |
| 238 it.ReadInt(&parsed_fields.window_show_state) && | |
| 239 it.ReadString(&parsed_fields.workspace)) { | |
| 240 // Validate the window_show_state. If the entire pickle parsed but the | |
| 241 // show state is invalid then assume corruption. | |
| 242 if (!IntToWindowShowState(parsed_fields.window_show_state, &show_state)) | |
| 243 return nullptr; | |
| 244 | |
| 245 // New fields added to the pickle in later versions would be parsed here. | |
| 246 | |
| 247 // Copy the parsed data. | |
| 248 fields = parsed_fields; | |
| 249 parsed = true; | |
| 250 } | |
| 251 } | |
| 252 | |
| 253 // Next try to parse the command as a WindowPayloadObsolete2. | |
| 254 if (!parsed) { | |
| 255 WindowPayloadObsolete2 payload2; | |
| 256 if (command->GetPayload(&payload2, sizeof(payload2))) { | |
| 257 fields.window_id = payload2.window_id; | |
| 258 fields.selected_tab_index = payload2.selected_tab_index; | |
| 259 fields.num_tabs = payload2.num_tabs; | |
| 260 fields.timestamp = payload2.timestamp; | |
| 261 parsed = true; | |
| 262 } | |
| 263 } | |
| 264 | |
| 265 // Finally, try the oldest WindowPayloadObsolete type. | |
| 266 if (!parsed) { | |
| 267 WindowPayloadObsolete payload; | |
| 268 if (command->GetPayload(&payload, sizeof(payload))) { | |
| 269 fields.window_id = payload.window_id; | |
| 270 fields.selected_tab_index = payload.selected_tab_index; | |
| 271 fields.num_tabs = payload.num_tabs; | |
| 272 parsed = true; | |
| 273 } | |
| 274 } | |
| 275 | |
| 276 if (!parsed) | |
| 277 return nullptr; | |
| 278 | |
| 279 // Create the Window entry. | |
| 280 std::unique_ptr<sessions::TabRestoreService::Window> window = | |
| 281 base::MakeUnique<sessions::TabRestoreService::Window>(); | |
| 282 window->selected_tab_index = fields.selected_tab_index; | |
| 283 window->timestamp = base::Time::FromInternalValue(fields.timestamp); | |
| 284 window->selected_tab_index = fields.selected_tab_index; | |
| 285 window->timestamp = base::Time::FromInternalValue(fields.timestamp); | |
| 286 *window_id = static_cast<SessionID::id_type>(fields.window_id); | |
| 287 *num_tabs = fields.num_tabs; | |
| 288 | |
| 289 // Set the bounds, show state and workspace if valid ones have been provided. | |
| 290 if (!(fields.window_x == 0 && fields.window_y == 0 && | |
| 291 fields.window_width == 0 && fields.window_height == 0)) { | |
| 292 window->bounds.SetRect(fields.window_x, fields.window_y, | |
| 293 fields.window_width, fields.window_height); | |
| 294 // |show_state| was converted from window->show_state earlier during | |
| 295 // validation. | |
| 296 window->show_state = show_state; | |
| 297 window->workspace = std::move(fields.workspace); | |
| 298 } | |
| 299 | |
| 300 return window; | |
| 301 } | |
| 302 | |
| 138 } // namespace | 303 } // namespace |
| 139 | 304 |
| 140 // PersistentTabRestoreService::Delegate --------------------------------------- | 305 // PersistentTabRestoreService::Delegate --------------------------------------- |
| 141 | 306 |
| 142 // This restore service will create and own a BaseSessionService and implement | 307 // This restore service will create and own a BaseSessionService and implement |
| 143 // the required BaseSessionServiceDelegate. | 308 // the required BaseSessionServiceDelegate. |
| 144 class PersistentTabRestoreService::Delegate | 309 class PersistentTabRestoreService::Delegate |
| 145 : public BaseSessionServiceDelegate, | 310 : public BaseSessionServiceDelegate, |
| 146 public TabRestoreServiceHelper::Observer { | 311 public TabRestoreServiceHelper::Observer { |
| 147 public: | 312 public: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 | 345 |
| 181 // Schedules the commands for a window close. | 346 // Schedules the commands for a window close. |
| 182 void ScheduleCommandsForWindow(const Window& window); | 347 void ScheduleCommandsForWindow(const Window& window); |
| 183 | 348 |
| 184 // Schedules the commands for a tab close. |selected_index| gives the index of | 349 // Schedules the commands for a tab close. |selected_index| gives the index of |
| 185 // the selected navigation. | 350 // the selected navigation. |
| 186 void ScheduleCommandsForTab(const Tab& tab, int selected_index); | 351 void ScheduleCommandsForTab(const Tab& tab, int selected_index); |
| 187 | 352 |
| 188 // Creates a window close command. | 353 // Creates a window close command. |
| 189 static std::unique_ptr<SessionCommand> CreateWindowCommand( | 354 static std::unique_ptr<SessionCommand> CreateWindowCommand( |
| 190 SessionID::id_type id, | 355 SessionID::id_type window_id, |
| 191 int selected_tab_index, | 356 int selected_tab_index, |
| 192 int num_tabs, | 357 int num_tabs, |
| 358 const gfx::Rect& bounds, | |
| 359 ui::WindowShowState show_state, | |
| 360 const std::string& workspace, | |
| 193 base::Time timestamp); | 361 base::Time timestamp); |
| 194 | 362 |
| 195 // Creates a tab close command. | 363 // Creates a tab close command. |
| 196 static std::unique_ptr<SessionCommand> CreateSelectedNavigationInTabCommand( | 364 static std::unique_ptr<SessionCommand> CreateSelectedNavigationInTabCommand( |
| 197 SessionID::id_type tab_id, | 365 SessionID::id_type tab_id, |
| 198 int32_t index, | 366 int32_t index, |
| 199 base::Time timestamp); | 367 base::Time timestamp); |
| 200 | 368 |
| 201 // Creates a restore command. | 369 // Creates a restore command. |
| 202 static std::unique_ptr<SessionCommand> CreateRestoredEntryCommand( | 370 static std::unique_ptr<SessionCommand> CreateRestoredEntryCommand( |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 428 valid_tab_count++; | 596 valid_tab_count++; |
| 429 } else if (static_cast<int>(i) < selected_tab) { | 597 } else if (static_cast<int>(i) < selected_tab) { |
| 430 real_selected_tab--; | 598 real_selected_tab--; |
| 431 } | 599 } |
| 432 } | 600 } |
| 433 if (valid_tab_count == 0) | 601 if (valid_tab_count == 0) |
| 434 return; // No tabs to persist. | 602 return; // No tabs to persist. |
| 435 | 603 |
| 436 base_session_service_->ScheduleCommand(CreateWindowCommand( | 604 base_session_service_->ScheduleCommand(CreateWindowCommand( |
| 437 window.id, std::min(real_selected_tab, valid_tab_count - 1), | 605 window.id, std::min(real_selected_tab, valid_tab_count - 1), |
| 438 valid_tab_count, window.timestamp)); | 606 valid_tab_count, window.bounds, window.show_state, window.workspace, |
| 607 window.timestamp)); | |
| 439 | 608 |
| 440 if (!window.app_name.empty()) { | 609 if (!window.app_name.empty()) { |
| 441 base_session_service_->ScheduleCommand(CreateSetWindowAppNameCommand( | 610 base_session_service_->ScheduleCommand(CreateSetWindowAppNameCommand( |
| 442 kCommandSetWindowAppName, window.id, window.app_name)); | 611 kCommandSetWindowAppName, window.id, window.app_name)); |
| 443 } | 612 } |
| 444 | 613 |
| 445 for (size_t i = 0; i < window.tabs.size(); ++i) { | 614 for (size_t i = 0; i < window.tabs.size(); ++i) { |
| 446 int selected_index = GetSelectedNavigationIndexToPersist(*window.tabs[i]); | 615 int selected_index = GetSelectedNavigationIndexToPersist(*window.tabs[i]); |
| 447 if (selected_index != -1) | 616 if (selected_index != -1) |
| 448 ScheduleCommandsForTab(*window.tabs[i], selected_index); | 617 ScheduleCommandsForTab(*window.tabs[i], selected_index); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation, | 666 CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation, |
| 498 tab.id, | 667 tab.id, |
| 499 navigations[i])); | 668 navigations[i])); |
| 500 } | 669 } |
| 501 } | 670 } |
| 502 } | 671 } |
| 503 | 672 |
| 504 // static | 673 // static |
| 505 std::unique_ptr<SessionCommand> | 674 std::unique_ptr<SessionCommand> |
| 506 PersistentTabRestoreService::Delegate::CreateWindowCommand( | 675 PersistentTabRestoreService::Delegate::CreateWindowCommand( |
| 507 SessionID::id_type id, | 676 SessionID::id_type window_id, |
| 508 int selected_tab_index, | 677 int selected_tab_index, |
| 509 int num_tabs, | 678 int num_tabs, |
| 679 const gfx::Rect& bounds, | |
| 680 ui::WindowShowState show_state, | |
| 681 const std::string& workspace, | |
| 510 base::Time timestamp) { | 682 base::Time timestamp) { |
| 511 WindowPayload2 payload; | 683 static_assert(sizeof(SessionID::id_type) == sizeof(int), |
| 512 // |timestamp| is aligned on a 16 byte boundary, leaving 4 bytes of | 684 "SessionID::id_type has changed size."); |
| 513 // uninitialized memory in the struct. | 685 |
| 514 memset(&payload, 0, sizeof(payload)); | 686 // Use a pickle to handle marshaling as this command contains variable-length |
| 515 payload.window_id = id; | 687 // content. |
| 516 payload.selected_tab_index = selected_tab_index; | 688 base::Pickle pickle; |
| 517 payload.num_tabs = num_tabs; | 689 pickle.WriteInt(static_cast<int>(window_id)); |
| 518 payload.timestamp = timestamp.ToInternalValue(); | 690 pickle.WriteInt(selected_tab_index); |
| 691 pickle.WriteInt(num_tabs); | |
| 692 pickle.WriteInt64(timestamp.ToInternalValue()); | |
| 693 pickle.WriteInt(bounds.x()); | |
| 694 pickle.WriteInt(bounds.y()); | |
| 695 pickle.WriteInt(bounds.width()); | |
| 696 pickle.WriteInt(bounds.height()); | |
| 697 pickle.WriteInt(WindowShowStateToInt(show_state)); | |
| 698 | |
| 699 // Enforce a maximum length on workspace names. A common size is 32 bytes for | |
| 700 // GUIDs. | |
| 701 if (workspace.size() <= 128) | |
| 702 pickle.WriteString(workspace); | |
| 703 else | |
| 704 pickle.WriteString(std::string()); | |
| 519 | 705 |
| 520 std::unique_ptr<SessionCommand> command( | 706 std::unique_ptr<SessionCommand> command( |
| 521 new SessionCommand(kCommandWindow, sizeof(payload))); | 707 new SessionCommand(kCommandWindow, pickle)); |
| 522 memcpy(command->contents(), &payload, sizeof(payload)); | |
| 523 return command; | 708 return command; |
| 524 } | 709 } |
| 525 | 710 |
| 526 // static | 711 // static |
| 527 std::unique_ptr<SessionCommand> | 712 std::unique_ptr<SessionCommand> |
| 528 PersistentTabRestoreService::Delegate::CreateSelectedNavigationInTabCommand( | 713 PersistentTabRestoreService::Delegate::CreateSelectedNavigationInTabCommand( |
| 529 SessionID::id_type tab_id, | 714 SessionID::id_type tab_id, |
| 530 int32_t index, | 715 int32_t index, |
| 531 base::Time timestamp) { | 716 base::Time timestamp) { |
| 532 SelectedNavigationInTabPayload2 payload; | 717 SelectedNavigationInTabPayload2 payload; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 618 current_window = nullptr; | 803 current_window = nullptr; |
| 619 | 804 |
| 620 RestoredEntryPayload payload; | 805 RestoredEntryPayload payload; |
| 621 if (!command.GetPayload(&payload, sizeof(payload))) | 806 if (!command.GetPayload(&payload, sizeof(payload))) |
| 622 return; | 807 return; |
| 623 RemoveEntryByID(payload, &entries); | 808 RemoveEntryByID(payload, &entries); |
| 624 break; | 809 break; |
| 625 } | 810 } |
| 626 | 811 |
| 627 case kCommandWindow: { | 812 case kCommandWindow: { |
| 628 WindowPayload2 payload; | 813 // Should never receive a window command while waiting for all the |
| 629 if (pending_window_tabs > 0) { | 814 // tabs in a window. |
| 630 // Should never receive a window command while waiting for all the | 815 if (pending_window_tabs > 0) |
| 631 // tabs in a window. | |
| 632 return; | 816 return; |
| 633 } | |
| 634 | 817 |
| 635 // Try the new payload first | 818 // Try to parse the command, and silently skip if it fails. |
| 636 if (!command.GetPayload(&payload, sizeof(payload))) { | 819 int32_t num_tabs = 0; |
| 637 // then the old payload | 820 SessionID::id_type window_id = 0; |
| 638 WindowPayload old_payload; | 821 std::unique_ptr<Window> window = |
| 639 if (!command.GetPayload(&old_payload, sizeof(old_payload))) | 822 CreateWindowEntryFromCommand(&command, &window_id, &num_tabs); |
| 640 return; | 823 if (!window) |
| 824 return; | |
| 641 | 825 |
| 642 // Copy the old payload data to the new payload. | 826 // Should always have at least 1 tab. Likely indicates corruption. |
| 643 payload.window_id = old_payload.window_id; | 827 pending_window_tabs = num_tabs; |
| 644 payload.selected_tab_index = old_payload.selected_tab_index; | 828 if (pending_window_tabs <= 0) |
| 645 payload.num_tabs = old_payload.num_tabs; | 829 return; |
| 646 // Since we don't have a time use time 0 which is used to mark as an | |
| 647 // unknown timestamp. | |
| 648 payload.timestamp = 0; | |
| 649 } | |
| 650 | 830 |
| 651 pending_window_tabs = payload.num_tabs; | 831 RemoveEntryByID(window_id, &entries); |
| 652 if (pending_window_tabs <= 0) { | 832 current_window = window.get(); |
| 653 // Should always have at least 1 tab. Likely indicates corruption. | 833 entries.push_back(std::move(window)); |
| 654 return; | |
| 655 } | |
| 656 | |
| 657 RemoveEntryByID(payload.window_id, &entries); | |
| 658 | |
| 659 entries.push_back(base::MakeUnique<Window>()); | |
| 660 current_window = static_cast<Window*>(entries.back().get()); | |
| 661 current_window->selected_tab_index = payload.selected_tab_index; | |
| 662 current_window->timestamp = | |
| 663 base::Time::FromInternalValue(payload.timestamp); | |
| 664 break; | 834 break; |
| 665 } | 835 } |
| 666 | 836 |
| 667 case kCommandSelectedNavigationInTab: { | 837 case kCommandSelectedNavigationInTab: { |
| 668 SelectedNavigationInTabPayload2 payload; | 838 SelectedNavigationInTabPayload2 payload; |
| 669 if (!command.GetPayload(&payload, sizeof(payload))) { | 839 if (!command.GetPayload(&payload, sizeof(payload))) { |
| 670 SelectedNavigationInTabPayload old_payload; | 840 SelectedNavigationInTabPayload old_payload; |
| 671 if (!command.GetPayload(&old_payload, sizeof(old_payload))) | 841 if (!command.GetPayload(&old_payload, sizeof(old_payload))) |
| 672 return; | 842 return; |
| 673 payload.id = old_payload.id; | 843 payload.id = old_payload.id; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 773 } | 943 } |
| 774 | 944 |
| 775 default: | 945 default: |
| 776 // Unknown type, usually indicates corruption of file. Ignore it. | 946 // Unknown type, usually indicates corruption of file. Ignore it. |
| 777 return; | 947 return; |
| 778 } | 948 } |
| 779 } | 949 } |
| 780 | 950 |
| 781 // If there was corruption some of the entries won't be valid. | 951 // If there was corruption some of the entries won't be valid. |
| 782 ValidateAndDeleteEmptyEntries(&entries); | 952 ValidateAndDeleteEmptyEntries(&entries); |
| 783 | |
| 784 loaded_entries->swap(entries); | 953 loaded_entries->swap(entries); |
| 785 } | 954 } |
| 786 | 955 |
| 787 // static | 956 // static |
| 788 void PersistentTabRestoreService::Delegate::ValidateAndDeleteEmptyEntries( | 957 void PersistentTabRestoreService::Delegate::ValidateAndDeleteEmptyEntries( |
| 789 std::vector<std::unique_ptr<Entry>>* entries) { | 958 std::vector<std::unique_ptr<Entry>>* entries) { |
| 790 std::vector<std::unique_ptr<Entry>> valid_entries; | 959 std::vector<std::unique_ptr<Entry>> valid_entries; |
| 791 | 960 |
| 792 // Iterate from the back so that we keep the most recently closed entries. | 961 // Iterate from the back so that we keep the most recently closed entries. |
| 793 for (auto i = entries->rbegin(); i != entries->rend(); ++i) { | 962 for (auto i = entries->rbegin(); i != entries->rend(); ++i) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 826 tab.timestamp = base::Time(); | 995 tab.timestamp = base::Time(); |
| 827 } | 996 } |
| 828 } | 997 } |
| 829 if (window->tabs.empty()) | 998 if (window->tabs.empty()) |
| 830 return false; | 999 return false; |
| 831 | 1000 |
| 832 window->selected_tab_index = | 1001 window->selected_tab_index = |
| 833 std::min(session_window->selected_tab_index, | 1002 std::min(session_window->selected_tab_index, |
| 834 static_cast<int>(window->tabs.size() - 1)); | 1003 static_cast<int>(window->tabs.size() - 1)); |
| 835 window->timestamp = base::Time(); | 1004 window->timestamp = base::Time(); |
| 1005 window->bounds = session_window->bounds; | |
| 1006 window->show_state = session_window->show_state; | |
| 1007 window->workspace = session_window->workspace; | |
| 836 return true; | 1008 return true; |
| 837 } | 1009 } |
| 838 | 1010 |
| 839 void PersistentTabRestoreService::Delegate::LoadStateChanged() { | 1011 void PersistentTabRestoreService::Delegate::LoadStateChanged() { |
| 840 if ((load_state_ & (LOADED_LAST_TABS | LOADED_LAST_SESSION)) != | 1012 if ((load_state_ & (LOADED_LAST_TABS | LOADED_LAST_SESSION)) != |
| 841 (LOADED_LAST_TABS | LOADED_LAST_SESSION)) { | 1013 (LOADED_LAST_TABS | LOADED_LAST_SESSION)) { |
| 842 // Still waiting on previous session or previous tabs. | 1014 // Still waiting on previous session or previous tabs. |
| 843 return; | 1015 return; |
| 844 } | 1016 } |
| 845 | 1017 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 964 | 1136 |
| 965 TabRestoreService::Entries* PersistentTabRestoreService::mutable_entries() { | 1137 TabRestoreService::Entries* PersistentTabRestoreService::mutable_entries() { |
| 966 return &helper_.entries_; | 1138 return &helper_.entries_; |
| 967 } | 1139 } |
| 968 | 1140 |
| 969 void PersistentTabRestoreService::PruneEntries() { | 1141 void PersistentTabRestoreService::PruneEntries() { |
| 970 helper_.PruneEntries(); | 1142 helper_.PruneEntries(); |
| 971 } | 1143 } |
| 972 | 1144 |
| 973 } // namespace sessions | 1145 } // namespace sessions |
| OLD | NEW |