15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/startup/startup_browser_creator.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>   // For max().
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "apps/app_load_service.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "apps/switches.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/shell.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/environment.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/file_util.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/metrics/statistics_recorder.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/app_mode/app_mode_utils.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/auto_launch_trial.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/automation_provider.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/automation_provider_list.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/testing_automation_provider.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/startup_helper.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/unpacked_installer.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/first_run/first_run.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/google/google_util.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/desktop_notification_service.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/incognito_mode_prefs.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/session_startup_pref.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/profiles/profiles_state.h"
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/search_engines/util.h"
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h"
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h"
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_result_codes.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_version_info.h"
60558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/common/net/url_fixer_upper.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/browser_distribution.h"
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/child_process_security_policy.h"
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/navigation_controller.h"
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/locale_settings.h"
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/chromeos/app_mode/app_launch_utils.h"
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h"
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h"
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/chromeos_switches.h"
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_VIEWS) && defined(OS_LINUX)
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/events/x/touch_factory_x11.h"
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/automation/chrome_frame_automation_provider_win.h"
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/startup/startup_browser_creator_win.h"
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#if defined(ENABLE_FULL_PRINTING)
90c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h"
91c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h"
92c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#include "chrome/browser/printing/print_dialog_cloud.h"
93c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#endif
94c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::ChildProcessSecurityPolicy;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Keeps track on which profiles have been launched.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProfileLaunchObserver : public content::NotificationObserver {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProfileLaunchObserver()
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : profile_to_activate_(NULL),
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        activated_profile_(false) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   content::NotificationService::AllSources());
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY,
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   content::NotificationService::AllSources());
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ProfileLaunchObserver() {}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationSource& source,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (type) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case chrome::NOTIFICATION_PROFILE_DESTROYED: {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Profile* profile = content::Source<Profile>(source).ptr();
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        launched_profiles_.erase(profile);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        opened_profiles_.erase(profile);
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (profile == profile_to_activate_)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          profile_to_activate_ = NULL;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // If this profile was the last launched one without an opened window,
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // then we may be ready to activate |profile_to_activate_|.
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        MaybeActivateProfile();
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case chrome::NOTIFICATION_BROWSER_WINDOW_READY: {
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        Browser* browser = content::Source<Browser>(source).ptr();
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DCHECK(browser);
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        opened_profiles_.insert(browser->profile());
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        MaybeActivateProfile();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool HasBeenLaunched(const Profile* profile) const {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return launched_profiles_.find(profile) != launched_profiles_.end();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddLaunched(Profile* profile) {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    launched_profiles_.insert(profile);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Since the startup code only executes for browsers launched in
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // desktop mode, i.e., HOST_DESKTOP_TYPE_NATIVE. Ash should never get here.
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (chrome::FindBrowserWithProfile(profile,
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       chrome::HOST_DESKTOP_TYPE_NATIVE)) {
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // A browser may get opened before we get initialized (e.g., in tests),
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // so we never see the NOTIFICATION_BROWSER_WINDOW_READY for it.
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      opened_profiles_.insert(profile);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Clear() {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    launched_profiles_.clear();
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    opened_profiles_.clear();
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool activated_profile() { return activated_profile_; }
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_profile_to_activate(Profile* profile) {
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    profile_to_activate_ = profile;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MaybeActivateProfile();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void MaybeActivateProfile() {
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!profile_to_activate_)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check that browsers have been opened for all the launched profiles.
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Note that browsers opened for profiles that were not added as launched
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // profiles are simply ignored.
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::set<const Profile*>::const_iterator i = launched_profiles_.begin();
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (; i != launched_profiles_.end(); ++i) {
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (opened_profiles_.find(*i) == opened_profiles_.end())
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return;
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Asynchronous post to give a chance to the last window to completely
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // open and activate before trying to activate |profile_to_activate_|.
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserThread::PostTask(
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        BrowserThread::UI, FROM_HERE,
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ProfileLaunchObserver::ActivateProfile,
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::Unretained(this)));
186a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // Avoid posting more than once before ActivateProfile gets called.
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    registrar_.Remove(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY,
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      content::NotificationService::AllSources());
189a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    registrar_.Remove(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
190a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                      content::NotificationService::AllSources());
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ActivateProfile() {
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We need to test again, in case the profile got deleted in the mean time.
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (profile_to_activate_) {
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Browser* browser = chrome::FindBrowserWithProfile(
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          profile_to_activate_, chrome::HOST_DESKTOP_TYPE_NATIVE);
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // |profile| may never get launched, e.g., if it only had
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // incognito Windows and one of them was used to exit Chrome.
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // So it won't have a browser in that case.
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (browser)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        browser->window()->Activate();
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // No need try to activate this profile again.
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_to_activate_ = NULL;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Assign true here, even if no browser was actually activated, so that
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // the test can stop waiting, and fail gracefully when needed.
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    activated_profile_ = true;
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These are the profiles that get launched by
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // StartupBrowserCreator::LaunchBrowser.
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<const Profile*> launched_profiles_;
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These are the profiles for which at least one browser window has been
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // opened. This is needed to know when it is safe to activate
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |profile_to_activate_|, otherwise, new browser windows being opened will
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // be activated on top of it.
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<const Profile*> opened_profiles_;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This is NULL until the profile to activate has been chosen. This value,
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // should only be set once all profiles have been launched, otherwise,
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // activation may not happen after the launch of newer profiles.
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Profile* profile_to_activate_;
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set once we attempted to activate a profile. We only get one shot at this.
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool activated_profile_;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ProfileLaunchObserver);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<ProfileLaunchObserver> profile_launch_observer =
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Dumps the current set of the browser process's histograms to |output_file|.
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// The file is overwritten if it exists. This function should only be called in
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// the blocking pool.
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DumpBrowserHistograms(const base::FilePath& output_file) {
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string output_string(base::StatisticsRecorder::ToJSON(std::string()));
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  file_util::WriteFile(output_file, output_string.data(),
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       static_cast<int>(output_string.size()));
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StartupBrowserCreator::StartupBrowserCreator()
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : is_default_browser_dialog_suppressed_(false),
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      show_main_browser_window_(true) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StartupBrowserCreator::~StartupBrowserCreator() {}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StartupBrowserCreator::was_restarted_read_ = false;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool StartupBrowserCreator::in_synchronous_profile_launch_ = false;
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StartupBrowserCreator::AddFirstRunTab(const GURL& url) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_run_tabs_.push_back(url);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StartupBrowserCreator::InSynchronousProfileLaunch() {
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return in_synchronous_profile_launch_;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StartupBrowserCreator::LaunchBrowser(
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CommandLine& command_line,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& cur_dir,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chrome::startup::IsProcessStartup process_startup,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chrome::startup::IsFirstRun is_first_run,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int* return_code) {
27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_synchronous_profile_launch_ =
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      process_startup == chrome::startup::IS_PROCESS_STARTUP;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(profile);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Continue with the incognito profile from here on if Incognito mode
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is forced.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IncognitoModePrefs::ShouldLaunchIncognito(command_line,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                profile->GetPrefs())) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    profile = profile->GetOffTheRecordProfile();
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (command_line.HasSwitch(switches::kIncognito)) {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "Incognito mode disabled by policy, launching a normal "
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << "browser session.";
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Note: This check should have been done in ProcessCmdLineImpl()
29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // before calling this function. However chromeos/login/login_utils.cc
29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // calls this function directly (see comments there) so it has to be checked
29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // again.
29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const bool silent_launch = command_line.HasSwitch(switches::kSilentLaunch);
29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!silent_launch) {
29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    StartupBrowserCreatorImpl lwp(cur_dir, command_line, this, is_first_run);
29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::vector<GURL> urls_to_launch =
29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        GetURLsFromCommandLine(command_line, cur_dir, profile);
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    chrome::HostDesktopType host_desktop_type =
301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        chrome::HOST_DESKTOP_TYPE_NATIVE;
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_WIN) && defined(USE_ASH)
304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // We want to maintain only one type of instance for now, either ASH
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // or desktop.
306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // TODO(shrikant): Remove this code once we decide on running both desktop
307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // and ASH instances side by side.
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (ash::Shell::HasInstance())
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      host_desktop_type = chrome::HOST_DESKTOP_TYPE_ASH;
310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const bool launched = lwp.Launch(profile, urls_to_launch,
31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               in_synchronous_profile_launch_,
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               host_desktop_type);
31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    in_synchronous_profile_launch_ = false;
31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!launched) {
31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      LOG(ERROR) << "launch error";
31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (return_code)
31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        *return_code = chrome::RESULT_CODE_INVALID_CMDLINE_URL;
32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return false;
32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  } else {
32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    in_synchronous_profile_launch_ = false;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_launch_observer.Get().AddLaunched(profile);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  g_browser_process->platform_part()->profile_helper()->ProfileStartup(
33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      profile,
33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      process_startup);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StartupBrowserCreator::WasRestarted() {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stores the value of the preference kWasRestarted had when it was read.
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool was_restarted = false;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!was_restarted_read_) {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefService* pref_service = g_browser_process->local_state();
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    was_restarted = pref_service->GetBoolean(prefs::kWasRestarted);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pref_service->SetBoolean(prefs::kWasRestarted, false);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    was_restarted_read_ = true;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return was_restarted;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionStartupPref StartupBrowserCreator::GetSessionStartupPref(
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CommandLine& command_line,
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(profile);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefService* prefs = profile->GetPrefs();
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SessionStartupPref pref = SessionStartupPref::GetStartupPref(prefs);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // IsChromeFirstRun() looks for a sentinel file to determine whether the user
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is starting Chrome for the first time. On Chrome OS, the sentinel is stored
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // in a location shared by all users and the check is meaningless. Query the
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // UserManager instead to determine whether the user is new.
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool is_first_run = chromeos::UserManager::Get()->IsCurrentUserNew();
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool is_first_run = first_run::IsChromeFirstRun();
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The pref has an OS-dependent default value. For the first run only, this
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // default is overridden with SessionStartupPref::DEFAULT so that first run
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // behavior (sync promo, welcome page) is consistently invoked.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This applies only if the pref is still at its default and has not been
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // set by the user, managed prefs or policy.
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_first_run && SessionStartupPref::TypeIsDefault(prefs))
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pref.type = SessionStartupPref::DEFAULT;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The switches::kRestoreLastSession command line switch is used to restore
37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // sessions after a browser self restart (e.g. after a Chrome upgrade).
37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // However, new profiles can be created from a browser process that has this
37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // switch so do not set the session pref to SessionStartupPref::LAST for
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // those as there is nothing to restore.
38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if ((command_line.HasSwitch(switches::kRestoreLastSession) ||
38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       StartupBrowserCreator::WasRestarted()) &&
38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      !profile->IsNewProfile()) {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pref.type = SessionStartupPref::LAST;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pref.type == SessionStartupPref::LAST &&
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IncognitoModePrefs::ShouldLaunchIncognito(command_line, prefs)) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We don't store session information when incognito. If the user has
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // chosen to restore last session and launched incognito, fallback to
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // default launch behavior.
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pref.type = SessionStartupPref::DEFAULT;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pref;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StartupBrowserCreator::ClearLaunchedProfilesForTesting() {
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  profile_launch_observer.Get().Clear();
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<GURL> StartupBrowserCreator::GetURLsFromCommandLine(
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CommandLine& command_line,
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& cur_dir,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile) {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<GURL> urls;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const CommandLine::StringVector& params = command_line.GetArgs();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < params.size(); ++i) {
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath param = base::FilePath(params[i]);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Handle Vista way of searching - "? <search-term>"
413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if ((param.value().size() > 2) && (param.value()[0] == '?') &&
414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        (param.value()[1] == ' ')) {
415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GURL url(GetDefaultSearchURLForSearchTerms(
416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          profile, param.LossyDisplayName().substr(2)));
417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (url.is_valid()) {
418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        urls.push_back(url);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Otherwise, fall through to treating it as a URL.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This will create a file URL or a regular URL.
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This call can (in rare circumstances) block the UI thread.
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Allow it until this bug is fixed.
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //  http://code.google.com/p/chromium/issues/detail?id=60641
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL url;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::ThreadRestrictions::ScopedAllowIO allow_io;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url = URLFixerUpper::FixupRelativeFile(cur_dir, param);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Exclude dangerous schemes.
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (url.is_valid()) {
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ChildProcessSecurityPolicy* policy =
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ChildProcessSecurityPolicy::GetInstance();
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (policy->IsWebSafeScheme(url.scheme()) ||
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          url.SchemeIs(chrome::kFileScheme) ||
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // In ChromeOS, allow a settings page to be specified on the
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // command line. See ExistingUserController::OnLoginSuccess.
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (url.spec().find(chrome::kChromeUISettingsURL) == 0) ||
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          (url.spec().compare(content::kAboutBlankURL) == 0)) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        urls.push_back(url);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (urls.empty()) {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we are in Windows 8 metro mode and were launched as a result of the
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // search charm or via a url navigation in metro, then fetch the
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // corresponding url.
455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    GURL url(chrome::GetURLToOpen(profile));
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (url.is_valid())
457eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      urls.push_back(url);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return urls;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StartupBrowserCreator::ProcessCmdLineImpl(
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CommandLine& command_line,
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& cur_dir,
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool process_startup,
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* last_used_profile,
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Profiles& last_opened_profiles,
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int* return_code,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartupBrowserCreator* browser_creator) {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(last_used_profile);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (process_startup) {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (command_line.HasSwitch(switches::kDisablePromptOnRepost))
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NavigationController::DisablePromptOnRepost();
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool silent_launch = false;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(ENABLE_AUTOMATION)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Look for the testing channel ID ONLY during process startup
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (process_startup &&
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command_line.HasSwitch(switches::kTestingChannelID)) {
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string testing_channel_id = command_line.GetSwitchValueASCII(
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switches::kTestingChannelID);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(sanjeevr) Check if we need to make this a singleton for
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // compatibility with the old testing code
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If there are any extra parameters, we expect each one to generate a
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // new tab; if there are none then we get one homepage tab.
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int expected_tab_count = 1;
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (command_line.HasSwitch(switches::kNoStartupWindow) &&
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !command_line.HasSwitch(switches::kAutoLaunchAtStartup)) {
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_tab_count = 0;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // kLoginManager will cause Chrome to start up with the ChromeOS login
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // screen instead of a browser window, so it won't load any tabs.
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else if (command_line.HasSwitch(chromeos::switches::kLoginManager)) {
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_tab_count = 0;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (command_line.HasSwitch(switches::kRestoreLastSession)) {
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string restore_session_value(
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          command_line.GetSwitchValueASCII(switches::kRestoreLastSession));
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::StringToInt(restore_session_value, &expected_tab_count);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<GURL> urls_to_open = GetURLsFromCommandLine(
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          command_line, cur_dir, last_used_profile);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_tab_count =
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          std::max(1, static_cast<int>(urls_to_open.size()));
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!CreateAutomationProvider<TestingAutomationProvider>(
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        testing_channel_id,
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        last_used_profile,
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<size_t>(expected_tab_count)))
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (command_line.HasSwitch(switches::kSilentLaunch)) {
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<GURL> urls_to_open = GetURLsFromCommandLine(
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        command_line, cur_dir, last_used_profile);
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t expected_tabs =
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::max(static_cast<int>(urls_to_open.size()), 0);
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (expected_tabs == 0)
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      silent_launch = true;
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command_line.HasSwitch(switches::kAutomationClientChannelID)) {
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string automation_channel_id = command_line.GetSwitchValueASCII(
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switches::kAutomationClientChannelID);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If there are any extra parameters, we expect each one to generate a
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // new tab; if there are none then we have no tabs
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<GURL> urls_to_open = GetURLsFromCommandLine(
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        command_line, cur_dir, last_used_profile);
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t expected_tabs =
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::max(static_cast<int>(urls_to_open.size()), 0);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expected_tabs == 0)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      silent_launch = true;
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (command_line.HasSwitch(switches::kChromeFrame)) {
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!CreateAutomationProvider<ChromeFrameAutomationProvider>(
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation_channel_id, last_used_profile, expected_tabs))
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!CreateAutomationProvider<AutomationProvider>(
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation_channel_id, last_used_profile, expected_tabs))
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(ENABLE_AUTOMATION)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#if defined(ENABLE_FULL_PRINTING)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we are just displaying a print dialog we shouldn't open browser
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // windows.
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command_line.HasSwitch(switches::kCloudPrintFile) &&
556d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      print_dialog_cloud::CreatePrintDialogFromCommandLine(last_used_profile,
557d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                                                           command_line)) {
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    silent_launch = true;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we are checking the proxy enabled policy, don't open any windows.
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command_line.HasSwitch(switches::kCheckCloudPrintConnectorPolicy)) {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    silent_launch = true;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CloudPrintProxyServiceFactory::GetForProfile(last_used_profile)->
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EnforceCloudPrintConnectorPolicyAndQuit())
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Success, nothing more needs to be done, so return false to stop
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // launching and quit.
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
570c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#endif  // defined(ENABLE_FULL_PRINTING)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command_line.HasSwitch(switches::kExplicitlyAllowedPorts)) {
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string allowed_ports =
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        command_line.GetSwitchValueASCII(switches::kExplicitlyAllowedPorts);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::SetExplicitlyAllowedPorts(allowed_ports);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (command_line.HasSwitch(switches::kInstallFromWebstore)) {
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    extensions::StartupHelper helper;
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    helper.InstallFromWebstore(command_line, last_used_profile);
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Nothing more needs to be done, so return false to stop launching and
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // quit.
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (command_line.HasSwitch(switches::kValidateCrx)) {
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!process_startup) {
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      LOG(ERROR) << "chrome is already running; you must close all running "
589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 << "instances before running with the --"
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 << switches::kValidateCrx << " flag";
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    extensions::StartupHelper helper;
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string message;
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string error;
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (helper.ValidateCrx(command_line, &error))
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      message = std::string("ValidateCrx Success");
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      message = std::string("ValidateCrx Failure: ") + error;
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    printf("%s\n", message.c_str());
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (command_line.HasSwitch(switches::kLimitedInstallFromWebstore)) {
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    extensions::StartupHelper helper;
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    helper.LimitedInstallFromWebstore(command_line, last_used_profile,
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      base::Bind(&base::DoNothing));
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The browser will be launched after the user logs in.
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (command_line.HasSwitch(chromeos::switches::kLoginManager) ||
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      command_line.HasSwitch(chromeos::switches::kLoginPassword)) {
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    silent_launch = true;
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (chrome::IsRunningInAppMode() &&
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line.HasSwitch(switches::kAppId)) {
6193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    chromeos::LaunchAppOrDie(
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        last_used_profile,
6213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        command_line.GetSwitchValueASCII(switches::kAppId));
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Skip browser launch since app mode launches its app window.
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    silent_launch = true;
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(TOOLKIT_VIEWS) && defined(USE_X11)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchFactory::SetTouchDeviceListFromCommandLine();
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!process_startup &&
633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      command_line.HasSwitch(switches::kDumpBrowserHistograms)) {
634f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Only handle --dump-browser-histograms from a rendezvous. In this case, do
635f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // not open a new browser window even if no output file was given.
636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::FilePath output_file(
637f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        command_line.GetSwitchValuePath(switches::kDumpBrowserHistograms));
638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!output_file.empty()) {
639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      BrowserThread::PostBlockingPoolTask(
640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          FROM_HERE,
641f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          base::Bind(&DumpBrowserHistograms, output_file));
642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    silent_launch = true;
644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we don't want to launch a new browser window or tab (in the case
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of an automation request), we are done here.
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (silent_launch)
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check for --load-and-launch-app.
652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (command_line.HasSwitch(apps::kLoadAndLaunchApp) &&
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !IncognitoModePrefs::ShouldLaunchIncognito(
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          command_line, last_used_profile->GetPrefs())) {
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CommandLine::StringType path = command_line.GetSwitchValueNative(
656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        apps::kLoadAndLaunchApp);
6575e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)
6585e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    if (!apps::AppLoadService::Get(last_used_profile)->LoadAndLaunch(
6595e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)            base::FilePath(path), command_line, cur_dir)) {
660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return false;
661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Return early here since we don't want to open a browser window.
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The exception is when there are no browser windows, since we don't want
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // chrome to shut down.
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(jackhou): Do this properly once keep-alive is handled by the
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // background page of apps. Tracked at http://crbug.com/175381
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (chrome::GetTotalBrowserCountForProfile(last_used_profile) != 0)
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome::startup::IsProcessStartup is_process_startup = process_startup ?
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chrome::startup::IS_PROCESS_STARTUP :
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chrome::startup::IS_NOT_PROCESS_STARTUP;
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome::startup::IsFirstRun is_first_run = first_run::IsChromeFirstRun() ?
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN;
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |last_opened_profiles| will be empty in the following circumstances:
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // - This is the first launch. |last_used_profile| is the initial profile.
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // - The user exited the browser by closing all windows for all
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // profiles. |last_used_profile| is the profile which owned the last open
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // window.
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // - Only incognito windows were open when the browser exited.
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |last_used_profile| is the last used incognito profile. Restoring it will
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // create a browser window for the corresponding original profile.
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (last_opened_profiles.empty()) {
686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // If the last used profile was a guest, show the user manager instead.
687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (profiles::IsNewProfileManagementEnabled() &&
688f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        last_used_profile->IsGuestSession()) {
689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      chrome::ShowUserManager(base::FilePath());
690f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return true;
691f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!browser_creator->LaunchBrowser(command_line, last_used_profile,
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        cur_dir, is_process_startup,
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        is_first_run, return_code)) {
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Launch the last used profile with the full command line, and the other
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // opened profiles without the URLs to launch.
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CommandLine command_line_without_urls(command_line.GetProgram());
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const CommandLine::SwitchMap& switches = command_line.GetSwitches();
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (CommandLine::SwitchMap::const_iterator switch_it = switches.begin();
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         switch_it != switches.end(); ++switch_it) {
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line_without_urls.AppendSwitchNative(switch_it->first,
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   switch_it->second);
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Launch the profiles in the order they became active.
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (Profiles::const_iterator it = last_opened_profiles.begin();
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         it != last_opened_profiles.end(); ++it) {
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Don't launch additional profiles which would only open a new tab
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // page. When restarting after an update, all profiles will reopen last
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // open pages.
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SessionStartupPref startup_pref =
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetSessionStartupPref(command_line, *it);
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (*it != last_used_profile &&
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          startup_pref.type == SessionStartupPref::DEFAULT &&
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          !HasPendingUncleanExit(*it))
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
719f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Don't re-open a browser window for the guest profile.
721f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (profiles::IsNewProfileManagementEnabled() &&
722f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          (*it)->IsGuestSession())
723f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        continue;
724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!browser_creator->LaunchBrowser((*it == last_used_profile) ?
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          command_line : command_line_without_urls, *it, cur_dir,
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          is_process_startup, is_first_run, return_code))
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // We've launched at least one browser.
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_process_startup = chrome::startup::IS_NOT_PROCESS_STARTUP;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This must be done after all profiles have been launched so the observer
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // knows about all profiles to wait for before activating this one.
734f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // If the last used profile was the guest one, we didn't open it so
736f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // we don't need to activate it either.
737f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!profiles::IsNewProfileManagementEnabled() &&
738f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        !last_used_profile->IsGuestSession())
739f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      profile_launch_observer.Get().set_profile_to_activate(last_used_profile);
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class AutomationProviderClass>
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StartupBrowserCreator::CreateAutomationProvider(
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& channel_id,
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t expected_tabs) {
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(ENABLE_AUTOMATION)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AutomationProviderClass> automation =
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new AutomationProviderClass(profile);
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!automation->InitializeChannel(channel_id))
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation->SetExpectedTabCount(expected_tabs);
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutomationProviderList* list = g_browser_process->GetAutomationProviderList();
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(list);
758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  list->AddProvider(automation.get());
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(ENABLE_AUTOMATION)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StartupBrowserCreator::ProcessCommandLineOnProfileCreated(
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const CommandLine& command_line,
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& cur_dir,
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile::CreateStatus status) {
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status == Profile::CREATE_STATUS_INITIALIZED)
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ProcessCmdLineImpl(command_line, cur_dir, false, profile, Profiles(), NULL,
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NULL);
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StartupBrowserCreator::ProcessCommandLineAlreadyRunning(
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const CommandLine& command_line,
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& cur_dir,
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& profile_path) {
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProfileManager* profile_manager = g_browser_process->profile_manager();
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Profile* profile = profile_manager->GetProfileByPath(profile_path);
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The profile isn't loaded yet and so needs to be loaded asynchronously.
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!profile) {
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    profile_manager->CreateProfileAsync(profile_path,
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&StartupBrowserCreator::ProcessCommandLineOnProfileCreated,
787a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   command_line, cur_dir), base::string16(), base::string16(),
7882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                   std::string());
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProcessCmdLineImpl(command_line, cur_dir, false, profile, Profiles(), NULL,
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     NULL);
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool StartupBrowserCreator::ActivatedProfile() {
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return profile_launch_observer.Get().activated_profile();
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasPendingUncleanExit(Profile* profile) {
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return profile->GetLastSessionExitType() == Profile::EXIT_CRASHED &&
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !profile_launch_observer.Get().HasBeenLaunched(profile);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805