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" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/environment.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/app_mode/app_mode_utils.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/auto_launch_trial.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/automation_provider.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/automation_provider_list.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/testing_automation_provider.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/custom_handlers/protocol_handler_registry.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/startup_helper.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/unpacked_installer.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/first_run/first_run.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/google/google_util.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/desktop_notification_service.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/incognito_mode_prefs.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/session_startup_pref.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/search_engines/util.h" 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/startup/startup_browser_creator_impl.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_result_codes.h" 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_version_info.h" 55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/common/net/url_fixer_upper.h" 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/browser_distribution.h" 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/child_process_security_policy.h" 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/navigation_controller.h" 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/locale_settings.h" 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/app_mode/startup_app_launcher.h" 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h" 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h" 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h" 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/chromeos_switches.h" 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_VIEWS) && defined(OS_LINUX) 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/touch/touch_factory_x11.h" 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/automation/chrome_frame_automation_provider_win.h" 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/startup/startup_browser_creator_win.h" 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 84a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#if defined(ENABLE_FULL_PRINTING) 85a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" 86a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h" 87a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#include "chrome/browser/printing/print_dialog_cloud.h" 88a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#endif 89a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::ChildProcessSecurityPolicy; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Keeps track on which profiles have been launched. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProfileLaunchObserver : public content::NotificationObserver { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileLaunchObserver() 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : profile_to_activate_(NULL), 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) activated_profile_(false) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllSources()); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY, 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NotificationService::AllSources()); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ProfileLaunchObserver() {} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Observe(int type, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) OVERRIDE { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_PROFILE_DESTROYED: { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = content::Source<Profile>(source).ptr(); 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launched_profiles_.erase(profile); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) opened_profiles_.erase(profile); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (profile == profile_to_activate_) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_to_activate_ = NULL; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If this profile was the last launched one without an opened window, 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // then we may be ready to activate |profile_to_activate_|. 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MaybeActivateProfile(); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case chrome::NOTIFICATION_BROWSER_WINDOW_READY: { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = content::Source<Browser>(source).ptr(); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(browser); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) opened_profiles_.insert(browser->profile()); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MaybeActivateProfile(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool HasBeenLaunched(const Profile* profile) const { 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return launched_profiles_.find(profile) != launched_profiles_.end(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AddLaunched(Profile* profile) { 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launched_profiles_.insert(profile); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Since the startup code only executes for browsers launched in 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // desktop mode, i.e., HOST_DESKTOP_TYPE_NATIVE. Ash should never get here. 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (chrome::FindBrowserWithProfile(profile, 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HOST_DESKTOP_TYPE_NATIVE)) { 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A browser may get opened before we get initialized (e.g., in tests), 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // so we never see the NOTIFICATION_BROWSER_WINDOW_READY for it. 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) opened_profiles_.insert(profile); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Clear() { 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launched_profiles_.clear(); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) opened_profiles_.clear(); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool activated_profile() { return activated_profile_; } 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_profile_to_activate(Profile* profile) { 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_to_activate_ = profile; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MaybeActivateProfile(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void MaybeActivateProfile() { 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!profile_to_activate_) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check that browsers have been opened for all the launched profiles. 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that browsers opened for profiles that were not added as launched 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // profiles are simply ignored. 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<const Profile*>::const_iterator i = launched_profiles_.begin(); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (; i != launched_profiles_.end(); ++i) { 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (opened_profiles_.find(*i) == opened_profiles_.end()) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Asynchronous post to give a chance to the last window to completely 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // open and activate before trying to activate |profile_to_activate_|. 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, FROM_HERE, 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ProfileLaunchObserver::ActivateProfile, 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 181a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Avoid posting more than once before ActivateProfile gets called. 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Remove(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY, 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NotificationService::AllSources()); 184a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) registrar_.Remove(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 185a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) content::NotificationService::AllSources()); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ActivateProfile() { 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We need to test again, in case the profile got deleted in the mean time. 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (profile_to_activate_) { 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithProfile( 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_to_activate_, chrome::HOST_DESKTOP_TYPE_NATIVE); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |profile| may never get launched, e.g., if it only had 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // incognito Windows and one of them was used to exit Chrome. 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // So it won't have a browser in that case. 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->window()->Activate(); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No need try to activate this profile again. 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_to_activate_ = NULL; 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Assign true here, even if no browser was actually activated, so that 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the test can stop waiting, and fail gracefully when needed. 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) activated_profile_ = true; 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These are the profiles that get launched by 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // StartupBrowserCreator::LaunchBrowser. 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<const Profile*> launched_profiles_; 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These are the profiles for which at least one browser window has been 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // opened. This is needed to know when it is safe to activate 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |profile_to_activate_|, otherwise, new browser windows being opened will 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // be activated on top of it. 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<const Profile*> opened_profiles_; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationRegistrar registrar_; 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is NULL until the profile to activate has been chosen. This value, 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // should only be set once all profiles have been launched, otherwise, 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // activation may not happen after the launch of newer profiles. 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile_to_activate_; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set once we attempted to activate a profile. We only get one shot at this. 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool activated_profile_; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ProfileLaunchObserver); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<ProfileLaunchObserver> profile_launch_observer = 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LAZY_INSTANCE_INITIALIZER; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StartupBrowserCreator::StartupBrowserCreator() 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : is_default_browser_dialog_suppressed_(false), 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_main_browser_window_(true) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StartupBrowserCreator::~StartupBrowserCreator() {} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StartupBrowserCreator::was_restarted_read_ = false; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool StartupBrowserCreator::in_synchronous_profile_launch_ = false; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StartupBrowserCreator::AddFirstRunTab(const GURL& url) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_run_tabs_.push_back(url); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StartupBrowserCreator::InSynchronousProfileLaunch() { 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return in_synchronous_profile_launch_; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StartupBrowserCreator::LaunchBrowser( 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CommandLine& command_line, 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& cur_dir, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::startup::IsProcessStartup process_startup, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::startup::IsFirstRun is_first_run, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* return_code) { 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) in_synchronous_profile_launch_ = 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_startup == chrome::startup::IS_PROCESS_STARTUP; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(profile); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Continue with the incognito profile from here on if Incognito mode 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is forced. 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IncognitoModePrefs::ShouldLaunchIncognito(command_line, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile->GetPrefs())) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile = profile->GetOffTheRecordProfile(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (command_line.HasSwitch(switches::kIncognito)) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Incognito mode disabled by policy, launching a normal " 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "browser session."; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Note: This check should have been done in ProcessCmdLineImpl() 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // before calling this function. However chromeos/login/login_utils.cc 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // calls this function directly (see comments there) so it has to be checked 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // again. 27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const bool silent_launch = command_line.HasSwitch(switches::kSilentLaunch); 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!silent_launch) { 28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StartupBrowserCreatorImpl lwp(cur_dir, command_line, this, is_first_run); 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<GURL> urls_to_launch = 28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetURLsFromCommandLine(command_line, cur_dir, profile); 28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const bool launched = lwp.Launch(profile, urls_to_launch, 28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) in_synchronous_profile_launch_, 28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::HOST_DESKTOP_TYPE_NATIVE); 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) in_synchronous_profile_launch_ = false; 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!launched) { 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LOG(ERROR) << "launch error"; 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (return_code) 29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *return_code = chrome::RESULT_CODE_INVALID_CMDLINE_URL; 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) in_synchronous_profile_launch_ = false; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_launch_observer.Get().AddLaunched(profile); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::ProfileHelper::ProfileStartup(profile, process_startup); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StartupBrowserCreator::WasRestarted() { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stores the value of the preference kWasRestarted had when it was read. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool was_restarted = false; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!was_restarted_read_) { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefService* pref_service = g_browser_process->local_state(); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_restarted = pref_service->GetBoolean(prefs::kWasRestarted); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_service->SetBoolean(prefs::kWasRestarted, false); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_restarted_read_ = true; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return was_restarted; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionStartupPref StartupBrowserCreator::GetSessionStartupPref( 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CommandLine& command_line, 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(profile); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefService* prefs = profile->GetPrefs(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionStartupPref pref = SessionStartupPref::GetStartupPref(prefs); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // IsChromeFirstRun() looks for a sentinel file to determine whether the user 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is starting Chrome for the first time. On Chrome OS, the sentinel is stored 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in a location shared by all users and the check is meaningless. Query the 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // UserManager instead to determine whether the user is new. 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS) 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool is_first_run = chromeos::UserManager::Get()->IsCurrentUserNew(); 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool is_first_run = first_run::IsChromeFirstRun(); 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The pref has an OS-dependent default value. For the first run only, this 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default is overridden with SessionStartupPref::DEFAULT so that first run 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // behavior (sync promo, welcome page) is consistently invoked. 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This applies only if the pref is still at its default and has not been 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // set by the user, managed prefs or policy. 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_first_run && SessionStartupPref::TypeIsDefault(prefs)) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref.type = SessionStartupPref::DEFAULT; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The switches::kRestoreLastSession command line switch is used to restore 34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // sessions after a browser self restart (e.g. after a Chrome upgrade). 34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // However, new profiles can be created from a browser process that has this 34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // switch so do not set the session pref to SessionStartupPref::LAST for 35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // those as there is nothing to restore. 35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if ((command_line.HasSwitch(switches::kRestoreLastSession) || 35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StartupBrowserCreator::WasRestarted()) && 35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) !profile->IsNewProfile()) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref.type = SessionStartupPref::LAST; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pref.type == SessionStartupPref::LAST && 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IncognitoModePrefs::ShouldLaunchIncognito(command_line, prefs)) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't store session information when incognito. If the user has 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // chosen to restore last session and launched incognito, fallback to 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default launch behavior. 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref.type = SessionStartupPref::DEFAULT; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Kiosk/Retail mode has no profile to restore and fails to open the tabs 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // specified in the startup_urls policy if we try to restore the non-existent 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // session which is the default for ChromeOS in general. 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (chromeos::KioskModeSettings::Get()->IsKioskModeEnabled()) { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pref.type == SessionStartupPref::LAST); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref.type = SessionStartupPref::DEFAULT; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_CHROMEOS 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pref; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StartupBrowserCreator::ClearLaunchedProfilesForTesting() { 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_launch_observer.Get().Clear(); 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<GURL> StartupBrowserCreator::GetURLsFromCommandLine( 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CommandLine& command_line, 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& cur_dir, 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile) { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> urls; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const CommandLine::StringVector& params = command_line.GetArgs(); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < params.size(); ++i) { 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath param = base::FilePath(params[i]); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle Vista way of searching - "? <search-term>" 393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ((param.value().size() > 2) && (param.value()[0] == '?') && 394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (param.value()[1] == ' ')) { 395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url(GetDefaultSearchURLForSearchTerms( 396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch profile, param.LossyDisplayName().substr(2))); 397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (url.is_valid()) { 398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch urls.push_back(url); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, fall through to treating it as a URL. 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will create a file URL or a regular URL. 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This call can (in rare circumstances) block the UI thread. 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allow it until this bug is fixed. 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://code.google.com/p/chromium/issues/detail?id=60641 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url = URLFixerUpper::FixupRelativeFile(cur_dir, param); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Exclude dangerous schemes. 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.is_valid()) { 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChildProcessSecurityPolicy* policy = 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChildProcessSecurityPolicy::GetInstance(); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (policy->IsWebSafeScheme(url.scheme()) || 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url.SchemeIs(chrome::kFileScheme) || 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In ChromeOS, allow a settings page to be specified on the 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // command line. See ExistingUserController::OnLoginSuccess. 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (url.spec().find(chrome::kChromeUISettingsURL) == 0) || 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (url.spec().compare(content::kAboutBlankURL) == 0)) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls.push_back(url); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (urls.empty()) { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we are in Windows 8 metro mode and were launched as a result of the 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // search charm or via a url navigation in metro, then fetch the 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // corresponding url. 435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url(chrome::GetURLToOpen(profile)); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.is_valid()) 437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch urls.push_back(url); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_WIN 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return urls; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StartupBrowserCreator::ProcessCmdLineImpl( 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CommandLine& command_line, 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& cur_dir, 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool process_startup, 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* last_used_profile, 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Profiles& last_opened_profiles, 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* return_code, 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartupBrowserCreator* browser_creator) { 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(last_used_profile); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (process_startup) { 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(switches::kDisablePromptOnRepost)) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NavigationController::DisablePromptOnRepost(); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool silent_launch = false; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(ENABLE_AUTOMATION) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Look for the testing channel ID ONLY during process startup 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (process_startup && 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.HasSwitch(switches::kTestingChannelID)) { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string testing_channel_id = command_line.GetSwitchValueASCII( 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kTestingChannelID); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sanjeevr) Check if we need to make this a singleton for 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // compatibility with the old testing code 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there are any extra parameters, we expect each one to generate a 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // new tab; if there are none then we get one homepage tab. 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int expected_tab_count = 1; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(switches::kNoStartupWindow) && 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !command_line.HasSwitch(switches::kAutoLaunchAtStartup)) { 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_tab_count = 0; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // kLoginManager will cause Chrome to start up with the ChromeOS login 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // screen instead of a browser window, so it won't load any tabs. 477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (command_line.HasSwitch(chromeos::switches::kLoginManager)) { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_tab_count = 0; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (command_line.HasSwitch(switches::kRestoreLastSession)) { 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string restore_session_value( 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.GetSwitchValueASCII(switches::kRestoreLastSession)); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringToInt(restore_session_value, &expected_tab_count); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> urls_to_open = GetURLsFromCommandLine( 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line, cur_dir, last_used_profile); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_tab_count = 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(1, static_cast<int>(urls_to_open.size())); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CreateAutomationProvider<TestingAutomationProvider>( 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing_channel_id, 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_used_profile, 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<size_t>(expected_tab_count))) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command_line.HasSwitch(switches::kSilentLaunch)) { 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<GURL> urls_to_open = GetURLsFromCommandLine( 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) command_line, cur_dir, last_used_profile); 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t expected_tabs = 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::max(static_cast<int>(urls_to_open.size()), 0); 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (expected_tabs == 0) 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) silent_launch = true; 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(switches::kAutomationClientChannelID)) { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string automation_channel_id = command_line.GetSwitchValueASCII( 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kAutomationClientChannelID); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there are any extra parameters, we expect each one to generate a 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // new tab; if there are none then we have no tabs 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> urls_to_open = GetURLsFromCommandLine( 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line, cur_dir, last_used_profile); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t expected_tabs = 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(static_cast<int>(urls_to_open.size()), 0); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (expected_tabs == 0) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silent_launch = true; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(switches::kChromeFrame)) { 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CreateAutomationProvider<ChromeFrameAutomationProvider>( 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) automation_channel_id, last_used_profile, expected_tabs)) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CreateAutomationProvider<AutomationProvider>( 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) automation_channel_id, last_used_profile, expected_tabs)) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(ENABLE_AUTOMATION) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 532a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#if defined(ENABLE_FULL_PRINTING) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we are just displaying a print dialog we shouldn't open browser 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // windows. 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(switches::kCloudPrintFile) && 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_dialog_cloud::CreatePrintDialogFromCommandLine(command_line)) { 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silent_launch = true; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we are checking the proxy enabled policy, don't open any windows. 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(switches::kCheckCloudPrintConnectorPolicy)) { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silent_launch = true; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CloudPrintProxyServiceFactory::GetForProfile(last_used_profile)-> 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnforceCloudPrintConnectorPolicyAndQuit()) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Success, nothing more needs to be done, so return false to stop 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // launching and quit. 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 549a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch#endif // defined(ENABLE_FULL_PRINTING) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(switches::kExplicitlyAllowedPorts)) { 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string allowed_ports = 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.GetSwitchValueASCII(switches::kExplicitlyAllowedPorts); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::SetExplicitlyAllowedPorts(allowed_ports); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command_line.HasSwitch(switches::kInstallFromWebstore)) { 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::StartupHelper helper; 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) helper.InstallFromWebstore(command_line, last_used_profile); 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Nothing more needs to be done, so return false to stop launching and 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // quit. 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (command_line.HasSwitch(switches::kValidateCrx)) { 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!process_startup) { 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "chrome is already running; you must close all running " 568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << "instances before running with the --" 569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << switches::kValidateCrx << " flag"; 570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extensions::StartupHelper helper; 573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string message; 574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string error; 575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (helper.ValidateCrx(command_line, &error)) 576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message = std::string("ValidateCrx Success"); 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message = std::string("ValidateCrx Failure: ") + error; 579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) printf("%s\n", message.c_str()); 580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command_line.HasSwitch(switches::kLimitedInstallFromWebstore)) { 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::StartupHelper helper; 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) helper.LimitedInstallFromWebstore(command_line, last_used_profile, 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&base::DoNothing)); 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The browser will be launched after the user logs in. 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (command_line.HasSwitch(chromeos::switches::kLoginManager) || 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) command_line.HasSwitch(chromeos::switches::kLoginPassword)) { 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) silent_launch = true; 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (chrome::IsRunningInAppMode() && 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) command_line.HasSwitch(switches::kAppId)) { 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // StartupAppLauncher deletes itself when done. 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (new chromeos::StartupAppLauncher( 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_used_profile, 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) command_line.GetSwitchValueASCII(switches::kAppId)))->Start(); 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Skip browser launch since app mode launches its app window. 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) silent_launch = true; 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(TOOLKIT_VIEWS) && defined(USE_X11) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::TouchFactory::SetTouchDeviceListFromCommandLine(); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we don't want to launch a new browser window or tab (in the case 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of an automation request), we are done here. 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (silent_launch) 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check for --load-and-launch-app. 618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (command_line.HasSwitch(apps::kLoadAndLaunchApp) && 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !IncognitoModePrefs::ShouldLaunchIncognito( 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) command_line, last_used_profile->GetPrefs())) { 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CommandLine::StringType path = command_line.GetSwitchValueNative( 622868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) apps::kLoadAndLaunchApp); 6235e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 6245e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) if (!apps::AppLoadService::Get(last_used_profile)->LoadAndLaunch( 6255e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) base::FilePath(path), command_line, cur_dir)) { 626868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 627868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 628868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Return early here since we don't want to open a browser window. 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The exception is when there are no browser windows, since we don't want 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // chrome to shut down. 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(jackhou): Do this properly once keep-alive is handled by the 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // background page of apps. Tracked at http://crbug.com/175381 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (chrome::GetTotalBrowserCountForProfile(last_used_profile) != 0) 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::startup::IsProcessStartup is_process_startup = process_startup ? 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::startup::IS_PROCESS_STARTUP : 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::startup::IS_NOT_PROCESS_STARTUP; 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::startup::IsFirstRun is_first_run = first_run::IsChromeFirstRun() ? 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN; 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |last_opened_profiles| will be empty in the following circumstances: 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - This is the first launch. |last_used_profile| is the initial profile. 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - The user exited the browser by closing all windows for all 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // profiles. |last_used_profile| is the profile which owned the last open 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // window. 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - Only incognito windows were open when the browser exited. 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |last_used_profile| is the last used incognito profile. Restoring it will 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // create a browser window for the corresponding original profile. 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (last_opened_profiles.empty()) { 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!browser_creator->LaunchBrowser(command_line, last_used_profile, 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cur_dir, is_process_startup, 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_first_run, return_code)) { 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Launch the last used profile with the full command line, and the other 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // opened profiles without the URLs to launch. 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CommandLine command_line_without_urls(command_line.GetProgram()); 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CommandLine::SwitchMap& switches = command_line.GetSwitches(); 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (CommandLine::SwitchMap::const_iterator switch_it = switches.begin(); 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch_it != switches.end(); ++switch_it) { 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) command_line_without_urls.AppendSwitchNative(switch_it->first, 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch_it->second); 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Launch the profiles in the order they became active. 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Profiles::const_iterator it = last_opened_profiles.begin(); 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != last_opened_profiles.end(); ++it) { 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't launch additional profiles which would only open a new tab 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // page. When restarting after an update, all profiles will reopen last 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // open pages. 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SessionStartupPref startup_pref = 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetSessionStartupPref(command_line, *it); 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (*it != last_used_profile && 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) startup_pref.type == SessionStartupPref::DEFAULT && 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !HasPendingUncleanExit(*it)) 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!browser_creator->LaunchBrowser((*it == last_used_profile) ? 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) command_line : command_line_without_urls, *it, cur_dir, 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_process_startup, is_first_run, return_code)) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We've launched at least one browser. 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_process_startup = chrome::startup::IS_NOT_PROCESS_STARTUP; 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This must be done after all profiles have been launched so the observer 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // knows about all profiles to wait for before activating this one. 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_launch_observer.Get().set_profile_to_activate(last_used_profile); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class AutomationProviderClass> 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StartupBrowserCreator::CreateAutomationProvider( 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& channel_id, 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t expected_tabs) { 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(ENABLE_AUTOMATION) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AutomationProviderClass> automation = 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new AutomationProviderClass(profile); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!automation->InitializeChannel(channel_id)) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) automation->SetExpectedTabCount(expected_tabs); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutomationProviderList* list = g_browser_process->GetAutomationProviderList(); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(list); 707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) list->AddProvider(automation.get()); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(ENABLE_AUTOMATION) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StartupBrowserCreator::ProcessCommandLineOnProfileCreated( 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CommandLine& command_line, 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& cur_dir, 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::CreateStatus status) { 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status == Profile::CREATE_STATUS_INITIALIZED) 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProcessCmdLineImpl(command_line, cur_dir, false, profile, Profiles(), NULL, 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StartupBrowserCreator::ProcessCommandLineAlreadyRunning( 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CommandLine& command_line, 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& cur_dir, 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& profile_path) { 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileManager* profile_manager = g_browser_process->profile_manager(); 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile = profile_manager->GetProfileByPath(profile_path); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The profile isn't loaded yet and so needs to be loaded asynchronously. 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile) { 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_manager->CreateProfileAsync(profile_path, 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&StartupBrowserCreator::ProcessCommandLineOnProfileCreated, 7362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch command_line, cur_dir), string16(), string16(), 7372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch std::string()); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProcessCmdLineImpl(command_line, cur_dir, false, profile, Profiles(), NULL, 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL); 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool StartupBrowserCreator::ActivatedProfile() { 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return profile_launch_observer.Get().activated_profile(); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasPendingUncleanExit(Profile* profile) { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return profile->GetLastSessionExitType() == Profile::EXIT_CRASHED && 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !profile_launch_observer.Get().HasBeenLaunched(profile); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 754