1 // Copyright (c) 2011 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 <map> 8 9 #include "base/command_line.h" 10 #include "base/file_util.h" 11 #include "base/path_service.h" 12 #include "base/synchronization/waitable_event.h" 13 #include "base/task.h" 14 #include "base/threading/thread.h" 15 #include "base/threading/thread_restrictions.h" 16 #include "chrome/browser/automation/automation_provider_list.h" 17 #include "chrome/browser/browser_main.h" 18 #include "chrome/browser/browser_process_sub_thread.h" 19 #include "chrome/browser/browser_trial.h" 20 #include "chrome/browser/debugger/browser_list_tabcontents_provider.h" 21 #include "chrome/browser/debugger/devtools_http_protocol_handler.h" 22 #include "chrome/browser/debugger/devtools_manager.h" 23 #include "chrome/browser/debugger/devtools_protocol_handler.h" 24 #include "chrome/browser/download/download_file_manager.h" 25 #include "chrome/browser/download/save_file_manager.h" 26 #include "chrome/browser/extensions/extension_event_router_forwarder.h" 27 #include "chrome/browser/extensions/extension_tab_id_map.h" 28 #include "chrome/browser/extensions/user_script_listener.h" 29 #include "chrome/browser/first_run/upgrade_util.h" 30 #include "chrome/browser/google/google_url_tracker.h" 31 #include "chrome/browser/gpu_process_host_ui_shim.h" 32 #include "chrome/browser/icon_manager.h" 33 #include "chrome/browser/intranet_redirect_detector.h" 34 #include "chrome/browser/io_thread.h" 35 #include "chrome/browser/metrics/metrics_service.h" 36 #include "chrome/browser/metrics/thread_watcher.h" 37 #include "chrome/browser/net/chrome_net_log.h" 38 #include "chrome/browser/net/predictor_api.h" 39 #include "chrome/browser/net/sdch_dictionary_fetcher.h" 40 #include "chrome/browser/notifications/notification_ui_manager.h" 41 #include "chrome/browser/platform_util.h" 42 #include "chrome/browser/plugin_data_remover.h" 43 #include "chrome/browser/plugin_updater.h" 44 #include "chrome/browser/policy/browser_policy_connector.h" 45 #include "chrome/browser/prefs/pref_service.h" 46 #include "chrome/browser/printing/print_job_manager.h" 47 #include "chrome/browser/printing/print_preview_tab_controller.h" 48 #include "chrome/browser/profiles/profile_manager.h" 49 #include "chrome/browser/safe_browsing/client_side_detection_service.h" 50 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 51 #include "chrome/browser/shell_integration.h" 52 #include "chrome/browser/sidebar/sidebar_manager.h" 53 #include "chrome/browser/tab_closeable_state_watcher.h" 54 #include "chrome/browser/ui/browser_list.h" 55 #include "chrome/common/chrome_constants.h" 56 #include "chrome/common/chrome_paths.h" 57 #include "chrome/common/chrome_switches.h" 58 #include "chrome/common/extensions/extension_l10n_util.h" 59 #include "chrome/common/extensions/extension_resource.h" 60 #include "chrome/common/json_pref_store.h" 61 #include "chrome/common/pref_names.h" 62 #include "chrome/common/switch_utils.h" 63 #include "chrome/common/url_constants.h" 64 #include "chrome/installer/util/google_update_constants.h" 65 #include "content/browser/browser_child_process_host.h" 66 #include "content/browser/browser_thread.h" 67 #include "content/browser/child_process_security_policy.h" 68 #include "content/browser/plugin_service.h" 69 #include "content/browser/renderer_host/render_process_host.h" 70 #include "content/browser/renderer_host/resource_dispatcher_host.h" 71 #include "content/common/notification_service.h" 72 #include "ipc/ipc_logging.h" 73 #include "net/url_request/url_request_context_getter.h" 74 #include "ui/base/clipboard/clipboard.h" 75 #include "ui/base/l10n/l10n_util.h" 76 #include "webkit/database/database_tracker.h" 77 78 #if defined(OS_WIN) 79 #include "views/focus/view_storage.h" 80 #endif 81 82 #if defined(IPC_MESSAGE_LOG_ENABLED) 83 #include "content/common/child_process_messages.h" 84 #endif 85 86 #if defined(OS_CHROMEOS) 87 #include "chrome/browser/chromeos/proxy_config_service_impl.h" 88 #endif // defined(OS_CHROMEOS) 89 90 #if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) 91 // How often to check if the persistent instance of Chrome needs to restart 92 // to install an update. 93 static const int kUpdateCheckIntervalHours = 6; 94 #endif 95 96 #if defined(USE_X11) 97 // How long to wait for the File thread to complete during EndSession, on 98 // Linux. We have a timeout here because we're unable to run the UI messageloop 99 // and there's some deadlock risk. Our only option is to exit anyway. 100 static const int kEndSessionTimeoutSeconds = 10; 101 #endif 102 103 BrowserProcessImpl::BrowserProcessImpl(const CommandLine& command_line) 104 : created_resource_dispatcher_host_(false), 105 created_metrics_service_(false), 106 created_io_thread_(false), 107 created_file_thread_(false), 108 created_db_thread_(false), 109 created_process_launcher_thread_(false), 110 created_cache_thread_(false), 111 created_gpu_thread_(false), 112 created_watchdog_thread_(false), 113 created_profile_manager_(false), 114 created_local_state_(false), 115 created_icon_manager_(false), 116 created_devtools_manager_(false), 117 created_sidebar_manager_(false), 118 created_browser_policy_connector_(false), 119 created_notification_ui_manager_(false), 120 created_safe_browsing_detection_service_(false), 121 module_ref_count_(0), 122 did_start_(false), 123 checked_for_new_frames_(false), 124 using_new_frames_(false) { 125 g_browser_process = this; 126 clipboard_.reset(new ui::Clipboard); 127 main_notification_service_.reset(new NotificationService); 128 129 notification_registrar_.Add(this, 130 NotificationType::APP_TERMINATING, 131 NotificationService::AllSources()); 132 133 // Must be created after the NotificationService. 134 print_job_manager_.reset(new printing::PrintJobManager); 135 136 shutdown_event_.reset(new base::WaitableEvent(true, false)); 137 138 net_log_.reset(new ChromeNetLog); 139 140 extension_event_router_forwarder_ = new ExtensionEventRouterForwarder; 141 142 ExtensionTabIdMap::GetInstance()->Init(); 143 } 144 145 BrowserProcessImpl::~BrowserProcessImpl() { 146 FilePath profile_path; 147 bool clear_local_state_on_exit; 148 149 // Store the profile path for clearing local state data on exit. 150 clear_local_state_on_exit = ShouldClearLocalState(&profile_path); 151 152 // Delete the AutomationProviderList before NotificationService, 153 // since it may try to unregister notifications 154 // Both NotificationService and AutomationProvider are singleton instances in 155 // the BrowserProcess. Since AutomationProvider may have some active 156 // notification observers, it is essential that it gets destroyed before the 157 // NotificationService. NotificationService won't be destroyed until after 158 // this destructor is run. 159 automation_provider_list_.reset(); 160 161 // We need to shutdown the SdchDictionaryFetcher as it regularly holds 162 // a pointer to a URLFetcher, and that URLFetcher (upon destruction) will do 163 // a PostDelayedTask onto the IO thread. This shutdown call will both discard 164 // any pending URLFetchers, and avoid creating any more. 165 SdchDictionaryFetcher::Shutdown(); 166 167 // We need to destroy the MetricsService, GoogleURLTracker, 168 // IntranetRedirectDetector, and SafeBrowsing ClientSideDetectionService 169 // before the io_thread_ gets destroyed, since their destructors can call the 170 // URLFetcher destructor, which does a PostDelayedTask operation on the IO 171 // thread. (The IO thread will handle that URLFetcher operation before going 172 // away.) 173 metrics_service_.reset(); 174 google_url_tracker_.reset(); 175 intranet_redirect_detector_.reset(); 176 safe_browsing_detection_service_.reset(); 177 178 // Need to clear the desktop notification balloons before the io_thread_ and 179 // before the profiles, since if there are any still showing we will access 180 // those things during teardown. 181 notification_ui_manager_.reset(); 182 183 // Need to clear profiles (download managers) before the io_thread_. 184 profile_manager_.reset(); 185 186 // Debugger must be cleaned up before IO thread and NotificationService. 187 if (devtools_http_handler_.get()) { 188 devtools_http_handler_->Stop(); 189 devtools_http_handler_ = NULL; 190 } 191 if (devtools_legacy_handler_.get()) { 192 devtools_legacy_handler_->Stop(); 193 devtools_legacy_handler_ = NULL; 194 } 195 196 if (resource_dispatcher_host_.get()) { 197 // Need to tell Safe Browsing Service that the IO thread is going away 198 // since it cached a pointer to it. 199 if (resource_dispatcher_host()->safe_browsing_service()) 200 resource_dispatcher_host()->safe_browsing_service()->ShutDown(); 201 202 // Cancel pending requests and prevent new requests. 203 resource_dispatcher_host()->Shutdown(); 204 } 205 206 ExtensionTabIdMap::GetInstance()->Shutdown(); 207 208 // The policy providers managed by |browser_policy_connector_| need to shut 209 // down while the IO and FILE threads are still alive. 210 browser_policy_connector_.reset(); 211 212 #if defined(USE_X11) 213 // The IO thread must outlive the BACKGROUND_X11 thread. 214 background_x11_thread_.reset(); 215 #endif 216 217 // Wait for removing plugin data to finish before shutting down the IO thread. 218 WaitForPluginDataRemoverToFinish(); 219 220 // Destroying the GpuProcessHostUIShims on the UI thread posts a task to 221 // delete related objects on the GPU thread. This must be done before 222 // stopping the GPU thread. The GPU thread will close IPC channels to renderer 223 // processes so this has to happen before stopping the IO thread. 224 GpuProcessHostUIShim::DestroyAll(); 225 gpu_thread_.reset(); 226 227 // Need to stop io_thread_ before resource_dispatcher_host_, since 228 // io_thread_ may still deref ResourceDispatcherHost and handle resource 229 // request before going away. 230 io_thread_.reset(); 231 232 // The IO thread was the only user of this thread. 233 cache_thread_.reset(); 234 235 // Stop the process launcher thread after the IO thread, in case the IO thread 236 // posted a task to terminate a process on the process launcher thread. 237 process_launcher_thread_.reset(); 238 239 // Clean up state that lives on the file_thread_ before it goes away. 240 if (resource_dispatcher_host_.get()) { 241 resource_dispatcher_host()->download_file_manager()->Shutdown(); 242 resource_dispatcher_host()->save_file_manager()->Shutdown(); 243 } 244 245 // Need to stop the file_thread_ here to force it to process messages in its 246 // message loop from the previous call to shutdown the DownloadFileManager, 247 // SaveFileManager and SessionService. 248 file_thread_.reset(); 249 250 // With the file_thread_ flushed, we can release any icon resources. 251 icon_manager_.reset(); 252 253 // Need to destroy ResourceDispatcherHost before PluginService and 254 // SafeBrowsingService, since it caches a pointer to it. This also 255 // causes the webkit thread to terminate. 256 resource_dispatcher_host_.reset(); 257 258 // Wait for the pending print jobs to finish. 259 print_job_manager_->OnQuit(); 260 print_job_manager_.reset(); 261 262 // Destroy TabCloseableStateWatcher before NotificationService since the 263 // former registers for notifications. 264 tab_closeable_state_watcher_.reset(); 265 266 // Now OK to destroy NotificationService. 267 main_notification_service_.reset(); 268 269 // Prior to clearing local state, we want to complete tasks pending 270 // on the db thread too. 271 db_thread_.reset(); 272 273 // Stop the watchdog thread after stopping other threads. 274 watchdog_thread_.reset(); 275 276 // At this point, no render process exist and the file, io, db, and 277 // webkit threads in this process have all terminated, so it's safe 278 // to access local state data such as cookies, database, or local storage. 279 if (clear_local_state_on_exit) 280 ClearLocalState(profile_path); 281 282 g_browser_process = NULL; 283 } 284 285 #if defined(OS_WIN) 286 // Send a QuitTask to the given MessageLoop. 287 static void PostQuit(MessageLoop* message_loop) { 288 message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask()); 289 } 290 #elif defined(USE_X11) 291 static void Signal(base::WaitableEvent* event) { 292 event->Signal(); 293 } 294 #endif 295 296 unsigned int BrowserProcessImpl::AddRefModule() { 297 DCHECK(CalledOnValidThread()); 298 did_start_ = true; 299 module_ref_count_++; 300 return module_ref_count_; 301 } 302 303 unsigned int BrowserProcessImpl::ReleaseModule() { 304 DCHECK(CalledOnValidThread()); 305 DCHECK_NE(0u, module_ref_count_); 306 module_ref_count_--; 307 if (0 == module_ref_count_) { 308 // Allow UI and IO threads to do blocking IO on shutdown, since we do a lot 309 // of it on shutdown for valid reasons. 310 base::ThreadRestrictions::SetIOAllowed(true); 311 io_thread()->message_loop()->PostTask( 312 FROM_HERE, 313 NewRunnableFunction(&base::ThreadRestrictions::SetIOAllowed, true)); 314 MessageLoop::current()->PostTask( 315 FROM_HERE, NewRunnableFunction(DidEndMainMessageLoop)); 316 MessageLoop::current()->Quit(); 317 } 318 return module_ref_count_; 319 } 320 321 void BrowserProcessImpl::EndSession() { 322 #if defined(OS_WIN) || defined(USE_X11) 323 // Notify we are going away. 324 shutdown_event_->Signal(); 325 #endif 326 327 // Mark all the profiles as clean. 328 ProfileManager* pm = profile_manager(); 329 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); 330 for (size_t i = 0; i < profiles.size(); ++i) 331 profiles[i]->MarkAsCleanShutdown(); 332 333 // Tell the metrics service it was cleanly shutdown. 334 MetricsService* metrics = g_browser_process->metrics_service(); 335 if (metrics && local_state()) { 336 metrics->RecordStartOfSessionEnd(); 337 338 // MetricsService lazily writes to prefs, force it to write now. 339 local_state()->SavePersistentPrefs(); 340 } 341 342 // We must write that the profile and metrics service shutdown cleanly, 343 // otherwise on startup we'll think we crashed. So we block until done and 344 // then proceed with normal shutdown. 345 #if defined(USE_X11) 346 // Can't run a local loop on linux. Instead create a waitable event. 347 base::WaitableEvent done_writing(false, false); 348 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 349 NewRunnableFunction(Signal, &done_writing)); 350 done_writing.TimedWait( 351 base::TimeDelta::FromSeconds(kEndSessionTimeoutSeconds)); 352 #elif defined(OS_WIN) 353 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 354 NewRunnableFunction(PostQuit, MessageLoop::current())); 355 MessageLoop::current()->Run(); 356 #else 357 NOTIMPLEMENTED(); 358 #endif 359 } 360 361 ResourceDispatcherHost* BrowserProcessImpl::resource_dispatcher_host() { 362 DCHECK(CalledOnValidThread()); 363 if (!created_resource_dispatcher_host_) 364 CreateResourceDispatcherHost(); 365 return resource_dispatcher_host_.get(); 366 } 367 368 MetricsService* BrowserProcessImpl::metrics_service() { 369 DCHECK(CalledOnValidThread()); 370 if (!created_metrics_service_) 371 CreateMetricsService(); 372 return metrics_service_.get(); 373 } 374 375 IOThread* BrowserProcessImpl::io_thread() { 376 DCHECK(CalledOnValidThread()); 377 if (!created_io_thread_) 378 CreateIOThread(); 379 return io_thread_.get(); 380 } 381 382 base::Thread* BrowserProcessImpl::file_thread() { 383 DCHECK(CalledOnValidThread()); 384 if (!created_file_thread_) 385 CreateFileThread(); 386 return file_thread_.get(); 387 } 388 389 base::Thread* BrowserProcessImpl::db_thread() { 390 DCHECK(CalledOnValidThread()); 391 if (!created_db_thread_) 392 CreateDBThread(); 393 return db_thread_.get(); 394 } 395 396 base::Thread* BrowserProcessImpl::process_launcher_thread() { 397 DCHECK(CalledOnValidThread()); 398 if (!created_process_launcher_thread_) 399 CreateProcessLauncherThread(); 400 return process_launcher_thread_.get(); 401 } 402 403 base::Thread* BrowserProcessImpl::cache_thread() { 404 DCHECK(CalledOnValidThread()); 405 if (!created_cache_thread_) 406 CreateCacheThread(); 407 return cache_thread_.get(); 408 } 409 410 base::Thread* BrowserProcessImpl::gpu_thread() { 411 DCHECK(CalledOnValidThread()); 412 if (!created_gpu_thread_) 413 CreateGpuThread(); 414 return gpu_thread_.get(); 415 } 416 417 #if defined(USE_X11) 418 base::Thread* BrowserProcessImpl::background_x11_thread() { 419 DCHECK(CalledOnValidThread()); 420 // The BACKGROUND_X11 thread is created when the IO thread is created. 421 if (!created_io_thread_) 422 CreateIOThread(); 423 return background_x11_thread_.get(); 424 } 425 #endif 426 427 WatchDogThread* BrowserProcessImpl::watchdog_thread() { 428 DCHECK(CalledOnValidThread()); 429 if (!created_watchdog_thread_) 430 CreateWatchdogThread(); 431 DCHECK(watchdog_thread_.get() != NULL); 432 return watchdog_thread_.get(); 433 } 434 435 ProfileManager* BrowserProcessImpl::profile_manager() { 436 DCHECK(CalledOnValidThread()); 437 if (!created_profile_manager_) 438 CreateProfileManager(); 439 return profile_manager_.get(); 440 } 441 442 PrefService* BrowserProcessImpl::local_state() { 443 DCHECK(CalledOnValidThread()); 444 if (!created_local_state_) 445 CreateLocalState(); 446 return local_state_.get(); 447 } 448 449 DevToolsManager* BrowserProcessImpl::devtools_manager() { 450 DCHECK(CalledOnValidThread()); 451 if (!created_devtools_manager_) 452 CreateDevToolsManager(); 453 return devtools_manager_.get(); 454 } 455 456 SidebarManager* BrowserProcessImpl::sidebar_manager() { 457 DCHECK(CalledOnValidThread()); 458 if (!created_sidebar_manager_) 459 CreateSidebarManager(); 460 return sidebar_manager_.get(); 461 } 462 463 ui::Clipboard* BrowserProcessImpl::clipboard() { 464 DCHECK(CalledOnValidThread()); 465 return clipboard_.get(); 466 } 467 468 net::URLRequestContextGetter* BrowserProcessImpl::system_request_context() { 469 DCHECK(CalledOnValidThread()); 470 return io_thread()->system_url_request_context_getter(); 471 } 472 473 #if defined(OS_CHROMEOS) 474 chromeos::ProxyConfigServiceImpl* 475 BrowserProcessImpl::chromeos_proxy_config_service_impl() { 476 DCHECK(CalledOnValidThread()); 477 if (!chromeos_proxy_config_service_impl_) { 478 chromeos_proxy_config_service_impl_ = 479 new chromeos::ProxyConfigServiceImpl(); 480 } 481 return chromeos_proxy_config_service_impl_; 482 } 483 #endif // defined(OS_CHROMEOS) 484 485 ExtensionEventRouterForwarder* 486 BrowserProcessImpl::extension_event_router_forwarder() { 487 return extension_event_router_forwarder_.get(); 488 } 489 490 NotificationUIManager* BrowserProcessImpl::notification_ui_manager() { 491 DCHECK(CalledOnValidThread()); 492 if (!created_notification_ui_manager_) 493 CreateNotificationUIManager(); 494 return notification_ui_manager_.get(); 495 } 496 497 policy::BrowserPolicyConnector* BrowserProcessImpl::browser_policy_connector() { 498 DCHECK(CalledOnValidThread()); 499 if (!created_browser_policy_connector_) { 500 DCHECK(browser_policy_connector_.get() == NULL); 501 created_browser_policy_connector_ = true; 502 browser_policy_connector_.reset(new policy::BrowserPolicyConnector()); 503 } 504 return browser_policy_connector_.get(); 505 } 506 507 IconManager* BrowserProcessImpl::icon_manager() { 508 DCHECK(CalledOnValidThread()); 509 if (!created_icon_manager_) 510 CreateIconManager(); 511 return icon_manager_.get(); 512 } 513 514 ThumbnailGenerator* BrowserProcessImpl::GetThumbnailGenerator() { 515 return &thumbnail_generator_; 516 } 517 518 AutomationProviderList* BrowserProcessImpl::InitAutomationProviderList() { 519 DCHECK(CalledOnValidThread()); 520 if (automation_provider_list_.get() == NULL) { 521 automation_provider_list_.reset(AutomationProviderList::GetInstance()); 522 } 523 return automation_provider_list_.get(); 524 } 525 526 void BrowserProcessImpl::InitDevToolsHttpProtocolHandler( 527 const std::string& ip, 528 int port, 529 const std::string& frontend_url) { 530 DCHECK(CalledOnValidThread()); 531 devtools_http_handler_ = 532 DevToolsHttpProtocolHandler::Start(ip, 533 port, 534 frontend_url, 535 new BrowserListTabContentsProvider()); 536 } 537 538 void BrowserProcessImpl::InitDevToolsLegacyProtocolHandler(int port) { 539 DCHECK(CalledOnValidThread()); 540 devtools_legacy_handler_ = DevToolsProtocolHandler::Start(port); 541 } 542 543 bool BrowserProcessImpl::IsShuttingDown() { 544 DCHECK(CalledOnValidThread()); 545 return did_start_ && 0 == module_ref_count_; 546 } 547 548 printing::PrintJobManager* BrowserProcessImpl::print_job_manager() { 549 // TODO(abarth): DCHECK(CalledOnValidThread()); 550 // http://code.google.com/p/chromium/issues/detail?id=6828 551 // print_job_manager_ is initialized in the constructor and destroyed in the 552 // destructor, so it should always be valid. 553 DCHECK(print_job_manager_.get()); 554 return print_job_manager_.get(); 555 } 556 557 printing::PrintPreviewTabController* 558 BrowserProcessImpl::print_preview_tab_controller() { 559 DCHECK(CalledOnValidThread()); 560 if (!print_preview_tab_controller_.get()) 561 CreatePrintPreviewTabController(); 562 return print_preview_tab_controller_.get(); 563 } 564 565 GoogleURLTracker* BrowserProcessImpl::google_url_tracker() { 566 DCHECK(CalledOnValidThread()); 567 if (!google_url_tracker_.get()) 568 CreateGoogleURLTracker(); 569 return google_url_tracker_.get(); 570 } 571 572 IntranetRedirectDetector* BrowserProcessImpl::intranet_redirect_detector() { 573 DCHECK(CalledOnValidThread()); 574 if (!intranet_redirect_detector_.get()) 575 CreateIntranetRedirectDetector(); 576 return intranet_redirect_detector_.get(); 577 } 578 579 const std::string& BrowserProcessImpl::GetApplicationLocale() { 580 DCHECK(!locale_.empty()); 581 return locale_; 582 } 583 584 void BrowserProcessImpl::SetApplicationLocale(const std::string& locale) { 585 locale_ = locale; 586 extension_l10n_util::SetProcessLocale(locale); 587 } 588 589 DownloadStatusUpdater* BrowserProcessImpl::download_status_updater() { 590 return &download_status_updater_; 591 } 592 593 base::WaitableEvent* BrowserProcessImpl::shutdown_event() { 594 return shutdown_event_.get(); 595 } 596 597 TabCloseableStateWatcher* BrowserProcessImpl::tab_closeable_state_watcher() { 598 DCHECK(CalledOnValidThread()); 599 if (!tab_closeable_state_watcher_.get()) 600 CreateTabCloseableStateWatcher(); 601 return tab_closeable_state_watcher_.get(); 602 } 603 604 safe_browsing::ClientSideDetectionService* 605 BrowserProcessImpl::safe_browsing_detection_service() { 606 DCHECK(CalledOnValidThread()); 607 if (!created_safe_browsing_detection_service_) { 608 CreateSafeBrowsingDetectionService(); 609 } 610 return safe_browsing_detection_service_.get(); 611 } 612 613 bool BrowserProcessImpl::plugin_finder_disabled() const { 614 return *plugin_finder_disabled_pref_; 615 } 616 617 void BrowserProcessImpl::Observe(NotificationType type, 618 const NotificationSource& source, 619 const NotificationDetails& details) { 620 if (type == NotificationType::APP_TERMINATING) { 621 Profile* profile = ProfileManager::GetDefaultProfile(); 622 if (profile) { 623 PrefService* prefs = profile->GetPrefs(); 624 if (prefs->GetBoolean(prefs::kClearSiteDataOnExit) && 625 local_state()->GetBoolean(prefs::kClearPluginLSODataEnabled)) { 626 plugin_data_remover_ = new PluginDataRemover(); 627 if (!plugin_data_remover_mime_type().empty()) 628 plugin_data_remover_->set_mime_type(plugin_data_remover_mime_type()); 629 plugin_data_remover_->StartRemoving(base::Time()); 630 } 631 } 632 } else if (type == NotificationType::PREF_CHANGED) { 633 std::string* pref = Details<std::string>(details).ptr(); 634 if (*pref == prefs::kDefaultBrowserSettingEnabled) { 635 if (local_state_->GetBoolean(prefs::kDefaultBrowserSettingEnabled)) 636 ShellIntegration::SetAsDefaultBrowser(); 637 } else if (*pref == prefs::kDisabledSchemes) { 638 ApplyDisabledSchemesPolicy(); 639 } 640 } else { 641 NOTREACHED(); 642 } 643 } 644 645 void BrowserProcessImpl::WaitForPluginDataRemoverToFinish() { 646 if (plugin_data_remover_.get()) 647 plugin_data_remover_->Wait(); 648 } 649 650 #if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) 651 void BrowserProcessImpl::StartAutoupdateTimer() { 652 autoupdate_timer_.Start( 653 base::TimeDelta::FromHours(kUpdateCheckIntervalHours), 654 this, 655 &BrowserProcessImpl::OnAutoupdateTimer); 656 } 657 #endif 658 659 ChromeNetLog* BrowserProcessImpl::net_log() { 660 return net_log_.get(); 661 } 662 663 void BrowserProcessImpl::ClearLocalState(const FilePath& profile_path) { 664 webkit_database::DatabaseTracker::ClearLocalState(profile_path); 665 } 666 667 bool BrowserProcessImpl::ShouldClearLocalState(FilePath* profile_path) { 668 FilePath user_data_dir; 669 Profile* profile; 670 671 // Check for the existence of a profile manager. When quitting early, 672 // e.g. because another chrome instance is running, or when invoked with 673 // options such as --uninstall or --try-chrome-again=0, the profile manager 674 // does not exist yet. 675 if (!profile_manager_.get()) 676 return false; 677 678 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 679 profile = profile_manager_->GetDefaultProfile(user_data_dir); 680 if (!profile) 681 return false; 682 *profile_path = profile->GetPath(); 683 return profile->GetPrefs()->GetBoolean(prefs::kClearSiteDataOnExit); 684 } 685 686 void BrowserProcessImpl::CreateResourceDispatcherHost() { 687 DCHECK(!created_resource_dispatcher_host_ && 688 resource_dispatcher_host_.get() == NULL); 689 created_resource_dispatcher_host_ = true; 690 691 // UserScriptListener will delete itself. 692 ResourceQueue::DelegateSet resource_queue_delegates; 693 resource_queue_delegates.insert(new UserScriptListener()); 694 695 resource_dispatcher_host_.reset( 696 new ResourceDispatcherHost(resource_queue_delegates)); 697 resource_dispatcher_host_->Initialize(); 698 } 699 700 void BrowserProcessImpl::CreateMetricsService() { 701 DCHECK(!created_metrics_service_ && metrics_service_.get() == NULL); 702 created_metrics_service_ = true; 703 704 metrics_service_.reset(new MetricsService); 705 } 706 707 void BrowserProcessImpl::CreateIOThread() { 708 DCHECK(!created_io_thread_ && io_thread_.get() == NULL); 709 created_io_thread_ = true; 710 711 // Prior to starting the io thread, we create the plugin service as 712 // it is predominantly used from the io thread, but must be created 713 // on the main thread. The service ctor is inexpensive and does not 714 // invoke the io_thread() accessor. 715 PluginService::GetInstance(); 716 717 #if defined(USE_X11) 718 // The lifetime of the BACKGROUND_X11 thread is a subset of the IO thread so 719 // we start it now. 720 scoped_ptr<base::Thread> background_x11_thread( 721 new BrowserProcessSubThread(BrowserThread::BACKGROUND_X11)); 722 if (!background_x11_thread->Start()) 723 return; 724 background_x11_thread_.swap(background_x11_thread); 725 #endif 726 727 scoped_ptr<IOThread> thread(new IOThread( 728 local_state(), net_log_.get(), extension_event_router_forwarder_.get())); 729 base::Thread::Options options; 730 options.message_loop_type = MessageLoop::TYPE_IO; 731 if (!thread->StartWithOptions(options)) 732 return; 733 io_thread_.swap(thread); 734 } 735 736 void BrowserProcessImpl::CreateFileThread() { 737 DCHECK(!created_file_thread_ && file_thread_.get() == NULL); 738 created_file_thread_ = true; 739 740 scoped_ptr<base::Thread> thread( 741 new BrowserProcessSubThread(BrowserThread::FILE)); 742 base::Thread::Options options; 743 #if defined(OS_WIN) 744 // On Windows, the FILE thread needs to be have a UI message loop which pumps 745 // messages in such a way that Google Update can communicate back to us. 746 options.message_loop_type = MessageLoop::TYPE_UI; 747 #else 748 options.message_loop_type = MessageLoop::TYPE_IO; 749 #endif 750 if (!thread->StartWithOptions(options)) 751 return; 752 file_thread_.swap(thread); 753 } 754 755 void BrowserProcessImpl::CreateDBThread() { 756 DCHECK(!created_db_thread_ && db_thread_.get() == NULL); 757 created_db_thread_ = true; 758 759 scoped_ptr<base::Thread> thread( 760 new BrowserProcessSubThread(BrowserThread::DB)); 761 if (!thread->Start()) 762 return; 763 db_thread_.swap(thread); 764 } 765 766 void BrowserProcessImpl::CreateProcessLauncherThread() { 767 DCHECK(!created_process_launcher_thread_ && !process_launcher_thread_.get()); 768 created_process_launcher_thread_ = true; 769 770 scoped_ptr<base::Thread> thread( 771 new BrowserProcessSubThread(BrowserThread::PROCESS_LAUNCHER)); 772 if (!thread->Start()) 773 return; 774 process_launcher_thread_.swap(thread); 775 } 776 777 void BrowserProcessImpl::CreateCacheThread() { 778 DCHECK(!created_cache_thread_ && !cache_thread_.get()); 779 created_cache_thread_ = true; 780 781 scoped_ptr<base::Thread> thread( 782 new BrowserThread(BrowserThread::CACHE)); 783 base::Thread::Options options; 784 options.message_loop_type = MessageLoop::TYPE_IO; 785 if (!thread->StartWithOptions(options)) 786 return; 787 cache_thread_.swap(thread); 788 } 789 790 void BrowserProcessImpl::CreateGpuThread() { 791 DCHECK(!created_gpu_thread_ && !gpu_thread_.get()); 792 created_gpu_thread_ = true; 793 794 scoped_ptr<base::Thread> thread(new BrowserThread(BrowserThread::GPU)); 795 796 base::Thread::Options options; 797 #if defined(OS_WIN) 798 // On Windows the GPU thread needs to pump the compositor child window's 799 // message loop. TODO(apatrick): make this an IO thread if / when we get rid 800 // of this child window. Unfortunately it might always be necessary for 801 // Windows XP because we cannot share the backing store textures between 802 // processes. 803 options.message_loop_type = MessageLoop::TYPE_UI; 804 #else 805 options.message_loop_type = MessageLoop::TYPE_IO; 806 #endif 807 808 if (!thread->StartWithOptions(options)) 809 return; 810 gpu_thread_.swap(thread); 811 } 812 813 void BrowserProcessImpl::CreateWatchdogThread() { 814 DCHECK(!created_watchdog_thread_ && watchdog_thread_.get() == NULL); 815 created_watchdog_thread_ = true; 816 817 scoped_ptr<WatchDogThread> thread(new WatchDogThread()); 818 if (!thread->Start()) 819 return; 820 watchdog_thread_.swap(thread); 821 } 822 823 void BrowserProcessImpl::CreateProfileManager() { 824 DCHECK(!created_profile_manager_ && profile_manager_.get() == NULL); 825 created_profile_manager_ = true; 826 827 profile_manager_.reset(new ProfileManager()); 828 } 829 830 void BrowserProcessImpl::CreateLocalState() { 831 DCHECK(!created_local_state_ && local_state_.get() == NULL); 832 created_local_state_ = true; 833 834 FilePath local_state_path; 835 PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path); 836 local_state_.reset( 837 PrefService::CreatePrefService(local_state_path, NULL, NULL)); 838 839 pref_change_registrar_.Init(local_state_.get()); 840 841 // Make sure the the plugin updater gets notifications of changes 842 // in the plugin policy lists. 843 local_state_->RegisterListPref(prefs::kPluginsDisabledPlugins); 844 pref_change_registrar_.Add(prefs::kPluginsDisabledPlugins, 845 PluginUpdater::GetInstance()); 846 local_state_->RegisterListPref(prefs::kPluginsDisabledPluginsExceptions); 847 pref_change_registrar_.Add(prefs::kPluginsDisabledPluginsExceptions, 848 PluginUpdater::GetInstance()); 849 local_state_->RegisterListPref(prefs::kPluginsEnabledPlugins); 850 pref_change_registrar_.Add(prefs::kPluginsEnabledPlugins, 851 PluginUpdater::GetInstance()); 852 853 // Initialize and set up notifications for the printing enabled 854 // preference. 855 local_state_->RegisterBooleanPref(prefs::kPrintingEnabled, true); 856 bool printing_enabled = 857 local_state_->GetBoolean(prefs::kPrintingEnabled); 858 print_job_manager_->set_printing_enabled(printing_enabled); 859 pref_change_registrar_.Add(prefs::kPrintingEnabled, 860 print_job_manager_.get()); 861 862 // Initialize the notification for the default browser setting policy. 863 local_state_->RegisterBooleanPref(prefs::kDefaultBrowserSettingEnabled, 864 false); 865 if (local_state_->IsManagedPreference(prefs::kDefaultBrowserSettingEnabled)) { 866 if (local_state_->GetBoolean(prefs::kDefaultBrowserSettingEnabled)) 867 ShellIntegration::SetAsDefaultBrowser(); 868 } 869 pref_change_registrar_.Add(prefs::kDefaultBrowserSettingEnabled, this); 870 871 // Initialize the preference for the plugin finder policy. 872 // This preference is only needed on the IO thread so make it available there. 873 local_state_->RegisterBooleanPref(prefs::kDisablePluginFinder, false); 874 plugin_finder_disabled_pref_.Init(prefs::kDisablePluginFinder, 875 local_state_.get(), NULL); 876 plugin_finder_disabled_pref_.MoveToThread(BrowserThread::IO); 877 878 // Initialize the preference for the disabled schemes policy, and 879 // load the initial policy on startup. 880 local_state_->RegisterListPref(prefs::kDisabledSchemes); 881 disabled_schemes_pref_.Init(prefs::kDisabledSchemes, local_state_.get(), 882 this); 883 ApplyDisabledSchemesPolicy(); 884 } 885 886 void BrowserProcessImpl::CreateIconManager() { 887 DCHECK(!created_icon_manager_ && icon_manager_.get() == NULL); 888 created_icon_manager_ = true; 889 icon_manager_.reset(new IconManager); 890 } 891 892 void BrowserProcessImpl::CreateDevToolsManager() { 893 DCHECK(devtools_manager_.get() == NULL); 894 created_devtools_manager_ = true; 895 devtools_manager_ = new DevToolsManager(); 896 } 897 898 void BrowserProcessImpl::CreateSidebarManager() { 899 DCHECK(sidebar_manager_.get() == NULL); 900 created_sidebar_manager_ = true; 901 sidebar_manager_ = new SidebarManager(); 902 } 903 904 void BrowserProcessImpl::CreateGoogleURLTracker() { 905 DCHECK(google_url_tracker_.get() == NULL); 906 scoped_ptr<GoogleURLTracker> google_url_tracker(new GoogleURLTracker); 907 google_url_tracker_.swap(google_url_tracker); 908 } 909 910 void BrowserProcessImpl::CreateIntranetRedirectDetector() { 911 DCHECK(intranet_redirect_detector_.get() == NULL); 912 scoped_ptr<IntranetRedirectDetector> intranet_redirect_detector( 913 new IntranetRedirectDetector); 914 intranet_redirect_detector_.swap(intranet_redirect_detector); 915 } 916 917 void BrowserProcessImpl::CreateNotificationUIManager() { 918 DCHECK(notification_ui_manager_.get() == NULL); 919 notification_ui_manager_.reset(NotificationUIManager::Create(local_state())); 920 921 created_notification_ui_manager_ = true; 922 } 923 924 void BrowserProcessImpl::CreateTabCloseableStateWatcher() { 925 DCHECK(tab_closeable_state_watcher_.get() == NULL); 926 tab_closeable_state_watcher_.reset(TabCloseableStateWatcher::Create()); 927 } 928 929 void BrowserProcessImpl::CreatePrintPreviewTabController() { 930 DCHECK(print_preview_tab_controller_.get() == NULL); 931 print_preview_tab_controller_ = new printing::PrintPreviewTabController(); 932 } 933 934 void BrowserProcessImpl::CreateSafeBrowsingDetectionService() { 935 DCHECK(safe_browsing_detection_service_.get() == NULL); 936 // Set this flag to true so that we don't retry indefinitely to 937 // create the service class if there was an error. 938 created_safe_browsing_detection_service_ = true; 939 940 FilePath model_file_path; 941 Profile* profile = profile_manager() ? 942 profile_manager()->GetDefaultProfile() : NULL; 943 if (IsSafeBrowsingDetectionServiceEnabled() && 944 PathService::Get(chrome::DIR_USER_DATA, &model_file_path) && 945 profile && profile->GetRequestContext()) { 946 safe_browsing_detection_service_.reset( 947 safe_browsing::ClientSideDetectionService::Create( 948 model_file_path.Append(chrome::kSafeBrowsingPhishingModelFilename), 949 profile->GetRequestContext())); 950 } 951 } 952 953 bool BrowserProcessImpl::IsSafeBrowsingDetectionServiceEnabled() { 954 // The safe browsing client-side detection is enabled only if the switch is 955 // enabled and when safe browsing related stats is allowed to be collected. 956 // For now we only enable client-side detection on the canary, dev and beta 957 // channel. 958 #ifdef OS_CHROMEOS 959 return false; 960 #else 961 std::string channel = platform_util::GetVersionStringModifier(); 962 return !CommandLine::ForCurrentProcess()->HasSwitch( 963 switches::kDisableClientSidePhishingDetection) && 964 resource_dispatcher_host()->safe_browsing_service() && 965 resource_dispatcher_host()->safe_browsing_service()->CanReportStats() && 966 // TODO(noelutz): use platform_util::GetChannel() once it has been 967 // pushed to the release branch. 968 (channel == "beta" || channel == "dev" || channel == "canary" || 969 channel == "beta-m" || channel == "dev-m" || channel == "canary-m"); 970 971 #endif 972 } 973 974 void BrowserProcessImpl::ApplyDisabledSchemesPolicy() { 975 std::set<std::string> schemes; 976 for (ListValue::const_iterator iter = (*disabled_schemes_pref_)->begin(); 977 iter != (*disabled_schemes_pref_)->end(); ++iter) { 978 std::string scheme; 979 if ((*iter)->GetAsString(&scheme)) 980 schemes.insert(scheme); 981 } 982 ChildProcessSecurityPolicy::GetInstance()->RegisterDisabledSchemes(schemes); 983 } 984 985 // The BrowserProcess object must outlive the file thread so we use traits 986 // which don't do any management. 987 DISABLE_RUNNABLE_METHOD_REFCOUNT(BrowserProcessImpl); 988 989 #if defined(IPC_MESSAGE_LOG_ENABLED) 990 991 void BrowserProcessImpl::SetIPCLoggingEnabled(bool enable) { 992 // First enable myself. 993 if (enable) 994 IPC::Logging::GetInstance()->Enable(); 995 else 996 IPC::Logging::GetInstance()->Disable(); 997 998 // Now tell subprocesses. Messages to ChildProcess-derived 999 // processes must be done on the IO thread. 1000 io_thread()->message_loop()->PostTask 1001 (FROM_HERE, 1002 NewRunnableMethod( 1003 this, 1004 &BrowserProcessImpl::SetIPCLoggingEnabledForChildProcesses, 1005 enable)); 1006 1007 // Finally, tell the renderers which don't derive from ChildProcess. 1008 // Messages to the renderers must be done on the UI (main) thread. 1009 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); 1010 !i.IsAtEnd(); i.Advance()) 1011 i.GetCurrentValue()->Send(new ChildProcessMsg_SetIPCLoggingEnabled(enable)); 1012 } 1013 1014 // Helper for SetIPCLoggingEnabled. 1015 void BrowserProcessImpl::SetIPCLoggingEnabledForChildProcesses(bool enabled) { 1016 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1017 1018 BrowserChildProcessHost::Iterator i; // default constr references a singleton 1019 while (!i.Done()) { 1020 i->Send(new ChildProcessMsg_SetIPCLoggingEnabled(enabled)); 1021 ++i; 1022 } 1023 } 1024 1025 #endif // IPC_MESSAGE_LOG_ENABLED 1026 1027 // Mac is currently not supported. 1028 #if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) 1029 1030 bool BrowserProcessImpl::CanAutorestartForUpdate() const { 1031 // Check if browser is in the background and if it needs to be restarted to 1032 // apply a pending update. 1033 return BrowserList::size() == 0 && BrowserList::WillKeepAlive() && 1034 upgrade_util::IsUpdatePendingRestart(); 1035 } 1036 1037 // Switches to add when auto-restarting Chrome. 1038 const char* const kSwitchesToAddOnAutorestart[] = { 1039 switches::kNoStartupWindow 1040 }; 1041 1042 void BrowserProcessImpl::RestartPersistentInstance() { 1043 CommandLine* old_cl = CommandLine::ForCurrentProcess(); 1044 scoped_ptr<CommandLine> new_cl(new CommandLine(old_cl->GetProgram())); 1045 1046 std::map<std::string, CommandLine::StringType> switches = 1047 old_cl->GetSwitches(); 1048 1049 switches::RemoveSwitchesForAutostart(&switches); 1050 1051 // Append the rest of the switches (along with their values, if any) 1052 // to the new command line 1053 for (std::map<std::string, CommandLine::StringType>::const_iterator i = 1054 switches.begin(); i != switches.end(); ++i) { 1055 CommandLine::StringType switch_value = i->second; 1056 if (switch_value.length() > 0) { 1057 new_cl->AppendSwitchNative(i->first, i->second); 1058 } else { 1059 new_cl->AppendSwitch(i->first); 1060 } 1061 } 1062 1063 // Ensure that our desired switches are set on the new process. 1064 for (size_t i = 0; i < arraysize(kSwitchesToAddOnAutorestart); ++i) { 1065 if (!new_cl->HasSwitch(kSwitchesToAddOnAutorestart[i])) 1066 new_cl->AppendSwitch(kSwitchesToAddOnAutorestart[i]); 1067 } 1068 1069 DLOG(WARNING) << "Shutting down current instance of the browser."; 1070 BrowserList::CloseAllBrowsersAndExit(); 1071 1072 // Transfer ownership to Upgrade. 1073 upgrade_util::SetNewCommandLine(new_cl.release()); 1074 } 1075 1076 void BrowserProcessImpl::OnAutoupdateTimer() { 1077 if (CanAutorestartForUpdate()) { 1078 DLOG(WARNING) << "Detected update. Restarting browser."; 1079 RestartPersistentInstance(); 1080 } 1081 } 1082 1083 #endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) 1084