| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "chrome/browser/sessions/persistent_tab_restore_service.h" | 5 #include "chrome/browser/sessions/persistent_tab_restore_service.h" |
| 6 | 6 |
| 7 #include <cstring> // memcpy | 7 #include <cstring> // memcpy |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 void Shutdown(); | 148 void Shutdown(); |
| 149 | 149 |
| 150 // Schedules the commands for a window close. | 150 // Schedules the commands for a window close. |
| 151 void ScheduleCommandsForWindow(const Window& window); | 151 void ScheduleCommandsForWindow(const Window& window); |
| 152 | 152 |
| 153 // Schedules the commands for a tab close. |selected_index| gives the index of | 153 // Schedules the commands for a tab close. |selected_index| gives the index of |
| 154 // the selected navigation. | 154 // the selected navigation. |
| 155 void ScheduleCommandsForTab(const Tab& tab, int selected_index); | 155 void ScheduleCommandsForTab(const Tab& tab, int selected_index); |
| 156 | 156 |
| 157 // Creates a window close command. | 157 // Creates a window close command. |
| 158 static SessionCommand* CreateWindowCommand(SessionID::id_type id, | 158 static scoped_ptr<SessionCommand> CreateWindowCommand(SessionID::id_type id, |
| 159 int selected_tab_index, | 159 int selected_tab_index, |
| 160 int num_tabs, | 160 int num_tabs, |
| 161 base::Time timestamp); | 161 base::Time timestamp); |
| 162 | 162 |
| 163 // Creates a tab close command. | 163 // Creates a tab close command. |
| 164 static SessionCommand* CreateSelectedNavigationInTabCommand( | 164 static scoped_ptr<SessionCommand> CreateSelectedNavigationInTabCommand( |
| 165 SessionID::id_type tab_id, | 165 SessionID::id_type tab_id, |
| 166 int32 index, | 166 int32 index, |
| 167 base::Time timestamp); | 167 base::Time timestamp); |
| 168 | 168 |
| 169 // Creates a restore command. | 169 // Creates a restore command. |
| 170 static SessionCommand* CreateRestoredEntryCommand( | 170 static scoped_ptr<SessionCommand> CreateRestoredEntryCommand( |
| 171 SessionID::id_type entry_id); | 171 SessionID::id_type entry_id); |
| 172 | 172 |
| 173 // Returns the index to persist as the selected index. This is the same as | 173 // Returns the index to persist as the selected index. This is the same as |
| 174 // |tab.current_navigation_index| unless the entry at | 174 // |tab.current_navigation_index| unless the entry at |
| 175 // |tab.current_navigation_index| shouldn't be persisted. Returns -1 if no | 175 // |tab.current_navigation_index| shouldn't be persisted. Returns -1 if no |
| 176 // valid navigation to persist. | 176 // valid navigation to persist. |
| 177 int GetSelectedNavigationIndexToPersist(const Tab& tab); | 177 int GetSelectedNavigationIndexToPersist(const Tab& tab); |
| 178 | 178 |
| 179 // Invoked when we've loaded the session commands that identify the previously | 179 // Invoked when we've loaded the session commands that identify the previously |
| 180 // closed tabs. This creates entries, adds them to staging_entries_, and | 180 // closed tabs. This creates entries, adds them to staging_entries_, and |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 } | 287 } |
| 288 if (pending_reset()) | 288 if (pending_reset()) |
| 289 entries_written_ = 0; | 289 entries_written_ = 0; |
| 290 BaseSessionService::Save(); | 290 BaseSessionService::Save(); |
| 291 } | 291 } |
| 292 | 292 |
| 293 void PersistentTabRestoreService::Delegate::OnClearEntries() { | 293 void PersistentTabRestoreService::Delegate::OnClearEntries() { |
| 294 // Mark all the tabs as closed so that we don't attempt to restore them. | 294 // Mark all the tabs as closed so that we don't attempt to restore them. |
| 295 const Entries& entries = tab_restore_service_helper_->entries(); | 295 const Entries& entries = tab_restore_service_helper_->entries(); |
| 296 for (Entries::const_iterator i = entries.begin(); i != entries.end(); ++i) | 296 for (Entries::const_iterator i = entries.begin(); i != entries.end(); ++i) |
| 297 ScheduleCommand(CreateRestoredEntryCommand((*i)->id)); | 297 ScheduleCommand(CreateRestoredEntryCommand((*i)->id).Pass()); |
| 298 | 298 |
| 299 entries_to_write_ = 0; | 299 entries_to_write_ = 0; |
| 300 | 300 |
| 301 // Schedule a pending reset so that we nuke the file on next write. | 301 // Schedule a pending reset so that we nuke the file on next write. |
| 302 set_pending_reset(true); | 302 set_pending_reset(true); |
| 303 | 303 |
| 304 // Schedule a command, otherwise if there are no pending commands Save does | 304 // Schedule a command, otherwise if there are no pending commands Save does |
| 305 // nothing. | 305 // nothing. |
| 306 ScheduleCommand(CreateRestoredEntryCommand(1)); | 306 ScheduleCommand(CreateRestoredEntryCommand(1).Pass()); |
| 307 } | 307 } |
| 308 | 308 |
| 309 void PersistentTabRestoreService::Delegate::OnRestoreEntryById( | 309 void PersistentTabRestoreService::Delegate::OnRestoreEntryById( |
| 310 SessionID::id_type id, | 310 SessionID::id_type id, |
| 311 Entries::const_iterator entry_iterator) { | 311 Entries::const_iterator entry_iterator) { |
| 312 size_t index = 0; | 312 size_t index = 0; |
| 313 const Entries& entries = tab_restore_service_helper_->entries(); | 313 const Entries& entries = tab_restore_service_helper_->entries(); |
| 314 for (Entries::const_iterator j = entries.begin(); | 314 for (Entries::const_iterator j = entries.begin(); |
| 315 j != entry_iterator && j != entries.end(); | 315 j != entry_iterator && j != entries.end(); |
| 316 ++j, ++index) {} | 316 ++j, ++index) {} |
| 317 if (static_cast<int>(index) < entries_to_write_) | 317 if (static_cast<int>(index) < entries_to_write_) |
| 318 entries_to_write_--; | 318 entries_to_write_--; |
| 319 | 319 |
| 320 ScheduleCommand(CreateRestoredEntryCommand(id)); | 320 ScheduleCommand(CreateRestoredEntryCommand(id).Pass()); |
| 321 } | 321 } |
| 322 | 322 |
| 323 void PersistentTabRestoreService::Delegate::OnAddEntry() { | 323 void PersistentTabRestoreService::Delegate::OnAddEntry() { |
| 324 // Start the save timer, when it fires we'll generate the commands. | 324 // Start the save timer, when it fires we'll generate the commands. |
| 325 StartSaveTimer(); | 325 StartSaveTimer(); |
| 326 entries_to_write_++; | 326 entries_to_write_++; |
| 327 } | 327 } |
| 328 | 328 |
| 329 void PersistentTabRestoreService::Delegate::LoadTabsFromLastSession() { | 329 void PersistentTabRestoreService::Delegate::LoadTabsFromLastSession() { |
| 330 if (load_state_ != NOT_LOADED) | 330 if (load_state_ != NOT_LOADED) |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 real_selected_tab--; | 404 real_selected_tab--; |
| 405 } | 405 } |
| 406 } | 406 } |
| 407 if (valid_tab_count == 0) | 407 if (valid_tab_count == 0) |
| 408 return; // No tabs to persist. | 408 return; // No tabs to persist. |
| 409 | 409 |
| 410 ScheduleCommand( | 410 ScheduleCommand( |
| 411 CreateWindowCommand(window.id, | 411 CreateWindowCommand(window.id, |
| 412 std::min(real_selected_tab, valid_tab_count - 1), | 412 std::min(real_selected_tab, valid_tab_count - 1), |
| 413 valid_tab_count, | 413 valid_tab_count, |
| 414 window.timestamp)); | 414 window.timestamp).Pass()); |
| 415 | 415 |
| 416 if (!window.app_name.empty()) { | 416 if (!window.app_name.empty()) { |
| 417 ScheduleCommand(CreateSetWindowAppNameCommand(kCommandSetWindowAppName, | 417 ScheduleCommand(CreateSetWindowAppNameCommand(kCommandSetWindowAppName, |
| 418 window.id, | 418 window.id, |
| 419 window.app_name)); | 419 window.app_name).Pass()); |
| 420 } | 420 } |
| 421 | 421 |
| 422 for (size_t i = 0; i < window.tabs.size(); ++i) { | 422 for (size_t i = 0; i < window.tabs.size(); ++i) { |
| 423 int selected_index = GetSelectedNavigationIndexToPersist(window.tabs[i]); | 423 int selected_index = GetSelectedNavigationIndexToPersist(window.tabs[i]); |
| 424 if (selected_index != -1) | 424 if (selected_index != -1) |
| 425 ScheduleCommandsForTab(window.tabs[i], selected_index); | 425 ScheduleCommandsForTab(window.tabs[i], selected_index); |
| 426 } | 426 } |
| 427 } | 427 } |
| 428 | 428 |
| 429 void PersistentTabRestoreService::Delegate::ScheduleCommandsForTab( | 429 void PersistentTabRestoreService::Delegate::ScheduleCommandsForTab( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 441 if (ShouldTrackEntry(navigations[i].virtual_url())) { | 441 if (ShouldTrackEntry(navigations[i].virtual_url())) { |
| 442 first_index_to_persist = i; | 442 first_index_to_persist = i; |
| 443 valid_count_before_selected++; | 443 valid_count_before_selected++; |
| 444 } | 444 } |
| 445 } | 445 } |
| 446 | 446 |
| 447 // Write the command that identifies the selected tab. | 447 // Write the command that identifies the selected tab. |
| 448 ScheduleCommand( | 448 ScheduleCommand( |
| 449 CreateSelectedNavigationInTabCommand(tab.id, | 449 CreateSelectedNavigationInTabCommand(tab.id, |
| 450 valid_count_before_selected, | 450 valid_count_before_selected, |
| 451 tab.timestamp)); | 451 tab.timestamp).Pass()); |
| 452 | 452 |
| 453 if (tab.pinned) { | 453 if (tab.pinned) { |
| 454 PinnedStatePayload payload = true; | 454 PinnedStatePayload payload = true; |
| 455 SessionCommand* command = | 455 scoped_ptr<SessionCommand> command( |
| 456 new SessionCommand(kCommandPinnedState, sizeof(payload)); | 456 new SessionCommand(kCommandPinnedState, sizeof(payload))); |
| 457 memcpy(command->contents(), &payload, sizeof(payload)); | 457 memcpy(command->contents(), &payload, sizeof(payload)); |
| 458 ScheduleCommand(command); | 458 ScheduleCommand(command.Pass()); |
| 459 } | 459 } |
| 460 | 460 |
| 461 if (!tab.extension_app_id.empty()) { | 461 if (!tab.extension_app_id.empty()) { |
| 462 ScheduleCommand(CreateSetTabExtensionAppIDCommand( | 462 ScheduleCommand(CreateSetTabExtensionAppIDCommand( |
| 463 kCommandSetExtensionAppID, | 463 kCommandSetExtensionAppID, |
| 464 tab.id, | 464 tab.id, |
| 465 tab.extension_app_id)); | 465 tab.extension_app_id).Pass()); |
| 466 } | 466 } |
| 467 | 467 |
| 468 if (!tab.user_agent_override.empty()) { | 468 if (!tab.user_agent_override.empty()) { |
| 469 ScheduleCommand(CreateSetTabUserAgentOverrideCommand( | 469 ScheduleCommand(CreateSetTabUserAgentOverrideCommand( |
| 470 kCommandSetTabUserAgentOverride, | 470 kCommandSetTabUserAgentOverride, |
| 471 tab.id, | 471 tab.id, |
| 472 tab.user_agent_override)); | 472 tab.user_agent_override).Pass()); |
| 473 } | 473 } |
| 474 | 474 |
| 475 // Then write the navigations. | 475 // Then write the navigations. |
| 476 for (int i = first_index_to_persist, wrote_count = 0; | 476 for (int i = first_index_to_persist, wrote_count = 0; |
| 477 i < max_index && wrote_count < 2 * max_persist_navigation_count; ++i) { | 477 i < max_index && wrote_count < 2 * max_persist_navigation_count; ++i) { |
| 478 if (ShouldTrackEntry(navigations[i].virtual_url())) { | 478 if (ShouldTrackEntry(navigations[i].virtual_url())) { |
| 479 ScheduleCommand(CreateUpdateTabNavigationCommand( | 479 ScheduleCommand(CreateUpdateTabNavigationCommand( |
| 480 kCommandUpdateTabNavigation, | 480 kCommandUpdateTabNavigation, |
| 481 tab.id, | 481 tab.id, |
| 482 navigations[i])); | 482 navigations[i])); |
| 483 } | 483 } |
| 484 } | 484 } |
| 485 } | 485 } |
| 486 | 486 |
| 487 // static | 487 // static |
| 488 SessionCommand* PersistentTabRestoreService::Delegate::CreateWindowCommand( | 488 scoped_ptr<SessionCommand> |
| 489 PersistentTabRestoreService::Delegate::CreateWindowCommand( |
| 489 SessionID::id_type id, | 490 SessionID::id_type id, |
| 490 int selected_tab_index, | 491 int selected_tab_index, |
| 491 int num_tabs, | 492 int num_tabs, |
| 492 base::Time timestamp) { | 493 base::Time timestamp) { |
| 493 WindowPayload2 payload; | 494 WindowPayload2 payload; |
| 494 // |timestamp| is aligned on a 16 byte boundary, leaving 4 bytes of | 495 // |timestamp| is aligned on a 16 byte boundary, leaving 4 bytes of |
| 495 // uninitialized memory in the struct. | 496 // uninitialized memory in the struct. |
| 496 memset(&payload, 0, sizeof(payload)); | 497 memset(&payload, 0, sizeof(payload)); |
| 497 payload.window_id = id; | 498 payload.window_id = id; |
| 498 payload.selected_tab_index = selected_tab_index; | 499 payload.selected_tab_index = selected_tab_index; |
| 499 payload.num_tabs = num_tabs; | 500 payload.num_tabs = num_tabs; |
| 500 payload.timestamp = timestamp.ToInternalValue(); | 501 payload.timestamp = timestamp.ToInternalValue(); |
| 501 | 502 |
| 502 SessionCommand* command = | 503 scoped_ptr<SessionCommand> command( |
| 503 new SessionCommand(kCommandWindow, sizeof(payload)); | 504 new SessionCommand(kCommandWindow, sizeof(payload))); |
| 504 memcpy(command->contents(), &payload, sizeof(payload)); | 505 memcpy(command->contents(), &payload, sizeof(payload)); |
| 505 return command; | 506 return command; |
| 506 } | 507 } |
| 507 | 508 |
| 508 // static | 509 // static |
| 509 SessionCommand* | 510 scoped_ptr<SessionCommand> |
| 510 PersistentTabRestoreService::Delegate::CreateSelectedNavigationInTabCommand( | 511 PersistentTabRestoreService::Delegate::CreateSelectedNavigationInTabCommand( |
| 511 SessionID::id_type tab_id, | 512 SessionID::id_type tab_id, |
| 512 int32 index, | 513 int32 index, |
| 513 base::Time timestamp) { | 514 base::Time timestamp) { |
| 514 SelectedNavigationInTabPayload2 payload; | 515 SelectedNavigationInTabPayload2 payload; |
| 515 payload.id = tab_id; | 516 payload.id = tab_id; |
| 516 payload.index = index; | 517 payload.index = index; |
| 517 payload.timestamp = timestamp.ToInternalValue(); | 518 payload.timestamp = timestamp.ToInternalValue(); |
| 518 SessionCommand* command = | 519 scoped_ptr<SessionCommand> command( |
| 519 new SessionCommand(kCommandSelectedNavigationInTab, sizeof(payload)); | 520 new SessionCommand(kCommandSelectedNavigationInTab, sizeof(payload))); |
| 520 memcpy(command->contents(), &payload, sizeof(payload)); | 521 memcpy(command->contents(), &payload, sizeof(payload)); |
| 521 return command; | 522 return command; |
| 522 } | 523 } |
| 523 | 524 |
| 524 // static | 525 // static |
| 525 SessionCommand* | 526 scoped_ptr<SessionCommand> |
| 526 PersistentTabRestoreService::Delegate::CreateRestoredEntryCommand( | 527 PersistentTabRestoreService::Delegate::CreateRestoredEntryCommand( |
| 527 SessionID::id_type entry_id) { | 528 SessionID::id_type entry_id) { |
| 528 RestoredEntryPayload payload = entry_id; | 529 RestoredEntryPayload payload = entry_id; |
| 529 SessionCommand* command = | 530 scoped_ptr<SessionCommand> command( |
| 530 new SessionCommand(kCommandRestoredEntry, sizeof(payload)); | 531 new SessionCommand(kCommandRestoredEntry, sizeof(payload))); |
| 531 memcpy(command->contents(), &payload, sizeof(payload)); | 532 memcpy(command->contents(), &payload, sizeof(payload)); |
| 532 return command; | 533 return command; |
| 533 } | 534 } |
| 534 | 535 |
| 535 int PersistentTabRestoreService::Delegate::GetSelectedNavigationIndexToPersist( | 536 int PersistentTabRestoreService::Delegate::GetSelectedNavigationIndexToPersist( |
| 536 const Tab& tab) { | 537 const Tab& tab) { |
| 537 const std::vector<sessions::SerializedNavigationEntry>& navigations = | 538 const std::vector<sessions::SerializedNavigationEntry>& navigations = |
| 538 tab.navigations; | 539 tab.navigations; |
| 539 int selected_index = tab.current_navigation_index; | 540 int selected_index = tab.current_navigation_index; |
| 540 int max_index = static_cast<int>(navigations.size()); | 541 int max_index = static_cast<int>(navigations.size()); |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 } | 999 } |
| 999 | 1000 |
| 1000 void PersistentTabRestoreService::PruneEntries() { | 1001 void PersistentTabRestoreService::PruneEntries() { |
| 1001 helper_.PruneEntries(); | 1002 helper_.PruneEntries(); |
| 1002 } | 1003 } |
| 1003 | 1004 |
| 1004 KeyedService* TabRestoreServiceFactory::BuildServiceInstanceFor( | 1005 KeyedService* TabRestoreServiceFactory::BuildServiceInstanceFor( |
| 1005 content::BrowserContext* profile) const { | 1006 content::BrowserContext* profile) const { |
| 1006 return new PersistentTabRestoreService(static_cast<Profile*>(profile), NULL); | 1007 return new PersistentTabRestoreService(static_cast<Profile*>(profile), NULL); |
| 1007 } | 1008 } |
| OLD | NEW |