summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/browser.cc7
-rw-r--r--chrome/browser/browser_browsertest.cc2
-rw-r--r--chrome/browser/browser_init.cc44
-rw-r--r--chrome/browser/browser_init.h10
-rw-r--r--chrome/browser/sessions/session_restore.cc12
-rw-r--r--chrome/browser/sessions/session_restore.h5
-rw-r--r--chrome/browser/sessions/session_restore_browsertest.cc49
-rw-r--r--chrome/browser/sessions/session_service.cc54
-rw-r--r--chrome/browser/sessions/session_service.h14
9 files changed, 158 insertions, 39 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index bde1736..0f7b25f 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -1007,7 +1007,12 @@ void Browser::Stop() {
void Browser::NewWindow() {
UserMetrics::RecordAction(UserMetricsAction("NewWindow"), profile_);
- Browser::OpenEmptyWindow(profile_->GetOriginalProfile());
+ SessionService* session_service =
+ profile_->GetOriginalProfile()->GetSessionService();
+ if (!session_service ||
+ !session_service->RestoreIfNecessary(std::vector<GURL>())) {
+ Browser::OpenEmptyWindow(profile_->GetOriginalProfile());
+ }
}
void Browser::NewIncognitoWindow() {
diff --git a/chrome/browser/browser_browsertest.cc b/chrome/browser/browser_browsertest.cc
index dc0a2cc..0d102fb 100644
--- a/chrome/browser/browser_browsertest.cc
+++ b/chrome/browser/browser_browsertest.cc
@@ -502,7 +502,7 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, RestorePinnedTabs) {
CommandLine dummy(CommandLine::ARGUMENTS_ONLY);
BrowserInit::LaunchWithProfile launch(std::wstring(), dummy);
launch.profile_ = browser()->profile();
- launch.OpenStartupURLs(std::vector<GURL>());
+ launch.ProcessStartupURLs(std::vector<GURL>());
// The launch should have created a new browser.
ASSERT_EQ(2u, BrowserList::GetBrowserCount(browser()->profile()));
diff --git a/chrome/browser/browser_init.cc b/chrome/browser/browser_init.cc
index b4518d7..56b296f 100644
--- a/chrome/browser/browser_init.cc
+++ b/chrome/browser/browser_init.cc
@@ -28,6 +28,7 @@
#include "chrome/browser/search_engines/template_url_model.h"
#include "chrome/browser/session_startup_pref.h"
#include "chrome/browser/sessions/session_restore.h"
+#include "chrome/browser/sessions/session_service.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/tabs/pinned_tab_codec.h"
#include "chrome/browser/tab_contents/infobar_delegate.h"
@@ -489,7 +490,6 @@ bool BrowserInit::LaunchWithProfile::Launch(Profile* profile,
std::vector<GURL> urls_to_open = GetURLsFromCommandLine(profile_);
RecordLaunchModeHistogram(urls_to_open.empty()?
LM_TO_BE_DECIDED : LM_WITH_URLS);
-
// TODO(viettrungluu): Temporary: Display a EULA before allowing the user to
// actually enable Flash, unless they've already accepted it. Process this
// in the same way as command-line URLs.
@@ -506,16 +506,7 @@ bool BrowserInit::LaunchWithProfile::Launch(Profile* profile,
}
}
- if (!process_startup || !OpenStartupURLs(urls_to_open)) {
- // Add the home page and any special first run URLs.
- Browser* browser = NULL;
- if (urls_to_open.empty())
- AddStartupURLs(&urls_to_open);
- else if (!command_line_.HasSwitch(switches::kOpenInNewWindow))
- browser = BrowserList::GetLastActive();
-
- OpenURLsInBrowser(browser, process_startup, urls_to_open);
- }
+ ProcessLaunchURLs(process_startup, urls_to_open);
// If this is an app launch, but we didn't open an app window, it may
// be an app tab.
@@ -628,7 +619,36 @@ bool BrowserInit::LaunchWithProfile::OpenApplicationWindow(Profile* profile) {
return false;
}
-bool BrowserInit::LaunchWithProfile::OpenStartupURLs(
+void BrowserInit::LaunchWithProfile::ProcessLaunchURLs(
+ bool process_startup,
+ const std::vector<GURL>& urls_to_open) {
+ if (process_startup && ProcessStartupURLs(urls_to_open)) {
+ // ProcessStartupURLs processed the urls, nothing else to do.
+ return;
+ }
+
+ if (!process_startup &&
+ (profile_->GetSessionService() &&
+ profile_->GetSessionService()->RestoreIfNecessary(urls_to_open))) {
+ // We're already running and session restore wanted to run. This can happen
+ // at various points, such as if there is only an app window running and the
+ // user double clicked the chrome icon. Return so we don't open the urls.
+ return;
+ }
+
+ // Session restore didn't occur, open the urls.
+
+ Browser* browser = NULL;
+ std::vector<GURL> adjust_urls = urls_to_open;
+ if (adjust_urls.empty())
+ AddStartupURLs(&adjust_urls);
+ else if (!command_line_.HasSwitch(switches::kOpenInNewWindow))
+ browser = BrowserList::GetLastActive();
+
+ OpenURLsInBrowser(browser, process_startup, adjust_urls);
+}
+
+bool BrowserInit::LaunchWithProfile::ProcessStartupURLs(
const std::vector<GURL>& urls_to_open) {
SessionStartupPref pref = GetSessionStartupPref(command_line_, profile_);
if (command_line_.HasSwitch(switches::kTestingChannelID) &&
diff --git a/chrome/browser/browser_init.h b/chrome/browser/browser_init.h
index 65d2ca9..2ed6bc7 100644
--- a/chrome/browser/browser_init.h
+++ b/chrome/browser/browser_init.h
@@ -142,6 +142,14 @@ class BrowserInit {
// returns false to specify default processing.
bool OpenApplicationWindow(Profile* profile);
+ // Invoked from OpenURLsInBrowser to handle processing of urls. This may
+ // do any of the following:
+ // . Invoke ProcessStartupURLs if |process_startup| is true.
+ // . Restore the last session if necessary.
+ // . Open the urls directly.
+ void ProcessLaunchURLs(bool process_startup,
+ const std::vector<GURL>& urls_to_open);
+
// Does the following:
// . If the user's startup pref is to restore the last session (or the
// command line flag is present to force using last session), it is
@@ -153,7 +161,7 @@ class BrowserInit {
//
// Otherwise false is returned, which indicates the caller must create a
// new browser.
- bool OpenStartupURLs(const std::vector<GURL>& urls_to_open);
+ bool ProcessStartupURLs(const std::vector<GURL>& urls_to_open);
// If the last session didn't exit cleanly and tab is a web contents tab,
// an infobar is added allowing the user to restore the last session.
diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc
index 99451b2..700290a 100644
--- a/chrome/browser/sessions/session_restore.cc
+++ b/chrome/browser/sessions/session_restore.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -26,6 +26,9 @@
#include "chrome/common/notification_registrar.h"
#include "chrome/common/notification_service.h"
+// Are we in the process of restoring?
+static bool restoring = false;
+
namespace {
// TabLoader ------------------------------------------------------------------
@@ -211,6 +214,7 @@ class SessionRestoreImpl : public NotificationObserver {
~SessionRestoreImpl() {
STLDeleteElements(&windows_);
+ restoring = false;
}
virtual void Observe(NotificationType type,
@@ -502,6 +506,7 @@ static void Restore(Profile* profile,
NOTREACHED();
return;
}
+ restoring = true;
profile->set_restored_last_session(true);
// SessionRestoreImpl takes care of deleting itself when done.
SessionRestoreImpl* restorer =
@@ -527,3 +532,8 @@ void SessionRestore::RestoreSessionSynchronously(
const std::vector<GURL>& urls_to_open) {
Restore(profile, NULL, true, false, true, urls_to_open);
}
+
+// static
+bool SessionRestore::IsRestoring() {
+ return restoring;
+}
diff --git a/chrome/browser/sessions/session_restore.h b/chrome/browser/sessions/session_restore.h
index eb44d9a..ba09694 100644
--- a/chrome/browser/sessions/session_restore.h
+++ b/chrome/browser/sessions/session_restore.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -42,6 +42,9 @@ class SessionRestore {
Profile* profile,
const std::vector<GURL>& urls_to_open);
+ // Returns true if we're in the process of restoring.
+ static bool IsRestoring();
+
// The max number of non-selected tabs SessionRestore loads when restoring
// a session. A value of 0 indicates all tabs are loaded at once.
static size_t num_tabs_to_load_;
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc
new file mode 100644
index 0000000..2df1ad6
--- /dev/null
+++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -0,0 +1,49 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/defaults.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_window.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/test/in_process_browser_test.h"
+#include "chrome/test/ui_test_utils.h"
+
+typedef InProcessBrowserTest SessionRestoreTest;
+
+// Makes sure when session restore is triggered in the same process we don't end
+// up with an extra tab.
+IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
+ RestoreOnNewWindowWithNoTabbedBrowsers) {
+ if (browser_defaults::kRestorePopups)
+ return;
+
+ GURL url(ui_test_utils::GetTestUrl(L".", L"title1.html"));
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Turn on session restore.
+ SessionStartupPref::SetStartupPref(
+ browser()->profile(),
+ SessionStartupPref(SessionStartupPref::LAST));
+
+ // Create a new popup.
+ Profile* profile = browser()->profile();
+ Browser* popup = Browser::CreateForPopup(profile);
+ popup->window()->Show();
+
+ // Close the browser.
+ browser()->window()->Close();
+
+ // Create a new window, which should trigger session restore.
+ popup->NewWindow();
+
+ Browser* new_browser = ui_test_utils::WaitForNewBrowser();
+
+ ASSERT_TRUE(new_browser != NULL);
+
+ // The browser should only have one tab.
+ ASSERT_EQ(1, new_browser->tab_count());
+
+ // And the first url should be url.
+ EXPECT_EQ(url, new_browser->GetTabContentsAt(0)->GetURL());
+}
diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc
index 94c67ee..1ef2a07 100644
--- a/chrome/browser/sessions/session_service.cc
+++ b/chrome/browser/sessions/session_service.cc
@@ -145,6 +145,10 @@ SessionService::~SessionService() {
Save();
}
+bool SessionService::RestoreIfNecessary(const std::vector<GURL>& urls_to_open) {
+ return RestoreIfNecessary(urls_to_open, NULL);
+}
+
void SessionService::ResetFromCurrentBrowsers() {
ScheduleReset();
}
@@ -439,6 +443,34 @@ void SessionService::Init() {
NotificationService::AllSources());
}
+bool SessionService::RestoreIfNecessary(const std::vector<GURL>& urls_to_open,
+ Browser* browser) {
+ if (!has_open_trackable_browsers_ && !BrowserInit::InProcessStartup() &&
+ !SessionRestore::IsRestoring()
+#if defined(OS_MACOSX)
+ // OSX has a fairly different idea of application lifetime than the
+ // other platforms. We need to check that we aren't opening a window
+ // from the dock or the menubar.
+ && !app_controller_mac::IsOpeningNewWindow()
+#endif
+ ) {
+ // We're going from no tabbed browsers to a tabbed browser (and not in
+ // process startup), restore the last session.
+ if (move_on_new_browser_) {
+ // Make the current session the last.
+ MoveCurrentSessionToLastSession();
+ move_on_new_browser_ = false;
+ }
+ SessionStartupPref pref = SessionStartupPref::GetStartupPref(profile());
+ if (pref.type == SessionStartupPref::LAST) {
+ SessionRestore::RestoreSession(
+ profile(), browser, false, browser ? false : true, urls_to_open);
+ return true;
+ }
+ }
+ return false;
+}
+
void SessionService::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
@@ -451,27 +483,7 @@ void SessionService::Observe(NotificationType type,
return;
}
- if (!has_open_trackable_browsers_ && !BrowserInit::InProcessStartup()
-#if defined(OS_MACOSX)
- // OSX has a fairly different idea of application lifetime than the
- // other platforms. We need to check that we aren't opening a window
- // from the dock or the menubar.
- && !app_controller_mac::IsOpeningNewWindow()
-#endif
- ) {
- // We're going from no tabbed browsers to a tabbed browser (and not in
- // process startup), restore the last session.
- if (move_on_new_browser_) {
- // Make the current session the last.
- MoveCurrentSessionToLastSession();
- move_on_new_browser_ = false;
- }
- SessionStartupPref pref = SessionStartupPref::GetStartupPref(profile());
- if (pref.type == SessionStartupPref::LAST) {
- SessionRestore::RestoreSession(
- profile(), browser, false, false, std::vector<GURL>());
- }
- }
+ RestoreIfNecessary(std::vector<GURL>(), browser);
SetWindowType(browser->session_id(), browser->type());
break;
}
diff --git a/chrome/browser/sessions/session_service.h b/chrome/browser/sessions/session_service.h
index a950224..278c94b 100644
--- a/chrome/browser/sessions/session_service.h
+++ b/chrome/browser/sessions/session_service.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -53,6 +53,13 @@ class SessionService : public BaseSessionService,
// For testing.
explicit SessionService(const FilePath& save_path);
+ // Invoke at a point when you think session restore might occur. For example,
+ // during startup and window creation this is invoked to see if a session
+ // needs to be restored. If a session needs to be restored it is done so
+ // asynchronously and true is returned. If false is returned the session was
+ // not restored and the caller needs to create a new window.
+ bool RestoreIfNecessary(const std::vector<GURL>& urls_to_open);
+
// Resets the contents of the file from the current state of all open
// browsers whose profile matches our profile.
void ResetFromCurrentBrowsers();
@@ -180,6 +187,11 @@ class SessionService : public BaseSessionService,
void Init();
+ // Implementation of RestoreIfNecessary. If |browser| is non-null and we need
+ // to restore, the tabs are added to it, otherwise a new browser is created.
+ bool RestoreIfNecessary(const std::vector<GURL>& urls_to_open,
+ Browser* browser);
+
virtual void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details);