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) { | |
sky
2012/09/21 16:26:31
Can we move the implementation of observing Browse
marja
2012/09/24 09:23:09
Ok, it seems that Browser already has this logic t
| |
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 |