Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / startup / startup_browser_creator.cc
index ce9a14c..a326080 100644 (file)
 #include "base/compiler_specific.h"
 #include "base/environment.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/path_service.h"
+#include "base/metrics/statistics_recorder.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/search_engines/util.h"
+#include "chrome/browser/profiles/profiles_state.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/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"
+#endif
 
 #if defined(OS_CHROMEOS)
 #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/user_manager.h"
+#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.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/automation/chrome_frame_automation_provider_win.h"
-#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"
@@ -103,11 +109,11 @@ class ProfileLaunchObserver : public content::NotificationObserver {
     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();
@@ -225,6 +231,17 @@ class ProfileLaunchObserver : public content::NotificationObserver {
 base::LazyInstance<ProfileLaunchObserver> profile_launch_observer =
     LAZY_INSTANCE_INITIALIZER;
 
+// Dumps the current set of the browser process's histograms to |output_file|.
+// The file is overwritten if it exists. This function should only be called in
+// the blocking pool.
+void DumpBrowserHistograms(const base::FilePath& output_file) {
+  base::ThreadRestrictions::AssertIOAllowed();
+
+  std::string output_string(base::StatisticsRecorder::ToJSON(std::string()));
+  base::WriteFile(output_file, output_string.data(),
+                  static_cast<int>(output_string.size()));
+}
+
 }  // namespace
 
 StartupBrowserCreator::StartupBrowserCreator()
@@ -281,9 +298,21 @@ bool StartupBrowserCreator::LaunchBrowser(
     StartupBrowserCreatorImpl lwp(cur_dir, command_line, this, is_first_run);
     const std::vector<GURL> urls_to_launch =
         GetURLsFromCommandLine(command_line, cur_dir, profile);
+    chrome::HostDesktopType host_desktop_type =
+        chrome::HOST_DESKTOP_TYPE_NATIVE;
+
+#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
+    // and ASH instances side by side.
+    if (ash::Shell::HasInstance())
+      host_desktop_type = chrome::HOST_DESKTOP_TYPE_ASH;
+#endif
+
     const bool launched = lwp.Launch(profile, urls_to_launch,
                                in_synchronous_profile_launch_,
-                               chrome::HOST_DESKTOP_TYPE_NATIVE);
+                               host_desktop_type);
     in_synchronous_profile_launch_ = false;
     if (!launched) {
       LOG(ERROR) << "launch error";
@@ -298,9 +327,7 @@ bool StartupBrowserCreator::LaunchBrowser(
   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;
 }
@@ -332,9 +359,15 @@ SessionStartupPref StartupBrowserCreator::GetSessionStartupPref(
   // 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
@@ -350,11 +383,23 @@ SessionStartupPref StartupBrowserCreator::GetSessionStartupPref(
   // 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
@@ -385,7 +430,8 @@ std::vector<GURL> StartupBrowserCreator::GetURLsFromCommandLine(
     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;
@@ -398,37 +444,33 @@ std::vector<GURL> StartupBrowserCreator::GetURLsFromCommandLine(
     // 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(chrome::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;
 }
 
@@ -441,6 +483,7 @@ bool StartupBrowserCreator::ProcessCmdLineImpl(
     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))
@@ -449,83 +492,12 @@ bool StartupBrowserCreator::ProcessCmdLineImpl(
 
   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 (command_line.HasSwitch(switches::kChromeFrame)) {
-#if defined(OS_WIN)
-      if (!CreateAutomationProvider<ChromeFrameAutomationProvider>(
-          automation_channel_id, last_used_profile, expected_tabs))
-        return false;
-#endif
-    } else {
-      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) &&
-      print_dialog_cloud::CreatePrintDialogFromCommandLine(command_line)) {
+      print_dialog_cloud::CreatePrintDialogFromCommandLine(last_used_profile,
+                                                           command_line)) {
     silent_launch = true;
   }
 
@@ -538,22 +510,24 @@ bool StartupBrowserCreator::ProcessCmdLineImpl(
       // 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 "
@@ -572,18 +546,16 @@ bool StartupBrowserCreator::ProcessCmdLineImpl(
     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)) {
@@ -594,17 +566,46 @@ bool StartupBrowserCreator::ProcessCmdLineImpl(
     // Skip browser launch since app mode launches its app window.
     silent_launch = true;
   }
-#endif
+
+  // If we are a demo app session and we crashed, there is no safe recovery
+  // possible. We should instead cleanly exit and go back to the OOBE screen,
+  // where we will launch again after the timeout has expired.
+  if (chromeos::DemoAppLauncher::IsDemoAppSession(
+      command_line.GetSwitchValueASCII(chromeos::switches::kLoginUser))) {
+    chrome::AttemptUserExit();
+    return false;
+  }
+#endif  // OS_CHROMEOS
 
 #if defined(TOOLKIT_VIEWS) && defined(USE_X11)
   ui::TouchFactory::SetTouchDeviceListFromCommandLine();
 #endif
 
-  // If we don't want to launch a new browser window or tab (in the case
-  // of an automation request), we are done here.
+  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
+    // not open a new browser window even if no output file was given.
+    base::FilePath output_file(
+        command_line.GetSwitchValuePath(switches::kDumpBrowserHistograms));
+    if (!output_file.empty()) {
+      BrowserThread::PostBlockingPoolTask(
+          FROM_HERE,
+          base::Bind(&DumpBrowserHistograms, output_file));
+    }
+    silent_launch = true;
+  }
+
+  // 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(
@@ -626,6 +627,7 @@ bool StartupBrowserCreator::ProcessCmdLineImpl(
       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;
@@ -640,12 +642,54 @@ bool StartupBrowserCreator::ProcessCmdLineImpl(
   // |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 (!browser_creator->LaunchBrowser(command_line, last_used_profile,
+    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;
+      }
+    }
+
+    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());
@@ -655,9 +699,11 @@ bool StartupBrowserCreator::ProcessCmdLineImpl(
       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.
@@ -667,6 +713,7 @@ bool StartupBrowserCreator::ProcessCmdLineImpl(
           startup_pref.type == SessionStartupPref::DEFAULT &&
           !HasPendingUncleanExit(*it))
         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))
@@ -674,30 +721,12 @@ bool StartupBrowserCreator::ProcessCmdLineImpl(
       // 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.
     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;
 }
 
@@ -724,7 +753,7 @@ void StartupBrowserCreator::ProcessCommandLineAlreadyRunning(
   if (!profile) {
     profile_manager->CreateProfileAsync(profile_path,
         base::Bind(&StartupBrowserCreator::ProcessCommandLineOnProfileCreated,
-                   command_line, cur_dir), string16(), string16(),
+                   command_line, cur_dir), base::string16(), base::string16(),
                    std::string());
     return;
   }
@@ -742,3 +771,21 @@ bool HasPendingUncleanExit(Profile* profile) {
   return profile->GetLastSessionExitType() == Profile::EXIT_CRASHED &&
       !profile_launch_observer.Get().HasBeenLaunched(profile);
 }
+
+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)) {
+    return AppListService::Get(chrome::HOST_DESKTOP_TYPE_NATIVE)->
+        GetProfilePath(user_data_dir);
+  }
+
+  return g_browser_process->profile_manager()->GetLastUsedProfileDir(
+      user_data_dir);
+}