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 18namespace chrome { 19namespace { 20 21const 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. 28class 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 53BrowserTabRestorer::~BrowserTabRestorer() { 54 tab_restore_service_->RemoveObserver(this); 55 BrowserList::GetInstance(browser_->host_desktop_type())->RemoveObserver(this); 56} 57 58// static 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 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 80void BrowserTabRestorer::TabRestoreServiceChanged(TabRestoreService* service) { 81} 82 83void BrowserTabRestorer::TabRestoreServiceDestroyed( 84 TabRestoreService* service) { 85} 86 87void BrowserTabRestorer::TabRestoreServiceLoaded(TabRestoreService* service) { 88 RestoreTab(browser_); 89 // This deletes us. 90 browser_->profile()->SetUserData(kBrowserTabRestorerKey, NULL); 91} 92 93void BrowserTabRestorer::OnBrowserRemoved(Browser* browser) { 94 // This deletes us. 95 browser_->profile()->SetUserData(kBrowserTabRestorerKey, NULL); 96} 97 98} // namespace 99 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