| 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> |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 has_open_trackable_browsers_(false), | 213 has_open_trackable_browsers_(false), |
| 214 move_on_new_browser_(false), | 214 move_on_new_browser_(false), |
| 215 save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)), | 215 save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)), |
| 216 save_delay_in_mins_(base::TimeDelta::FromMinutes(10)), | 216 save_delay_in_mins_(base::TimeDelta::FromMinutes(10)), |
| 217 save_delay_in_hrs_(base::TimeDelta::FromHours(8)), | 217 save_delay_in_hrs_(base::TimeDelta::FromHours(8)), |
| 218 force_browser_not_alive_with_no_windows_(false) { | 218 force_browser_not_alive_with_no_windows_(false) { |
| 219 Init(); | 219 Init(); |
| 220 } | 220 } |
| 221 | 221 |
| 222 SessionService::~SessionService() { | 222 SessionService::~SessionService() { |
| 223 for (BrowserList::const_iterator iter = BrowserList::begin(); |
| 224 iter != BrowserList::end(); ++iter) { |
| 225 OnBrowserRemoved(*iter); |
| 226 } |
| 227 BrowserList::RemoveObserver(this); |
| 223 Save(); | 228 Save(); |
| 224 } | 229 } |
| 225 | 230 |
| 226 bool SessionService::RestoreIfNecessary(const std::vector<GURL>& urls_to_open) { | 231 bool SessionService::RestoreIfNecessary(const std::vector<GURL>& urls_to_open) { |
| 227 return RestoreIfNecessary(urls_to_open, NULL); | 232 return RestoreIfNecessary(urls_to_open, NULL); |
| 228 } | 233 } |
| 229 | 234 |
| 230 void SessionService::ResetFromCurrentBrowsers() { | 235 void SessionService::ResetFromCurrentBrowsers() { |
| 231 ScheduleReset(); | 236 ScheduleReset(); |
| 232 } | 237 } |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 &last_updated_save_time_); | 519 &last_updated_save_time_); |
| 515 content::NotificationService::current()->Notify( | 520 content::NotificationService::current()->Notify( |
| 516 chrome::NOTIFICATION_SESSION_SERVICE_SAVED, | 521 chrome::NOTIFICATION_SESSION_SERVICE_SAVED, |
| 517 content::Source<Profile>(profile()), | 522 content::Source<Profile>(profile()), |
| 518 content::NotificationService::NoDetails()); | 523 content::NotificationService::NoDetails()); |
| 519 } | 524 } |
| 520 } | 525 } |
| 521 | 526 |
| 522 void SessionService::Init() { | 527 void SessionService::Init() { |
| 523 // Register for the notifications we're interested in. | 528 // Register for the notifications we're interested in. |
| 524 registrar_.Add(this, chrome::NOTIFICATION_TAB_PARENTED, | |
| 525 content::NotificationService::AllSources()); | |
| 526 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, | |
| 527 content::NotificationService::AllSources()); | |
| 528 registrar_.Add(this, content::NOTIFICATION_NAV_LIST_PRUNED, | 529 registrar_.Add(this, content::NOTIFICATION_NAV_LIST_PRUNED, |
| 529 content::NotificationService::AllSources()); | 530 content::NotificationService::AllSources()); |
| 530 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED, | 531 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED, |
| 531 content::NotificationService::AllSources()); | 532 content::NotificationService::AllSources()); |
| 532 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 533 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
| 533 content::NotificationService::AllSources()); | 534 content::NotificationService::AllSources()); |
| 534 // Wait for NOTIFICATION_BROWSER_WINDOW_READY so that is_app() is set. | 535 // Wait for NOTIFICATION_BROWSER_WINDOW_READY so that is_app() is set. |
| 535 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY, | 536 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY, |
| 536 content::NotificationService::AllBrowserContextsAndSources()); | 537 content::NotificationService::AllBrowserContextsAndSources()); |
| 537 registrar_.Add( | 538 registrar_.Add( |
| 538 this, chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED, | 539 this, chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED, |
| 539 content::NotificationService::AllSources()); | 540 content::NotificationService::AllSources()); |
| 541 BrowserList::AddObserver(this); |
| 542 for (BrowserList::const_iterator iter = BrowserList::begin(); |
| 543 iter != BrowserList::end(); ++iter) { |
| 544 OnBrowserAdded(*iter); |
| 545 } |
| 540 } | 546 } |
| 541 | 547 |
| 542 bool SessionService::ShouldNewWindowStartSession() { | 548 bool SessionService::ShouldNewWindowStartSession() { |
| 543 // ChromeOS and OSX have different ideas of application lifetime than | 549 // ChromeOS and OSX have different ideas of application lifetime than |
| 544 // the other platforms. | 550 // the other platforms. |
| 545 // On ChromeOS opening a new window should never start a new session. | 551 // On ChromeOS opening a new window should never start a new session. |
| 546 #if defined(OS_CHROMEOS) | 552 #if defined(OS_CHROMEOS) |
| 547 if (!force_browser_not_alive_with_no_windows_) | 553 if (!force_browser_not_alive_with_no_windows_) |
| 548 return false; | 554 return false; |
| 549 #endif | 555 #endif |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 if (browser->profile() != profile() || | 601 if (browser->profile() != profile() || |
| 596 !should_track_changes_for_browser_type(browser->type(), app_type)) | 602 !should_track_changes_for_browser_type(browser->type(), app_type)) |
| 597 return; | 603 return; |
| 598 | 604 |
| 599 RestoreIfNecessary(std::vector<GURL>(), browser); | 605 RestoreIfNecessary(std::vector<GURL>(), browser); |
| 600 SetWindowType(browser->session_id(), browser->type(), app_type); | 606 SetWindowType(browser->session_id(), browser->type(), app_type); |
| 601 SetWindowAppName(browser->session_id(), browser->app_name()); | 607 SetWindowAppName(browser->session_id(), browser->app_name()); |
| 602 break; | 608 break; |
| 603 } | 609 } |
| 604 | 610 |
| 605 case chrome::NOTIFICATION_TAB_PARENTED: { | |
| 606 WebContents* web_contents = content::Source<WebContents>(source).ptr(); | |
| 607 if (web_contents->GetBrowserContext() != profile()) | |
| 608 return; | |
| 609 SessionTabHelper* session_tab_helper = | |
| 610 SessionTabHelper::FromWebContents(web_contents); | |
| 611 SetTabWindow(session_tab_helper->window_id(), | |
| 612 session_tab_helper->session_id()); | |
| 613 extensions::TabHelper* extensions_tab_helper = | |
| 614 extensions::TabHelper::FromWebContents(web_contents); | |
| 615 if (extensions_tab_helper && | |
| 616 extensions_tab_helper->extension_app()) { | |
| 617 SetTabExtensionAppID( | |
| 618 session_tab_helper->window_id(), | |
| 619 session_tab_helper->session_id(), | |
| 620 extensions_tab_helper->extension_app()->id()); | |
| 621 } | |
| 622 | |
| 623 // Record the association between the SessionStorageNamespace and the | |
| 624 // tab. | |
| 625 // | |
| 626 // TODO(ajwong): This should be processing the whole map rather than | |
| 627 // just the default. This in particular will not work for tabs with only | |
| 628 // isolated apps which won't have a default partition. | |
| 629 content::SessionStorageNamespace* session_storage_namespace = | |
| 630 web_contents->GetController().GetDefaultSessionStorageNamespace(); | |
| 631 ScheduleCommand(CreateSessionStorageAssociatedCommand( | |
| 632 session_tab_helper->session_id(), | |
| 633 session_storage_namespace->persistent_id())); | |
| 634 session_storage_namespace->SetShouldPersist(true); | |
| 635 break; | |
| 636 } | |
| 637 | |
| 638 case chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED: { | |
| 639 TabContents* tab = content::Source<TabContents>(source).ptr(); | |
| 640 if (!tab || tab->profile() != profile()) | |
| 641 return; | |
| 642 // Allow the associated sessionStorage to get deleted; it won't be needed | |
| 643 // in the session restore. | |
| 644 content::SessionStorageNamespace* session_storage_namespace = | |
| 645 tab->web_contents()->GetController(). | |
| 646 GetDefaultSessionStorageNamespace(); | |
| 647 session_storage_namespace->SetShouldPersist(false); | |
| 648 SessionTabHelper* session_tab_helper = | |
| 649 SessionTabHelper::FromWebContents(tab->web_contents()); | |
| 650 TabClosed(session_tab_helper->window_id(), | |
| 651 session_tab_helper->session_id(), | |
| 652 tab->web_contents()->GetClosedByUserGesture()); | |
| 653 RecordSessionUpdateHistogramData(type, &last_updated_tab_closed_time_); | |
| 654 break; | |
| 655 } | |
| 656 | |
| 657 case content::NOTIFICATION_NAV_LIST_PRUNED: { | 611 case content::NOTIFICATION_NAV_LIST_PRUNED: { |
| 658 WebContents* web_contents = | 612 WebContents* web_contents = |
| 659 content::Source<content::NavigationController>(source).ptr()-> | 613 content::Source<content::NavigationController>(source).ptr()-> |
| 660 GetWebContents(); | 614 GetWebContents(); |
| 661 SessionTabHelper* session_tab_helper = | 615 SessionTabHelper* session_tab_helper = |
| 662 SessionTabHelper::FromWebContents(web_contents); | 616 SessionTabHelper::FromWebContents(web_contents); |
| 663 if (!session_tab_helper || web_contents->GetBrowserContext() != profile()) | 617 if (!session_tab_helper || web_contents->GetBrowserContext() != profile()) |
| 664 return; | 618 return; |
| 665 content::Details<content::PrunedDetails> pruned_details(details); | 619 content::Details<content::PrunedDetails> pruned_details(details); |
| 666 if (pruned_details->from_front) { | 620 if (pruned_details->from_front) { |
| (...skipping 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1756 50); | 1710 50); |
| 1757 if (use_long_period) { | 1711 if (use_long_period) { |
| 1758 std::string long_name_("SessionRestore.SaveLongPeriod"); | 1712 std::string long_name_("SessionRestore.SaveLongPeriod"); |
| 1759 UMA_HISTOGRAM_CUSTOM_TIMES(long_name_, | 1713 UMA_HISTOGRAM_CUSTOM_TIMES(long_name_, |
| 1760 delta, | 1714 delta, |
| 1761 save_delay_in_mins_, | 1715 save_delay_in_mins_, |
| 1762 save_delay_in_hrs_, | 1716 save_delay_in_hrs_, |
| 1763 50); | 1717 50); |
| 1764 } | 1718 } |
| 1765 } | 1719 } |
| 1720 |
| 1721 void SessionService::OnBrowserAdded(Browser* browser) { |
| 1722 if (!profile() || !profile()->IsSameProfile(browser->profile())) |
| 1723 return; |
| 1724 browser->tab_strip_model()->AddObserver(this); |
| 1725 } |
| 1726 |
| 1727 void SessionService::OnBrowserRemoved(Browser* browser) { |
| 1728 if (!profile() || !profile()->IsSameProfile(browser->profile())) |
| 1729 return; |
| 1730 browser->tab_strip_model()->RemoveObserver(this); |
| 1731 } |
| 1732 |
| 1733 void SessionService::TabInsertedAt(TabContents* contents, |
| 1734 int index, |
| 1735 bool foreground) { |
| 1736 if (contents->profile() != profile()) |
| 1737 return; |
| 1738 WebContents* web_contents = contents->web_contents(); |
| 1739 SessionTabHelper* session_tab_helper = |
| 1740 SessionTabHelper::FromWebContents(web_contents); |
| 1741 SetTabWindow(session_tab_helper->window_id(), |
| 1742 session_tab_helper->session_id()); |
| 1743 extensions::TabHelper* extensions_tab_helper = |
| 1744 extensions::TabHelper::FromWebContents(web_contents); |
| 1745 if (extensions_tab_helper && |
| 1746 extensions_tab_helper->extension_app()) { |
| 1747 SetTabExtensionAppID( |
| 1748 session_tab_helper->window_id(), |
| 1749 session_tab_helper->session_id(), |
| 1750 extensions_tab_helper->extension_app()->id()); |
| 1751 } |
| 1752 |
| 1753 // Record the association between the SessionStorageNamespace and the |
| 1754 // tab. |
| 1755 // |
| 1756 // TODO(ajwong): This should be processing the whole map rather than |
| 1757 // just the default. This in particular will not work for tabs with only |
| 1758 // isolated apps which won't have a default partition. |
| 1759 content::SessionStorageNamespace* session_storage_namespace = |
| 1760 web_contents->GetController().GetDefaultSessionStorageNamespace(); |
| 1761 ScheduleCommand(CreateSessionStorageAssociatedCommand( |
| 1762 session_tab_helper->session_id(), |
| 1763 session_storage_namespace->persistent_id())); |
| 1764 session_storage_namespace->SetShouldPersist(true); |
| 1765 } |
| 1766 |
| 1767 void SessionService::TabClosingAt(TabStripModel* tab_strip_model, |
| 1768 TabContents* contents, |
| 1769 int index) { |
| 1770 if (!contents || contents->profile() != profile()) |
| 1771 return; |
| 1772 WebContents* web_contents = contents->web_contents(); |
| 1773 // Allow the associated sessionStorage to get deleted; it won't be needed |
| 1774 // in the session restore. |
| 1775 content::SessionStorageNamespace* session_storage_namespace = |
| 1776 web_contents->GetController().GetDefaultSessionStorageNamespace(); |
| 1777 session_storage_namespace->SetShouldPersist(false); |
| 1778 SessionTabHelper* session_tab_helper = |
| 1779 SessionTabHelper::FromWebContents(web_contents); |
| 1780 TabClosed(session_tab_helper->window_id(), |
| 1781 session_tab_helper->session_id(), |
| 1782 web_contents->GetClosedByUserGesture()); |
| 1783 RecordSessionUpdateHistogramData(chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, |
| 1784 &last_updated_tab_closed_time_); |
| 1785 } |
| 1786 |
| 1787 void SessionService::TabReplacedAt(TabStripModel* tab_strip_model, |
| 1788 TabContents* old_contents, |
| 1789 TabContents* new_contents, |
| 1790 int index) { |
| 1791 TabClosingAt(tab_strip_model, old_contents, index); |
| 1792 TabInsertedAt(new_contents, index, true /* foreground is not used */); |
| 1793 } |
| OLD | NEW |