#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/environment.h"
-#include "base/file_util.h"
#include "base/files/file_path.h"
+#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
#include "base/metrics/statistics_recorder.h"
-#include "base/path_service.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/app_mode/app_mode_utils.h"
#include "chrome/browser/auto_launch_trial.h"
-#include "chrome/browser/automation/automation_provider.h"
-#include "chrome/browser/automation/automation_provider_list.h"
-#include "chrome/browser/automation/testing_automation_provider.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
#include "chrome/browser/extensions/startup_helper.h"
#include "chrome/browser/extensions/unpacked_installer.h"
#include "chrome/browser/first_run/first_run.h"
-#include "chrome/browser/google/google_util.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profiles_state.h"
-#include "chrome/browser/search_engines/util.h"
+#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/app_list/app_list_service.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
+#include "chrome/browser/ui/user_manager.h"
#include "chrome/common/chrome_constants.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/net/url_fixer_upper.h"
#include "chrome/common/pref_names.h"
-#include "chrome/common/profile_management_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/installer/util/browser_distribution.h"
+#include "components/google/core/browser/google_util.h"
+#include "components/search_engines/util.h"
+#include "components/signin/core/common/profile_management_switches.h"
+#include "components/url_fixer/url_fixer.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/navigation_controller.h"
-#include "grit/locale_settings.h"
#include "net/base/net_util.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
#if defined(USE_ASH)
#include "ash/shell.h"
#include "chrome/browser/chromeos/app_mode/app_launch_utils.h"
#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
-#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chromeos/chromeos_switches.h"
+#include "components/user_manager/user_manager.h"
#endif
#if defined(TOOLKIT_VIEWS) && defined(OS_LINUX)
-#include "ui/events/x/touch_factory_x11.h"
+#include "ui/events/devices/x11/touch_factory_x11.h"
#endif
-#if defined(OS_WIN)
-#include "chrome/browser/ui/startup/startup_browser_creator_win.h"
+#if defined(OS_MACOSX)
+#include "chrome/browser/web_applications/web_app_mac.h"
#endif
-#if defined(ENABLE_FULL_PRINTING)
+#if defined(ENABLE_PRINT_PREVIEW)
#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h"
#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h"
#include "chrome/browser/printing/print_dialog_cloud.h"
registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY,
content::NotificationService::AllSources());
}
- virtual ~ProfileLaunchObserver() {}
+ ~ProfileLaunchObserver() override {}
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE {
+ void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) override {
switch (type) {
case chrome::NOTIFICATION_PROFILE_DESTROYED: {
Profile* profile = content::Source<Profile>(source).ptr();
chrome::HostDesktopType host_desktop_type =
chrome::HOST_DESKTOP_TYPE_NATIVE;
-#if defined(OS_WIN) && defined(USE_ASH)
+#if defined(USE_ASH) && !defined(OS_CHROMEOS)
// We want to maintain only one type of instance for now, either ASH
// or desktop.
// TODO(shrikant): Remove this code once we decide on running both desktop
profile_launch_observer.Get().AddLaunched(profile);
#if defined(OS_CHROMEOS)
- g_browser_process->platform_part()->profile_helper()->ProfileStartup(
- profile,
- process_startup);
+ chromeos::ProfileHelper::Get()->ProfileStartup(profile, process_startup);
#endif
return true;
}
// in a location shared by all users and the check is meaningless. Query the
// UserManager instead to determine whether the user is new.
#if defined(OS_CHROMEOS)
- const bool is_first_run = chromeos::UserManager::Get()->IsCurrentUserNew();
+ const bool is_first_run =
+ user_manager::UserManager::Get()->IsCurrentUserNew();
+ // On ChromeOS restarts force the user to login again. The expectation is that
+ // after a login the user gets clean state. For this reason we ignore
+ // StartupBrowserCreator::WasRestarted().
+ const bool did_restart = false;
#else
const bool is_first_run = first_run::IsChromeFirstRun();
+ const bool did_restart = StartupBrowserCreator::WasRestarted();
#endif
// The pref has an OS-dependent default value. For the first run only, this
// However, new profiles can be created from a browser process that has this
// switch so do not set the session pref to SessionStartupPref::LAST for
// those as there is nothing to restore.
- if ((command_line.HasSwitch(switches::kRestoreLastSession) ||
- StartupBrowserCreator::WasRestarted()) &&
+ if ((command_line.HasSwitch(switches::kRestoreLastSession) || did_restart) &&
!profile->IsNewProfile()) {
pref.type = SessionStartupPref::LAST;
}
+
+ // A browser starting for a profile being unlocked should always restore.
+ if (!profile->IsGuestSession()) {
+ ProfileInfoCache& info_cache =
+ g_browser_process->profile_manager()->GetProfileInfoCache();
+ size_t index = info_cache.GetIndexOfProfileWithPath(profile->GetPath());
+
+ if (index != std::string::npos &&
+ info_cache.ProfileIsSigninRequiredAtIndex(index)) {
+ pref.type = SessionStartupPref::LAST;
+ }
+ }
+
if (pref.type == SessionStartupPref::LAST &&
IncognitoModePrefs::ShouldLaunchIncognito(command_line, prefs)) {
// We don't store session information when incognito. If the user has
if ((param.value().size() > 2) && (param.value()[0] == '?') &&
(param.value()[1] == ' ')) {
GURL url(GetDefaultSearchURLForSearchTerms(
- profile, param.LossyDisplayName().substr(2)));
+ TemplateURLServiceFactory::GetForProfile(profile),
+ param.LossyDisplayName().substr(2)));
if (url.is_valid()) {
urls.push_back(url);
continue;
// This call can (in rare circumstances) block the UI thread.
// Allow it until this bug is fixed.
// http://code.google.com/p/chromium/issues/detail?id=60641
- GURL url;
- {
+ GURL url = GURL(param.MaybeAsASCII());
+ // http://crbug.com/371030: Only use URLFixerUpper if we don't have a valid
+ // URL, otherwise we will look in the current directory for a file named
+ // 'about' if the browser was started with a about:foo argument.
+ if (!url.is_valid()) {
base::ThreadRestrictions::ScopedAllowIO allow_io;
- url = URLFixerUpper::FixupRelativeFile(cur_dir, param);
+ url = url_fixer::FixupRelativeFile(cur_dir, param);
}
// Exclude dangerous schemes.
if (url.is_valid()) {
ChildProcessSecurityPolicy* policy =
ChildProcessSecurityPolicy::GetInstance();
if (policy->IsWebSafeScheme(url.scheme()) ||
- url.SchemeIs(content::kFileScheme) ||
+ url.SchemeIs(url::kFileScheme) ||
#if defined(OS_CHROMEOS)
- // In ChromeOS, allow a settings page to be specified on the
- // command line. See ExistingUserController::OnLoginSuccess.
+ // In ChromeOS, allow any settings page to be specified on the command
+ // line. See ExistingUserController::OnLoginSuccess.
(url.spec().find(chrome::kChromeUISettingsURL) == 0) ||
+#else
+ ((url.spec().find(std::string(chrome::kChromeUISettingsURL) +
+ chrome::kResetProfileSettingsSubPage) == 0)) ||
#endif
- (url.spec().compare(content::kAboutBlankURL) == 0)) {
+ (url.spec().compare(url::kAboutBlankURL) == 0)) {
urls.push_back(url);
}
}
}
-#if defined(OS_WIN)
- if (urls.empty()) {
- // If we are in Windows 8 metro mode and were launched as a result of the
- // search charm or via a url navigation in metro, then fetch the
- // corresponding url.
- GURL url(chrome::GetURLToOpen(profile));
- if (url.is_valid())
- urls.push_back(url);
- }
-#endif // OS_WIN
return urls;
}
const Profiles& last_opened_profiles,
int* return_code,
StartupBrowserCreator* browser_creator) {
+ VLOG(2) << "ProcessCmdLineImpl : BEGIN";
DCHECK(last_used_profile);
if (process_startup) {
if (command_line.HasSwitch(switches::kDisablePromptOnRepost))
bool silent_launch = false;
-#if defined(ENABLE_AUTOMATION)
- // Look for the testing channel ID ONLY during process startup
- if (process_startup &&
- command_line.HasSwitch(switches::kTestingChannelID)) {
- std::string testing_channel_id = command_line.GetSwitchValueASCII(
- switches::kTestingChannelID);
- // TODO(sanjeevr) Check if we need to make this a singleton for
- // compatibility with the old testing code
- // If there are any extra parameters, we expect each one to generate a
- // new tab; if there are none then we get one homepage tab.
- int expected_tab_count = 1;
- if (command_line.HasSwitch(switches::kNoStartupWindow) &&
- !command_line.HasSwitch(switches::kAutoLaunchAtStartup)) {
- expected_tab_count = 0;
-#if defined(OS_CHROMEOS)
- // kLoginManager will cause Chrome to start up with the ChromeOS login
- // screen instead of a browser window, so it won't load any tabs.
- } else if (command_line.HasSwitch(chromeos::switches::kLoginManager)) {
- expected_tab_count = 0;
-#endif
- } else if (command_line.HasSwitch(switches::kRestoreLastSession)) {
- std::string restore_session_value(
- command_line.GetSwitchValueASCII(switches::kRestoreLastSession));
- base::StringToInt(restore_session_value, &expected_tab_count);
- } else {
- std::vector<GURL> urls_to_open = GetURLsFromCommandLine(
- command_line, cur_dir, last_used_profile);
- expected_tab_count =
- std::max(1, static_cast<int>(urls_to_open.size()));
- }
- if (!CreateAutomationProvider<TestingAutomationProvider>(
- testing_channel_id,
- last_used_profile,
- static_cast<size_t>(expected_tab_count)))
- return false;
- }
-
- if (command_line.HasSwitch(switches::kSilentLaunch)) {
- std::vector<GURL> urls_to_open = GetURLsFromCommandLine(
- command_line, cur_dir, last_used_profile);
- size_t expected_tabs =
- std::max(static_cast<int>(urls_to_open.size()), 0);
- if (expected_tabs == 0)
- silent_launch = true;
- }
-
- if (command_line.HasSwitch(switches::kAutomationClientChannelID)) {
- std::string automation_channel_id = command_line.GetSwitchValueASCII(
- switches::kAutomationClientChannelID);
- // If there are any extra parameters, we expect each one to generate a
- // new tab; if there are none then we have no tabs
- std::vector<GURL> urls_to_open = GetURLsFromCommandLine(
- command_line, cur_dir, last_used_profile);
- size_t expected_tabs =
- std::max(static_cast<int>(urls_to_open.size()), 0);
- if (expected_tabs == 0)
- silent_launch = true;
-
- if (!CreateAutomationProvider<AutomationProvider>(
- automation_channel_id, last_used_profile, expected_tabs))
- return false;
- }
-#endif // defined(ENABLE_AUTOMATION)
-
-#if defined(ENABLE_FULL_PRINTING)
+#if defined(ENABLE_PRINT_PREVIEW)
// If we are just displaying a print dialog we shouldn't open browser
// windows.
if (command_line.HasSwitch(switches::kCloudPrintFile) &&
// launching and quit.
return false;
}
-#endif // defined(ENABLE_FULL_PRINTING)
+#endif // defined(ENABLE_PRINT_PREVIEW)
+ VLOG(2) << "ProcessCmdLineImpl: PLACE 1";
if (command_line.HasSwitch(switches::kExplicitlyAllowedPorts)) {
std::string allowed_ports =
command_line.GetSwitchValueASCII(switches::kExplicitlyAllowedPorts);
net::SetExplicitlyAllowedPorts(allowed_ports);
}
- if (command_line.HasSwitch(switches::kInstallFromWebstore)) {
+ if (command_line.HasSwitch(switches::kInstallEphemeralAppFromWebstore)) {
extensions::StartupHelper helper;
- helper.InstallFromWebstore(command_line, last_used_profile);
+ helper.InstallEphemeralApp(command_line, last_used_profile);
// Nothing more needs to be done, so return false to stop launching and
// quit.
return false;
}
+ VLOG(2) << "ProcessCmdLineImpl: PLACE 2";
if (command_line.HasSwitch(switches::kValidateCrx)) {
if (!process_startup) {
LOG(ERROR) << "chrome is already running; you must close all running "
return false;
}
- if (command_line.HasSwitch(switches::kLimitedInstallFromWebstore)) {
- extensions::StartupHelper helper;
- helper.LimitedInstallFromWebstore(command_line, last_used_profile,
- base::Bind(&base::DoNothing));
- }
-
#if defined(OS_CHROMEOS)
+
+#if defined(USE_ATHENA)
+ // Athena will never launch browser.
+ silent_launch = true;
+#endif
+
// The browser will be launched after the user logs in.
- if (command_line.HasSwitch(chromeos::switches::kLoginManager) ||
- command_line.HasSwitch(chromeos::switches::kLoginPassword)) {
+ if (command_line.HasSwitch(chromeos::switches::kLoginManager))
silent_launch = true;
- }
if (chrome::IsRunningInAppMode() &&
command_line.HasSwitch(switches::kAppId)) {
chrome::AttemptUserExit();
return false;
}
-#endif
+#endif // OS_CHROMEOS
#if defined(TOOLKIT_VIEWS) && defined(USE_X11)
ui::TouchFactory::SetTouchDeviceListFromCommandLine();
#endif
+ VLOG(2) << "ProcessCmdLineImpl: PLACE 3";
+#if defined(OS_MACOSX)
+ if (web_app::MaybeRebuildShortcut(command_line))
+ return true;
+#endif
+
if (!process_startup &&
command_line.HasSwitch(switches::kDumpBrowserHistograms)) {
// Only handle --dump-browser-histograms from a rendezvous. In this case, do
silent_launch = true;
}
- // 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 we don't want to launch a new browser window or tab we are done here.
if (silent_launch)
return true;
+ VLOG(2) << "ProcessCmdLineImpl: PLACE 4";
// Check for --load-and-launch-app.
if (command_line.HasSwitch(apps::kLoadAndLaunchApp) &&
!IncognitoModePrefs::ShouldLaunchIncognito(
return true;
}
+ VLOG(2) << "ProcessCmdLineImpl: PLACE 5";
chrome::startup::IsProcessStartup is_process_startup = process_startup ?
chrome::startup::IS_PROCESS_STARTUP :
chrome::startup::IS_NOT_PROCESS_STARTUP;
// |last_used_profile| is the last used incognito profile. Restoring it will
// create a browser window for the corresponding original profile.
if (last_opened_profiles.empty()) {
- // If the last used profile was a guest, show the user manager instead.
- if (switches::IsNewProfileManagement() &&
- last_used_profile->IsGuestSession()) {
- chrome::ShowUserManager(base::FilePath());
- return true;
+ VLOG(2) << "ProcessCmdLineImpl: PLACE 6.A";
+ // If the last used profile is locked or was a guest, show the user manager.
+ if (switches::IsNewAvatarMenu()) {
+ ProfileInfoCache& profile_info =
+ g_browser_process->profile_manager()->GetProfileInfoCache();
+ size_t profile_index = profile_info.GetIndexOfProfileWithPath(
+ last_used_profile->GetPath());
+ bool signin_required = profile_index != std::string::npos &&
+ profile_info.ProfileIsSigninRequiredAtIndex(profile_index);
+
+ // Guest or locked profiles cannot be re-opened on startup. The only
+ // exception is if there's already a Guest window open in a separate
+ // process (for example, launching a new browser after clicking on a
+ // downloaded file in Guest mode).
+ bool has_guest_browsers = last_used_profile->IsGuestSession() &&
+ chrome::GetTotalBrowserCountForProfile(
+ last_used_profile->GetOffTheRecordProfile()) > 0;
+ if (signin_required ||
+ (last_used_profile->IsGuestSession() && !has_guest_browsers)) {
+ UserManager::Show(base::FilePath(),
+ profiles::USER_MANAGER_NO_TUTORIAL,
+ profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION);
+ return true;
+ }
}
- if (!browser_creator->LaunchBrowser(command_line, last_used_profile,
+
+ VLOG(2) << "ProcessCmdLineImpl: PLACE 7.A";
+ Profile* profile_to_open = last_used_profile->IsGuestSession() ?
+ last_used_profile->GetOffTheRecordProfile() : last_used_profile;
+
+ VLOG(2) << "ProcessCmdLineImpl: PLACE 8.A";
+ if (!browser_creator->LaunchBrowser(command_line, profile_to_open,
cur_dir, is_process_startup,
is_first_run, return_code)) {
return false;
}
} else {
+ VLOG(2) << "ProcessCmdLineImpl: PLACE 6.B";
+ // Guest profiles should not be reopened on startup. This can happen if
+ // the last used profile was a Guest, but other profiles were also open
+ // when Chrome was closed. In this case, pick a different open profile
+ // to be the active one, since the Guest profile is never added to the list
+ // of open profiles.
+ if (switches::IsNewAvatarMenu() && last_used_profile->IsGuestSession()) {
+ DCHECK(!last_opened_profiles[0]->IsGuestSession());
+ last_used_profile = last_opened_profiles[0];
+ }
+
// Launch the last used profile with the full command line, and the other
// opened profiles without the URLs to launch.
CommandLine command_line_without_urls(command_line.GetProgram());
command_line_without_urls.AppendSwitchNative(switch_it->first,
switch_it->second);
}
+ VLOG(2) << "ProcessCmdLineImpl: PLACE 7.B";
// Launch the profiles in the order they became active.
for (Profiles::const_iterator it = last_opened_profiles.begin();
it != last_opened_profiles.end(); ++it) {
+ DCHECK(!(*it)->IsGuestSession());
// Don't launch additional profiles which would only open a new tab
// page. When restarting after an update, all profiles will reopen last
// open pages.
!HasPendingUncleanExit(*it))
continue;
- // Don't re-open a browser window for the guest profile.
- if (switches::IsNewProfileManagement() &&
- (*it)->IsGuestSession())
- continue;
-
if (!browser_creator->LaunchBrowser((*it == last_used_profile) ?
command_line : command_line_without_urls, *it, cur_dir,
is_process_startup, is_first_run, return_code))
// We've launched at least one browser.
is_process_startup = chrome::startup::IS_NOT_PROCESS_STARTUP;
}
+ VLOG(2) << "ProcessCmdLineImpl: PLACE 8.B";
// This must be done after all profiles have been launched so the observer
// knows about all profiles to wait for before activating this one.
-
- // If the last used profile was the guest one, we didn't open it so
- // we don't need to activate it either.
- if (!switches::IsNewProfileManagement() &&
- !last_used_profile->IsGuestSession())
- profile_launch_observer.Get().set_profile_to_activate(last_used_profile);
+ profile_launch_observer.Get().set_profile_to_activate(last_used_profile);
}
- return true;
-}
-
-template <class AutomationProviderClass>
-bool StartupBrowserCreator::CreateAutomationProvider(
- const std::string& channel_id,
- Profile* profile,
- size_t expected_tabs) {
-#if defined(ENABLE_AUTOMATION)
- scoped_refptr<AutomationProviderClass> automation =
- new AutomationProviderClass(profile);
- if (!automation->InitializeChannel(channel_id))
- return false;
- automation->SetExpectedTabCount(expected_tabs);
-
- AutomationProviderList* list = g_browser_process->GetAutomationProviderList();
- DCHECK(list);
- list->AddProvider(automation.get());
-#endif // defined(ENABLE_AUTOMATION)
-
+ VLOG(2) << "ProcessCmdLineImpl: END";
return true;
}
base::FilePath GetStartupProfilePath(const base::FilePath& user_data_dir,
const CommandLine& command_line) {
+ if (command_line.HasSwitch(switches::kProfileDirectory)) {
+ return user_data_dir.Append(
+ command_line.GetSwitchValuePath(switches::kProfileDirectory));
+ }
+
// If we are showing the app list then chrome isn't shown so load the app
// list's profile rather than chrome's.
if (command_line.HasSwitch(switches::kShowAppList)) {
GetProfilePath(user_data_dir);
}
- if (command_line.HasSwitch(switches::kProfileDirectory)) {
- return user_data_dir.Append(
- command_line.GetSwitchValuePath(switches::kProfileDirectory));
- }
-
return g_browser_process->profile_manager()->GetLastUsedProfileDir(
user_data_dir);
}