diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-11 16:49:31 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-11 16:49:31 +0000 |
commit | 1000fea5be75d197dc7b92bbda5618df0704962b (patch) | |
tree | 9adf62ef316b29b9fdf4ed4ef80d2d0cfa2497eb /chrome/browser | |
parent | 2feb1d45ac69026744a79ba0396497542e4bee81 (diff) | |
download | chromium_src-1000fea5be75d197dc7b92bbda5618df0704962b.zip chromium_src-1000fea5be75d197dc7b92bbda5618df0704962b.tar.gz chromium_src-1000fea5be75d197dc7b92bbda5618df0704962b.tar.bz2 |
Revert 136573 - Extract StartupTabs and startup types from StartupBrowserCreator.
BUG=none
TEST=none
TBR=sky
Review URL: https://chromiumcodereview.appspot.com/10384106
TBR=ben@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10332117
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@136582 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
24 files changed, 1103 insertions, 1202 deletions
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index 5d676e5..1a9329c 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm @@ -40,7 +40,6 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/startup/startup_browser_creator.h" -#include "chrome/browser/ui/startup/startup_browser_creator_impl.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h" #import "chrome/browser/ui/cocoa/browser_window_cocoa.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" @@ -1000,8 +999,8 @@ const AEEventClass kAECloudPrintUninstallClass = 'GCPu'; StartupBrowserCreator browser_creator; browser_creator.LaunchBrowser( command_line, [self lastProfile], FilePath(), - browser::startup::IS_NOT_PROCESS_STARTUP, - browser::startup::IS_NOT_FIRST_RUN, &return_code); + StartupBrowserCreator::IS_NOT_PROCESS_STARTUP, + StartupBrowserCreator::IS_NOT_FIRST_RUN, &return_code); } // We've handled the reopen event, so return NO to tell AppKit not @@ -1106,9 +1105,10 @@ const AEEventClass kAECloudPrintUninstallClass = 'GCPu'; } CommandLine dummy(CommandLine::NO_PROGRAM); - browser::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? - browser::startup::IS_FIRST_RUN : browser::startup::IS_NOT_FIRST_RUN; - StartupBrowserCreatorImpl launch(FilePath(), dummy, first_run); + StartupBrowserCreator::IsFirstRun first_run = first_run::IsChromeFirstRun() ? + StartupBrowserCreator::IS_FIRST_RUN : + StartupBrowserCreator::IS_NOT_FIRST_RUN; + StartupBrowserCreator::LaunchWithProfile launch(FilePath(), dummy, first_run); launch.OpenURLsInBrowser(browser, false, urls); } diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc index 9f67138..17e958b 100644 --- a/chrome/browser/chromeos/login/login_utils.cc +++ b/chrome/browser/chromeos/login/login_utils.cc @@ -717,21 +717,22 @@ void LoginUtilsImpl::DoBrowserLaunch(Profile* profile, VLOG(1) << "Launching browser..."; StartupBrowserCreator browser_creator; int return_code; - browser::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? - browser::startup::IS_FIRST_RUN : - browser::startup::IS_NOT_FIRST_RUN; + StartupBrowserCreator::IsFirstRun first_run = first_run::IsChromeFirstRun() ? + StartupBrowserCreator::IS_FIRST_RUN : + StartupBrowserCreator::IS_NOT_FIRST_RUN; browser_creator.LaunchBrowser(*CommandLine::ForCurrentProcess(), profile, FilePath(), - browser::startup::IS_PROCESS_STARTUP, + StartupBrowserCreator::IS_PROCESS_STARTUP, first_run, &return_code); // Mark login host for deletion after browser starts. This // guarantees that the message loop will be referenced by the // browser before it is dereferenced by the login host. - if (login_host) + if (login_host) { login_host->OnSessionStart(); + } UserManager::Get()->SessionStarted(); } diff --git a/chrome/browser/profiles/avatar_menu_model.cc b/chrome/browser/profiles/avatar_menu_model.cc index 550ed9b..8a8df27 100644 --- a/chrome/browser/profiles/avatar_menu_model.cc +++ b/chrome/browser/profiles/avatar_menu_model.cc @@ -36,8 +36,8 @@ void OnProfileCreated(bool always_create, if (status == Profile::CREATE_STATUS_INITIALIZED) { ProfileManager::FindOrCreateNewWindowForProfile( profile, - browser::startup::IS_NOT_PROCESS_STARTUP, - browser::startup::IS_NOT_FIRST_RUN, + StartupBrowserCreator::IS_NOT_PROCESS_STARTUP, + StartupBrowserCreator::IS_NOT_FIRST_RUN, always_create); } } diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index b6b4ede..4abb87e 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc @@ -29,7 +29,6 @@ #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/startup/startup_browser_creator.h" #include "chrome/browser/ui/webui/sync_promo/sync_promo_ui.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_notification_types.h" @@ -151,8 +150,8 @@ void OnOpenWindowForNewProfile(Profile* profile, if (status == Profile::CREATE_STATUS_INITIALIZED) { ProfileManager::FindOrCreateNewWindowForProfile( profile, - browser::startup::IS_PROCESS_STARTUP, - browser::startup::IS_FIRST_RUN, + StartupBrowserCreator::IS_PROCESS_STARTUP, + StartupBrowserCreator::IS_FIRST_RUN, false); } } @@ -470,8 +469,8 @@ Profile* ProfileManager::GetProfileByPath(const FilePath& path) const { // static void ProfileManager::FindOrCreateNewWindowForProfile( Profile* profile, - browser::startup::IsProcessStartup process_startup, - browser::startup::IsFirstRun is_first_run, + StartupBrowserCreator::IsProcessStartup process_startup, + StartupBrowserCreator::IsFirstRun is_first_run, bool always_create) { DCHECK(profile); diff --git a/chrome/browser/profiles/profile_manager.h b/chrome/browser/profiles/profile_manager.h index 22219e9..8f02319 100644 --- a/chrome/browser/profiles/profile_manager.h +++ b/chrome/browser/profiles/profile_manager.h @@ -21,7 +21,7 @@ #include "base/threading/non_thread_safe.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/startup/startup_types.h" +#include "chrome/browser/ui/startup/startup_browser_creator.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -147,8 +147,8 @@ class ProfileManager : public base::NonThreadSafe, // creation of a window from the multi-profile dropdown menu. static void FindOrCreateNewWindowForProfile( Profile* profile, - browser::startup::IsProcessStartup process_startup, - browser::startup::IsFirstRun is_first_run, + StartupBrowserCreator::IsProcessStartup process_startup, + StartupBrowserCreator::IsFirstRun is_first_run, bool always_create); // Profile::Delegate implementation: diff --git a/chrome/browser/protector/base_setting_change.h b/chrome/browser/protector/base_setting_change.h index 91bcb8c..d378af2 100644 --- a/chrome/browser/protector/base_setting_change.h +++ b/chrome/browser/protector/base_setting_change.h @@ -10,7 +10,7 @@ #include "base/basictypes.h" #include "base/string16.h" -#include "chrome/browser/ui/startup/startup_tab.h" +#include "chrome/browser/tabs/pinned_tab_codec.h" #include "googleurl/src/gurl.h" class Browser; @@ -144,9 +144,9 @@ BaseSettingChange* CreateDefaultSearchProviderChange(TemplateURL* actual, // startup setting, including the pinned tabs. Reports corresponding histograms. BaseSettingChange* CreateSessionStartupChange( const SessionStartupPref& actual_startup_pref, - const StartupTabs& actual_pinned_tabs, + const PinnedTabCodec::Tabs& actual_pinned_tabs, const SessionStartupPref& backup_startup_pref, - const StartupTabs& backup_pinned_tabs); + const PinnedTabCodec::Tabs& backup_pinned_tabs); BaseSettingChange* CreateHomepageChange( const std::string& actual_homepage, diff --git a/chrome/browser/protector/composite_settings_change.h b/chrome/browser/protector/composite_settings_change.h index eeb5135..727dd93 100644 --- a/chrome/browser/protector/composite_settings_change.h +++ b/chrome/browser/protector/composite_settings_change.h @@ -8,7 +8,6 @@ #include <queue> -#include "base/compiler_specific.h" #include "base/memory/scoped_vector.h" #include "chrome/browser/protector/base_setting_change.h" diff --git a/chrome/browser/protector/homepage_change.cc b/chrome/browser/protector/homepage_change.cc index 0614d06..c6d1c87 100644 --- a/chrome/browser/protector/homepage_change.cc +++ b/chrome/browser/protector/homepage_change.cc @@ -6,7 +6,6 @@ #include "base/metrics/histogram.h" #include "base/utf_string_conversions.h" #include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/protector/base_prefs_change.h" #include "chrome/browser/protector/histograms.h" #include "chrome/common/pref_names.h" diff --git a/chrome/browser/protector/session_startup_change.cc b/chrome/browser/protector/session_startup_change.cc index 35e67fd..86595d1 100644 --- a/chrome/browser/protector/session_startup_change.cc +++ b/chrome/browser/protector/session_startup_change.cc @@ -12,7 +12,6 @@ #include "chrome/browser/protector/histograms.h" #include "chrome/browser/protector/protector_service.h" #include "chrome/browser/protector/protector_service_factory.h" -#include "chrome/browser/tabs/pinned_tab_codec.h" #include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_navigator.h" @@ -28,9 +27,9 @@ namespace protector { class SessionStartupChange : public BasePrefsChange { public: SessionStartupChange(const SessionStartupPref& actual_startup_pref, - const StartupTabs& actual_pinned_tabs, + const PinnedTabCodec::Tabs& actual_pinned_tabs, const SessionStartupPref& backup_startup_pref, - const StartupTabs& backup_pinned_tabs); + const PinnedTabCodec::Tabs& backup_pinned_tabs); // BaseSettingChange overrides: virtual bool Init(Profile* profile) OVERRIDE; @@ -56,21 +55,21 @@ class SessionStartupChange : public BasePrefsChange { GURL GetFirstNewURL() const; // Opens all tabs in |tabs| and makes them pinned. - void OpenPinnedTabs(Browser* browser, const StartupTabs& tabs); + void OpenPinnedTabs(Browser* browser, const PinnedTabCodec::Tabs& tabs); const SessionStartupPref new_startup_pref_; const SessionStartupPref backup_startup_pref_; - const StartupTabs new_pinned_tabs_; - const StartupTabs backup_pinned_tabs_; + const PinnedTabCodec::Tabs new_pinned_tabs_; + const PinnedTabCodec::Tabs backup_pinned_tabs_; DISALLOW_COPY_AND_ASSIGN(SessionStartupChange); }; SessionStartupChange::SessionStartupChange( const SessionStartupPref& actual_startup_pref, - const StartupTabs& actual_pinned_tabs, + const PinnedTabCodec::Tabs& actual_pinned_tabs, const SessionStartupPref& backup_startup_pref, - const StartupTabs& backup_pinned_tabs) + const PinnedTabCodec::Tabs& backup_pinned_tabs) : new_startup_pref_(actual_startup_pref), backup_startup_pref_(backup_startup_pref), new_pinned_tabs_(actual_pinned_tabs), @@ -205,8 +204,9 @@ GURL SessionStartupChange::GetFirstNewURL() const { return new_urls[0]; } -void SessionStartupChange::OpenPinnedTabs(Browser* browser, - const StartupTabs& tabs) { +void SessionStartupChange::OpenPinnedTabs( + Browser* browser, + const PinnedTabCodec::Tabs& tabs) { for (size_t i = 0; i < tabs.size(); ++i) { browser::NavigateParams params(browser, tabs[i].url, content::PAGE_TRANSITION_START_PAGE); @@ -220,9 +220,9 @@ void SessionStartupChange::OpenPinnedTabs(Browser* browser, BaseSettingChange* CreateSessionStartupChange( const SessionStartupPref& actual_startup_pref, - const StartupTabs& actual_pinned_tabs, + const PinnedTabCodec::Tabs& actual_pinned_tabs, const SessionStartupPref& backup_startup_pref, - const StartupTabs& backup_pinned_tabs) { + const PinnedTabCodec::Tabs& backup_pinned_tabs) { return new SessionStartupChange(actual_startup_pref, actual_pinned_tabs, backup_startup_pref, backup_pinned_tabs); } diff --git a/chrome/browser/protector/session_startup_change_unittest.cc b/chrome/browser/protector/session_startup_change_unittest.cc index 38de32c..abfbf24 100644 --- a/chrome/browser/protector/session_startup_change_unittest.cc +++ b/chrome/browser/protector/session_startup_change_unittest.cc @@ -7,7 +7,6 @@ #include "base/values.h" #include "chrome/browser/prefs/session_startup_pref.h" #include "chrome/browser/protector/base_setting_change.h" -#include "chrome/browser/ui/startup/startup_tab.h" #include "chrome/test/base/testing_profile.h" #include "testing/gtest/include/gtest/gtest.h" #include "grit/generated_resources.h" @@ -43,7 +42,7 @@ class SessionStartupChangeTest : public testing::Test { protected: TestingProfile profile_; SessionStartupPref initial_startup_pref_; - StartupTabs empty_pinned_tabs_; + PinnedTabCodec::Tabs empty_pinned_tabs_; }; TEST_F(SessionStartupChangeTest, InitAndApply) { @@ -104,8 +103,8 @@ TEST_F(SessionStartupChangeTest, ApplyButtonCaptions) { EXPECT_EQ(kNoDisplayName, change->GetApplyDisplayName()); // Pinned tabs count as startup URLs as well. - StartupTabs new_pinned_tabs; - StartupTab pinned_tab; + PinnedTabCodec::Tabs new_pinned_tabs; + StartupBrowserCreator::LaunchWithProfile::Tab pinned_tab; pinned_tab.url = GURL(kStartupUrl3); new_pinned_tabs.push_back(pinned_tab); change.reset( diff --git a/chrome/browser/tabs/pinned_tab_codec.cc b/chrome/browser/tabs/pinned_tab_codec.cc index de0e73d..d50d1f0 100644 --- a/chrome/browser/tabs/pinned_tab_codec.cc +++ b/chrome/browser/tabs/pinned_tab_codec.cc @@ -20,6 +20,8 @@ using content::NavigationEntry; +typedef StartupBrowserCreator::LaunchWithProfile::Tab Tab; + // Key used in dictionaries for the app id. static const char kAppID[] = "app_id"; @@ -37,7 +39,7 @@ static bool HasPinnedTabs(Browser* browser) { } // Adds a DictionaryValue to |values| representing |tab|. -static void EncodeTab(const StartupTab& tab, ListValue* values) { +static void EncodeTab(const Tab& tab, ListValue* values) { scoped_ptr<DictionaryValue> value(new DictionaryValue); value->SetString(kURL, tab.url.spec()); if (tab.is_app) @@ -84,7 +86,7 @@ static void EncodePinnedTabs(Browser* browser, ListValue* values) { // Decodes the previously written values in |value| to |tab|, returning true // on success. -static bool DecodeTab(const DictionaryValue& value, StartupTab* tab) { +static bool DecodeTab(const DictionaryValue& value, Tab* tab) { tab->is_app = false; std::string url_string; @@ -122,8 +124,7 @@ void PinnedTabCodec::WritePinnedTabs(Profile* profile) { } // static -void PinnedTabCodec::WritePinnedTabs(Profile* profile, - const StartupTabs& tabs) { +void PinnedTabCodec::WritePinnedTabs(Profile* profile, const Tabs& tabs) { PrefService* prefs = profile->GetPrefs(); if (!prefs) return; @@ -131,21 +132,21 @@ void PinnedTabCodec::WritePinnedTabs(Profile* profile, ListPrefUpdate update(prefs, prefs::kPinnedTabs); ListValue* values = update.Get(); values->Clear(); - for (StartupTabs::const_iterator i = tabs.begin(); i != tabs.end(); ++i) + for (Tabs::const_iterator i = tabs.begin(); i != tabs.end(); ++i) EncodeTab(*i, values); } // static -StartupTabs PinnedTabCodec::ReadPinnedTabs(Profile* profile) { +PinnedTabCodec::Tabs PinnedTabCodec::ReadPinnedTabs(Profile* profile) { PrefService* prefs = profile->GetPrefs(); if (!prefs) - return StartupTabs(); + return Tabs(); return ReadPinnedTabs(prefs->GetList(prefs::kPinnedTabs)); } // static -StartupTabs PinnedTabCodec::ReadPinnedTabs(const base::Value* value) { - StartupTabs results; +PinnedTabCodec::Tabs PinnedTabCodec::ReadPinnedTabs(const base::Value* value) { + Tabs results; const base::ListValue* tabs_list = NULL; if (!value->GetAsList(&tabs_list)) @@ -154,7 +155,7 @@ StartupTabs PinnedTabCodec::ReadPinnedTabs(const base::Value* value) { for (size_t i = 0, max = tabs_list->GetSize(); i < max; ++i) { base::DictionaryValue* tab_values = NULL; if (tabs_list->GetDictionary(i, &tab_values)) { - StartupTab tab; + Tab tab; if (DecodeTab(*tab_values, &tab)) results.push_back(tab); } diff --git a/chrome/browser/tabs/pinned_tab_codec.h b/chrome/browser/tabs/pinned_tab_codec.h index 5ef0c29..2872f90 100644 --- a/chrome/browser/tabs/pinned_tab_codec.h +++ b/chrome/browser/tabs/pinned_tab_codec.h @@ -8,7 +8,7 @@ #include <vector> -#include "chrome/browser/ui/startup/startup_tab.h" +#include "chrome/browser/ui/startup/startup_browser_creator.h" #include "googleurl/src/gurl.h" namespace base { @@ -27,6 +27,8 @@ class Profile; // dictionary describing the entry. class PinnedTabCodec { public: + typedef std::vector<StartupBrowserCreator::LaunchWithProfile::Tab> Tabs; + // Registers the preference used by this class. static void RegisterUserPrefs(PrefService* prefs); @@ -34,11 +36,11 @@ class PinnedTabCodec { static void WritePinnedTabs(Profile* profile); // Sets the preferences state from the specified tab list. - static void WritePinnedTabs(Profile* profile, const StartupTabs& tabs); + static void WritePinnedTabs(Profile* profile, const Tabs& tabs); // Reads and returns the set of pinned tabs to restore from preferences. - static StartupTabs ReadPinnedTabs(Profile* profile); - static StartupTabs ReadPinnedTabs(const base::Value* value); + static Tabs ReadPinnedTabs(Profile* profile); + static Tabs ReadPinnedTabs(const base::Value* value); private: PinnedTabCodec(); diff --git a/chrome/browser/tabs/pinned_tab_codec_unittest.cc b/chrome/browser/tabs/pinned_tab_codec_unittest.cc index 4adce35..e1458d0 100644 --- a/chrome/browser/tabs/pinned_tab_codec_unittest.cc +++ b/chrome/browser/tabs/pinned_tab_codec_unittest.cc @@ -9,7 +9,6 @@ #include "chrome/browser/tabs/pinned_tab_test_utils.h" #include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/startup/startup_tab.h" #include "chrome/test/base/browser_with_test_window_test.h" #include "chrome/test/base/testing_profile.h" #include "testing/gtest/include/gtest/gtest.h" @@ -42,7 +41,7 @@ TEST_F(PinnedTabCodecTest, PinnedAndNonPinned) { PinnedTabCodec::WritePinnedTabs(profile()); - StartupTabs pinned_tabs = PinnedTabCodec::ReadPinnedTabs(profile()); + PinnedTabCodec::Tabs pinned_tabs = PinnedTabCodec::ReadPinnedTabs(profile()); std::string result = PinnedTabTestUtils::TabsToString(pinned_tabs); EXPECT_EQ("http://www.google.com/::pinned:", result); diff --git a/chrome/browser/tabs/pinned_tab_test_utils.cc b/chrome/browser/tabs/pinned_tab_test_utils.cc index d49f6fe..0360a02 100644 --- a/chrome/browser/tabs/pinned_tab_test_utils.cc +++ b/chrome/browser/tabs/pinned_tab_test_utils.cc @@ -4,9 +4,11 @@ #include "chrome/browser/tabs/pinned_tab_test_utils.h" +typedef StartupBrowserCreator::LaunchWithProfile::Tab Tab; + namespace { -std::string TabToString(const StartupTab& tab) { +std::string TabToString(const Tab& tab) { return tab.url.spec() + ":" + (tab.is_app ? "app" : "") + ":" + (tab.is_pinned ? "pinned" : "") + ":" + tab.app_id; } @@ -15,7 +17,7 @@ std::string TabToString(const StartupTab& tab) { // static std::string PinnedTabTestUtils::TabsToString( - const std::vector<StartupTab>& values) { + const std::vector<StartupBrowserCreator::LaunchWithProfile::Tab>& values) { std::string result; for (size_t i = 0; i < values.size(); ++i) { if (i != 0) diff --git a/chrome/browser/tabs/pinned_tab_test_utils.h b/chrome/browser/tabs/pinned_tab_test_utils.h index 8cb6a40..57850de 100644 --- a/chrome/browser/tabs/pinned_tab_test_utils.h +++ b/chrome/browser/tabs/pinned_tab_test_utils.h @@ -10,14 +10,15 @@ #include <vector> #include "base/basictypes.h" -#include "chrome/browser/ui/startup/startup_tab.h" +#include "chrome/browser/ui/startup/startup_browser_creator.h" class PinnedTabTestUtils { public: // Converts a set of Tabs into a string. The format is a space separated list // of urls. If the tab is an app, ':app' is appended, and if the tab is // pinned, ':pinned' is appended. - static std::string TabsToString(const std::vector<StartupTab>& values); + static std::string TabsToString( + const std::vector<StartupBrowserCreator::LaunchWithProfile::Tab>& values); private: DISALLOW_IMPLICIT_CONSTRUCTORS(PinnedTabTestUtils); diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc index 5fa8e4c..0dd7420 100644 --- a/chrome/browser/ui/browser_browsertest.cc +++ b/chrome/browser/ui/browser_browsertest.cc @@ -36,7 +36,6 @@ #include "chrome/browser/ui/fullscreen_controller.h" #include "chrome/browser/ui/fullscreen_exit_bubble_type.h" #include "chrome/browser/ui/startup/startup_browser_creator.h" -#include "chrome/browser/ui/startup/startup_browser_creator_impl.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" @@ -899,10 +898,11 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, AppIdSwitch) { CommandLine command_line(CommandLine::NO_PROGRAM); command_line.AppendSwitchASCII(switches::kAppId, extension_app->id()); - browser::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? - browser::startup::IS_FIRST_RUN : - browser::startup::IS_NOT_FIRST_RUN; - StartupBrowserCreatorImpl launch(FilePath(), command_line, first_run); + StartupBrowserCreator::IsFirstRun first_run = first_run::IsChromeFirstRun() ? + StartupBrowserCreator::IS_FIRST_RUN : + StartupBrowserCreator::IS_NOT_FIRST_RUN; + StartupBrowserCreator::LaunchWithProfile launch(FilePath(), command_line, + first_run); ASSERT_TRUE(launch.OpenApplicationWindow(browser()->profile())); // Check that the new browser has an app name. @@ -1252,9 +1252,10 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, RestorePinnedTabs) { // Simulate launching again. CommandLine dummy(CommandLine::NO_PROGRAM); - browser::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? - browser::startup::IS_FIRST_RUN : browser::startup::IS_NOT_FIRST_RUN; - StartupBrowserCreatorImpl launch(FilePath(), dummy, first_run); + StartupBrowserCreator::IsFirstRun first_run = first_run::IsChromeFirstRun() ? + StartupBrowserCreator::IS_FIRST_RUN : + StartupBrowserCreator::IS_NOT_FIRST_RUN; + StartupBrowserCreator::LaunchWithProfile launch(FilePath(), dummy, first_run); launch.profile_ = browser()->profile(); launch.ProcessStartupURLs(std::vector<GURL>()); diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index 1436909..e6bff02 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc @@ -9,9 +9,9 @@ #include "base/bind.h" #include "base/bind_helpers.h" -#include "base/command_line.h" #include "base/compiler_specific.h" #include "base/environment.h" +#include "base/event_recorder.h" #include "base/file_path.h" #include "base/lazy_instance.h" #include "base/memory/scoped_ptr.h" @@ -33,9 +33,15 @@ #include "chrome/browser/component_updater/recovery_component_installer.h" #include "chrome/browser/component_updater/swiftshader_component_installer.h" #include "chrome/browser/custom_handlers/protocol_handler_registry.h" +#include "chrome/browser/defaults.h" +#include "chrome/browser/extensions/extension_creator.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/pack_extension_job.h" #include "chrome/browser/first_run/first_run.h" #include "chrome/browser/google/google_util.h" +#include "chrome/browser/infobars/infobar_tab_helper.h" #include "chrome/browser/net/crl_set_fetcher.h" +#include "chrome/browser/net/predictor.h" #include "chrome/browser/net/url_fixer_upper.h" #include "chrome/browser/notifications/desktop_notification_service.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" @@ -45,22 +51,49 @@ #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h" #include "chrome/browser/printing/print_dialog_cloud.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_io_data.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/protector/base_setting_change.h" +#include "chrome/browser/protector/protected_prefs_watcher.h" +#include "chrome/browser/protector/protector_service.h" +#include "chrome/browser/protector/protector_service_factory.h" +#include "chrome/browser/protector/protector_utils.h" #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_service.h" #include "chrome/browser/search_engines/template_url_service_factory.h" -#include "chrome/browser/ui/startup/startup_browser_creator_impl.h" +#include "chrome/browser/sessions/session_restore.h" +#include "chrome/browser/sessions/session_service.h" +#include "chrome/browser/sessions/session_service_factory.h" +#include "chrome/browser/shell_integration.h" +#include "chrome/browser/tab_contents/link_infobar_delegate.h" +#include "chrome/browser/tabs/pinned_tab_codec.h" +#include "chrome/browser/tabs/tab_strip_model.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/startup/autolaunch_prompt.h" +#include "chrome/browser/ui/startup/bad_flags_prompt.h" +#include "chrome/browser/ui/startup/default_browser_prompt.h" +#include "chrome/browser/ui/startup/obsolete_os_prompt.h" +#include "chrome/browser/ui/startup/session_crashed_prompt.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" +#include "chrome/browser/ui/webui/sync_promo/sync_promo_trial.h" +#include "chrome/browser/ui/webui/sync_promo/sync_promo_ui.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_result_codes.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_version_info.h" +#include "chrome/common/extensions/extension_constants.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/installer/util/browser_distribution.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_security_policy.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_view.h" #include "grit/locale_settings.h" #include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" @@ -70,20 +103,162 @@ #include "chrome/browser/chromeos/profile_startup.h" #endif +#if defined(OS_MACOSX) +#include "base/mac/mac_util.h" +#include "chrome/browser/ui/cocoa/keystone_infobar_delegate.h" +#endif + +#if defined(TOOLKIT_GTK) +#include "chrome/browser/ui/gtk/gtk_util.h" +#endif + #if defined(TOOLKIT_VIEWS) && defined(OS_LINUX) #include "ui/base/touch/touch_factory.h" #endif #if defined(OS_WIN) +#include "base/win/windows_version.h" #include "chrome/browser/ui/startup/startup_browser_creator_win.h" #endif using content::BrowserThread; using content::ChildProcessSecurityPolicy; +using content::WebContents; +using protector::BaseSettingChange; +using protector::ProtectedPrefsWatcher; +using protector::ProtectorService; +using protector::ProtectorServiceFactory; + +namespace { bool in_synchronous_profile_launch = false; -namespace { +// Utility functions ---------------------------------------------------------- + +enum LaunchMode { + LM_TO_BE_DECIDED = 0, // Possibly direct launch or via a shortcut. + LM_AS_WEBAPP, // Launched as a installed web application. + LM_WITH_URLS, // Launched with urls in the cmd line. + LM_SHORTCUT_NONE, // Not launched from a shortcut. + LM_SHORTCUT_NONAME, // Launched from shortcut but no name available. + LM_SHORTCUT_UNKNOWN, // Launched from user-defined shortcut. + LM_SHORTCUT_QUICKLAUNCH, // Launched from the quick launch bar. + LM_SHORTCUT_DESKTOP, // Launched from a desktop shortcut. + LM_SHORTCUT_TASKBAR, // Launched from the taskbar. + LM_LINUX_MAC_BEOS // Other OS buckets start here. +}; + +#if defined(OS_WIN) +// Undocumented flag in the startup info structure tells us what shortcut was +// used to launch the browser. See http://www.catch22.net/tuts/undoc01 for +// more information. Confirmed to work on XP, Vista and Win7. +LaunchMode GetLaunchShortcutKind() { + STARTUPINFOW si = { sizeof(si) }; + GetStartupInfoW(&si); + if (si.dwFlags & 0x800) { + if (!si.lpTitle) + return LM_SHORTCUT_NONAME; + string16 shortcut(si.lpTitle); + // The windows quick launch path is not localized. + if (shortcut.find(L"\\Quick Launch\\") != string16::npos) { + if (base::win::GetVersion() >= base::win::VERSION_WIN7) + return LM_SHORTCUT_TASKBAR; + else + return LM_SHORTCUT_QUICKLAUNCH; + } + scoped_ptr<base::Environment> env(base::Environment::Create()); + std::string appdata_path; + env->GetVar("USERPROFILE", &appdata_path); + if (!appdata_path.empty() && + shortcut.find(ASCIIToWide(appdata_path)) != std::wstring::npos) + return LM_SHORTCUT_DESKTOP; + return LM_SHORTCUT_UNKNOWN; + } + return LM_SHORTCUT_NONE; +} +#else +// TODO(cpu): Port to other platforms. +LaunchMode GetLaunchShortcutKind() { + return LM_LINUX_MAC_BEOS; +} +#endif + +// Log in a histogram the frequency of launching by the different methods. See +// LaunchMode enum for the actual values of the buckets. +void RecordLaunchModeHistogram(LaunchMode mode) { + int bucket = (mode == LM_TO_BE_DECIDED) ? GetLaunchShortcutKind() : mode; + UMA_HISTOGRAM_COUNTS_100("Launch.Modes", bucket); +} + +GURL GetWelcomePageURL() { + std::string welcome_url = l10n_util::GetStringUTF8(IDS_WELCOME_PAGE_URL); + return GURL(welcome_url); +} + +void UrlsToTabs( + const std::vector<GURL>& urls, + std::vector<StartupBrowserCreator::LaunchWithProfile::Tab>* tabs) { + for (size_t i = 0; i < urls.size(); ++i) { + StartupBrowserCreator::LaunchWithProfile::Tab tab; + tab.is_pinned = false; + tab.url = urls[i]; + tabs->push_back(tab); + } +} + +// Return true if the command line option --app-id is used. Set +// |out_extension| to the app to open, and |out_launch_container| +// to the type of window into which the app should be open. +bool GetAppLaunchContainer( + Profile* profile, + const std::string& app_id, + const Extension** out_extension, + extension_misc::LaunchContainer* out_launch_container) { + + ExtensionService* extensions_service = profile->GetExtensionService(); + const Extension* extension = + extensions_service->GetExtensionById(app_id, false); + + // The extension with id |app_id| may have been uninstalled. + if (!extension) + return false; + + // Look at preferences to find the right launch container. If no + // preference is set, launch as a window. + extension_misc::LaunchContainer launch_container = + extensions_service->extension_prefs()->GetLaunchContainer( + extension, ExtensionPrefs::LAUNCH_WINDOW); + + *out_extension = extension; + *out_launch_container = launch_container; + return true; +} + +void RecordCmdLineAppHistogram() { + AppLauncherHandler::RecordAppLaunchType( + extension_misc::APP_LAUNCH_CMD_LINE_APP); +} + +void RecordAppLaunches( + Profile* profile, + const std::vector<GURL>& cmd_line_urls, + const std::vector<StartupBrowserCreator::LaunchWithProfile::Tab>& + autolaunch_tabs) { + ExtensionService* extension_service = profile->GetExtensionService(); + DCHECK(extension_service); + for (size_t i = 0; i < cmd_line_urls.size(); ++i) { + if (extension_service->IsInstalledApp(cmd_line_urls.at(i))) { + AppLauncherHandler::RecordAppLaunchType( + extension_misc::APP_LAUNCH_CMD_LINE_URL); + } + } + for (size_t i = 0; i < autolaunch_tabs.size(); ++i) { + if (extension_service->IsInstalledApp(autolaunch_tabs.at(i).url)) { + AppLauncherHandler::RecordAppLaunchType( + extension_misc::APP_LAUNCH_AUTOLAUNCH); + } + } +} void RegisterComponentsForUpdate(const CommandLine& command_line) { ComponentUpdateService* cus = g_browser_process->component_updater(); @@ -151,6 +326,13 @@ class ProfileLaunchObserver : public content::NotificationObserver { base::LazyInstance<ProfileLaunchObserver> profile_launch_observer = LAZY_INSTANCE_INITIALIZER; +// Returns true if |profile| has exited uncleanly and has not been launched +// after the unclean exit. +bool HasPendingUncleanExit(Profile* profile) { + return !profile->DidLastSessionExitCleanly() && + !profile_launch_observer.Get().HasBeenLaunched(profile); +} + } // namespace StartupBrowserCreator::StartupBrowserCreator() {} @@ -169,15 +351,13 @@ bool StartupBrowserCreator::InSynchronousProfileLaunch() { return in_synchronous_profile_launch; } -bool StartupBrowserCreator::LaunchBrowser( - const CommandLine& command_line, - Profile* profile, - const FilePath& cur_dir, - browser::startup::IsProcessStartup process_startup, - browser::startup::IsFirstRun is_first_run, - int* return_code) { - in_synchronous_profile_launch = - process_startup == browser::startup::IS_PROCESS_STARTUP; +bool StartupBrowserCreator::LaunchBrowser(const CommandLine& command_line, + Profile* profile, + const FilePath& cur_dir, + IsProcessStartup process_startup, + IsFirstRun is_first_run, + int* return_code) { + in_synchronous_profile_launch = process_startup == IS_PROCESS_STARTUP; DCHECK(profile); // Continue with the incognito profile from here on if Incognito mode @@ -190,7 +370,8 @@ bool StartupBrowserCreator::LaunchBrowser( << "browser session."; } - StartupBrowserCreatorImpl lwp(cur_dir, command_line, this, is_first_run); + StartupBrowserCreator::LaunchWithProfile lwp(cur_dir, command_line, this, + is_first_run); std::vector<GURL> urls_to_launch = StartupBrowserCreator::GetURLsFromCommandLine(command_line, cur_dir, profile); @@ -251,6 +432,657 @@ SessionStartupPref StartupBrowserCreator::GetSessionStartupPref( return pref; } + +// StartupBrowserCreator::LaunchWithProfile::Tab ------------------------------- + +StartupBrowserCreator::LaunchWithProfile::Tab::Tab() + : is_app(false), + is_pinned(true) { +} + +StartupBrowserCreator::LaunchWithProfile::Tab::~Tab() { +} + +// StartupBrowserCreator::LaunchWithProfile ------------------------------------ + +StartupBrowserCreator::LaunchWithProfile::LaunchWithProfile( + const FilePath& cur_dir, + const CommandLine& command_line, + IsFirstRun is_first_run) + : cur_dir_(cur_dir), + command_line_(command_line), + profile_(NULL), + browser_creator_(NULL), + is_first_run_(is_first_run == IS_FIRST_RUN) { +} + +StartupBrowserCreator::LaunchWithProfile::LaunchWithProfile( + const FilePath& cur_dir, + const CommandLine& command_line, + StartupBrowserCreator* browser_creator, + IsFirstRun is_first_run) + : cur_dir_(cur_dir), + command_line_(command_line), + profile_(NULL), + browser_creator_(browser_creator), + is_first_run_(is_first_run == IS_FIRST_RUN) { +} + +StartupBrowserCreator::LaunchWithProfile::~LaunchWithProfile() { +} + +bool StartupBrowserCreator::LaunchWithProfile::Launch( + Profile* profile, + const std::vector<GURL>& urls_to_open, + bool process_startup) { + DCHECK(profile); + profile_ = profile; + + if (command_line_.HasSwitch(switches::kDnsLogDetails)) + chrome_browser_net::EnablePredictorDetailedLog(true); + if (command_line_.HasSwitch(switches::kDnsPrefetchDisable) && + profile->GetNetworkPredictor()) { + profile->GetNetworkPredictor()->EnablePredictor(false); + } + + if (command_line_.HasSwitch(switches::kDumpHistogramsOnExit)) + base::StatisticsRecorder::set_dump_on_exit(true); + + if (command_line_.HasSwitch(switches::kRemoteDebuggingPort)) { + std::string port_str = + command_line_.GetSwitchValueASCII(switches::kRemoteDebuggingPort); + int64 port; + if (base::StringToInt64(port_str, &port) && port > 0 && port < 65535) { + std::string frontend_str; + if (command_line_.HasSwitch(switches::kRemoteDebuggingFrontend)) { + frontend_str = command_line_.GetSwitchValueASCII( + switches::kRemoteDebuggingFrontend); + } + g_browser_process->InitDevToolsHttpProtocolHandler( + profile, + "127.0.0.1", + static_cast<int>(port), + frontend_str); + } else { + DLOG(WARNING) << "Invalid http debugger port number " << port; + } + } + + // Open the required browser windows and tabs. First, see if + // we're being run as an application window. If so, the user + // opened an app shortcut. Don't restore tabs or open initial + // URLs in that case. The user should see the window as an app, + // not as chrome. + // Special case is when app switches are passed but we do want to restore + // session. In that case open app window + focus it after session is restored. + if (OpenApplicationWindow(profile) && !browser_defaults::kAppRestoreSession) { + RecordLaunchModeHistogram(LM_AS_WEBAPP); + } else { + Browser* browser_to_focus = NULL; + // In case of app mode + session restore we want to focus that app. + if (browser_defaults::kAppRestoreSession) + browser_to_focus = BrowserList::GetLastActive(); + + RecordLaunchModeHistogram(urls_to_open.empty()? + LM_TO_BE_DECIDED : LM_WITH_URLS); + + // Notify user if the Preferences backup is invalid or changes to settings + // affecting browser startup have been detected. + CheckPreferencesBackup(profile); + + 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. + OpenApplicationTab(profile); + + if (browser_to_focus) + browser_to_focus->GetSelectedWebContents()->GetView()->SetInitialFocus(); + + if (process_startup) { + if (browser_defaults::kOSSupportsOtherBrowsers && + !command_line_.HasSwitch(switches::kNoDefaultBrowserCheck)) { + if (!browser::ShowAutolaunchPrompt(profile)) + browser::ShowDefaultBrowserPrompt(profile); + } +#if defined(OS_MACOSX) + // Check whether the auto-update system needs to be promoted from user + // to system. + KeystoneInfoBar::PromotionInfoBar(profile); +#endif + } + } + +#if defined(OS_WIN) + // Print the selected page if the command line switch exists. Note that the + // current selected tab would be the page which will be printed. + if (command_line_.HasSwitch(switches::kPrint)) { + Browser* browser = BrowserList::GetLastActive(); + browser->Print(); + } +#endif + + // If we're recording or playing back, startup the EventRecorder now + // unless otherwise specified. + if (!command_line_.HasSwitch(switches::kNoEvents)) { + FilePath script_path; + PathService::Get(chrome::FILE_RECORDED_SCRIPT, &script_path); + + bool record_mode = command_line_.HasSwitch(switches::kRecordMode); + bool playback_mode = command_line_.HasSwitch(switches::kPlaybackMode); + + if (record_mode && chrome::kRecordModeEnabled) + base::EventRecorder::current()->StartRecording(script_path); + if (playback_mode) + base::EventRecorder::current()->StartPlayback(script_path); + } + +#if defined(OS_WIN) + if (process_startup) + ShellIntegration::MigrateChromiumShortcuts(); +#endif // defined(OS_WIN) + + return true; +} + +bool StartupBrowserCreator::LaunchWithProfile::IsAppLaunch( + std::string* app_url, + std::string* app_id) { + if (command_line_.HasSwitch(switches::kApp)) { + if (app_url) + *app_url = command_line_.GetSwitchValueASCII(switches::kApp); + return true; + } + if (command_line_.HasSwitch(switches::kAppId)) { + if (app_id) + *app_id = command_line_.GetSwitchValueASCII(switches::kAppId); + return true; + } + return false; +} + +bool StartupBrowserCreator::LaunchWithProfile::OpenApplicationTab( + Profile* profile) { + std::string app_id; + // App shortcuts to URLs always open in an app window. Because this + // function will open an app that should be in a tab, there is no need + // to look at the app URL. OpenApplicationWindow() will open app url + // shortcuts. + if (!IsAppLaunch(NULL, &app_id) || app_id.empty()) + return false; + + extension_misc::LaunchContainer launch_container; + const Extension* extension; + if (!GetAppLaunchContainer(profile, app_id, &extension, &launch_container)) + return false; + + // If the user doesn't want to open a tab, fail. + if (launch_container != extension_misc::LAUNCH_TAB) + return false; + + RecordCmdLineAppHistogram(); + + WebContents* app_tab = Browser::OpenApplicationTab(profile, extension, GURL(), + NEW_FOREGROUND_TAB); + return (app_tab != NULL); +} + +bool StartupBrowserCreator::LaunchWithProfile::OpenApplicationWindow( + Profile* profile) { + std::string url_string, app_id; + if (!IsAppLaunch(&url_string, &app_id)) + return false; + + // This can fail if the app_id is invalid. It can also fail if the + // extension is external, and has not yet been installed. + // TODO(skerner): Do something reasonable here. Pop up a warning panel? + // Open an URL to the gallery page of the extension id? + if (!app_id.empty()) { + extension_misc::LaunchContainer launch_container; + const Extension* extension; + if (!GetAppLaunchContainer(profile, app_id, &extension, &launch_container)) + return false; + + // TODO(skerner): Could pass in |extension| and |launch_container|, + // and avoid calling GetAppLaunchContainer() both here and in + // OpenApplicationTab(). + + if (launch_container == extension_misc::LAUNCH_TAB) + return false; + + RecordCmdLineAppHistogram(); + WebContents* tab_in_app_window = Browser::OpenApplication( + profile, extension, launch_container, GURL(), NEW_WINDOW); + // Platform apps fire off a launch event which may or may not open a window. + return (tab_in_app_window != NULL || extension->is_platform_app()); + } + + if (url_string.empty()) + return false; + +#if defined(OS_WIN) // Fix up Windows shortcuts. + ReplaceSubstringsAfterOffset(&url_string, 0, "\\x", "%"); +#endif + GURL url(url_string); + + // Restrict allowed URLs for --app switch. + if (!url.is_empty() && url.is_valid()) { + ChildProcessSecurityPolicy *policy = + ChildProcessSecurityPolicy::GetInstance(); + if (policy->IsWebSafeScheme(url.scheme()) || + url.SchemeIs(chrome::kFileScheme)) { + + if (profile->GetExtensionService()->IsInstalledApp(url)) { + RecordCmdLineAppHistogram(); + } else { + AppLauncherHandler::RecordAppLaunchType( + extension_misc::APP_LAUNCH_CMD_LINE_APP_LEGACY); + } + WebContents* app_tab = Browser::OpenAppShortcutWindow( + profile, + url, + true); // Update app info. + return (app_tab != NULL); + } + } + return false; +} + +void StartupBrowserCreator::LaunchWithProfile::ProcessLaunchURLs( + bool process_startup, + const std::vector<GURL>& urls_to_open) { + // If we're starting up in "background mode" (no open browser window) then + // don't open any browser windows, unless kAutoLaunchAtStartup is also + // specified. + if (process_startup && + command_line_.HasSwitch(switches::kNoStartupWindow) && + !command_line_.HasSwitch(switches::kAutoLaunchAtStartup)) { + return; + } + + if (process_startup && ProcessStartupURLs(urls_to_open)) { + // ProcessStartupURLs processed the urls, nothing else to do. + return; + } + + IsProcessStartup is_process_startup = process_startup ? + IS_PROCESS_STARTUP : IS_NOT_PROCESS_STARTUP; + if (!process_startup) { + // Even if we're not starting a new process, this may conceptually be + // "startup" for the user and so should be handled in a similar way. Eg., + // Chrome may have been running in the background due to an app with a + // background page being installed, or running with only an app window + // displayed. + SessionService* service = SessionServiceFactory::GetForProfile(profile_); + if (service && service->ShouldNewWindowStartSession()) { + // Restore the last session if any. + if (!HasPendingUncleanExit(profile_) && + service->RestoreIfNecessary(urls_to_open)) { + return; + } + // Open user-specified URLs like pinned tabs and startup tabs. + Browser* browser = ProcessSpecifiedURLs(urls_to_open); + if (browser) { + AddInfoBarsIfNecessary(browser, is_process_startup); + return; + } + } + } + + // Session startup 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::GetLastActiveWithProfile(profile_); + + // This will launch a browser; prevent session restore. + in_synchronous_profile_launch = true; + browser = OpenURLsInBrowser(browser, process_startup, adjust_urls); + in_synchronous_profile_launch = false; + AddInfoBarsIfNecessary(browser, is_process_startup); +} + +bool StartupBrowserCreator::LaunchWithProfile::ProcessStartupURLs( + const std::vector<GURL>& urls_to_open) { + SessionStartupPref pref = GetSessionStartupPref(command_line_, profile_); + + if (pref.type == SessionStartupPref::LAST) { + if (!profile_->DidLastSessionExitCleanly() && + !command_line_.HasSwitch(switches::kRestoreLastSession)) { + // The last session crashed. It's possible automatically loading the + // page will trigger another crash, locking the user out of chrome. + // To avoid this, don't restore on startup but instead show the crashed + // infobar. + return false; + } + + uint32 restore_behavior = SessionRestore::SYNCHRONOUS | + SessionRestore::ALWAYS_CREATE_TABBED_BROWSER; +#if defined(OS_MACOSX) + // On Mac, when restoring a session with no windows, suppress the creation + // of a new window in the case where the system is launching Chrome via a + // login item or Lion's resume feature. + if (base::mac::WasLaunchedAsLoginOrResumeItem()) { + restore_behavior = restore_behavior & + ~SessionRestore::ALWAYS_CREATE_TABBED_BROWSER; + } +#endif + + Browser* browser = SessionRestore::RestoreSession(profile_, + NULL, + restore_behavior, + urls_to_open); + AddInfoBarsIfNecessary(browser, IS_PROCESS_STARTUP); + return true; + } + + Browser* browser = ProcessSpecifiedURLs(urls_to_open); + if (!browser) + return false; + + AddInfoBarsIfNecessary(browser, IS_PROCESS_STARTUP); + return true; +} + +Browser* StartupBrowserCreator::LaunchWithProfile::ProcessSpecifiedURLs( + const std::vector<GURL>& urls_to_open) { + SessionStartupPref pref = GetSessionStartupPref(command_line_, profile_); + std::vector<Tab> tabs; + // Pinned tabs should not be displayed when chrome is launched in incognito + // mode. Also, no pages should be opened automatically if the session + // crashed. Otherwise it might trigger another crash, locking the user out of + // chrome. The crash infobar is shown in this case. + if (!IncognitoModePrefs::ShouldLaunchIncognito(command_line_, + profile_->GetPrefs()) && + !HasPendingUncleanExit(profile_)) { + tabs = PinnedTabCodec::ReadPinnedTabs(profile_); + } + + RecordAppLaunches(profile_, urls_to_open, tabs); + + if (!urls_to_open.empty()) { + // If urls were specified on the command line, use them. + UrlsToTabs(urls_to_open, &tabs); + } else if (pref.type == SessionStartupPref::URLS && !pref.urls.empty() && + !HasPendingUncleanExit(profile_)) { + // Only use the set of urls specified in preferences if nothing was + // specified on the command line. Filter out any urls that are to be + // restored by virtue of having been previously pinned. + AddUniqueURLs(pref.urls, &tabs); + } else if (pref.type == SessionStartupPref::DEFAULT) { + std::vector<GURL> urls; + AddStartupURLs(&urls); + UrlsToTabs(urls, &tabs); + + } else if (pref.type == SessionStartupPref::HOMEPAGE) { + // If 'homepage' selected, either by the user or by a policy, we should + // have migrated them to another value. + NOTREACHED() << "SessionStartupPref has deprecated type HOMEPAGE"; + } + + if (tabs.empty()) + return NULL; + + Browser* browser = OpenTabsInBrowser(NULL, true, tabs); + return browser; +} + +void StartupBrowserCreator::LaunchWithProfile::AddUniqueURLs( + const std::vector<GURL>& urls, + std::vector<Tab>* tabs) { + size_t num_existing_tabs = tabs->size(); + for (size_t i = 0; i < urls.size(); ++i) { + bool in_tabs = false; + for (size_t j = 0; j < num_existing_tabs; ++j) { + if (urls[i] == (*tabs)[j].url) { + in_tabs = true; + break; + } + } + if (!in_tabs) { + StartupBrowserCreator::LaunchWithProfile::Tab tab; + tab.is_pinned = false; + tab.url = urls[i]; + tabs->push_back(tab); + } + } +} + +Browser* StartupBrowserCreator::LaunchWithProfile::OpenURLsInBrowser( + Browser* browser, + bool process_startup, + const std::vector<GURL>& urls) { + std::vector<Tab> tabs; + UrlsToTabs(urls, &tabs); + return OpenTabsInBrowser(browser, process_startup, tabs); +} + +Browser* StartupBrowserCreator::LaunchWithProfile::OpenTabsInBrowser( + Browser* browser, + bool process_startup, + const std::vector<Tab>& tabs) { + DCHECK(!tabs.empty()); + + // If we don't yet have a profile, try to use the one we're given from + // |browser|. While we may not end up actually using |browser| (since it + // could be a popup window), we can at least use the profile. + if (!profile_ && browser) + profile_ = browser->profile(); + + if (!browser || !browser->is_type_tabbed()) { + browser = Browser::Create(profile_); + } else { +#if defined(TOOLKIT_GTK) + // Setting the time of the last action on the window here allows us to steal + // focus, which is what the user wants when opening a new tab in an existing + // browser window. + gtk_util::SetWMLastUserActionTime(browser->window()->GetNativeHandle()); +#endif + } + +#if !defined(OS_MACOSX) + // In kiosk mode, we want to always be fullscreen, so switch to that now. + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) + browser->ToggleFullscreenMode(); +#endif + + bool first_tab = true; + for (size_t i = 0; i < tabs.size(); ++i) { + // We skip URLs that we'd have to launch an external protocol handler for. + // This avoids us getting into an infinite loop asking ourselves to open + // a URL, should the handler be (incorrectly) configured to be us. Anyone + // asking us to open such a URL should really ask the handler directly. + bool handled_by_chrome = ProfileIOData::IsHandledURL(tabs[i].url) || + (profile_ && profile_->GetProtocolHandlerRegistry()->IsHandledProtocol( + tabs[i].url.scheme())); + if (!process_startup && !handled_by_chrome) + continue; + + int add_types = first_tab ? TabStripModel::ADD_ACTIVE : + TabStripModel::ADD_NONE; + add_types |= TabStripModel::ADD_FORCE_INDEX; + if (tabs[i].is_pinned) + add_types |= TabStripModel::ADD_PINNED; + int index = browser->GetIndexForInsertionDuringRestore(i); + + browser::NavigateParams params(browser, tabs[i].url, + content::PAGE_TRANSITION_START_PAGE); + params.disposition = first_tab ? NEW_FOREGROUND_TAB : + NEW_BACKGROUND_TAB; + params.tabstrip_index = index; + params.tabstrip_add_types = add_types; + params.extension_app_id = tabs[i].app_id; + browser::Navigate(¶ms); + + first_tab = false; + } + if (!browser->GetSelectedWebContents()) { + // TODO: this is a work around for 110909. Figure out why it's needed. + if (!browser->tab_count()) + browser->AddBlankTab(true); + else + browser->ActivateTabAt(0, false); + } + + browser->window()->Show(); + // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial + // focus explicitly. + browser->GetSelectedWebContents()->GetView()->SetInitialFocus(); + + return browser; +} + +void StartupBrowserCreator::LaunchWithProfile::AddInfoBarsIfNecessary( + Browser* browser, + IsProcessStartup is_process_startup) { + if (!browser || !profile_ || browser->tab_count() == 0) + return; + + if (HasPendingUncleanExit(browser->profile())) + browser::ShowSessionCrashedPrompt(browser); + + // The bad flags info bar and the obsolete system info bar are only added to + // the first profile which is launched. Other profiles might be restoring the + // browsing sessions asynchronously, so we cannot add the info bars to the + // focused tabs here. + if (is_process_startup == IS_PROCESS_STARTUP) { + browser::ShowBadFlagsPrompt(browser); + browser::ShowObsoleteOSPrompt(browser); + } +} + + +void StartupBrowserCreator::LaunchWithProfile::AddStartupURLs( + std::vector<GURL>* startup_urls) const { + // If we have urls specified beforehand (i.e. from command line) use them + // and nothing else. + if (!startup_urls->empty()) + return; + + // If we have urls specified by the first run master preferences use them + // and nothing else. + if (browser_creator_) { + if (!browser_creator_->first_run_tabs_.empty()) { + std::vector<GURL>::iterator it = + browser_creator_->first_run_tabs_.begin(); + while (it != browser_creator_->first_run_tabs_.end()) { + // Replace magic names for the actual urls. + if (it->host() == "new_tab_page") { + startup_urls->push_back(GURL(chrome::kChromeUINewTabURL)); + } else if (it->host() == "welcome_page") { + startup_urls->push_back(GetWelcomePageURL()); + } else { + startup_urls->push_back(*it); + } + ++it; + } + browser_creator_->first_run_tabs_.clear(); + } + } + + // Otherwise open at least the new tab page (and the welcome page, if this + // is the first time the browser is being started), or the set of URLs + // specified on the command line. + if (startup_urls->empty()) { + startup_urls->push_back(GURL(chrome::kChromeUINewTabURL)); + PrefService* prefs = g_browser_process->local_state(); + if (prefs->FindPreference(prefs::kShouldShowWelcomePage) && + prefs->GetBoolean(prefs::kShouldShowWelcomePage)) { + // Reset the preference so we don't show the welcome page next time. + prefs->ClearPref(prefs::kShouldShowWelcomePage); + startup_urls->push_back(GetWelcomePageURL()); + } + } + + // If the sync promo page is going to be displayed then insert it at the front + // of the list. + if (SyncPromoUI::ShouldShowSyncPromoAtStartup(profile_, is_first_run_)) { + SyncPromoUI::DidShowSyncPromoAtStartup(profile_); + GURL old_url = (*startup_urls)[0]; + (*startup_urls)[0] = + SyncPromoUI::GetSyncPromoURL(GURL(chrome::kChromeUINewTabURL), + SyncPromoUI::SOURCE_START_PAGE); + + // An empty URL means to go to the home page. + if (old_url.is_empty() && + profile_->GetHomePage() == GURL(chrome::kChromeUINewTabURL)) { + old_url = GURL(chrome::kChromeUINewTabURL); + } + + // If the old URL is not the NTP then insert it right after the sync promo. + if (old_url != GURL(chrome::kChromeUINewTabURL)) + startup_urls->insert(startup_urls->begin() + 1, old_url); + + // If we have more than two startup tabs then skip the welcome page. + if (startup_urls->size() > 2) { + std::vector<GURL>::iterator it = std::find( + startup_urls->begin(), startup_urls->end(), GetWelcomePageURL()); + if (it != startup_urls->end()) + startup_urls->erase(it); + } + } +} + +void StartupBrowserCreator::LaunchWithProfile::CheckPreferencesBackup( + Profile* profile) { + ProtectorService* protector_service = + ProtectorServiceFactory::GetForProfile(profile); + ProtectedPrefsWatcher* prefs_watcher = protector_service->GetPrefsWatcher(); + + // Check if backup is valid. + if (!prefs_watcher->is_backup_valid()) { + protector_service->ShowChange(protector::CreatePrefsBackupInvalidChange()); + // Further checks make no sense. + return; + } + + // Check for session startup (including pinned tabs) changes. + if (SessionStartupPref::DidStartupPrefChange(profile) || + prefs_watcher->DidPrefChange(prefs::kPinnedTabs)) { + LOG(WARNING) << "Session startup settings have changed"; + SessionStartupPref new_pref = SessionStartupPref::GetStartupPref(profile); + PinnedTabCodec::Tabs new_tabs = PinnedTabCodec::ReadPinnedTabs(profile); + const base::Value* tabs_backup = + prefs_watcher->GetBackupForPref(prefs::kPinnedTabs); + protector_service->ShowChange(protector::CreateSessionStartupChange( + new_pref, + new_tabs, + SessionStartupPref::GetStartupPrefBackup(profile), + PinnedTabCodec::ReadPinnedTabs(tabs_backup))); + } + + // Check for homepage changes. + if (prefs_watcher->DidPrefChange(prefs::kHomePage) || + prefs_watcher->DidPrefChange(prefs::kHomePageIsNewTabPage) || + prefs_watcher->DidPrefChange(prefs::kShowHomeButton)) { + LOG(WARNING) << "Homepage has changed"; + PrefService* prefs = profile->GetPrefs(); + std::string backup_homepage; + bool backup_homepage_is_ntp; + bool backup_show_home_button; + if (!prefs_watcher->GetBackupForPref(prefs::kHomePage)-> + GetAsString(&backup_homepage) || + !prefs_watcher->GetBackupForPref(prefs::kHomePageIsNewTabPage)-> + GetAsBoolean(&backup_homepage_is_ntp) || + !prefs_watcher->GetBackupForPref(prefs::kShowHomeButton)-> + GetAsBoolean(&backup_show_home_button)) { + NOTREACHED(); + } + protector_service->ShowChange(protector::CreateHomepageChange( + // New: + prefs->GetString(prefs::kHomePage), + prefs->GetBoolean(prefs::kHomePageIsNewTabPage), + prefs->GetBoolean(prefs::kShowHomeButton), + // Backup: + backup_homepage, + backup_homepage_is_ntp, + backup_show_home_button)); + } +} + std::vector<GURL> StartupBrowserCreator::GetURLsFromCommandLine( const CommandLine& command_line, const FilePath& cur_dir, @@ -316,7 +1148,6 @@ std::vector<GURL> StartupBrowserCreator::GetURLsFromCommandLine( return urls; } -// static bool StartupBrowserCreator::ProcessCmdLineImpl( const CommandLine& command_line, const FilePath& cur_dir, @@ -463,11 +1294,10 @@ bool StartupBrowserCreator::ProcessCmdLineImpl( // If we don't want to launch a new browser window or tab (in the case // of an automation request), we are done here. if (!silent_launch) { - browser::startup::IsProcessStartup is_process_startup = process_startup ? - browser::startup::IS_PROCESS_STARTUP : - browser::startup::IS_NOT_PROCESS_STARTUP; - browser::startup::IsFirstRun is_first_run = first_run::IsChromeFirstRun() ? - browser::startup::IS_FIRST_RUN : browser::startup::IS_NOT_FIRST_RUN; + IsProcessStartup is_process_startup = process_startup ? + IS_PROCESS_STARTUP : IS_NOT_PROCESS_STARTUP; + IsFirstRun is_first_run = first_run::IsChromeFirstRun() ? + IS_FIRST_RUN : IS_NOT_FIRST_RUN; // |last_opened_profiles| will be empty in the following circumstances: // - This is the first launch. |last_used_profile| is the initial profile. // - The user exited the browser by closing all windows for all @@ -509,7 +1339,7 @@ bool StartupBrowserCreator::ProcessCmdLineImpl( is_process_startup, is_first_run, return_code)) return false; // We've launched at least one browser. - is_process_startup = browser::startup::IS_NOT_PROCESS_STARTUP; + is_process_startup = StartupBrowserCreator::IS_NOT_PROCESS_STARTUP; } } } @@ -570,9 +1400,3 @@ void StartupBrowserCreator::ProcessCommandLineAlreadyRunning( } ProcessCmdLineImpl(cmd_line, cur_dir, false, profile, Profiles(), NULL, NULL); } - -bool HasPendingUncleanExit(Profile* profile) { - return !profile->DidLastSessionExitCleanly() && - !profile_launch_observer.Get().HasBeenLaunched(profile); -} - diff --git a/chrome/browser/ui/startup/startup_browser_creator.h b/chrome/browser/ui/startup/startup_browser_creator.h index f4c3260..88cc3fa 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.h +++ b/chrome/browser/ui/startup/startup_browser_creator.h @@ -14,8 +14,6 @@ #include "base/gtest_prod_util.h" #include "chrome/browser/prefs/session_startup_pref.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/startup/startup_types.h" -#include "chrome/browser/ui/startup/startup_tab.h" #include "googleurl/src/gurl.h" class Browser; @@ -30,6 +28,15 @@ class StartupBrowserCreator { public: typedef std::vector<Profile*> Profiles; + enum IsProcessStartup { + IS_NOT_PROCESS_STARTUP, + IS_PROCESS_STARTUP + }; + enum IsFirstRun { + IS_NOT_FIRST_RUN, + IS_FIRST_RUN + }; + StartupBrowserCreator(); ~StartupBrowserCreator(); @@ -71,8 +78,8 @@ class StartupBrowserCreator { bool LaunchBrowser(const CommandLine& command_line, Profile* profile, const FilePath& cur_dir, - browser::startup::IsProcessStartup is_process_startup, - browser::startup::IsFirstRun is_first_run, + IsProcessStartup is_process_startup, + IsFirstRun is_first_run, int* return_code); // When called the first time, reads the value of the preference kWasRestarted @@ -84,10 +91,144 @@ class StartupBrowserCreator { const CommandLine& command_line, Profile* profile); + // LaunchWithProfile --------------------------------------------------------- + // + // Assists launching the application and appending the initial tabs for a + // browser window. + + class LaunchWithProfile { + public: + // Used by OpenTabsInBrowser. + struct Tab { + Tab(); + ~Tab(); + + // The url to load. + GURL url; + + // If true, the tab corresponds to an app an |app_id| gives the id of the + // app. + bool is_app; + + // True if the is tab pinned. + bool is_pinned; + + // Id of the app. + std::string app_id; + }; + + // There are two ctors. The first one implies a NULL browser_creator object + // and thus no access to distribution-specific first-run behaviors. The + // second one is always called when the browser starts even if it is not + // the first run. |is_first_run| indicates that this is a new profile. + LaunchWithProfile(const FilePath& cur_dir, + const CommandLine& command_line, + IsFirstRun is_first_run); + LaunchWithProfile(const FilePath& cur_dir, + const CommandLine& command_line, + StartupBrowserCreator* browser_creator, + IsFirstRun is_first_run); + ~LaunchWithProfile(); + + // Creates the necessary windows for startup. Returns true on success, + // false on failure. process_startup is true if Chrome is just + // starting up. If process_startup is false, it indicates Chrome was + // already running and the user wants to launch another instance. + bool Launch(Profile* profile, + const std::vector<GURL>& urls_to_open, + bool process_startup); + + // Convenience for OpenTabsInBrowser that converts |urls| into a set of + // Tabs. + Browser* OpenURLsInBrowser(Browser* browser, + bool process_startup, + const std::vector<GURL>& urls); + + // Creates a tab for each of the Tabs in |tabs|. If browser is non-null + // and a tabbed browser, the tabs are added to it. Otherwise a new tabbed + // browser is created and the tabs are added to it. The browser the tabs + // are added to is returned, which is either |browser| or the newly created + // browser. + Browser* OpenTabsInBrowser(Browser* browser, + bool process_startup, + const std::vector<Tab>& tabs); + + private: + FRIEND_TEST_ALL_PREFIXES(BrowserTest, RestorePinnedTabs); + FRIEND_TEST_ALL_PREFIXES(BrowserTest, AppIdSwitch); + + // If the process was launched with the web application command line flags, + // e.g. --app=http://www.google.com/ or --app_id=... return true. + // In this case |app_url| or |app_id| are populated if they're non-null. + bool IsAppLaunch(std::string* app_url, std::string* app_id); + + // If IsAppLaunch is true, tries to open an application window. + // If the app is specified to start in a tab, or IsAppLaunch is false, + // returns false to specify default processing. + bool OpenApplicationWindow(Profile* profile); + + // If IsAppLaunch is true and the user set a pref indicating that the app + // should open in a tab, do so. + bool OpenApplicationTab(Profile* profile); + + // Invoked from Launch to handle processing of urls. This may do any of the + // following: + // . Invoke ProcessStartupURLs if |process_startup| is true. + // . If |process_startup| is false, restore the last session if necessary, + // or invoke ProcessSpecifiedURLs. + // . 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 + // restored. + // . Otherwise invoke ProcessSpecifiedURLs + // If a browser was created, true is returned. Otherwise returns false and + // the caller must create a new browser. + bool ProcessStartupURLs(const std::vector<GURL>& urls_to_open); + + // Invoked from either ProcessLaunchURLs or ProcessStartupURLs to handle + // processing of URLs where the behavior is common between process startup + // and launch via an existing process (i.e. those explicitly specified by + // the user somehow). Does the following: + // . Attempts to restore any pinned tabs from last run of chrome. + // . If urls_to_open is non-empty, they are opened. + // . If the user's startup pref is to launch a specific set of URLs they + // are opened. + // + // If any tabs were opened, the Browser which was created is returned. + // Otherwise null is returned and the caller must create a new browser. + Browser* ProcessSpecifiedURLs(const std::vector<GURL>& urls_to_open); + + // Adds a Tab to |tabs| for each url in |urls| that doesn't already exist + // in |tabs|. + void AddUniqueURLs(const std::vector<GURL>& urls, + std::vector<Tab>* tabs); + + // Adds any startup infobars to the selected tab of the given browser. + void AddInfoBarsIfNecessary(Browser* browser, + IsProcessStartup is_process_startup); + + // Adds additional startup URLs to the specified vector. + void AddStartupURLs(std::vector<GURL>* startup_urls) const; + + // Checks whether the Preferences backup is invalid and notifies user in + // that case. + void CheckPreferencesBackup(Profile* profile); + + const FilePath cur_dir_; + const CommandLine& command_line_; + Profile* profile_; + StartupBrowserCreator* browser_creator_; + bool is_first_run_; + DISALLOW_COPY_AND_ASSIGN(LaunchWithProfile); + }; + private: friend class CloudPrintProxyPolicyTest; friend class CloudPrintProxyPolicyStartupTest; - friend class StartupBrowserCreatorImpl; FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, ReadingWasRestartedAfterNormalStart); FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc index 5f29058..7adb270 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc @@ -20,7 +20,6 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/startup/startup_browser_creator.h" -#include "chrome/browser/ui/startup/startup_browser_creator_impl.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" @@ -110,8 +109,8 @@ class OpenURLsPopupObserver : public BrowserList::Observer { }; // Test that when there is a popup as the active browser any requests to -// StartupBrowserCreatorImpl::OpenURLsInBrowser don't crash because there's no -// explicit profile given. +// StartupBrowserCreator::LaunchWithProfile::OpenURLsInBrowser don't crash +// because there's no explicit profile given. IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, OpenURLsPopup) { std::vector<GURL> urls; urls.push_back(GURL("http://localhost")); @@ -130,10 +129,10 @@ IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, OpenURLsPopup) { ASSERT_EQ(popup, observer.added_browser_); CommandLine dummy(CommandLine::NO_PROGRAM); - browser::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? - browser::startup::IS_FIRST_RUN : - browser::startup::IS_NOT_FIRST_RUN; - StartupBrowserCreatorImpl launch(FilePath(), dummy, first_run); + StartupBrowserCreator::IsFirstRun first_run = first_run::IsChromeFirstRun() ? + StartupBrowserCreator::IS_FIRST_RUN : + StartupBrowserCreator::IS_NOT_FIRST_RUN; + StartupBrowserCreator::LaunchWithProfile launch(FilePath(), dummy, first_run); // This should create a new window, but re-use the profile from |popup|. If // it used a NULL or invalid profile, it would crash. launch.OpenURLsInBrowser(popup, false, urls); @@ -166,10 +165,10 @@ IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, // Do a simple non-process-startup browser launch. CommandLine dummy(CommandLine::NO_PROGRAM); - browser::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? - browser::startup::IS_FIRST_RUN : - browser::startup::IS_NOT_FIRST_RUN; - StartupBrowserCreatorImpl launch(FilePath(), dummy, first_run); + StartupBrowserCreator::IsFirstRun first_run = first_run::IsChromeFirstRun() ? + StartupBrowserCreator::IS_FIRST_RUN : + StartupBrowserCreator::IS_NOT_FIRST_RUN; + StartupBrowserCreator::LaunchWithProfile launch(FilePath(), dummy, first_run); ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false)); // This should have created a new browser window. |browser()| is still @@ -210,9 +209,10 @@ IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, // Do a simple non-process-startup browser launch. CommandLine dummy(CommandLine::NO_PROGRAM); - browser::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? - browser::startup::IS_FIRST_RUN : browser::startup::IS_NOT_FIRST_RUN; - StartupBrowserCreatorImpl launch(FilePath(), dummy, first_run); + StartupBrowserCreator::IsFirstRun first_run = first_run::IsChromeFirstRun() ? + StartupBrowserCreator::IS_FIRST_RUN : + StartupBrowserCreator::IS_NOT_FIRST_RUN; + StartupBrowserCreator::LaunchWithProfile launch(FilePath(), dummy, first_run); ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false)); // This should have created a new browser window. @@ -234,9 +234,11 @@ IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, OpenAppShortcutNoPref) { CommandLine command_line(CommandLine::NO_PROGRAM); command_line.AppendSwitchASCII(switches::kAppId, extension_app->id()); - browser::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? - browser::startup::IS_FIRST_RUN : browser::startup::IS_NOT_FIRST_RUN; - StartupBrowserCreatorImpl launch(FilePath(), command_line, first_run); + StartupBrowserCreator::IsFirstRun first_run = first_run::IsChromeFirstRun() ? + StartupBrowserCreator::IS_FIRST_RUN : + StartupBrowserCreator::IS_NOT_FIRST_RUN; + StartupBrowserCreator::LaunchWithProfile launch(FilePath(), command_line, + first_run); ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false)); // No pref was set, so the app should have opened in a window. @@ -262,9 +264,11 @@ IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, OpenAppShortcutWindowPref) { CommandLine command_line(CommandLine::NO_PROGRAM); command_line.AppendSwitchASCII(switches::kAppId, extension_app->id()); - browser::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? - browser::startup::IS_FIRST_RUN : browser::startup::IS_NOT_FIRST_RUN; - StartupBrowserCreatorImpl launch(FilePath(), command_line, first_run); + StartupBrowserCreator::IsFirstRun first_run = first_run::IsChromeFirstRun() ? + StartupBrowserCreator::IS_FIRST_RUN : + StartupBrowserCreator::IS_NOT_FIRST_RUN; + StartupBrowserCreator::LaunchWithProfile launch(FilePath(), command_line, + first_run); ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false)); // Pref was set to open in a window, so the app should have opened in a @@ -292,9 +296,11 @@ IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, OpenAppShortcutTabPref) { CommandLine command_line(CommandLine::NO_PROGRAM); command_line.AppendSwitchASCII(switches::kAppId, extension_app->id()); - browser::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? - browser::startup::IS_FIRST_RUN : browser::startup::IS_NOT_FIRST_RUN; - StartupBrowserCreatorImpl launch(FilePath(), command_line, first_run); + StartupBrowserCreator::IsFirstRun first_run = first_run::IsChromeFirstRun() ? + StartupBrowserCreator::IS_FIRST_RUN : + StartupBrowserCreator::IS_NOT_FIRST_RUN; + StartupBrowserCreator::LaunchWithProfile launch(FilePath(), command_line, + first_run); ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false)); // When an app shortcut is open and the pref indicates a tab should @@ -321,9 +327,11 @@ IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, OpenAppShortcutPanel) { CommandLine command_line(CommandLine::NO_PROGRAM); command_line.AppendSwitchASCII(switches::kAppId, extension_app->id()); - browser::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? - browser::startup::IS_FIRST_RUN : browser::startup::IS_NOT_FIRST_RUN; - StartupBrowserCreatorImpl launch(FilePath(), command_line, first_run); + StartupBrowserCreator::IsFirstRun first_run = first_run::IsChromeFirstRun() ? + StartupBrowserCreator::IS_FIRST_RUN : + StartupBrowserCreator::IS_NOT_FIRST_RUN; + StartupBrowserCreator::LaunchWithProfile launch(FilePath(), command_line, + first_run); ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false)); // The launch should have created a new browser, with a panel type. diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc deleted file mode 100644 index b96acfe..0000000 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc +++ /dev/null @@ -1,856 +0,0 @@ -// Copyright (c) 2012 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/ui/startup/startup_browser_creator_impl.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/compiler_specific.h" -#include "base/environment.h" -#include "base/event_recorder.h" -#include "base/lazy_instance.h" -#include "base/memory/scoped_ptr.h" -#include "base/metrics/histogram.h" -#include "base/path_service.h" -#include "base/string_number_conversions.h" -#include "base/string_split.h" -#include "base/threading/thread_restrictions.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/auto_launch_trial.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/custom_handlers/protocol_handler_registry.h" -#include "chrome/browser/defaults.h" -#include "chrome/browser/extensions/extension_creator.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/extensions/pack_extension_job.h" -#include "chrome/browser/first_run/first_run.h" -#include "chrome/browser/net/predictor.h" -#include "chrome/browser/net/url_fixer_upper.h" -#include "chrome/browser/notifications/desktop_notification_service.h" -#include "chrome/browser/prefs/incognito_mode_prefs.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/prefs/session_startup_pref.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_io_data.h" -#include "chrome/browser/protector/protected_prefs_watcher.h" -#include "chrome/browser/protector/protector_service.h" -#include "chrome/browser/protector/protector_service_factory.h" -#include "chrome/browser/protector/protector_utils.h" -#include "chrome/browser/sessions/session_restore.h" -#include "chrome/browser/sessions/session_service.h" -#include "chrome/browser/sessions/session_service_factory.h" -#include "chrome/browser/shell_integration.h" -#include "chrome/browser/tabs/pinned_tab_codec.h" -#include "chrome/browser/tabs/tab_strip_model.h" -#include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/browser_navigator.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/startup/autolaunch_prompt.h" -#include "chrome/browser/ui/startup/bad_flags_prompt.h" -#include "chrome/browser/ui/startup/default_browser_prompt.h" -#include "chrome/browser/ui/startup/obsolete_os_prompt.h" -#include "chrome/browser/ui/startup/session_crashed_prompt.h" -#include "chrome/browser/ui/startup/startup_browser_creator.h" -#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" -#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" -#include "chrome/browser/ui/webui/sync_promo/sync_promo_trial.h" -#include "chrome/browser/ui/webui/sync_promo/sync_promo_ui.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/chrome_notification_types.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/chrome_result_codes.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/chrome_version_info.h" -#include "chrome/common/extensions/extension_constants.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "chrome/installer/util/browser_distribution.h" -#include "content/public/browser/child_process_security_policy.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_view.h" -#include "grit/locale_settings.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" - -#if defined(OS_MACOSX) -#include "base/mac/mac_util.h" -#include "chrome/browser/ui/cocoa/keystone_infobar_delegate.h" -#endif - -#if defined(TOOLKIT_GTK) -#include "chrome/browser/ui/gtk/gtk_util.h" -#endif - -#if defined(OS_WIN) -#include "base/win/windows_version.h" -#endif - -using content::ChildProcessSecurityPolicy; -using content::WebContents; -using protector::ProtectedPrefsWatcher; -using protector::ProtectorService; -using protector::ProtectorServiceFactory; - -extern bool in_synchronous_profile_launch; - -namespace { - -// Utility functions ---------------------------------------------------------- - -enum LaunchMode { - LM_TO_BE_DECIDED = 0, // Possibly direct launch or via a shortcut. - LM_AS_WEBAPP, // Launched as a installed web application. - LM_WITH_URLS, // Launched with urls in the cmd line. - LM_SHORTCUT_NONE, // Not launched from a shortcut. - LM_SHORTCUT_NONAME, // Launched from shortcut but no name available. - LM_SHORTCUT_UNKNOWN, // Launched from user-defined shortcut. - LM_SHORTCUT_QUICKLAUNCH, // Launched from the quick launch bar. - LM_SHORTCUT_DESKTOP, // Launched from a desktop shortcut. - LM_SHORTCUT_TASKBAR, // Launched from the taskbar. - LM_LINUX_MAC_BEOS // Other OS buckets start here. -}; - -#if defined(OS_WIN) -// Undocumented flag in the startup info structure tells us what shortcut was -// used to launch the browser. See http://www.catch22.net/tuts/undoc01 for -// more information. Confirmed to work on XP, Vista and Win7. -LaunchMode GetLaunchShortcutKind() { - STARTUPINFOW si = { sizeof(si) }; - GetStartupInfoW(&si); - if (si.dwFlags & 0x800) { - if (!si.lpTitle) - return LM_SHORTCUT_NONAME; - string16 shortcut(si.lpTitle); - // The windows quick launch path is not localized. - if (shortcut.find(L"\\Quick Launch\\") != string16::npos) { - if (base::win::GetVersion() >= base::win::VERSION_WIN7) - return LM_SHORTCUT_TASKBAR; - else - return LM_SHORTCUT_QUICKLAUNCH; - } - scoped_ptr<base::Environment> env(base::Environment::Create()); - std::string appdata_path; - env->GetVar("USERPROFILE", &appdata_path); - if (!appdata_path.empty() && - shortcut.find(ASCIIToWide(appdata_path)) != std::wstring::npos) - return LM_SHORTCUT_DESKTOP; - return LM_SHORTCUT_UNKNOWN; - } - return LM_SHORTCUT_NONE; -} -#else -// TODO(cpu): Port to other platforms. -LaunchMode GetLaunchShortcutKind() { - return LM_LINUX_MAC_BEOS; -} -#endif - -// Log in a histogram the frequency of launching by the different methods. See -// LaunchMode enum for the actual values of the buckets. -void RecordLaunchModeHistogram(LaunchMode mode) { - int bucket = (mode == LM_TO_BE_DECIDED) ? GetLaunchShortcutKind() : mode; - UMA_HISTOGRAM_COUNTS_100("Launch.Modes", bucket); -} - -GURL GetWelcomePageURL() { - std::string welcome_url = l10n_util::GetStringUTF8(IDS_WELCOME_PAGE_URL); - return GURL(welcome_url); -} - -void UrlsToTabs(const std::vector<GURL>& urls, StartupTabs* tabs) { - for (size_t i = 0; i < urls.size(); ++i) { - StartupTab tab; - tab.is_pinned = false; - tab.url = urls[i]; - tabs->push_back(tab); - } -} - -// Return true if the command line option --app-id is used. Set -// |out_extension| to the app to open, and |out_launch_container| -// to the type of window into which the app should be open. -bool GetAppLaunchContainer( - Profile* profile, - const std::string& app_id, - const Extension** out_extension, - extension_misc::LaunchContainer* out_launch_container) { - - ExtensionService* extensions_service = profile->GetExtensionService(); - const Extension* extension = - extensions_service->GetExtensionById(app_id, false); - - // The extension with id |app_id| may have been uninstalled. - if (!extension) - return false; - - // Look at preferences to find the right launch container. If no - // preference is set, launch as a window. - extension_misc::LaunchContainer launch_container = - extensions_service->extension_prefs()->GetLaunchContainer( - extension, ExtensionPrefs::LAUNCH_WINDOW); - - *out_extension = extension; - *out_launch_container = launch_container; - return true; -} - -void RecordCmdLineAppHistogram() { - AppLauncherHandler::RecordAppLaunchType( - extension_misc::APP_LAUNCH_CMD_LINE_APP); -} - -void RecordAppLaunches(Profile* profile, - const std::vector<GURL>& cmd_line_urls, - StartupTabs& autolaunch_tabs) { - ExtensionService* extension_service = profile->GetExtensionService(); - DCHECK(extension_service); - for (size_t i = 0; i < cmd_line_urls.size(); ++i) { - if (extension_service->IsInstalledApp(cmd_line_urls.at(i))) { - AppLauncherHandler::RecordAppLaunchType( - extension_misc::APP_LAUNCH_CMD_LINE_URL); - } - } - for (size_t i = 0; i < autolaunch_tabs.size(); ++i) { - if (extension_service->IsInstalledApp(autolaunch_tabs.at(i).url)) { - AppLauncherHandler::RecordAppLaunchType( - extension_misc::APP_LAUNCH_AUTOLAUNCH); - } - } -} - -} // namespace - -StartupBrowserCreatorImpl::StartupBrowserCreatorImpl( - const FilePath& cur_dir, - const CommandLine& command_line, - browser::startup::IsFirstRun is_first_run) - : cur_dir_(cur_dir), - command_line_(command_line), - profile_(NULL), - browser_creator_(NULL), - is_first_run_(is_first_run == browser::startup::IS_FIRST_RUN) { -} - -StartupBrowserCreatorImpl::StartupBrowserCreatorImpl( - const FilePath& cur_dir, - const CommandLine& command_line, - StartupBrowserCreator* browser_creator, - browser::startup::IsFirstRun is_first_run) - : cur_dir_(cur_dir), - command_line_(command_line), - profile_(NULL), - browser_creator_(browser_creator), - is_first_run_(is_first_run == browser::startup::IS_FIRST_RUN) { -} - -StartupBrowserCreatorImpl::~StartupBrowserCreatorImpl() { -} - -bool StartupBrowserCreatorImpl::Launch(Profile* profile, - const std::vector<GURL>& urls_to_open, - bool process_startup) { - DCHECK(profile); - profile_ = profile; - - if (command_line_.HasSwitch(switches::kDnsLogDetails)) - chrome_browser_net::EnablePredictorDetailedLog(true); - if (command_line_.HasSwitch(switches::kDnsPrefetchDisable) && - profile->GetNetworkPredictor()) { - profile->GetNetworkPredictor()->EnablePredictor(false); - } - - if (command_line_.HasSwitch(switches::kDumpHistogramsOnExit)) - base::StatisticsRecorder::set_dump_on_exit(true); - - if (command_line_.HasSwitch(switches::kRemoteDebuggingPort)) { - std::string port_str = - command_line_.GetSwitchValueASCII(switches::kRemoteDebuggingPort); - int64 port; - if (base::StringToInt64(port_str, &port) && port > 0 && port < 65535) { - std::string frontend_str; - if (command_line_.HasSwitch(switches::kRemoteDebuggingFrontend)) { - frontend_str = command_line_.GetSwitchValueASCII( - switches::kRemoteDebuggingFrontend); - } - g_browser_process->InitDevToolsHttpProtocolHandler( - profile, - "127.0.0.1", - static_cast<int>(port), - frontend_str); - } else { - DLOG(WARNING) << "Invalid http debugger port number " << port; - } - } - - // Open the required browser windows and tabs. First, see if - // we're being run as an application window. If so, the user - // opened an app shortcut. Don't restore tabs or open initial - // URLs in that case. The user should see the window as an app, - // not as chrome. - // Special case is when app switches are passed but we do want to restore - // session. In that case open app window + focus it after session is restored. - if (OpenApplicationWindow(profile) && !browser_defaults::kAppRestoreSession) { - RecordLaunchModeHistogram(LM_AS_WEBAPP); - } else { - Browser* browser_to_focus = NULL; - // In case of app mode + session restore we want to focus that app. - if (browser_defaults::kAppRestoreSession) - browser_to_focus = BrowserList::GetLastActive(); - - RecordLaunchModeHistogram(urls_to_open.empty()? - LM_TO_BE_DECIDED : LM_WITH_URLS); - - // Notify user if the Preferences backup is invalid or changes to settings - // affecting browser startup have been detected. - CheckPreferencesBackup(profile); - - 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. - OpenApplicationTab(profile); - - if (browser_to_focus) - browser_to_focus->GetSelectedWebContents()->GetView()->SetInitialFocus(); - - if (process_startup) { - if (browser_defaults::kOSSupportsOtherBrowsers && - !command_line_.HasSwitch(switches::kNoDefaultBrowserCheck)) { - if (!browser::ShowAutolaunchPrompt(profile)) - browser::ShowDefaultBrowserPrompt(profile); - } -#if defined(OS_MACOSX) - // Check whether the auto-update system needs to be promoted from user - // to system. - KeystoneInfoBar::PromotionInfoBar(profile); -#endif - } - } - -#if defined(OS_WIN) - // Print the selected page if the command line switch exists. Note that the - // current selected tab would be the page which will be printed. - if (command_line_.HasSwitch(switches::kPrint)) { - Browser* browser = BrowserList::GetLastActive(); - browser->Print(); - } -#endif - - // If we're recording or playing back, startup the EventRecorder now - // unless otherwise specified. - if (!command_line_.HasSwitch(switches::kNoEvents)) { - FilePath script_path; - PathService::Get(chrome::FILE_RECORDED_SCRIPT, &script_path); - - bool record_mode = command_line_.HasSwitch(switches::kRecordMode); - bool playback_mode = command_line_.HasSwitch(switches::kPlaybackMode); - - if (record_mode && chrome::kRecordModeEnabled) - base::EventRecorder::current()->StartRecording(script_path); - if (playback_mode) - base::EventRecorder::current()->StartPlayback(script_path); - } - -#if defined(OS_WIN) - if (process_startup) - ShellIntegration::MigrateChromiumShortcuts(); -#endif // defined(OS_WIN) - - return true; -} - -bool StartupBrowserCreatorImpl::IsAppLaunch(std::string* app_url, - std::string* app_id) { - if (command_line_.HasSwitch(switches::kApp)) { - if (app_url) - *app_url = command_line_.GetSwitchValueASCII(switches::kApp); - return true; - } - if (command_line_.HasSwitch(switches::kAppId)) { - if (app_id) - *app_id = command_line_.GetSwitchValueASCII(switches::kAppId); - return true; - } - return false; -} - -bool StartupBrowserCreatorImpl::OpenApplicationTab(Profile* profile) { - std::string app_id; - // App shortcuts to URLs always open in an app window. Because this - // function will open an app that should be in a tab, there is no need - // to look at the app URL. OpenApplicationWindow() will open app url - // shortcuts. - if (!IsAppLaunch(NULL, &app_id) || app_id.empty()) - return false; - - extension_misc::LaunchContainer launch_container; - const Extension* extension; - if (!GetAppLaunchContainer(profile, app_id, &extension, &launch_container)) - return false; - - // If the user doesn't want to open a tab, fail. - if (launch_container != extension_misc::LAUNCH_TAB) - return false; - - RecordCmdLineAppHistogram(); - - WebContents* app_tab = Browser::OpenApplicationTab(profile, extension, GURL(), - NEW_FOREGROUND_TAB); - return (app_tab != NULL); -} - -bool StartupBrowserCreatorImpl::OpenApplicationWindow(Profile* profile) { - std::string url_string, app_id; - if (!IsAppLaunch(&url_string, &app_id)) - return false; - - // This can fail if the app_id is invalid. It can also fail if the - // extension is external, and has not yet been installed. - // TODO(skerner): Do something reasonable here. Pop up a warning panel? - // Open an URL to the gallery page of the extension id? - if (!app_id.empty()) { - extension_misc::LaunchContainer launch_container; - const Extension* extension; - if (!GetAppLaunchContainer(profile, app_id, &extension, &launch_container)) - return false; - - // TODO(skerner): Could pass in |extension| and |launch_container|, - // and avoid calling GetAppLaunchContainer() both here and in - // OpenApplicationTab(). - - if (launch_container == extension_misc::LAUNCH_TAB) - return false; - - RecordCmdLineAppHistogram(); - WebContents* tab_in_app_window = Browser::OpenApplication( - profile, extension, launch_container, GURL(), NEW_WINDOW); - // Platform apps fire off a launch event which may or may not open a window. - return (tab_in_app_window != NULL || extension->is_platform_app()); - } - - if (url_string.empty()) - return false; - -#if defined(OS_WIN) // Fix up Windows shortcuts. - ReplaceSubstringsAfterOffset(&url_string, 0, "\\x", "%"); -#endif - GURL url(url_string); - - // Restrict allowed URLs for --app switch. - if (!url.is_empty() && url.is_valid()) { - ChildProcessSecurityPolicy *policy = - ChildProcessSecurityPolicy::GetInstance(); - if (policy->IsWebSafeScheme(url.scheme()) || - url.SchemeIs(chrome::kFileScheme)) { - - if (profile->GetExtensionService()->IsInstalledApp(url)) { - RecordCmdLineAppHistogram(); - } else { - AppLauncherHandler::RecordAppLaunchType( - extension_misc::APP_LAUNCH_CMD_LINE_APP_LEGACY); - } - WebContents* app_tab = Browser::OpenAppShortcutWindow( - profile, - url, - true); // Update app info. - return (app_tab != NULL); - } - } - return false; -} - -void StartupBrowserCreatorImpl::ProcessLaunchURLs( - bool process_startup, - const std::vector<GURL>& urls_to_open) { - // If we're starting up in "background mode" (no open browser window) then - // don't open any browser windows, unless kAutoLaunchAtStartup is also - // specified. - if (process_startup && - command_line_.HasSwitch(switches::kNoStartupWindow) && - !command_line_.HasSwitch(switches::kAutoLaunchAtStartup)) { - return; - } - - if (process_startup && ProcessStartupURLs(urls_to_open)) { - // ProcessStartupURLs processed the urls, nothing else to do. - return; - } - - browser::startup::IsProcessStartup is_process_startup = process_startup ? - browser::startup::IS_PROCESS_STARTUP : - browser::startup::IS_NOT_PROCESS_STARTUP; - if (!process_startup) { - // Even if we're not starting a new process, this may conceptually be - // "startup" for the user and so should be handled in a similar way. Eg., - // Chrome may have been running in the background due to an app with a - // background page being installed, or running with only an app window - // displayed. - SessionService* service = SessionServiceFactory::GetForProfile(profile_); - if (service && service->ShouldNewWindowStartSession()) { - // Restore the last session if any. - if (!HasPendingUncleanExit(profile_) && - service->RestoreIfNecessary(urls_to_open)) { - return; - } - // Open user-specified URLs like pinned tabs and startup tabs. - Browser* browser = ProcessSpecifiedURLs(urls_to_open); - if (browser) { - AddInfoBarsIfNecessary(browser, is_process_startup); - return; - } - } - } - - // Session startup 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::GetLastActiveWithProfile(profile_); - - // This will launch a browser; prevent session restore. - in_synchronous_profile_launch = true; - browser = OpenURLsInBrowser(browser, process_startup, adjust_urls); - in_synchronous_profile_launch = false; - AddInfoBarsIfNecessary(browser, is_process_startup); -} - -bool StartupBrowserCreatorImpl::ProcessStartupURLs( - const std::vector<GURL>& urls_to_open) { - SessionStartupPref pref = - StartupBrowserCreator::GetSessionStartupPref(command_line_, profile_); - - if (pref.type == SessionStartupPref::LAST) { - if (!profile_->DidLastSessionExitCleanly() && - !command_line_.HasSwitch(switches::kRestoreLastSession)) { - // The last session crashed. It's possible automatically loading the - // page will trigger another crash, locking the user out of chrome. - // To avoid this, don't restore on startup but instead show the crashed - // infobar. - return false; - } - - uint32 restore_behavior = SessionRestore::SYNCHRONOUS | - SessionRestore::ALWAYS_CREATE_TABBED_BROWSER; -#if defined(OS_MACOSX) - // On Mac, when restoring a session with no windows, suppress the creation - // of a new window in the case where the system is launching Chrome via a - // login item or Lion's resume feature. - if (base::mac::WasLaunchedAsLoginOrResumeItem()) { - restore_behavior = restore_behavior & - ~SessionRestore::ALWAYS_CREATE_TABBED_BROWSER; - } -#endif - - Browser* browser = SessionRestore::RestoreSession(profile_, - NULL, - restore_behavior, - urls_to_open); - AddInfoBarsIfNecessary(browser, browser::startup::IS_PROCESS_STARTUP); - return true; - } - - Browser* browser = ProcessSpecifiedURLs(urls_to_open); - if (!browser) - return false; - - AddInfoBarsIfNecessary(browser, browser::startup::IS_PROCESS_STARTUP); - return true; -} - -Browser* StartupBrowserCreatorImpl::ProcessSpecifiedURLs( - const std::vector<GURL>& urls_to_open) { - SessionStartupPref pref = - StartupBrowserCreator::GetSessionStartupPref(command_line_, profile_); - StartupTabs tabs; - // Pinned tabs should not be displayed when chrome is launched in incognito - // mode. Also, no pages should be opened automatically if the session - // crashed. Otherwise it might trigger another crash, locking the user out of - // chrome. The crash infobar is shown in this case. - if (!IncognitoModePrefs::ShouldLaunchIncognito(command_line_, - profile_->GetPrefs()) && - !HasPendingUncleanExit(profile_)) { - tabs = PinnedTabCodec::ReadPinnedTabs(profile_); - } - - RecordAppLaunches(profile_, urls_to_open, tabs); - - if (!urls_to_open.empty()) { - // If urls were specified on the command line, use them. - UrlsToTabs(urls_to_open, &tabs); - } else if (pref.type == SessionStartupPref::URLS && !pref.urls.empty() && - !HasPendingUncleanExit(profile_)) { - // Only use the set of urls specified in preferences if nothing was - // specified on the command line. Filter out any urls that are to be - // restored by virtue of having been previously pinned. - AddUniqueURLs(pref.urls, &tabs); - } else if (pref.type == SessionStartupPref::DEFAULT) { - std::vector<GURL> urls; - AddStartupURLs(&urls); - UrlsToTabs(urls, &tabs); - - } else if (pref.type == SessionStartupPref::HOMEPAGE) { - // If 'homepage' selected, either by the user or by a policy, we should - // have migrated them to another value. - NOTREACHED() << "SessionStartupPref has deprecated type HOMEPAGE"; - } - - if (tabs.empty()) - return NULL; - - Browser* browser = OpenTabsInBrowser(NULL, true, tabs); - return browser; -} - -void StartupBrowserCreatorImpl::AddUniqueURLs(const std::vector<GURL>& urls, - StartupTabs* tabs) { - size_t num_existing_tabs = tabs->size(); - for (size_t i = 0; i < urls.size(); ++i) { - bool in_tabs = false; - for (size_t j = 0; j < num_existing_tabs; ++j) { - if (urls[i] == (*tabs)[j].url) { - in_tabs = true; - break; - } - } - if (!in_tabs) { - StartupTab tab; - tab.is_pinned = false; - tab.url = urls[i]; - tabs->push_back(tab); - } - } -} - -Browser* StartupBrowserCreatorImpl::OpenURLsInBrowser( - Browser* browser, - bool process_startup, - const std::vector<GURL>& urls) { - StartupTabs tabs; - UrlsToTabs(urls, &tabs); - return OpenTabsInBrowser(browser, process_startup, tabs); -} - -Browser* StartupBrowserCreatorImpl::OpenTabsInBrowser(Browser* browser, - bool process_startup, - const StartupTabs& tabs) { - DCHECK(!tabs.empty()); - - // If we don't yet have a profile, try to use the one we're given from - // |browser|. While we may not end up actually using |browser| (since it - // could be a popup window), we can at least use the profile. - if (!profile_ && browser) - profile_ = browser->profile(); - - if (!browser || !browser->is_type_tabbed()) { - browser = Browser::Create(profile_); - } else { -#if defined(TOOLKIT_GTK) - // Setting the time of the last action on the window here allows us to steal - // focus, which is what the user wants when opening a new tab in an existing - // browser window. - gtk_util::SetWMLastUserActionTime(browser->window()->GetNativeHandle()); -#endif - } - -#if !defined(OS_MACOSX) - // In kiosk mode, we want to always be fullscreen, so switch to that now. - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) - browser->ToggleFullscreenMode(); -#endif - - bool first_tab = true; - for (size_t i = 0; i < tabs.size(); ++i) { - // We skip URLs that we'd have to launch an external protocol handler for. - // This avoids us getting into an infinite loop asking ourselves to open - // a URL, should the handler be (incorrectly) configured to be us. Anyone - // asking us to open such a URL should really ask the handler directly. - bool handled_by_chrome = ProfileIOData::IsHandledURL(tabs[i].url) || - (profile_ && profile_->GetProtocolHandlerRegistry()->IsHandledProtocol( - tabs[i].url.scheme())); - if (!process_startup && !handled_by_chrome) - continue; - - int add_types = first_tab ? TabStripModel::ADD_ACTIVE : - TabStripModel::ADD_NONE; - add_types |= TabStripModel::ADD_FORCE_INDEX; - if (tabs[i].is_pinned) - add_types |= TabStripModel::ADD_PINNED; - int index = browser->GetIndexForInsertionDuringRestore(i); - - browser::NavigateParams params(browser, tabs[i].url, - content::PAGE_TRANSITION_START_PAGE); - params.disposition = first_tab ? NEW_FOREGROUND_TAB : - NEW_BACKGROUND_TAB; - params.tabstrip_index = index; - params.tabstrip_add_types = add_types; - params.extension_app_id = tabs[i].app_id; - browser::Navigate(¶ms); - - first_tab = false; - } - if (!browser->GetSelectedWebContents()) { - // TODO: this is a work around for 110909. Figure out why it's needed. - if (!browser->tab_count()) - browser->AddBlankTab(true); - else - browser->ActivateTabAt(0, false); - } - - browser->window()->Show(); - // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial - // focus explicitly. - browser->GetSelectedWebContents()->GetView()->SetInitialFocus(); - - return browser; -} - -void StartupBrowserCreatorImpl::AddInfoBarsIfNecessary( - Browser* browser, - browser::startup::IsProcessStartup is_process_startup) { - if (!browser || !profile_ || browser->tab_count() == 0) - return; - - if (HasPendingUncleanExit(browser->profile())) - browser::ShowSessionCrashedPrompt(browser); - - // The bad flags info bar and the obsolete system info bar are only added to - // the first profile which is launched. Other profiles might be restoring the - // browsing sessions asynchronously, so we cannot add the info bars to the - // focused tabs here. - if (is_process_startup == browser::startup::IS_PROCESS_STARTUP) { - browser::ShowBadFlagsPrompt(browser); - browser::ShowObsoleteOSPrompt(browser); - } -} - - -void StartupBrowserCreatorImpl::AddStartupURLs( - std::vector<GURL>* startup_urls) const { - // If we have urls specified beforehand (i.e. from command line) use them - // and nothing else. - if (!startup_urls->empty()) - return; - - // If we have urls specified by the first run master preferences use them - // and nothing else. - if (browser_creator_) { - if (!browser_creator_->first_run_tabs_.empty()) { - std::vector<GURL>::iterator it = - browser_creator_->first_run_tabs_.begin(); - while (it != browser_creator_->first_run_tabs_.end()) { - // Replace magic names for the actual urls. - if (it->host() == "new_tab_page") { - startup_urls->push_back(GURL(chrome::kChromeUINewTabURL)); - } else if (it->host() == "welcome_page") { - startup_urls->push_back(GetWelcomePageURL()); - } else { - startup_urls->push_back(*it); - } - ++it; - } - browser_creator_->first_run_tabs_.clear(); - } - } - - // Otherwise open at least the new tab page (and the welcome page, if this - // is the first time the browser is being started), or the set of URLs - // specified on the command line. - if (startup_urls->empty()) { - startup_urls->push_back(GURL(chrome::kChromeUINewTabURL)); - PrefService* prefs = g_browser_process->local_state(); - if (prefs->FindPreference(prefs::kShouldShowWelcomePage) && - prefs->GetBoolean(prefs::kShouldShowWelcomePage)) { - // Reset the preference so we don't show the welcome page next time. - prefs->ClearPref(prefs::kShouldShowWelcomePage); - startup_urls->push_back(GetWelcomePageURL()); - } - } - - // If the sync promo page is going to be displayed then insert it at the front - // of the list. - if (SyncPromoUI::ShouldShowSyncPromoAtStartup(profile_, is_first_run_)) { - SyncPromoUI::DidShowSyncPromoAtStartup(profile_); - GURL old_url = (*startup_urls)[0]; - (*startup_urls)[0] = - SyncPromoUI::GetSyncPromoURL(GURL(chrome::kChromeUINewTabURL), - SyncPromoUI::SOURCE_START_PAGE); - - // An empty URL means to go to the home page. - if (old_url.is_empty() && - profile_->GetHomePage() == GURL(chrome::kChromeUINewTabURL)) { - old_url = GURL(chrome::kChromeUINewTabURL); - } - - // If the old URL is not the NTP then insert it right after the sync promo. - if (old_url != GURL(chrome::kChromeUINewTabURL)) - startup_urls->insert(startup_urls->begin() + 1, old_url); - - // If we have more than two startup tabs then skip the welcome page. - if (startup_urls->size() > 2) { - std::vector<GURL>::iterator it = std::find( - startup_urls->begin(), startup_urls->end(), GetWelcomePageURL()); - if (it != startup_urls->end()) - startup_urls->erase(it); - } - } -} - -void StartupBrowserCreatorImpl::CheckPreferencesBackup(Profile* profile) { - ProtectorService* protector_service = - ProtectorServiceFactory::GetForProfile(profile); - ProtectedPrefsWatcher* prefs_watcher = protector_service->GetPrefsWatcher(); - - // Check if backup is valid. - if (!prefs_watcher->is_backup_valid()) { - protector_service->ShowChange(protector::CreatePrefsBackupInvalidChange()); - // Further checks make no sense. - return; - } - - // Check for session startup (including pinned tabs) changes. - if (SessionStartupPref::DidStartupPrefChange(profile) || - prefs_watcher->DidPrefChange(prefs::kPinnedTabs)) { - LOG(WARNING) << "Session startup settings have changed"; - SessionStartupPref new_pref = SessionStartupPref::GetStartupPref(profile); - StartupTabs new_tabs = PinnedTabCodec::ReadPinnedTabs(profile); - const base::Value* tabs_backup = - prefs_watcher->GetBackupForPref(prefs::kPinnedTabs); - protector_service->ShowChange(protector::CreateSessionStartupChange( - new_pref, - new_tabs, - SessionStartupPref::GetStartupPrefBackup(profile), - PinnedTabCodec::ReadPinnedTabs(tabs_backup))); - } - - // Check for homepage changes. - if (prefs_watcher->DidPrefChange(prefs::kHomePage) || - prefs_watcher->DidPrefChange(prefs::kHomePageIsNewTabPage) || - prefs_watcher->DidPrefChange(prefs::kShowHomeButton)) { - LOG(WARNING) << "Homepage has changed"; - PrefService* prefs = profile->GetPrefs(); - std::string backup_homepage; - bool backup_homepage_is_ntp; - bool backup_show_home_button; - if (!prefs_watcher->GetBackupForPref(prefs::kHomePage)-> - GetAsString(&backup_homepage) || - !prefs_watcher->GetBackupForPref(prefs::kHomePageIsNewTabPage)-> - GetAsBoolean(&backup_homepage_is_ntp) || - !prefs_watcher->GetBackupForPref(prefs::kShowHomeButton)-> - GetAsBoolean(&backup_show_home_button)) { - NOTREACHED(); - } - protector_service->ShowChange(protector::CreateHomepageChange( - // New: - prefs->GetString(prefs::kHomePage), - prefs->GetBoolean(prefs::kHomePageIsNewTabPage), - prefs->GetBoolean(prefs::kShowHomeButton), - // Backup: - backup_homepage, - backup_homepage_is_ntp, - backup_show_home_button)); - } -} diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.h b/chrome/browser/ui/startup/startup_browser_creator_impl.h deleted file mode 100644 index 09537b0..0000000 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.h +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_UI_STARTUP_STARTUP_BROWSER_CREATOR_IMPL_H_ -#define CHROME_BROWSER_UI_STARTUP_STARTUP_BROWSER_CREATOR_IMPL_H_ -#pragma once - -#include <string> -#include <vector> - -#include "base/file_path.h" -#include "base/gtest_prod_util.h" -#include "chrome/browser/ui/startup/startup_tab.h" -#include "chrome/browser/ui/startup/startup_types.h" -#include "googleurl/src/gurl.h" - -class Browser; -class CommandLine; -class FilePath; -class Profile; -class StartupBrowserCreator; - -// Assists launching the application and appending the initial tabs for a -// browser window. -class StartupBrowserCreatorImpl { - public: - // There are two ctors. The first one implies a NULL browser_creator object - // and thus no access to distribution-specific first-run behaviors. The - // second one is always called when the browser starts even if it is not - // the first run. |is_first_run| indicates that this is a new profile. - StartupBrowserCreatorImpl(const FilePath& cur_dir, - const CommandLine& command_line, - browser::startup::IsFirstRun is_first_run); - StartupBrowserCreatorImpl(const FilePath& cur_dir, - const CommandLine& command_line, - StartupBrowserCreator* browser_creator, - browser::startup::IsFirstRun is_first_run); - ~StartupBrowserCreatorImpl(); - - // Creates the necessary windows for startup. Returns true on success, - // false on failure. process_startup is true if Chrome is just - // starting up. If process_startup is false, it indicates Chrome was - // already running and the user wants to launch another instance. - bool Launch(Profile* profile, - const std::vector<GURL>& urls_to_open, - bool process_startup); - - // Convenience for OpenTabsInBrowser that converts |urls| into a set of - // Tabs. - Browser* OpenURLsInBrowser(Browser* browser, - bool process_startup, - const std::vector<GURL>& urls); - - // Creates a tab for each of the Tabs in |tabs|. If browser is non-null - // and a tabbed browser, the tabs are added to it. Otherwise a new tabbed - // browser is created and the tabs are added to it. The browser the tabs - // are added to is returned, which is either |browser| or the newly created - // browser. - Browser* OpenTabsInBrowser(Browser* browser, - bool process_startup, - const StartupTabs& tabs); - - private: - FRIEND_TEST_ALL_PREFIXES(BrowserTest, RestorePinnedTabs); - FRIEND_TEST_ALL_PREFIXES(BrowserTest, AppIdSwitch); - - // If the process was launched with the web application command line flags, - // e.g. --app=http://www.google.com/ or --app_id=... return true. - // In this case |app_url| or |app_id| are populated if they're non-null. - bool IsAppLaunch(std::string* app_url, std::string* app_id); - - // If IsAppLaunch is true, tries to open an application window. - // If the app is specified to start in a tab, or IsAppLaunch is false, - // returns false to specify default processing. - bool OpenApplicationWindow(Profile* profile); - - // If IsAppLaunch is true and the user set a pref indicating that the app - // should open in a tab, do so. - bool OpenApplicationTab(Profile* profile); - - // Invoked from Launch to handle processing of urls. This may do any of the - // following: - // . Invoke ProcessStartupURLs if |process_startup| is true. - // . If |process_startup| is false, restore the last session if necessary, - // or invoke ProcessSpecifiedURLs. - // . 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 - // restored. - // . Otherwise invoke ProcessSpecifiedURLs - // If a browser was created, true is returned. Otherwise returns false and - // the caller must create a new browser. - bool ProcessStartupURLs(const std::vector<GURL>& urls_to_open); - - // Invoked from either ProcessLaunchURLs or ProcessStartupURLs to handle - // processing of URLs where the behavior is common between process startup - // and launch via an existing process (i.e. those explicitly specified by - // the user somehow). Does the following: - // . Attempts to restore any pinned tabs from last run of chrome. - // . If urls_to_open is non-empty, they are opened. - // . If the user's startup pref is to launch a specific set of URLs they - // are opened. - // - // If any tabs were opened, the Browser which was created is returned. - // Otherwise null is returned and the caller must create a new browser. - Browser* ProcessSpecifiedURLs(const std::vector<GURL>& urls_to_open); - - // Adds a Tab to |tabs| for each url in |urls| that doesn't already exist - // in |tabs|. - void AddUniqueURLs(const std::vector<GURL>& urls, StartupTabs* tabs); - - // Adds any startup infobars to the selected tab of the given browser. - void AddInfoBarsIfNecessary( - Browser* browser, - browser::startup::IsProcessStartup is_process_startup); - - // Adds additional startup URLs to the specified vector. - void AddStartupURLs(std::vector<GURL>* startup_urls) const; - - // Checks whether the Preferences backup is invalid and notifies user in - // that case. - void CheckPreferencesBackup(Profile* profile); - - const FilePath cur_dir_; - const CommandLine& command_line_; - Profile* profile_; - StartupBrowserCreator* browser_creator_; - bool is_first_run_; - DISALLOW_COPY_AND_ASSIGN(StartupBrowserCreatorImpl); -}; - -// Returns true if |profile| has exited uncleanly and has not been launched -// after the unclean exit. -bool HasPendingUncleanExit(Profile* profile); - -#endif // CHROME_BROWSER_UI_STARTUP_STARTUP_BROWSER_CREATOR_IMPL_H_ diff --git a/chrome/browser/ui/startup/startup_tab.cc b/chrome/browser/ui/startup/startup_tab.cc deleted file mode 100644 index 0249ba30..0000000 --- a/chrome/browser/ui/startup/startup_tab.cc +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2012 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/ui/startup/startup_tab.h" - -StartupTab::StartupTab() - : is_app(false), - is_pinned(true) { -} - -StartupTab::~StartupTab() { -} diff --git a/chrome/browser/ui/startup/startup_tab.h b/chrome/browser/ui/startup/startup_tab.h deleted file mode 100644 index 5597fc2..0000000 --- a/chrome/browser/ui/startup/startup_tab.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_UI_STARTUP_STARTUP_TAB_H_ -#define CHROME_BROWSER_UI_STARTUP_STARTUP_TAB_H_ -#pragma once - -#include <string> -#include <vector> - -#include "googleurl/src/gurl.h" - -// Represents tab data at startup. -struct StartupTab { - StartupTab(); - ~StartupTab(); - - // The url to load. - GURL url; - - // If true, the tab corresponds to an app an |app_id| gives the id of the - // app. - bool is_app; - - // True if the is tab pinned. - bool is_pinned; - - // Id of the app. - std::string app_id; -}; - -typedef std::vector<StartupTab> StartupTabs; - -#endif // CHROME_BROWSER_UI_STARTUP_STARTUP_TAB_H_ diff --git a/chrome/browser/ui/startup/startup_types.h b/chrome/browser/ui/startup/startup_types.h deleted file mode 100644 index 5f2d177..0000000 --- a/chrome/browser/ui/startup/startup_types.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_BROWSER_UI_STARTUP_STARTUP_TYPES_H_ -#define CHROME_BROWSER_UI_STARTUP_STARTUP_TYPES_H_ -#pragma once - -namespace browser { -namespace startup { - -enum IsProcessStartup { - IS_NOT_PROCESS_STARTUP, // Session is being created when a Chrome process is - // already running, e.g. clicking on a taskbar icon - // when Chrome is already running, or restoring a - // profile. - IS_PROCESS_STARTUP // Session is being created when the Chrome process - // is not already running. -}; -enum IsFirstRun { - IS_NOT_FIRST_RUN, // Session is being created after Chrome has already - // been run at least once on the system. - IS_FIRST_RUN // Session is being created immediately after Chrome - // has been installed on the system. -}; - -} // namespace startup -} // namespace browser - -#endif // CHROME_BROWSER_UI_STARTUP_STARTUP_TYPES_H_ |