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. 148 static 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. 156 static const int kEndSessionTimeoutSeconds = 10; 157 #endif 158 159 using content::BrowserThread; 160 using content::ChildProcessSecurityPolicy; 161 using content::PluginService; 162 using content::ResourceDispatcherHost; 163 164 BrowserProcessImpl::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 226 BrowserProcessImpl::~BrowserProcessImpl() { 227 tracked_objects::ThreadData::EnsureCleanupWasCalled(4); 228 229 g_browser_process = NULL; 230 } 231 232 void 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 313 void 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 332 unsigned 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 349 static void ShutdownServiceWorkerContext(content::StoragePartition* partition) { 350 partition->GetServiceWorkerContext()->Terminate(); 351 } 352 353 unsigned 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 395 namespace { 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. 401 class 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 430 RundownTaskCounter::RundownTaskCounter() 431 : count_(1), waitable_event_(true, false) { 432 } 433 434 void 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 447 void RundownTaskCounter::Decrement() { 448 if (!base::AtomicRefCountDec(&count_)) 449 waitable_event_.Signal(); 450 } 451 452 bool 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 459 bool 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 475 void 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 540 MetricsServicesManager* 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 547 metrics::MetricsService* BrowserProcessImpl::metrics_service() { 548 DCHECK(CalledOnValidThread()); 549 return GetMetricsServicesManager()->GetMetricsService(); 550 } 551 552 rappor::RapporService* BrowserProcessImpl::rappor_service() { 553 DCHECK(CalledOnValidThread()); 554 return GetMetricsServicesManager()->GetRapporService(); 555 } 556 557 IOThread* BrowserProcessImpl::io_thread() { 558 DCHECK(CalledOnValidThread()); 559 DCHECK(io_thread_.get()); 560 return io_thread_.get(); 561 } 562 563 WatchDogThread* 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 571 ProfileManager* BrowserProcessImpl::profile_manager() { 572 DCHECK(CalledOnValidThread()); 573 if (!created_profile_manager_) 574 CreateProfileManager(); 575 return profile_manager_.get(); 576 } 577 578 PrefService* BrowserProcessImpl::local_state() { 579 DCHECK(CalledOnValidThread()); 580 if (!created_local_state_) 581 CreateLocalState(); 582 return local_state_.get(); 583 } 584 585 net::URLRequestContextGetter* BrowserProcessImpl::system_request_context() { 586 DCHECK(CalledOnValidThread()); 587 return io_thread()->system_url_request_context_getter(); 588 } 589 590 chrome_variations::VariationsService* BrowserProcessImpl::variations_service() { 591 DCHECK(CalledOnValidThread()); 592 return GetMetricsServicesManager()->GetVariationsService(); 593 } 594 595 BrowserProcessPlatformPart* BrowserProcessImpl::platform_part() { 596 return platform_part_.get(); 597 } 598 599 extensions::EventRouterForwarder* 600 BrowserProcessImpl::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 608 NotificationUIManager* BrowserProcessImpl::notification_ui_manager() { 609 DCHECK(CalledOnValidThread()); 610 if (!created_notification_ui_manager_) 611 CreateNotificationUIManager(); 612 return notification_ui_manager_.get(); 613 } 614 615 message_center::MessageCenter* BrowserProcessImpl::message_center() { 616 DCHECK(CalledOnValidThread()); 617 return message_center::MessageCenter::Get(); 618 } 619 620 policy::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 634 policy::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 644 IconManager* BrowserProcessImpl::icon_manager() { 645 DCHECK(CalledOnValidThread()); 646 if (!created_icon_manager_) 647 CreateIconManager(); 648 return icon_manager_.get(); 649 } 650 651 GLStringManager* 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 658 GpuModeManager* 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 665 void 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 680 bool BrowserProcessImpl::IsShuttingDown() { 681 DCHECK(CalledOnValidThread()); 682 return did_start_ && 0 == module_ref_count_; 683 } 684 685 printing::PrintJobManager* BrowserProcessImpl::print_job_manager() { 686 DCHECK(CalledOnValidThread()); 687 return print_job_manager_.get(); 688 } 689 690 printing::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 703 printing::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 716 IntranetRedirectDetector* BrowserProcessImpl::intranet_redirect_detector() { 717 DCHECK(CalledOnValidThread()); 718 if (!intranet_redirect_detector_.get()) 719 CreateIntranetRedirectDetector(); 720 return intranet_redirect_detector_.get(); 721 } 722 723 const std::string& BrowserProcessImpl::GetApplicationLocale() { 724 DCHECK(!locale_.empty()); 725 return locale_; 726 } 727 728 void 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 736 DownloadStatusUpdater* BrowserProcessImpl::download_status_updater() { 737 return download_status_updater_.get(); 738 } 739 740 MediaFileSystemRegistry* 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 750 bool BrowserProcessImpl::created_local_state() const { 751 return created_local_state_; 752 } 753 754 #if defined(ENABLE_WEBRTC) 755 WebRtcLogUploader* 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 762 network_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 771 gcm::GCMDriver* BrowserProcessImpl::gcm_driver() { 772 DCHECK(CalledOnValidThread()); 773 if (!gcm_driver_) 774 CreateGCMDriver(); 775 return gcm_driver_.get(); 776 } 777 778 // static 779 void 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 823 DownloadRequestLimiter* 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 830 BackgroundModeManager* 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 842 void BrowserProcessImpl::set_background_mode_manager_for_test( 843 scoped_ptr<BackgroundModeManager> manager) { 844 background_mode_manager_ = manager.Pass(); 845 } 846 847 StatusTray* BrowserProcessImpl::status_tray() { 848 DCHECK(CalledOnValidThread()); 849 if (!status_tray_.get()) 850 CreateStatusTray(); 851 return status_tray_.get(); 852 } 853 854 855 SafeBrowsingService* BrowserProcessImpl::safe_browsing_service() { 856 DCHECK(CalledOnValidThread()); 857 if (!created_safe_browsing_service_) 858 CreateSafeBrowsingService(); 859 return safe_browsing_service_.get(); 860 } 861 862 safe_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) 871 void BrowserProcessImpl::StartAutoupdateTimer() { 872 autoupdate_timer_.Start(FROM_HERE, 873 base::TimeDelta::FromHours(kUpdateCheckIntervalHours), 874 this, 875 &BrowserProcessImpl::OnAutoupdateTimer); 876 } 877 #endif 878 879 ChromeNetLog* BrowserProcessImpl::net_log() { 880 return net_log_.get(); 881 } 882 883 prerender::PrerenderTracker* BrowserProcessImpl::prerender_tracker() { 884 if (!prerender_tracker_.get()) 885 prerender_tracker_.reset(new prerender::PrerenderTracker); 886 887 return prerender_tracker_.get(); 888 } 889 890 component_updater::ComponentUpdateService* 891 BrowserProcessImpl::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 906 CRLSetFetcher* BrowserProcessImpl::crl_set_fetcher() { 907 if (!crl_set_fetcher_.get()) 908 crl_set_fetcher_ = new CRLSetFetcher(); 909 return crl_set_fetcher_.get(); 910 } 911 912 component_updater::PnaclComponentInstaller* 913 BrowserProcessImpl::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 925 void 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 938 void 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 950 void 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 959 void 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 1002 void BrowserProcessImpl::PreCreateThreads() { 1003 io_thread_.reset( 1004 new IOThread(local_state(), policy_service(), net_log_.get(), 1005 extension_event_router_forwarder())); 1006 } 1007 1008 void 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 1066 void BrowserProcessImpl::CreateIconManager() { 1067 DCHECK(!created_icon_manager_ && icon_manager_.get() == NULL); 1068 created_icon_manager_ = true; 1069 icon_manager_.reset(new IconManager); 1070 } 1071 1072 void 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 1079 void 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 1087 void 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 1094 void BrowserProcessImpl::CreateStatusTray() { 1095 DCHECK(status_tray_.get() == NULL); 1096 status_tray_.reset(StatusTray::Create()); 1097 } 1098 1099 void 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 1109 void 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 1118 void 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 1129 void 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 1150 void 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 1158 void BrowserProcessImpl::ApplyAllowCrossOriginAuthPromptPolicy() { 1159 bool value = local_state()->GetBoolean(prefs::kAllowCrossOriginAuthPrompt); 1160 ResourceDispatcherHost::Get()->SetAllowCrossOriginAuthPrompt(value); 1161 } 1162 1163 void 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 1176 bool 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. 1184 const char* const kSwitchesToAddOnAutorestart[] = { 1185 switches::kNoStartupWindow 1186 }; 1187 1188 void 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 1222 void 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