Home | History | Annotate | Download | only in browser
      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