| 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/session_service.h" | 5 #include "chrome/browser/sessions/session_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
| 14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 15 #include "base/file_util.h" | 15 #include "base/file_util.h" |
| 16 #include "base/memory/scoped_vector.h" | 16 #include "base/memory/scoped_vector.h" |
| 17 #include "base/message_loop.h" | 17 #include "base/message_loop.h" |
| 18 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
| 19 #include "base/pickle.h" | 19 #include "base/pickle.h" |
| 20 #include "base/threading/thread.h" | 20 #include "base/threading/thread.h" |
| 21 #include "chrome/browser/extensions/tab_helper.h" | 21 #include "chrome/browser/extensions/tab_helper.h" |
| 22 #include "chrome/browser/prefs/session_startup_pref.h" | 22 #include "chrome/browser/prefs/session_startup_pref.h" |
| 23 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
| 24 #include "chrome/browser/sessions/restore_tab_helper.h" | |
| 25 #include "chrome/browser/sessions/session_backend.h" | 24 #include "chrome/browser/sessions/session_backend.h" |
| 26 #include "chrome/browser/sessions/session_command.h" | 25 #include "chrome/browser/sessions/session_command.h" |
| 27 #include "chrome/browser/sessions/session_restore.h" | 26 #include "chrome/browser/sessions/session_restore.h" |
| 27 #include "chrome/browser/sessions/session_tab_helper.h" |
| 28 #include "chrome/browser/sessions/session_types.h" | 28 #include "chrome/browser/sessions/session_types.h" |
| 29 #include "chrome/browser/ui/browser_list.h" | 29 #include "chrome/browser/ui/browser_list.h" |
| 30 #include "chrome/browser/ui/browser_tabstrip.h" | 30 #include "chrome/browser/ui/browser_tabstrip.h" |
| 31 #include "chrome/browser/ui/browser_window.h" | 31 #include "chrome/browser/ui/browser_window.h" |
| 32 #include "chrome/browser/ui/startup/startup_browser_creator.h" | 32 #include "chrome/browser/ui/startup/startup_browser_creator.h" |
| 33 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 33 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
| 34 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 34 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 35 #include "chrome/common/chrome_notification_types.h" | 35 #include "chrome/common/chrome_notification_types.h" |
| 36 #include "chrome/common/extensions/extension.h" | 36 #include "chrome/common/extensions/extension.h" |
| 37 #include "content/public/browser/navigation_details.h" | 37 #include "content/public/browser/navigation_details.h" |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 tab_to_available_range_.end()) { | 440 tab_to_available_range_.end()) { |
| 441 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; | 441 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; |
| 442 range.first = std::min(index, range.first); | 442 range.first = std::min(index, range.first); |
| 443 range.second = std::max(index, range.second); | 443 range.second = std::max(index, range.second); |
| 444 } | 444 } |
| 445 ScheduleCommand(CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation, | 445 ScheduleCommand(CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation, |
| 446 tab_id.id(), index, entry)); | 446 tab_id.id(), index, entry)); |
| 447 } | 447 } |
| 448 | 448 |
| 449 void SessionService::TabRestored(TabContents* tab, bool pinned) { | 449 void SessionService::TabRestored(TabContents* tab, bool pinned) { |
| 450 if (!ShouldTrackChangesToWindow(tab->restore_tab_helper()->window_id())) | 450 if (!ShouldTrackChangesToWindow(tab->session_tab_helper()->window_id())) |
| 451 return; | 451 return; |
| 452 | 452 |
| 453 BuildCommandsForTab(tab->restore_tab_helper()->window_id(), tab, -1, | 453 BuildCommandsForTab(tab->session_tab_helper()->window_id(), tab, -1, |
| 454 pinned, &pending_commands(), NULL); | 454 pinned, &pending_commands(), NULL); |
| 455 StartSaveTimer(); | 455 StartSaveTimer(); |
| 456 } | 456 } |
| 457 | 457 |
| 458 void SessionService::SetSelectedNavigationIndex(const SessionID& window_id, | 458 void SessionService::SetSelectedNavigationIndex(const SessionID& window_id, |
| 459 const SessionID& tab_id, | 459 const SessionID& tab_id, |
| 460 int index) { | 460 int index) { |
| 461 if (!ShouldTrackChangesToWindow(window_id)) | 461 if (!ShouldTrackChangesToWindow(window_id)) |
| 462 return; | 462 return; |
| 463 | 463 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 RestoreIfNecessary(std::vector<GURL>(), browser); | 600 RestoreIfNecessary(std::vector<GURL>(), browser); |
| 601 SetWindowType(browser->session_id(), browser->type(), app_type); | 601 SetWindowType(browser->session_id(), browser->type(), app_type); |
| 602 SetWindowAppName(browser->session_id(), browser->app_name()); | 602 SetWindowAppName(browser->session_id(), browser->app_name()); |
| 603 break; | 603 break; |
| 604 } | 604 } |
| 605 | 605 |
| 606 case chrome::NOTIFICATION_TAB_PARENTED: { | 606 case chrome::NOTIFICATION_TAB_PARENTED: { |
| 607 TabContents* tab = content::Source<TabContents>(source).ptr(); | 607 TabContents* tab = content::Source<TabContents>(source).ptr(); |
| 608 if (tab->profile() != profile()) | 608 if (tab->profile() != profile()) |
| 609 return; | 609 return; |
| 610 SetTabWindow(tab->restore_tab_helper()->window_id(), | 610 SetTabWindow(tab->session_tab_helper()->window_id(), |
| 611 tab->restore_tab_helper()->session_id()); | 611 tab->session_tab_helper()->session_id()); |
| 612 if (tab->extension_tab_helper()->extension_app()) { | 612 if (tab->extension_tab_helper()->extension_app()) { |
| 613 SetTabExtensionAppID( | 613 SetTabExtensionAppID( |
| 614 tab->restore_tab_helper()->window_id(), | 614 tab->session_tab_helper()->window_id(), |
| 615 tab->restore_tab_helper()->session_id(), | 615 tab->session_tab_helper()->session_id(), |
| 616 tab->extension_tab_helper()->extension_app()->id()); | 616 tab->extension_tab_helper()->extension_app()->id()); |
| 617 } | 617 } |
| 618 | 618 |
| 619 // Record the association between the SessionStorageNamespace and the | 619 // Record the association between the SessionStorageNamespace and the |
| 620 // tab. | 620 // tab. |
| 621 // | 621 // |
| 622 // TODO(ajwong): This should be processing the whole map rather than | 622 // TODO(ajwong): This should be processing the whole map rather than |
| 623 // just the default. This in particular will not work for tabs with only | 623 // just the default. This in particular will not work for tabs with only |
| 624 // isolated apps which won't have a default partition. | 624 // isolated apps which won't have a default partition. |
| 625 content::SessionStorageNamespace* session_storage_namespace = | 625 content::SessionStorageNamespace* session_storage_namespace = |
| 626 tab->web_contents()->GetController(). | 626 tab->web_contents()->GetController(). |
| 627 GetDefaultSessionStorageNamespace(); | 627 GetDefaultSessionStorageNamespace(); |
| 628 ScheduleCommand(CreateSessionStorageAssociatedCommand( | 628 ScheduleCommand(CreateSessionStorageAssociatedCommand( |
| 629 tab->restore_tab_helper()->session_id(), | 629 tab->session_tab_helper()->session_id(), |
| 630 session_storage_namespace->persistent_id())); | 630 session_storage_namespace->persistent_id())); |
| 631 session_storage_namespace->SetShouldPersist(true); | 631 session_storage_namespace->SetShouldPersist(true); |
| 632 break; | 632 break; |
| 633 } | 633 } |
| 634 | 634 |
| 635 case chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED: { | 635 case chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED: { |
| 636 TabContents* tab = content::Source<TabContents>(source).ptr(); | 636 TabContents* tab = content::Source<TabContents>(source).ptr(); |
| 637 if (!tab || tab->profile() != profile()) | 637 if (!tab || tab->profile() != profile()) |
| 638 return; | 638 return; |
| 639 // Allow the associated sessionStorage to get deleted; it won't be needed | 639 // Allow the associated sessionStorage to get deleted; it won't be needed |
| 640 // in the session restore. | 640 // in the session restore. |
| 641 content::SessionStorageNamespace* session_storage_namespace = | 641 content::SessionStorageNamespace* session_storage_namespace = |
| 642 tab->web_contents()->GetController(). | 642 tab->web_contents()->GetController(). |
| 643 GetDefaultSessionStorageNamespace(); | 643 GetDefaultSessionStorageNamespace(); |
| 644 session_storage_namespace->SetShouldPersist(false); | 644 session_storage_namespace->SetShouldPersist(false); |
| 645 TabClosed(tab->restore_tab_helper()->window_id(), | 645 TabClosed(tab->session_tab_helper()->window_id(), |
| 646 tab->restore_tab_helper()->session_id(), | 646 tab->session_tab_helper()->session_id(), |
| 647 tab->web_contents()->GetClosedByUserGesture()); | 647 tab->web_contents()->GetClosedByUserGesture()); |
| 648 RecordSessionUpdateHistogramData(type, &last_updated_tab_closed_time_); | 648 RecordSessionUpdateHistogramData(type, &last_updated_tab_closed_time_); |
| 649 break; | 649 break; |
| 650 } | 650 } |
| 651 | 651 |
| 652 case content::NOTIFICATION_NAV_LIST_PRUNED: { | 652 case content::NOTIFICATION_NAV_LIST_PRUNED: { |
| 653 TabContents* tab = TabContents::FromWebContents( | 653 TabContents* tab = TabContents::FromWebContents( |
| 654 content::Source<content::NavigationController>(source).ptr()-> | 654 content::Source<content::NavigationController>(source).ptr()-> |
| 655 GetWebContents()); | 655 GetWebContents()); |
| 656 if (!tab || tab->profile() != profile()) | 656 if (!tab || tab->profile() != profile()) |
| 657 return; | 657 return; |
| 658 content::Details<content::PrunedDetails> pruned_details(details); | 658 content::Details<content::PrunedDetails> pruned_details(details); |
| 659 if (pruned_details->from_front) { | 659 if (pruned_details->from_front) { |
| 660 TabNavigationPathPrunedFromFront( | 660 TabNavigationPathPrunedFromFront( |
| 661 tab->restore_tab_helper()->window_id(), | 661 tab->session_tab_helper()->window_id(), |
| 662 tab->restore_tab_helper()->session_id(), | 662 tab->session_tab_helper()->session_id(), |
| 663 pruned_details->count); | 663 pruned_details->count); |
| 664 } else { | 664 } else { |
| 665 TabNavigationPathPrunedFromBack( | 665 TabNavigationPathPrunedFromBack( |
| 666 tab->restore_tab_helper()->window_id(), | 666 tab->session_tab_helper()->window_id(), |
| 667 tab->restore_tab_helper()->session_id(), | 667 tab->session_tab_helper()->session_id(), |
| 668 tab->web_contents()->GetController().GetEntryCount()); | 668 tab->web_contents()->GetController().GetEntryCount()); |
| 669 } | 669 } |
| 670 RecordSessionUpdateHistogramData(content::NOTIFICATION_NAV_LIST_PRUNED, | 670 RecordSessionUpdateHistogramData(content::NOTIFICATION_NAV_LIST_PRUNED, |
| 671 &last_updated_nav_list_pruned_time_); | 671 &last_updated_nav_list_pruned_time_); |
| 672 break; | 672 break; |
| 673 } | 673 } |
| 674 | 674 |
| 675 case content::NOTIFICATION_NAV_ENTRY_CHANGED: { | 675 case content::NOTIFICATION_NAV_ENTRY_CHANGED: { |
| 676 TabContents* tab = TabContents::FromWebContents( | 676 TabContents* tab = TabContents::FromWebContents( |
| 677 content::Source<content::NavigationController>(source).ptr()-> | 677 content::Source<content::NavigationController>(source).ptr()-> |
| 678 GetWebContents()); | 678 GetWebContents()); |
| 679 if (!tab || tab->profile() != profile()) | 679 if (!tab || tab->profile() != profile()) |
| 680 return; | 680 return; |
| 681 content::Details<content::EntryChangedDetails> changed(details); | 681 content::Details<content::EntryChangedDetails> changed(details); |
| 682 UpdateTabNavigation( | 682 UpdateTabNavigation( |
| 683 tab->restore_tab_helper()->window_id(), | 683 tab->session_tab_helper()->window_id(), |
| 684 tab->restore_tab_helper()->session_id(), | 684 tab->session_tab_helper()->session_id(), |
| 685 changed->index, *changed->changed_entry); | 685 changed->index, *changed->changed_entry); |
| 686 break; | 686 break; |
| 687 } | 687 } |
| 688 | 688 |
| 689 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { | 689 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { |
| 690 TabContents* tab = TabContents::FromWebContents( | 690 TabContents* tab = TabContents::FromWebContents( |
| 691 content::Source<content::NavigationController>(source).ptr()-> | 691 content::Source<content::NavigationController>(source).ptr()-> |
| 692 GetWebContents()); | 692 GetWebContents()); |
| 693 if (!tab || tab->profile() != profile()) | 693 if (!tab || tab->profile() != profile()) |
| 694 return; | 694 return; |
| 695 int current_entry_index = | 695 int current_entry_index = |
| 696 tab->web_contents()->GetController().GetCurrentEntryIndex(); | 696 tab->web_contents()->GetController().GetCurrentEntryIndex(); |
| 697 SetSelectedNavigationIndex(tab->restore_tab_helper()->window_id(), | 697 SetSelectedNavigationIndex(tab->session_tab_helper()->window_id(), |
| 698 tab->restore_tab_helper()->session_id(), | 698 tab->session_tab_helper()->session_id(), |
| 699 current_entry_index); | 699 current_entry_index); |
| 700 UpdateTabNavigation( | 700 UpdateTabNavigation( |
| 701 tab->restore_tab_helper()->window_id(), | 701 tab->session_tab_helper()->window_id(), |
| 702 tab->restore_tab_helper()->session_id(), | 702 tab->session_tab_helper()->session_id(), |
| 703 current_entry_index, | 703 current_entry_index, |
| 704 *tab->web_contents()->GetController().GetEntryAtIndex( | 704 *tab->web_contents()->GetController().GetEntryAtIndex( |
| 705 current_entry_index)); | 705 current_entry_index)); |
| 706 content::Details<content::LoadCommittedDetails> changed(details); | 706 content::Details<content::LoadCommittedDetails> changed(details); |
| 707 if (changed->type == content::NAVIGATION_TYPE_NEW_PAGE || | 707 if (changed->type == content::NAVIGATION_TYPE_NEW_PAGE || |
| 708 changed->type == content::NAVIGATION_TYPE_EXISTING_PAGE) { | 708 changed->type == content::NAVIGATION_TYPE_EXISTING_PAGE) { |
| 709 RecordSessionUpdateHistogramData( | 709 RecordSessionUpdateHistogramData( |
| 710 content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 710 content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
| 711 &last_updated_nav_entry_commit_time_); | 711 &last_updated_nav_entry_commit_time_); |
| 712 } | 712 } |
| 713 break; | 713 break; |
| 714 } | 714 } |
| 715 | 715 |
| 716 case chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED: { | 716 case chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED: { |
| 717 extensions::TabHelper* extension_tab_helper = | 717 extensions::TabHelper* extension_tab_helper = |
| 718 content::Source<extensions::TabHelper>(source).ptr(); | 718 content::Source<extensions::TabHelper>(source).ptr(); |
| 719 if (extension_tab_helper->tab_contents()->profile() != profile()) | 719 if (extension_tab_helper->tab_contents()->profile() != profile()) |
| 720 return; | 720 return; |
| 721 if (extension_tab_helper->extension_app()) { | 721 if (extension_tab_helper->extension_app()) { |
| 722 RestoreTabHelper* helper = | 722 SessionTabHelper* helper = |
| 723 extension_tab_helper->tab_contents()->restore_tab_helper(); | 723 extension_tab_helper->tab_contents()->session_tab_helper(); |
| 724 SetTabExtensionAppID(helper->window_id(), | 724 SetTabExtensionAppID(helper->window_id(), |
| 725 helper->session_id(), | 725 helper->session_id(), |
| 726 extension_tab_helper->extension_app()->id()); | 726 extension_tab_helper->extension_app()->id()); |
| 727 } | 727 } |
| 728 break; | 728 break; |
| 729 } | 729 } |
| 730 | 730 |
| 731 default: | 731 default: |
| 732 NOTREACHED(); | 732 NOTREACHED(); |
| 733 } | 733 } |
| (...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1289 } | 1289 } |
| 1290 | 1290 |
| 1291 void SessionService::BuildCommandsForTab( | 1291 void SessionService::BuildCommandsForTab( |
| 1292 const SessionID& window_id, | 1292 const SessionID& window_id, |
| 1293 TabContents* tab, | 1293 TabContents* tab, |
| 1294 int index_in_window, | 1294 int index_in_window, |
| 1295 bool is_pinned, | 1295 bool is_pinned, |
| 1296 std::vector<SessionCommand*>* commands, | 1296 std::vector<SessionCommand*>* commands, |
| 1297 IdToRange* tab_to_available_range) { | 1297 IdToRange* tab_to_available_range) { |
| 1298 DCHECK(tab && commands && window_id.id()); | 1298 DCHECK(tab && commands && window_id.id()); |
| 1299 const SessionID& session_id(tab->restore_tab_helper()->session_id()); | 1299 const SessionID& session_id(tab->session_tab_helper()->session_id()); |
| 1300 commands->push_back(CreateSetTabWindowCommand(window_id, session_id)); | 1300 commands->push_back(CreateSetTabWindowCommand(window_id, session_id)); |
| 1301 | 1301 |
| 1302 const int current_index = | 1302 const int current_index = |
| 1303 tab->web_contents()->GetController().GetCurrentEntryIndex(); | 1303 tab->web_contents()->GetController().GetCurrentEntryIndex(); |
| 1304 const int min_index = std::max(0, | 1304 const int min_index = std::max(0, |
| 1305 current_index - max_persist_navigation_count); | 1305 current_index - max_persist_navigation_count); |
| 1306 const int max_index = | 1306 const int max_index = |
| 1307 std::min(current_index + max_persist_navigation_count, | 1307 std::min(current_index + max_persist_navigation_count, |
| 1308 tab->web_contents()->GetController().GetEntryCount()); | 1308 tab->web_contents()->GetController().GetEntryCount()); |
| 1309 const int pending_index = | 1309 const int pending_index = |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1347 | 1347 |
| 1348 if (index_in_window != -1) { | 1348 if (index_in_window != -1) { |
| 1349 commands->push_back( | 1349 commands->push_back( |
| 1350 CreateSetTabIndexInWindowCommand(session_id, index_in_window)); | 1350 CreateSetTabIndexInWindowCommand(session_id, index_in_window)); |
| 1351 } | 1351 } |
| 1352 | 1352 |
| 1353 // Record the association between the sessionStorage namespace and the tab. | 1353 // Record the association between the sessionStorage namespace and the tab. |
| 1354 content::SessionStorageNamespace* session_storage_namespace = | 1354 content::SessionStorageNamespace* session_storage_namespace = |
| 1355 tab->web_contents()->GetController().GetDefaultSessionStorageNamespace(); | 1355 tab->web_contents()->GetController().GetDefaultSessionStorageNamespace(); |
| 1356 ScheduleCommand(CreateSessionStorageAssociatedCommand( | 1356 ScheduleCommand(CreateSessionStorageAssociatedCommand( |
| 1357 tab->restore_tab_helper()->session_id(), | 1357 tab->session_tab_helper()->session_id(), |
| 1358 session_storage_namespace->persistent_id())); | 1358 session_storage_namespace->persistent_id())); |
| 1359 } | 1359 } |
| 1360 | 1360 |
| 1361 void SessionService::BuildCommandsForBrowser( | 1361 void SessionService::BuildCommandsForBrowser( |
| 1362 Browser* browser, | 1362 Browser* browser, |
| 1363 std::vector<SessionCommand*>* commands, | 1363 std::vector<SessionCommand*>* commands, |
| 1364 IdToRange* tab_to_available_range, | 1364 IdToRange* tab_to_available_range, |
| 1365 std::set<SessionID::id_type>* windows_to_track) { | 1365 std::set<SessionID::id_type>* windows_to_track) { |
| 1366 DCHECK(browser && commands); | 1366 DCHECK(browser && commands); |
| 1367 DCHECK(browser->session_id().id()); | 1367 DCHECK(browser->session_id().id()); |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1731 50); | 1731 50); |
| 1732 if (use_long_period) { | 1732 if (use_long_period) { |
| 1733 std::string long_name_("SessionRestore.SaveLongPeriod"); | 1733 std::string long_name_("SessionRestore.SaveLongPeriod"); |
| 1734 UMA_HISTOGRAM_CUSTOM_TIMES(long_name_, | 1734 UMA_HISTOGRAM_CUSTOM_TIMES(long_name_, |
| 1735 delta, | 1735 delta, |
| 1736 save_delay_in_mins_, | 1736 save_delay_in_mins_, |
| 1737 save_delay_in_hrs_, | 1737 save_delay_in_hrs_, |
| 1738 50); | 1738 50); |
| 1739 } | 1739 } |
| 1740 } | 1740 } |
| OLD | NEW |