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. 93static 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. 100static const int kEndSessionTimeoutSeconds = 10; 101#endif 102 103BrowserProcessImpl::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 145BrowserProcessImpl::~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. 287static void PostQuit(MessageLoop* message_loop) { 288 message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask()); 289} 290#elif defined(USE_X11) 291static void Signal(base::WaitableEvent* event) { 292 event->Signal(); 293} 294#endif 295 296unsigned int BrowserProcessImpl::AddRefModule() { 297 DCHECK(CalledOnValidThread()); 298 did_start_ = true; 299 module_ref_count_++; 300 return module_ref_count_; 301} 302 303unsigned 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 321void 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 361ResourceDispatcherHost* BrowserProcessImpl::resource_dispatcher_host() { 362 DCHECK(CalledOnValidThread()); 363 if (!created_resource_dispatcher_host_) 364 CreateResourceDispatcherHost(); 365 return resource_dispatcher_host_.get(); 366} 367 368MetricsService* BrowserProcessImpl::metrics_service() { 369 DCHECK(CalledOnValidThread()); 370 if (!created_metrics_service_) 371 CreateMetricsService(); 372 return metrics_service_.get(); 373} 374 375IOThread* BrowserProcessImpl::io_thread() { 376 DCHECK(CalledOnValidThread()); 377 if (!created_io_thread_) 378 CreateIOThread(); 379 return io_thread_.get(); 380} 381 382base::Thread* BrowserProcessImpl::file_thread() { 383 DCHECK(CalledOnValidThread()); 384 if (!created_file_thread_) 385 CreateFileThread(); 386 return file_thread_.get(); 387} 388 389base::Thread* BrowserProcessImpl::db_thread() { 390 DCHECK(CalledOnValidThread()); 391 if (!created_db_thread_) 392 CreateDBThread(); 393 return db_thread_.get(); 394} 395 396base::Thread* BrowserProcessImpl::process_launcher_thread() { 397 DCHECK(CalledOnValidThread()); 398 if (!created_process_launcher_thread_) 399 CreateProcessLauncherThread(); 400 return process_launcher_thread_.get(); 401} 402 403base::Thread* BrowserProcessImpl::cache_thread() { 404 DCHECK(CalledOnValidThread()); 405 if (!created_cache_thread_) 406 CreateCacheThread(); 407 return cache_thread_.get(); 408} 409 410base::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) 418base::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 427WatchDogThread* 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 435ProfileManager* BrowserProcessImpl::profile_manager() { 436 DCHECK(CalledOnValidThread()); 437 if (!created_profile_manager_) 438 CreateProfileManager(); 439 return profile_manager_.get(); 440} 441 442PrefService* BrowserProcessImpl::local_state() { 443 DCHECK(CalledOnValidThread()); 444 if (!created_local_state_) 445 CreateLocalState(); 446 return local_state_.get(); 447} 448 449DevToolsManager* BrowserProcessImpl::devtools_manager() { 450 DCHECK(CalledOnValidThread()); 451 if (!created_devtools_manager_) 452 CreateDevToolsManager(); 453 return devtools_manager_.get(); 454} 455 456SidebarManager* BrowserProcessImpl::sidebar_manager() { 457 DCHECK(CalledOnValidThread()); 458 if (!created_sidebar_manager_) 459 CreateSidebarManager(); 460 return sidebar_manager_.get(); 461} 462 463ui::Clipboard* BrowserProcessImpl::clipboard() { 464 DCHECK(CalledOnValidThread()); 465 return clipboard_.get(); 466} 467 468net::URLRequestContextGetter* BrowserProcessImpl::system_request_context() { 469 DCHECK(CalledOnValidThread()); 470 return io_thread()->system_url_request_context_getter(); 471} 472 473#if defined(OS_CHROMEOS) 474chromeos::ProxyConfigServiceImpl* 475BrowserProcessImpl::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 485ExtensionEventRouterForwarder* 486BrowserProcessImpl::extension_event_router_forwarder() { 487 return extension_event_router_forwarder_.get(); 488} 489 490NotificationUIManager* BrowserProcessImpl::notification_ui_manager() { 491 DCHECK(CalledOnValidThread()); 492 if (!created_notification_ui_manager_) 493 CreateNotificationUIManager(); 494 return notification_ui_manager_.get(); 495} 496 497policy::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 507IconManager* BrowserProcessImpl::icon_manager() { 508 DCHECK(CalledOnValidThread()); 509 if (!created_icon_manager_) 510 CreateIconManager(); 511 return icon_manager_.get(); 512} 513 514ThumbnailGenerator* BrowserProcessImpl::GetThumbnailGenerator() { 515 return &thumbnail_generator_; 516} 517 518AutomationProviderList* 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 526void 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 538void BrowserProcessImpl::InitDevToolsLegacyProtocolHandler(int port) { 539 DCHECK(CalledOnValidThread()); 540 devtools_legacy_handler_ = DevToolsProtocolHandler::Start(port); 541} 542 543bool BrowserProcessImpl::IsShuttingDown() { 544 DCHECK(CalledOnValidThread()); 545 return did_start_ && 0 == module_ref_count_; 546} 547 548printing::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 557printing::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 565GoogleURLTracker* BrowserProcessImpl::google_url_tracker() { 566 DCHECK(CalledOnValidThread()); 567 if (!google_url_tracker_.get()) 568 CreateGoogleURLTracker(); 569 return google_url_tracker_.get(); 570} 571 572IntranetRedirectDetector* BrowserProcessImpl::intranet_redirect_detector() { 573 DCHECK(CalledOnValidThread()); 574 if (!intranet_redirect_detector_.get()) 575 CreateIntranetRedirectDetector(); 576 return intranet_redirect_detector_.get(); 577} 578 579const std::string& BrowserProcessImpl::GetApplicationLocale() { 580 DCHECK(!locale_.empty()); 581 return locale_; 582} 583 584void BrowserProcessImpl::SetApplicationLocale(const std::string& locale) { 585 locale_ = locale; 586 extension_l10n_util::SetProcessLocale(locale); 587} 588 589DownloadStatusUpdater* BrowserProcessImpl::download_status_updater() { 590 return &download_status_updater_; 591} 592 593base::WaitableEvent* BrowserProcessImpl::shutdown_event() { 594 return shutdown_event_.get(); 595} 596 597TabCloseableStateWatcher* 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 604safe_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 613bool BrowserProcessImpl::plugin_finder_disabled() const { 614 return *plugin_finder_disabled_pref_; 615} 616 617void 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 645void 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) 651void BrowserProcessImpl::StartAutoupdateTimer() { 652 autoupdate_timer_.Start( 653 base::TimeDelta::FromHours(kUpdateCheckIntervalHours), 654 this, 655 &BrowserProcessImpl::OnAutoupdateTimer); 656} 657#endif 658 659ChromeNetLog* BrowserProcessImpl::net_log() { 660 return net_log_.get(); 661} 662 663void BrowserProcessImpl::ClearLocalState(const FilePath& profile_path) { 664 webkit_database::DatabaseTracker::ClearLocalState(profile_path); 665} 666 667bool 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 686void 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 700void 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 707void 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 736void 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 755void 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 766void 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 777void 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 790void 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 813void 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 823void 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 830void 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 886void BrowserProcessImpl::CreateIconManager() { 887 DCHECK(!created_icon_manager_ && icon_manager_.get() == NULL); 888 created_icon_manager_ = true; 889 icon_manager_.reset(new IconManager); 890} 891 892void BrowserProcessImpl::CreateDevToolsManager() { 893 DCHECK(devtools_manager_.get() == NULL); 894 created_devtools_manager_ = true; 895 devtools_manager_ = new DevToolsManager(); 896} 897 898void BrowserProcessImpl::CreateSidebarManager() { 899 DCHECK(sidebar_manager_.get() == NULL); 900 created_sidebar_manager_ = true; 901 sidebar_manager_ = new SidebarManager(); 902} 903 904void 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 910void 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 917void 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 924void BrowserProcessImpl::CreateTabCloseableStateWatcher() { 925 DCHECK(tab_closeable_state_watcher_.get() == NULL); 926 tab_closeable_state_watcher_.reset(TabCloseableStateWatcher::Create()); 927} 928 929void BrowserProcessImpl::CreatePrintPreviewTabController() { 930 DCHECK(print_preview_tab_controller_.get() == NULL); 931 print_preview_tab_controller_ = new printing::PrintPreviewTabController(); 932} 933 934void 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 953bool 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 974void 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. 987DISABLE_RUNNABLE_METHOD_REFCOUNT(BrowserProcessImpl); 988 989#if defined(IPC_MESSAGE_LOG_ENABLED) 990 991void 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. 1015void 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 1030bool 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. 1038const char* const kSwitchesToAddOnAutorestart[] = { 1039 switches::kNoStartupWindow 1040}; 1041 1042void 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 1076void 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