1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/browser_process_impl.h" 6 7#include <algorithm> 8#include <map> 9#include <vector> 10 11#include "base/atomic_ref_count.h" 12#include "base/bind.h" 13#include "base/bind_helpers.h" 14#include "base/command_line.h" 15#include "base/debug/alias.h" 16#include "base/debug/leak_annotations.h" 17#include "base/files/file_path.h" 18#include "base/metrics/field_trial.h" 19#include "base/path_service.h" 20#include "base/prefs/json_pref_store.h" 21#include "base/prefs/pref_registry_simple.h" 22#include "base/prefs/pref_service.h" 23#include "base/synchronization/waitable_event.h" 24#include "base/threading/thread.h" 25#include "base/threading/thread_restrictions.h" 26#include "base/time/default_tick_clock.h" 27#include "chrome/browser/background/background_mode_manager.h" 28#include "chrome/browser/chrome_browser_main.h" 29#include "chrome/browser/chrome_content_browser_client.h" 30#include "chrome/browser/chrome_notification_types.h" 31#include "chrome/browser/component_updater/chrome_component_updater_configurator.h" 32#include "chrome/browser/defaults.h" 33#include "chrome/browser/devtools/remote_debugging_server.h" 34#include "chrome/browser/download/download_request_limiter.h" 35#include "chrome/browser/download/download_status_updater.h" 36#include "chrome/browser/first_run/upgrade_util.h" 37#include "chrome/browser/gpu/gl_string_manager.h" 38#include "chrome/browser/gpu/gpu_mode_manager.h" 39#include "chrome/browser/icon_manager.h" 40#include "chrome/browser/idle.h" 41#include "chrome/browser/intranet_redirect_detector.h" 42#include "chrome/browser/io_thread.h" 43#include "chrome/browser/lifetime/application_lifetime.h" 44#include "chrome/browser/metrics/metrics_services_manager.h" 45#include "chrome/browser/metrics/thread_watcher.h" 46#include "chrome/browser/net/chrome_net_log.h" 47#include "chrome/browser/net/crl_set_fetcher.h" 48#include "chrome/browser/notifications/notification_ui_manager.h" 49#include "chrome/browser/omaha_query_params/chrome_omaha_query_params_delegate.h" 50#include "chrome/browser/plugins/chrome_plugin_service_filter.h" 51#include "chrome/browser/plugins/plugin_finder.h" 52#include "chrome/browser/prefs/browser_prefs.h" 53#include "chrome/browser/prefs/chrome_pref_service_factory.h" 54#include "chrome/browser/prerender/prerender_tracker.h" 55#include "chrome/browser/printing/background_printing_manager.h" 56#include "chrome/browser/printing/print_job_manager.h" 57#include "chrome/browser/printing/print_preview_dialog_controller.h" 58#include "chrome/browser/profiles/profile_manager.h" 59#include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h" 60#include "chrome/browser/safe_browsing/safe_browsing_service.h" 61#include "chrome/browser/shell_integration.h" 62#include "chrome/browser/status_icons/status_tray.h" 63#include "chrome/browser/ui/apps/chrome_app_window_client.h" 64#include "chrome/browser/ui/browser_dialogs.h" 65#include "chrome/browser/ui/browser_finder.h" 66#include "chrome/browser/ui/user_manager.h" 67#include "chrome/browser/web_resource/promo_resource_service.h" 68#include "chrome/common/chrome_constants.h" 69#include "chrome/common/chrome_paths.h" 70#include "chrome/common/chrome_switches.h" 71#include "chrome/common/extensions/chrome_extensions_client.h" 72#include "chrome/common/pref_names.h" 73#include "chrome/common/switch_utils.h" 74#include "chrome/common/url_constants.h" 75#include "chrome/installer/util/google_update_constants.h" 76#include "chrome/installer/util/google_update_settings.h" 77#include "components/component_updater/component_updater_service.h" 78#include "components/gcm_driver/gcm_driver.h" 79#include "components/metrics/metrics_service.h" 80#include "components/network_time/network_time_tracker.h" 81#include "components/omaha_query_params/omaha_query_params.h" 82#include "components/policy/core/common/policy_service.h" 83#include "components/signin/core/common/profile_management_switches.h" 84#include "components/translate/core/browser/translate_download_manager.h" 85#include "content/public/browser/browser_thread.h" 86#include "content/public/browser/child_process_security_policy.h" 87#include "content/public/browser/notification_details.h" 88#include "content/public/browser/plugin_service.h" 89#include "content/public/browser/render_process_host.h" 90#include "content/public/browser/resource_dispatcher_host.h" 91#include "content/public/browser/service_worker_context.h" 92#include "content/public/browser/storage_partition.h" 93#include "extensions/common/constants.h" 94#include "extensions/common/extension_l10n_util.h" 95#include "net/socket/client_socket_pool_manager.h" 96#include "net/url_request/url_request_context_getter.h" 97#include "ui/base/l10n/l10n_util.h" 98#include "ui/message_center/message_center.h" 99 100#if defined(OS_WIN) 101#include "base/win/windows_version.h" 102#include "ui/views/focus/view_storage.h" 103#elif defined(OS_MACOSX) 104#include "chrome/browser/chrome_browser_main_mac.h" 105#endif 106 107#if defined(OS_ANDROID) 108#include "components/gcm_driver/gcm_driver_android.h" 109#else 110#include "chrome/browser/chrome_device_client.h" 111#include "chrome/browser/services/gcm/gcm_desktop_utils.h" 112#include "components/gcm_driver/gcm_client_factory.h" 113#endif 114 115#if defined(USE_AURA) 116#include "ui/aura/env.h" 117#endif 118 119#if defined(ENABLE_CONFIGURATION_POLICY) 120#include "components/policy/core/browser/browser_policy_connector.h" 121#else 122#include "components/policy/core/common/policy_service_stub.h" 123#endif // defined(ENABLE_CONFIGURATION_POLICY) 124 125#if defined(ENABLE_EXTENSIONS) 126#include "chrome/browser/extensions/chrome_extensions_browser_client.h" 127#include "chrome/browser/extensions/event_router_forwarder.h" 128#include "chrome/browser/extensions/extension_renderer_state.h" 129#include "chrome/browser/media_galleries/media_file_system_registry.h" 130#include "components/storage_monitor/storage_monitor.h" 131#endif 132 133#if !defined(DISABLE_NACL) 134#include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h" 135#endif 136 137#if defined(ENABLE_PLUGIN_INSTALLATION) 138#include "chrome/browser/plugins/plugins_resource_service.h" 139#endif 140 141#if defined(ENABLE_WEBRTC) 142#include "chrome/browser/media/webrtc_log_uploader.h" 143#endif 144 145#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) 146// How often to check if the persistent instance of Chrome needs to restart 147// to install an update. 148static const int kUpdateCheckIntervalHours = 6; 149#endif 150 151#if defined(USE_X11) || defined(OS_WIN) 152// How long to wait for the File thread to complete during EndSession, on Linux 153// and Windows. We have a timeout here because we're unable to run the UI 154// messageloop and there's some deadlock risk. Our only option is to exit 155// anyway. 156static const int kEndSessionTimeoutSeconds = 10; 157#endif 158 159using content::BrowserThread; 160using content::ChildProcessSecurityPolicy; 161using content::PluginService; 162using content::ResourceDispatcherHost; 163 164BrowserProcessImpl::BrowserProcessImpl( 165 base::SequencedTaskRunner* local_state_task_runner, 166 const CommandLine& command_line) 167 : created_watchdog_thread_(false), 168 created_browser_policy_connector_(false), 169 created_profile_manager_(false), 170 created_local_state_(false), 171 created_icon_manager_(false), 172 created_notification_ui_manager_(false), 173 created_safe_browsing_service_(false), 174 module_ref_count_(0), 175 did_start_(false), 176 download_status_updater_(new DownloadStatusUpdater), 177 local_state_task_runner_(local_state_task_runner) { 178 g_browser_process = this; 179 platform_part_.reset(new BrowserProcessPlatformPart()); 180 181#if defined(ENABLE_PRINTING) 182 // Must be created after the NotificationService. 183 print_job_manager_.reset(new printing::PrintJobManager); 184#endif 185 186 net_log_.reset(new ChromeNetLog); 187 188 ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme( 189 extensions::kExtensionScheme); 190 ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme( 191 extensions::kExtensionResourceScheme); 192 ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme( 193 chrome::kChromeSearchScheme); 194 195#if defined(OS_MACOSX) 196 InitIdleMonitor(); 197#endif 198 199#if !defined(OS_ANDROID) 200 device_client_.reset(new ChromeDeviceClient); 201#endif 202 203#if defined(ENABLE_EXTENSIONS) 204#if !defined(USE_ATHENA) 205 // Athena sets its own instance during Athena's init process. 206 extensions::AppWindowClient::Set(ChromeAppWindowClient::GetInstance()); 207#endif 208 209 extension_event_router_forwarder_ = new extensions::EventRouterForwarder; 210 ExtensionRendererState::GetInstance()->Init(); 211 212 extensions::ExtensionsClient::Set( 213 extensions::ChromeExtensionsClient::GetInstance()); 214 215 extensions_browser_client_.reset( 216 new extensions::ChromeExtensionsBrowserClient); 217 extensions::ExtensionsBrowserClient::Set(extensions_browser_client_.get()); 218#endif 219 220 message_center::MessageCenter::Initialize(); 221 222 omaha_query_params::OmahaQueryParams::SetDelegate( 223 ChromeOmahaQueryParamsDelegate::GetInstance()); 224} 225 226BrowserProcessImpl::~BrowserProcessImpl() { 227 tracked_objects::ThreadData::EnsureCleanupWasCalled(4); 228 229 g_browser_process = NULL; 230} 231 232void BrowserProcessImpl::StartTearDown() { 233 TRACE_EVENT0("shutdown", "BrowserProcessImpl::StartTearDown"); 234 // We need to destroy the MetricsServicesManager, IntranetRedirectDetector, 235 // PromoResourceService, and SafeBrowsing ClientSideDetectionService (owned by 236 // the SafeBrowsingService) before the io_thread_ gets destroyed, since their 237 // destructors can call the URLFetcher destructor, which does a 238 // PostDelayedTask operation on the IO thread. (The IO thread will handle that 239 // URLFetcher operation before going away.) 240 metrics_services_manager_.reset(); 241 intranet_redirect_detector_.reset(); 242#if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING) 243 if (safe_browsing_service_.get()) 244 safe_browsing_service()->ShutDown(); 245#endif 246 247 // Need to clear the desktop notification balloons before the io_thread_ and 248 // before the profiles, since if there are any still showing we will access 249 // those things during teardown. 250 notification_ui_manager_.reset(); 251 252 // Need to clear profiles (download managers) before the io_thread_. 253 { 254 TRACE_EVENT0("shutdown", 255 "BrowserProcessImpl::StartTearDown:ProfileManager"); 256 // The desktop User Manager needs to be closed before the guest profile 257 // can be destroyed. 258 if (switches::IsNewAvatarMenu()) 259 UserManager::Hide(); 260 profile_manager_.reset(); 261 } 262 263#if !defined(OS_ANDROID) 264 // Debugger must be cleaned up before IO thread and NotificationService. 265 remote_debugging_server_.reset(); 266#endif 267 268#if defined(ENABLE_EXTENSIONS) 269 ExtensionRendererState::GetInstance()->Shutdown(); 270 271 media_file_system_registry_.reset(); 272 // Remove the global instance of the Storage Monitor now. Otherwise the 273 // FILE thread would be gone when we try to release it in the dtor and 274 // Valgrind would report a leak on almost every single browser_test. 275 // TODO(gbillock): Make this unnecessary. 276 storage_monitor::StorageMonitor::Destroy(); 277#endif 278 279 message_center::MessageCenter::Shutdown(); 280 281#if defined(ENABLE_CONFIGURATION_POLICY) 282 // The policy providers managed by |browser_policy_connector_| need to shut 283 // down while the IO and FILE threads are still alive. 284 if (browser_policy_connector_) 285 browser_policy_connector_->Shutdown(); 286#endif 287 288 // The |gcm_driver_| must shut down while the IO thread is still alive. 289 if (gcm_driver_) 290 gcm_driver_->Shutdown(); 291 292 // Stop the watchdog thread before stopping other threads. 293 watchdog_thread_.reset(); 294 295#if defined(USE_AURA) 296 // Delete aura after the metrics service has been deleted as it accesses 297 // monitor information. 298 aura::Env::DeleteInstance(); 299#endif 300 301 platform_part()->StartTearDown(); 302 303#if defined(ENABLE_WEBRTC) 304 // Cancel any uploads to release the system url request context references. 305 if (webrtc_log_uploader_) 306 webrtc_log_uploader_->StartShutdown(); 307#endif 308 309 if (local_state()) 310 local_state()->CommitPendingWrite(); 311} 312 313void BrowserProcessImpl::PostDestroyThreads() { 314 // With the file_thread_ flushed, we can release any icon resources. 315 icon_manager_.reset(); 316 317#if defined(ENABLE_WEBRTC) 318 // Must outlive the file thread. 319 webrtc_log_uploader_.reset(); 320#endif 321 322 // Reset associated state right after actual thread is stopped, 323 // as io_thread_.global_ cleanup happens in CleanUp on the IO 324 // thread, i.e. as the thread exits its message loop. 325 // 326 // This is important also because in various places, the 327 // IOThread object being NULL is considered synonymous with the 328 // IO thread having stopped. 329 io_thread_.reset(); 330} 331 332unsigned int BrowserProcessImpl::AddRefModule() { 333 DCHECK(CalledOnValidThread()); 334 335 // CHECK(!IsShuttingDown()); 336 if (IsShuttingDown()) { 337 // Copy the stacktrace which released the final reference onto our stack so 338 // it will be available in the crash report for inspection. 339 base::debug::StackTrace callstack = release_last_reference_callstack_; 340 base::debug::Alias(&callstack); 341 CHECK(false); 342 } 343 344 did_start_ = true; 345 module_ref_count_++; 346 return module_ref_count_; 347} 348 349static void ShutdownServiceWorkerContext(content::StoragePartition* partition) { 350 partition->GetServiceWorkerContext()->Terminate(); 351} 352 353unsigned int BrowserProcessImpl::ReleaseModule() { 354 DCHECK(CalledOnValidThread()); 355 DCHECK_NE(0u, module_ref_count_); 356 module_ref_count_--; 357 if (0 == module_ref_count_) { 358 release_last_reference_callstack_ = base::debug::StackTrace(); 359 360 // Stop service workers 361 ProfileManager* pm = profile_manager(); 362 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); 363 for (size_t i = 0; i < profiles.size(); ++i) { 364 content::BrowserContext::ForEachStoragePartition( 365 profiles[i], base::Bind(ShutdownServiceWorkerContext)); 366 } 367 368#if defined(ENABLE_PRINTING) 369 // Wait for the pending print jobs to finish. Don't do this later, since 370 // this might cause a nested message loop to run, and we don't want pending 371 // tasks to run once teardown has started. 372 print_job_manager_->Shutdown(); 373#endif 374 375#if defined(LEAK_SANITIZER) 376 // Check for memory leaks now, before we start shutting down threads. Doing 377 // this early means we won't report any shutdown-only leaks (as they have 378 // not yet happened at this point). 379 // If leaks are found, this will make the process exit immediately. 380 __lsan_do_leak_check(); 381#endif 382 383 CHECK(base::MessageLoop::current()->is_running()); 384 385#if defined(OS_MACOSX) 386 base::MessageLoop::current()->PostTask( 387 FROM_HERE, 388 base::Bind(ChromeBrowserMainPartsMac::DidEndMainMessageLoop)); 389#endif 390 base::MessageLoop::current()->Quit(); 391 } 392 return module_ref_count_; 393} 394 395namespace { 396 397// Used at the end of session to block the UI thread for completion of sentinel 398// tasks on the set of threads used to persist profile data and local state. 399// This is done to ensure that the data has been persisted to disk before 400// continuing. 401class RundownTaskCounter : 402 public base::RefCountedThreadSafe<RundownTaskCounter> { 403 public: 404 RundownTaskCounter(); 405 406 // Posts a rundown task to |task_runner|, can be invoked an arbitrary number 407 // of times before calling TimedWait. 408 void Post(base::SequencedTaskRunner* task_runner); 409 410 // Waits until the count is zero or |max_time| has passed. 411 // This can only be called once per instance. 412 bool TimedWait(const base::TimeDelta& max_time); 413 414 private: 415 friend class base::RefCountedThreadSafe<RundownTaskCounter>; 416 ~RundownTaskCounter() {} 417 418 // Decrements the counter and releases the waitable event on transition to 419 // zero. 420 void Decrement(); 421 422 // The count starts at one to defer the possibility of one->zero transitions 423 // until TimedWait is called. 424 base::AtomicRefCount count_; 425 base::WaitableEvent waitable_event_; 426 427 DISALLOW_COPY_AND_ASSIGN(RundownTaskCounter); 428}; 429 430RundownTaskCounter::RundownTaskCounter() 431 : count_(1), waitable_event_(true, false) { 432} 433 434void RundownTaskCounter::Post(base::SequencedTaskRunner* task_runner) { 435 // As the count starts off at one, it should never get to zero unless 436 // TimedWait has been called. 437 DCHECK(!base::AtomicRefCountIsZero(&count_)); 438 439 base::AtomicRefCountInc(&count_); 440 441 // The task must be non-nestable to guarantee that it runs after all tasks 442 // currently scheduled on |task_runner| have completed. 443 task_runner->PostNonNestableTask(FROM_HERE, 444 base::Bind(&RundownTaskCounter::Decrement, this)); 445} 446 447void RundownTaskCounter::Decrement() { 448 if (!base::AtomicRefCountDec(&count_)) 449 waitable_event_.Signal(); 450} 451 452bool RundownTaskCounter::TimedWait(const base::TimeDelta& max_time) { 453 // Decrement the excess count from the constructor. 454 Decrement(); 455 456 return waitable_event_.TimedWait(max_time); 457} 458 459bool ExperimentUseBrokenSynchronization() { 460 // The logoff behavior used to have a race, whereby it would perform profile 461 // IO writes on the blocking thread pool, but would sycnhronize to the FILE 462 // thread. Windows feels free to terminate any process that's hidden or 463 // destroyed all it's windows, and sometimes Chrome would be terminated 464 // with pending profile IO due to this mis-synchronization. 465 // Under the "WindowsLogoffRace" experiment group, the broken behavior is 466 // emulated, in order to allow measuring what fraction of unclean shutdowns 467 // are due to this bug. 468 const std::string group_name = 469 base::FieldTrialList::FindFullName("WindowsLogoffRace"); 470 return group_name == "BrokenSynchronization"; 471} 472 473} // namespace 474 475void BrowserProcessImpl::EndSession() { 476 bool use_broken_synchronization = ExperimentUseBrokenSynchronization(); 477 478 // Mark all the profiles as clean. 479 ProfileManager* pm = profile_manager(); 480 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); 481 scoped_refptr<RundownTaskCounter> rundown_counter(new RundownTaskCounter()); 482 for (size_t i = 0; i < profiles.size(); ++i) { 483 Profile* profile = profiles[i]; 484 profile->SetExitType(Profile::EXIT_SESSION_ENDED); 485 486 if (!use_broken_synchronization) 487 rundown_counter->Post(profile->GetIOTaskRunner().get()); 488 } 489 490 // Tell the metrics service it was cleanly shutdown. 491 metrics::MetricsService* metrics = g_browser_process->metrics_service(); 492 if (metrics && local_state()) { 493 metrics->RecordStartOfSessionEnd(); 494#if !defined(OS_CHROMEOS) 495 // MetricsService lazily writes to prefs, force it to write now. 496 // On ChromeOS, chrome gets killed when hangs, so no need to 497 // commit metrics::prefs::kStabilitySessionEndCompleted change immediately. 498 local_state()->CommitPendingWrite(); 499 500 if (!use_broken_synchronization) 501 rundown_counter->Post(local_state_task_runner_.get()); 502#endif 503 } 504 505 // http://crbug.com/125207 506 base::ThreadRestrictions::ScopedAllowWait allow_wait; 507 508 // We must write that the profile and metrics service shutdown cleanly, 509 // otherwise on startup we'll think we crashed. So we block until done and 510 // then proceed with normal shutdown. 511 // 512 // If you change the condition here, be sure to also change 513 // ProfileBrowserTests to match. 514#if defined(USE_X11) || defined(OS_WIN) 515 if (use_broken_synchronization) { 516 rundown_counter->Post( 517 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get()); 518 } 519 520 // Do a best-effort wait on the successful countdown of rundown tasks. Note 521 // that if we don't complete "quickly enough", Windows will terminate our 522 // process. 523 // 524 // On Windows, we previously posted a message to FILE and then ran a nested 525 // message loop, waiting for that message to be processed until quitting. 526 // However, doing so means that other messages will also be processed. In 527 // particular, if the GPU process host notices that the GPU has been killed 528 // during shutdown, it races exiting the nested loop with the process host 529 // blocking the message loop attempting to re-establish a connection to the 530 // GPU process synchronously. Because the system may not be allowing 531 // processes to launch, this can result in a hang. See 532 // http://crbug.com/318527. 533 rundown_counter->TimedWait( 534 base::TimeDelta::FromSeconds(kEndSessionTimeoutSeconds)); 535#else 536 NOTIMPLEMENTED(); 537#endif 538} 539 540MetricsServicesManager* BrowserProcessImpl::GetMetricsServicesManager() { 541 DCHECK(CalledOnValidThread()); 542 if (!metrics_services_manager_) 543 metrics_services_manager_.reset(new MetricsServicesManager(local_state())); 544 return metrics_services_manager_.get(); 545} 546 547metrics::MetricsService* BrowserProcessImpl::metrics_service() { 548 DCHECK(CalledOnValidThread()); 549 return GetMetricsServicesManager()->GetMetricsService(); 550} 551 552rappor::RapporService* BrowserProcessImpl::rappor_service() { 553 DCHECK(CalledOnValidThread()); 554 return GetMetricsServicesManager()->GetRapporService(); 555} 556 557IOThread* BrowserProcessImpl::io_thread() { 558 DCHECK(CalledOnValidThread()); 559 DCHECK(io_thread_.get()); 560 return io_thread_.get(); 561} 562 563WatchDogThread* BrowserProcessImpl::watchdog_thread() { 564 DCHECK(CalledOnValidThread()); 565 if (!created_watchdog_thread_) 566 CreateWatchdogThread(); 567 DCHECK(watchdog_thread_.get() != NULL); 568 return watchdog_thread_.get(); 569} 570 571ProfileManager* BrowserProcessImpl::profile_manager() { 572 DCHECK(CalledOnValidThread()); 573 if (!created_profile_manager_) 574 CreateProfileManager(); 575 return profile_manager_.get(); 576} 577 578PrefService* BrowserProcessImpl::local_state() { 579 DCHECK(CalledOnValidThread()); 580 if (!created_local_state_) 581 CreateLocalState(); 582 return local_state_.get(); 583} 584 585net::URLRequestContextGetter* BrowserProcessImpl::system_request_context() { 586 DCHECK(CalledOnValidThread()); 587 return io_thread()->system_url_request_context_getter(); 588} 589 590chrome_variations::VariationsService* BrowserProcessImpl::variations_service() { 591 DCHECK(CalledOnValidThread()); 592 return GetMetricsServicesManager()->GetVariationsService(); 593} 594 595BrowserProcessPlatformPart* BrowserProcessImpl::platform_part() { 596 return platform_part_.get(); 597} 598 599extensions::EventRouterForwarder* 600BrowserProcessImpl::extension_event_router_forwarder() { 601#if defined(ENABLE_EXTENSIONS) 602 return extension_event_router_forwarder_.get(); 603#else 604 return NULL; 605#endif 606} 607 608NotificationUIManager* BrowserProcessImpl::notification_ui_manager() { 609 DCHECK(CalledOnValidThread()); 610 if (!created_notification_ui_manager_) 611 CreateNotificationUIManager(); 612 return notification_ui_manager_.get(); 613} 614 615message_center::MessageCenter* BrowserProcessImpl::message_center() { 616 DCHECK(CalledOnValidThread()); 617 return message_center::MessageCenter::Get(); 618} 619 620policy::BrowserPolicyConnector* BrowserProcessImpl::browser_policy_connector() { 621 DCHECK(CalledOnValidThread()); 622#if defined(ENABLE_CONFIGURATION_POLICY) 623 if (!created_browser_policy_connector_) { 624 DCHECK(!browser_policy_connector_); 625 browser_policy_connector_ = platform_part_->CreateBrowserPolicyConnector(); 626 created_browser_policy_connector_ = true; 627 } 628 return browser_policy_connector_.get(); 629#else 630 return NULL; 631#endif 632} 633 634policy::PolicyService* BrowserProcessImpl::policy_service() { 635#if defined(ENABLE_CONFIGURATION_POLICY) 636 return browser_policy_connector()->GetPolicyService(); 637#else 638 if (!policy_service_.get()) 639 policy_service_.reset(new policy::PolicyServiceStub()); 640 return policy_service_.get(); 641#endif 642} 643 644IconManager* BrowserProcessImpl::icon_manager() { 645 DCHECK(CalledOnValidThread()); 646 if (!created_icon_manager_) 647 CreateIconManager(); 648 return icon_manager_.get(); 649} 650 651GLStringManager* BrowserProcessImpl::gl_string_manager() { 652 DCHECK(CalledOnValidThread()); 653 if (!gl_string_manager_.get()) 654 gl_string_manager_.reset(new GLStringManager()); 655 return gl_string_manager_.get(); 656} 657 658GpuModeManager* BrowserProcessImpl::gpu_mode_manager() { 659 DCHECK(CalledOnValidThread()); 660 if (!gpu_mode_manager_.get()) 661 gpu_mode_manager_.reset(new GpuModeManager()); 662 return gpu_mode_manager_.get(); 663} 664 665void BrowserProcessImpl::CreateDevToolsHttpProtocolHandler( 666 chrome::HostDesktopType host_desktop_type, 667 const std::string& ip, 668 int port) { 669 DCHECK(CalledOnValidThread()); 670#if !defined(OS_ANDROID) 671 // StartupBrowserCreator::LaunchBrowser can be run multiple times when browser 672 // is started with several profiles or existing browser process is reused. 673 if (!remote_debugging_server_.get()) { 674 remote_debugging_server_.reset( 675 new RemoteDebuggingServer(host_desktop_type, ip, port)); 676 } 677#endif 678} 679 680bool BrowserProcessImpl::IsShuttingDown() { 681 DCHECK(CalledOnValidThread()); 682 return did_start_ && 0 == module_ref_count_; 683} 684 685printing::PrintJobManager* BrowserProcessImpl::print_job_manager() { 686 DCHECK(CalledOnValidThread()); 687 return print_job_manager_.get(); 688} 689 690printing::PrintPreviewDialogController* 691 BrowserProcessImpl::print_preview_dialog_controller() { 692#if defined(ENABLE_FULL_PRINTING) 693 DCHECK(CalledOnValidThread()); 694 if (!print_preview_dialog_controller_.get()) 695 CreatePrintPreviewDialogController(); 696 return print_preview_dialog_controller_.get(); 697#else 698 NOTIMPLEMENTED(); 699 return NULL; 700#endif 701} 702 703printing::BackgroundPrintingManager* 704 BrowserProcessImpl::background_printing_manager() { 705#if defined(ENABLE_FULL_PRINTING) 706 DCHECK(CalledOnValidThread()); 707 if (!background_printing_manager_.get()) 708 CreateBackgroundPrintingManager(); 709 return background_printing_manager_.get(); 710#else 711 NOTIMPLEMENTED(); 712 return NULL; 713#endif 714} 715 716IntranetRedirectDetector* BrowserProcessImpl::intranet_redirect_detector() { 717 DCHECK(CalledOnValidThread()); 718 if (!intranet_redirect_detector_.get()) 719 CreateIntranetRedirectDetector(); 720 return intranet_redirect_detector_.get(); 721} 722 723const std::string& BrowserProcessImpl::GetApplicationLocale() { 724 DCHECK(!locale_.empty()); 725 return locale_; 726} 727 728void BrowserProcessImpl::SetApplicationLocale(const std::string& locale) { 729 locale_ = locale; 730 extension_l10n_util::SetProcessLocale(locale); 731 chrome::ChromeContentBrowserClient::SetApplicationLocale(locale); 732 translate::TranslateDownloadManager::GetInstance()->set_application_locale( 733 locale); 734} 735 736DownloadStatusUpdater* BrowserProcessImpl::download_status_updater() { 737 return download_status_updater_.get(); 738} 739 740MediaFileSystemRegistry* BrowserProcessImpl::media_file_system_registry() { 741#if defined(ENABLE_EXTENSIONS) 742 if (!media_file_system_registry_) 743 media_file_system_registry_.reset(new MediaFileSystemRegistry()); 744 return media_file_system_registry_.get(); 745#else 746 return NULL; 747#endif 748} 749 750bool BrowserProcessImpl::created_local_state() const { 751 return created_local_state_; 752} 753 754#if defined(ENABLE_WEBRTC) 755WebRtcLogUploader* BrowserProcessImpl::webrtc_log_uploader() { 756 if (!webrtc_log_uploader_.get()) 757 webrtc_log_uploader_.reset(new WebRtcLogUploader()); 758 return webrtc_log_uploader_.get(); 759} 760#endif 761 762network_time::NetworkTimeTracker* BrowserProcessImpl::network_time_tracker() { 763 if (!network_time_tracker_) { 764 network_time_tracker_.reset(new network_time::NetworkTimeTracker( 765 scoped_ptr<base::TickClock>(new base::DefaultTickClock()), 766 local_state())); 767 } 768 return network_time_tracker_.get(); 769} 770 771gcm::GCMDriver* BrowserProcessImpl::gcm_driver() { 772 DCHECK(CalledOnValidThread()); 773 if (!gcm_driver_) 774 CreateGCMDriver(); 775 return gcm_driver_.get(); 776} 777 778// static 779void BrowserProcessImpl::RegisterPrefs(PrefRegistrySimple* registry) { 780 registry->RegisterBooleanPref(prefs::kDefaultBrowserSettingEnabled, 781 false); 782 // This policy needs to be defined before the net subsystem is initialized, 783 // so we do it here. 784 registry->RegisterIntegerPref(prefs::kMaxConnectionsPerProxy, 785 net::kDefaultMaxSocketsPerProxyServer); 786 787 registry->RegisterBooleanPref(prefs::kAllowCrossOriginAuthPrompt, false); 788 789#if defined(OS_CHROMEOS) || defined(OS_ANDROID) || defined(OS_IOS) 790 registry->RegisterBooleanPref(prefs::kEulaAccepted, false); 791#endif // defined(OS_CHROMEOS) || defined(OS_ANDROID) || defined(OS_IOS) 792#if defined(OS_WIN) 793 if (base::win::GetVersion() >= base::win::VERSION_WIN7) { 794 registry->RegisterStringPref(prefs::kRelaunchMode, 795 upgrade_util::kRelaunchModeDefault); 796 } 797#endif 798 799 // TODO(brettw,*): this comment about ResourceBundle was here since 800 // initial commit. This comment seems unrelated, bit-rotten and 801 // a candidate for removal. 802 // Initialize ResourceBundle which handles files loaded from external 803 // sources. This has to be done before uninstall code path and before prefs 804 // are registered. 805 registry->RegisterStringPref(prefs::kApplicationLocale, std::string()); 806#if defined(OS_CHROMEOS) 807 registry->RegisterStringPref(prefs::kOwnerLocale, std::string()); 808 registry->RegisterStringPref(prefs::kHardwareKeyboardLayout, 809 std::string()); 810#endif // defined(OS_CHROMEOS) 811#if !defined(OS_CHROMEOS) 812 registry->RegisterBooleanPref( 813 prefs::kMetricsReportingEnabled, 814 GoogleUpdateSettings::GetCollectStatsConsent()); 815#endif // !defined(OS_CHROMEOS) 816 817#if defined(OS_ANDROID) 818 registry->RegisterBooleanPref( 819 prefs::kCrashReportingEnabled, false); 820#endif // defined(OS_ANDROID) 821} 822 823DownloadRequestLimiter* BrowserProcessImpl::download_request_limiter() { 824 DCHECK(CalledOnValidThread()); 825 if (!download_request_limiter_.get()) 826 download_request_limiter_ = new DownloadRequestLimiter(); 827 return download_request_limiter_.get(); 828} 829 830BackgroundModeManager* BrowserProcessImpl::background_mode_manager() { 831 DCHECK(CalledOnValidThread()); 832#if defined(ENABLE_BACKGROUND) 833 if (!background_mode_manager_.get()) 834 CreateBackgroundModeManager(); 835 return background_mode_manager_.get(); 836#else 837 NOTIMPLEMENTED(); 838 return NULL; 839#endif 840} 841 842void BrowserProcessImpl::set_background_mode_manager_for_test( 843 scoped_ptr<BackgroundModeManager> manager) { 844 background_mode_manager_ = manager.Pass(); 845} 846 847StatusTray* BrowserProcessImpl::status_tray() { 848 DCHECK(CalledOnValidThread()); 849 if (!status_tray_.get()) 850 CreateStatusTray(); 851 return status_tray_.get(); 852} 853 854 855SafeBrowsingService* BrowserProcessImpl::safe_browsing_service() { 856 DCHECK(CalledOnValidThread()); 857 if (!created_safe_browsing_service_) 858 CreateSafeBrowsingService(); 859 return safe_browsing_service_.get(); 860} 861 862safe_browsing::ClientSideDetectionService* 863 BrowserProcessImpl::safe_browsing_detection_service() { 864 DCHECK(CalledOnValidThread()); 865 if (safe_browsing_service()) 866 return safe_browsing_service()->safe_browsing_detection_service(); 867 return NULL; 868} 869 870#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) 871void BrowserProcessImpl::StartAutoupdateTimer() { 872 autoupdate_timer_.Start(FROM_HERE, 873 base::TimeDelta::FromHours(kUpdateCheckIntervalHours), 874 this, 875 &BrowserProcessImpl::OnAutoupdateTimer); 876} 877#endif 878 879ChromeNetLog* BrowserProcessImpl::net_log() { 880 return net_log_.get(); 881} 882 883prerender::PrerenderTracker* BrowserProcessImpl::prerender_tracker() { 884 if (!prerender_tracker_.get()) 885 prerender_tracker_.reset(new prerender::PrerenderTracker); 886 887 return prerender_tracker_.get(); 888} 889 890component_updater::ComponentUpdateService* 891BrowserProcessImpl::component_updater() { 892 if (!component_updater_.get()) { 893 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) 894 return NULL; 895 component_updater::Configurator* configurator = 896 component_updater::MakeChromeComponentUpdaterConfigurator( 897 CommandLine::ForCurrentProcess(), 898 io_thread()->system_url_request_context_getter()); 899 // Creating the component updater does not do anything, components 900 // need to be registered and Start() needs to be called. 901 component_updater_.reset(ComponentUpdateServiceFactory(configurator)); 902 } 903 return component_updater_.get(); 904} 905 906CRLSetFetcher* BrowserProcessImpl::crl_set_fetcher() { 907 if (!crl_set_fetcher_.get()) 908 crl_set_fetcher_ = new CRLSetFetcher(); 909 return crl_set_fetcher_.get(); 910} 911 912component_updater::PnaclComponentInstaller* 913BrowserProcessImpl::pnacl_component_installer() { 914#if !defined(DISABLE_NACL) 915 if (!pnacl_component_installer_.get()) { 916 pnacl_component_installer_.reset( 917 new component_updater::PnaclComponentInstaller()); 918 } 919 return pnacl_component_installer_.get(); 920#else 921 return NULL; 922#endif 923} 924 925void BrowserProcessImpl::ResourceDispatcherHostCreated() { 926 resource_dispatcher_host_delegate_.reset( 927 new ChromeResourceDispatcherHostDelegate(prerender_tracker())); 928 ResourceDispatcherHost::Get()->SetDelegate( 929 resource_dispatcher_host_delegate_.get()); 930 931 pref_change_registrar_.Add( 932 prefs::kAllowCrossOriginAuthPrompt, 933 base::Bind(&BrowserProcessImpl::ApplyAllowCrossOriginAuthPromptPolicy, 934 base::Unretained(this))); 935 ApplyAllowCrossOriginAuthPromptPolicy(); 936} 937 938void BrowserProcessImpl::CreateWatchdogThread() { 939 DCHECK(!created_watchdog_thread_ && watchdog_thread_.get() == NULL); 940 created_watchdog_thread_ = true; 941 942 scoped_ptr<WatchDogThread> thread(new WatchDogThread()); 943 base::Thread::Options options; 944 options.timer_slack = base::TIMER_SLACK_MAXIMUM; 945 if (!thread->StartWithOptions(options)) 946 return; 947 watchdog_thread_.swap(thread); 948} 949 950void BrowserProcessImpl::CreateProfileManager() { 951 DCHECK(!created_profile_manager_ && profile_manager_.get() == NULL); 952 created_profile_manager_ = true; 953 954 base::FilePath user_data_dir; 955 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 956 profile_manager_.reset(new ProfileManager(user_data_dir)); 957} 958 959void BrowserProcessImpl::CreateLocalState() { 960 DCHECK(!created_local_state_ && local_state_.get() == NULL); 961 created_local_state_ = true; 962 963 base::FilePath local_state_path; 964 CHECK(PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path)); 965 scoped_refptr<PrefRegistrySimple> pref_registry = new PrefRegistrySimple; 966 967 // Register local state preferences. 968 chrome::RegisterLocalState(pref_registry.get()); 969 970 local_state_ = 971 chrome_prefs::CreateLocalState(local_state_path, 972 local_state_task_runner_.get(), 973 policy_service(), 974 pref_registry, 975 false).Pass(); 976 977 pref_change_registrar_.Init(local_state_.get()); 978 979 // Initialize the notification for the default browser setting policy. 980 pref_change_registrar_.Add( 981 prefs::kDefaultBrowserSettingEnabled, 982 base::Bind(&BrowserProcessImpl::ApplyDefaultBrowserPolicy, 983 base::Unretained(this))); 984 985 // This preference must be kept in sync with external values; update them 986 // whenever the preference or its controlling policy changes. 987#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) && !defined(OS_IOS) 988 pref_change_registrar_.Add( 989 prefs::kMetricsReportingEnabled, 990 base::Bind(&BrowserProcessImpl::ApplyMetricsReportingPolicy, 991 base::Unretained(this))); 992#endif 993 994 int max_per_proxy = local_state_->GetInteger(prefs::kMaxConnectionsPerProxy); 995 net::ClientSocketPoolManager::set_max_sockets_per_proxy_server( 996 net::HttpNetworkSession::NORMAL_SOCKET_POOL, 997 std::max(std::min(max_per_proxy, 99), 998 net::ClientSocketPoolManager::max_sockets_per_group( 999 net::HttpNetworkSession::NORMAL_SOCKET_POOL))); 1000} 1001 1002void BrowserProcessImpl::PreCreateThreads() { 1003 io_thread_.reset( 1004 new IOThread(local_state(), policy_service(), net_log_.get(), 1005 extension_event_router_forwarder())); 1006} 1007 1008void BrowserProcessImpl::PreMainMessageLoopRun() { 1009#if defined(ENABLE_CONFIGURATION_POLICY) 1010 // browser_policy_connector() is created very early because local_state() 1011 // needs policy to be initialized with the managed preference values. 1012 // However, policy fetches from the network and loading of disk caches 1013 // requires that threads are running; this Init() call lets the connector 1014 // resume its initialization now that the loops are spinning and the 1015 // system request context is available for the fetchers. 1016 browser_policy_connector()->Init(local_state(), system_request_context()); 1017#endif 1018 1019 if (local_state_->IsManagedPreference(prefs::kDefaultBrowserSettingEnabled)) 1020 ApplyDefaultBrowserPolicy(); 1021 1022#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) && !defined(OS_IOS) 1023 ApplyMetricsReportingPolicy(); 1024#endif 1025 1026#if defined(ENABLE_PLUGINS) 1027 PluginService* plugin_service = PluginService::GetInstance(); 1028 plugin_service->SetFilter(ChromePluginServiceFilter::GetInstance()); 1029 plugin_service->StartWatchingPlugins(); 1030 1031#if defined(OS_POSIX) 1032 // Also find plugins in a user-specific plugins dir, 1033 // e.g. ~/.config/chromium/Plugins. 1034 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); 1035 if (!cmd_line.HasSwitch(switches::kDisablePluginsDiscovery)) { 1036 base::FilePath user_data_dir; 1037 if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) 1038 plugin_service->AddExtraPluginDir(user_data_dir.Append("Plugins")); 1039 } 1040#endif 1041 1042 // Triggers initialization of the singleton instance on UI thread. 1043 PluginFinder::GetInstance()->Init(); 1044 1045#if defined(ENABLE_PLUGIN_INSTALLATION) 1046 DCHECK(!plugins_resource_service_.get()); 1047 plugins_resource_service_ = new PluginsResourceService(local_state()); 1048 plugins_resource_service_->Init(); 1049#endif 1050#endif // defined(ENABLE_PLUGINS) 1051 1052 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 1053 if (!command_line.HasSwitch(switches::kDisableWebResources)) { 1054 DCHECK(!promo_resource_service_.get()); 1055 promo_resource_service_ = new PromoResourceService; 1056 promo_resource_service_->StartAfterDelay(); 1057 } 1058 1059#if !defined(OS_ANDROID) && !defined(OS_IOS) 1060 storage_monitor::StorageMonitor::Create(); 1061#endif 1062 1063 platform_part_->PreMainMessageLoopRun(); 1064} 1065 1066void BrowserProcessImpl::CreateIconManager() { 1067 DCHECK(!created_icon_manager_ && icon_manager_.get() == NULL); 1068 created_icon_manager_ = true; 1069 icon_manager_.reset(new IconManager); 1070} 1071 1072void BrowserProcessImpl::CreateIntranetRedirectDetector() { 1073 DCHECK(intranet_redirect_detector_.get() == NULL); 1074 scoped_ptr<IntranetRedirectDetector> intranet_redirect_detector( 1075 new IntranetRedirectDetector); 1076 intranet_redirect_detector_.swap(intranet_redirect_detector); 1077} 1078 1079void BrowserProcessImpl::CreateNotificationUIManager() { 1080#if defined(ENABLE_NOTIFICATIONS) 1081 DCHECK(notification_ui_manager_.get() == NULL); 1082 notification_ui_manager_.reset(NotificationUIManager::Create(local_state())); 1083 created_notification_ui_manager_ = true; 1084#endif 1085} 1086 1087void BrowserProcessImpl::CreateBackgroundModeManager() { 1088 DCHECK(background_mode_manager_.get() == NULL); 1089 background_mode_manager_.reset( 1090 new BackgroundModeManager(CommandLine::ForCurrentProcess(), 1091 &profile_manager()->GetProfileInfoCache())); 1092} 1093 1094void BrowserProcessImpl::CreateStatusTray() { 1095 DCHECK(status_tray_.get() == NULL); 1096 status_tray_.reset(StatusTray::Create()); 1097} 1098 1099void BrowserProcessImpl::CreatePrintPreviewDialogController() { 1100#if defined(ENABLE_FULL_PRINTING) 1101 DCHECK(print_preview_dialog_controller_.get() == NULL); 1102 print_preview_dialog_controller_ = 1103 new printing::PrintPreviewDialogController(); 1104#else 1105 NOTIMPLEMENTED(); 1106#endif 1107} 1108 1109void BrowserProcessImpl::CreateBackgroundPrintingManager() { 1110#if defined(ENABLE_FULL_PRINTING) 1111 DCHECK(background_printing_manager_.get() == NULL); 1112 background_printing_manager_.reset(new printing::BackgroundPrintingManager()); 1113#else 1114 NOTIMPLEMENTED(); 1115#endif 1116} 1117 1118void BrowserProcessImpl::CreateSafeBrowsingService() { 1119 DCHECK(safe_browsing_service_.get() == NULL); 1120 // Set this flag to true so that we don't retry indefinitely to 1121 // create the service class if there was an error. 1122 created_safe_browsing_service_ = true; 1123#if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING) 1124 safe_browsing_service_ = SafeBrowsingService::CreateSafeBrowsingService(); 1125 safe_browsing_service_->Initialize(); 1126#endif 1127} 1128 1129void BrowserProcessImpl::CreateGCMDriver() { 1130 DCHECK(!gcm_driver_); 1131 1132#if defined(OS_ANDROID) 1133 gcm_driver_.reset(new gcm::GCMDriverAndroid); 1134#else 1135 base::FilePath store_path; 1136 CHECK(PathService::Get(chrome::DIR_GLOBAL_GCM_STORE, &store_path)); 1137 gcm_driver_ = gcm::CreateGCMDriverDesktop( 1138 make_scoped_ptr(new gcm::GCMClientFactory), 1139 local_state(), 1140 store_path, 1141 system_request_context()); 1142 // Sign-in is not required for device-level GCM usage. So we just call 1143 // OnSignedIn to assume always signed-in. Note that GCM will not be started 1144 // at this point since no one has asked for it yet. 1145 // TODO(jianli): To be removed when sign-in enforcement is dropped. 1146 gcm_driver_->OnSignedIn(); 1147#endif // defined(OS_ANDROID) 1148} 1149 1150void BrowserProcessImpl::ApplyDefaultBrowserPolicy() { 1151 if (local_state()->GetBoolean(prefs::kDefaultBrowserSettingEnabled)) { 1152 scoped_refptr<ShellIntegration::DefaultWebClientWorker> 1153 set_browser_worker = new ShellIntegration::DefaultBrowserWorker(NULL); 1154 set_browser_worker->StartSetAsDefault(); 1155 } 1156} 1157 1158void BrowserProcessImpl::ApplyAllowCrossOriginAuthPromptPolicy() { 1159 bool value = local_state()->GetBoolean(prefs::kAllowCrossOriginAuthPrompt); 1160 ResourceDispatcherHost::Get()->SetAllowCrossOriginAuthPrompt(value); 1161} 1162 1163void BrowserProcessImpl::ApplyMetricsReportingPolicy() { 1164#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) && !defined(OS_IOS) 1165 CHECK(BrowserThread::PostTask( 1166 BrowserThread::FILE, FROM_HERE, 1167 base::Bind( 1168 base::IgnoreResult(&GoogleUpdateSettings::SetCollectStatsConsent), 1169 local_state()->GetBoolean(prefs::kMetricsReportingEnabled)))); 1170#endif 1171} 1172 1173// Mac is currently not supported. 1174#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) 1175 1176bool BrowserProcessImpl::CanAutorestartForUpdate() const { 1177 // Check if browser is in the background and if it needs to be restarted to 1178 // apply a pending update. 1179 return chrome::GetTotalBrowserCount() == 0 && chrome::WillKeepAlive() && 1180 upgrade_util::IsUpdatePendingRestart(); 1181} 1182 1183// Switches to add when auto-restarting Chrome. 1184const char* const kSwitchesToAddOnAutorestart[] = { 1185 switches::kNoStartupWindow 1186}; 1187 1188void BrowserProcessImpl::RestartBackgroundInstance() { 1189 CommandLine* old_cl = CommandLine::ForCurrentProcess(); 1190 scoped_ptr<CommandLine> new_cl(new CommandLine(old_cl->GetProgram())); 1191 1192 std::map<std::string, CommandLine::StringType> switches = 1193 old_cl->GetSwitches(); 1194 1195 switches::RemoveSwitchesForAutostart(&switches); 1196 1197 // Append the rest of the switches (along with their values, if any) 1198 // to the new command line 1199 for (std::map<std::string, CommandLine::StringType>::const_iterator i = 1200 switches.begin(); i != switches.end(); ++i) { 1201 CommandLine::StringType switch_value = i->second; 1202 if (switch_value.length() > 0) { 1203 new_cl->AppendSwitchNative(i->first, i->second); 1204 } else { 1205 new_cl->AppendSwitch(i->first); 1206 } 1207 } 1208 1209 // Ensure that our desired switches are set on the new process. 1210 for (size_t i = 0; i < arraysize(kSwitchesToAddOnAutorestart); ++i) { 1211 if (!new_cl->HasSwitch(kSwitchesToAddOnAutorestart[i])) 1212 new_cl->AppendSwitch(kSwitchesToAddOnAutorestart[i]); 1213 } 1214 1215 DLOG(WARNING) << "Shutting down current instance of the browser."; 1216 chrome::AttemptExit(); 1217 1218 // Transfer ownership to Upgrade. 1219 upgrade_util::SetNewCommandLine(new_cl.release()); 1220} 1221 1222void BrowserProcessImpl::OnAutoupdateTimer() { 1223 if (CanAutorestartForUpdate()) { 1224 DLOG(WARNING) << "Detected update. Restarting browser."; 1225 RestartBackgroundInstance(); 1226 } 1227} 1228 1229#endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) 1230