1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/metrics/user_metrics_action.h" 6 #include "base/supports_user_data.h" 7 #include "chrome/browser/profiles/profile.h" 8 #include "chrome/browser/sessions/tab_restore_service.h" 9 #include "chrome/browser/sessions/tab_restore_service_factory.h" 10 #include "chrome/browser/sessions/tab_restore_service_observer.h" 11 #include "chrome/browser/ui/browser.h" 12 #include "chrome/browser/ui/browser_commands.h" 13 #include "chrome/browser/ui/browser_list.h" 14 #include "chrome/browser/ui/browser_list_observer.h" 15 #include "chrome/browser/ui/browser_tab_restore_service_delegate.h" 16 #include "content/public/browser/user_metrics.h" 17 18 namespace chrome { 19 namespace { 20 21 const char kBrowserTabRestorerKey[] = "BrowserTabRestorer"; 22 23 // BrowserTabRestorer is responsible for restoring a tab when the 24 // TabRestoreService finishes loading. A TabRestoreService is associated with a 25 // single Browser and deletes itself if the Browser is destroyed. 26 // BrowserTabRestorer is installed on the Profile (by way of user data), only 27 // one instance is created per profile at a time. 28 class BrowserTabRestorer : public TabRestoreServiceObserver, 29 public chrome::BrowserListObserver, 30 public base::SupportsUserData::Data { 31 public: 32 virtual ~BrowserTabRestorer(); 33 34 static void CreateIfNecessary(Browser* browser); 35 36 private: 37 explicit BrowserTabRestorer(Browser* browser); 38 39 // TabRestoreServiceObserver: 40 virtual void TabRestoreServiceChanged(TabRestoreService* service) OVERRIDE; 41 virtual void TabRestoreServiceDestroyed(TabRestoreService* service) OVERRIDE; 42 virtual void TabRestoreServiceLoaded(TabRestoreService* service) OVERRIDE; 43 44 // BrowserListObserver: 45 virtual void OnBrowserRemoved(Browser* browser) OVERRIDE; 46 47 Browser* browser_; 48 TabRestoreService* tab_restore_service_; 49 50 DISALLOW_COPY_AND_ASSIGN(BrowserTabRestorer); 51 }; 52 ~BrowserTabRestorer()53BrowserTabRestorer::~BrowserTabRestorer() { 54 tab_restore_service_->RemoveObserver(this); 55 BrowserList::GetInstance(browser_->host_desktop_type())->RemoveObserver(this); 56 } 57 58 // static CreateIfNecessary(Browser * browser)59void BrowserTabRestorer::CreateIfNecessary(Browser* browser) { 60 DCHECK(browser); 61 if (browser->profile()->GetUserData(kBrowserTabRestorerKey)) 62 return; // Only allow one restore for a given profile at a time. 63 64 // BrowserTabRestorer is deleted at the appropriate time. 65 new BrowserTabRestorer(browser); 66 } 67 BrowserTabRestorer(Browser * browser)68BrowserTabRestorer::BrowserTabRestorer(Browser* browser) 69 : browser_(browser), 70 tab_restore_service_( 71 TabRestoreServiceFactory::GetForProfile(browser->profile())) { 72 DCHECK(tab_restore_service_); 73 DCHECK(!tab_restore_service_->IsLoaded()); 74 tab_restore_service_->AddObserver(this); 75 BrowserList::GetInstance(browser->host_desktop_type())->AddObserver(this); 76 browser_->profile()->SetUserData(kBrowserTabRestorerKey, this); 77 tab_restore_service_->LoadTabsFromLastSession(); 78 } 79 TabRestoreServiceChanged(TabRestoreService * service)80void BrowserTabRestorer::TabRestoreServiceChanged(TabRestoreService* service) { 81 } 82 TabRestoreServiceDestroyed(TabRestoreService * service)83void BrowserTabRestorer::TabRestoreServiceDestroyed( 84 TabRestoreService* service) { 85 } 86 TabRestoreServiceLoaded(TabRestoreService * service)87void BrowserTabRestorer::TabRestoreServiceLoaded(TabRestoreService* service) { 88 RestoreTab(browser_); 89 // This deletes us. 90 browser_->profile()->SetUserData(kBrowserTabRestorerKey, NULL); 91 } 92 OnBrowserRemoved(Browser * browser)93void BrowserTabRestorer::OnBrowserRemoved(Browser* browser) { 94 // This deletes us. 95 browser_->profile()->SetUserData(kBrowserTabRestorerKey, NULL); 96 } 97 98 } // namespace 99 RestoreTab(Browser * browser)100void RestoreTab(Browser* browser) { 101 content::RecordAction(base::UserMetricsAction("RestoreTab")); 102 TabRestoreService* service = 103 TabRestoreServiceFactory::GetForProfile(browser->profile()); 104 if (!service) 105 return; 106 107 if (service->IsLoaded()) { 108 service->RestoreMostRecentEntry(browser->tab_restore_service_delegate(), 109 browser->host_desktop_type()); 110 return; 111 } 112 113 BrowserTabRestorer::CreateIfNecessary(browser); 114 } 115 116 } // namespace chrome 117