Home | History | Annotate | Download | only in browser
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/browser_process_impl.h"
      6 
      7 #include <algorithm>
      8 #include <map>
      9 #include <vector>
     10 
     11 #include "base/bind.h"
     12 #include "base/bind_helpers.h"
     13 #include "base/command_line.h"
     14 #include "base/debug/alias.h"
     15 #include "base/path_service.h"
     16 #include "base/prefs/json_pref_store.h"
     17 #include "base/prefs/pref_registry_simple.h"
     18 #include "base/prefs/pref_service.h"
     19 #include "base/synchronization/waitable_event.h"
     20 #include "base/threading/thread.h"
     21 #include "base/threading/thread_restrictions.h"
     22 #include "chrome/browser/automation/automation_provider_list.h"
     23 #include "chrome/browser/background/background_mode_manager.h"
     24 #include "chrome/browser/chrome_browser_main.h"
     25 #include "chrome/browser/chrome_content_browser_client.h"
     26 #include "chrome/browser/chrome_notification_types.h"
     27 #include "chrome/browser/component_updater/component_updater_configurator.h"
     28 #include "chrome/browser/component_updater/component_updater_service.h"
     29 #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h"
     30 #include "chrome/browser/defaults.h"
     31 #include "chrome/browser/devtools/remote_debugging_server.h"
     32 #include "chrome/browser/download/download_request_limiter.h"
     33 #include "chrome/browser/download/download_status_updater.h"
     34 #include "chrome/browser/extensions/event_router_forwarder.h"
     35 #include "chrome/browser/extensions/extension_renderer_state.h"
     36 #include "chrome/browser/first_run/upgrade_util.h"
     37 #include "chrome/browser/gpu/gl_string_manager.h"
     38 #include "chrome/browser/gpu/gpu_mode_manager.h"
     39 #include "chrome/browser/icon_manager.h"
     40 #include "chrome/browser/idle.h"
     41 #include "chrome/browser/intranet_redirect_detector.h"
     42 #include "chrome/browser/io_thread.h"
     43 #include "chrome/browser/lifetime/application_lifetime.h"
     44 #include "chrome/browser/metrics/metrics_service.h"
     45 #include "chrome/browser/metrics/thread_watcher.h"
     46 #include "chrome/browser/metrics/variations/variations_service.h"
     47 #include "chrome/browser/net/chrome_net_log.h"
     48 #include "chrome/browser/net/crl_set_fetcher.h"
     49 #include "chrome/browser/net/sdch_dictionary_fetcher.h"
     50 #include "chrome/browser/notifications/notification_ui_manager.h"
     51 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
     52 #include "chrome/browser/plugins/plugin_finder.h"
     53 #include "chrome/browser/policy/policy_service.h"
     54 #include "chrome/browser/prefs/browser_prefs.h"
     55 #include "chrome/browser/prefs/chrome_pref_service_factory.h"
     56 #include "chrome/browser/prerender/prerender_tracker.h"
     57 #include "chrome/browser/printing/background_printing_manager.h"
     58 #include "chrome/browser/printing/print_job_manager.h"
     59 #include "chrome/browser/printing/print_preview_dialog_controller.h"
     60 #include "chrome/browser/profiles/profile_manager.h"
     61 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"
     62 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
     63 #include "chrome/browser/shell_integration.h"
     64 #include "chrome/browser/status_icons/status_tray.h"
     65 #include "chrome/browser/storage_monitor/storage_monitor.h"
     66 #include "chrome/browser/thumbnails/render_widget_snapshot_taker.h"
     67 #include "chrome/browser/ui/bookmarks/bookmark_prompt_controller.h"
     68 #include "chrome/browser/ui/browser_finder.h"
     69 #include "chrome/browser/web_resource/promo_resource_service.h"
     70 #include "chrome/common/chrome_constants.h"
     71 #include "chrome/common/chrome_paths.h"
     72 #include "chrome/common/chrome_switches.h"
     73 #include "chrome/common/extensions/chrome_extensions_client.h"
     74 #include "chrome/common/extensions/extension_l10n_util.h"
     75 #include "chrome/common/pref_names.h"
     76 #include "chrome/common/switch_utils.h"
     77 #include "chrome/common/url_constants.h"
     78 #include "chrome/installer/util/google_update_constants.h"
     79 #include "content/public/browser/browser_thread.h"
     80 #include "content/public/browser/child_process_security_policy.h"
     81 #include "content/public/browser/notification_details.h"
     82 #include "content/public/browser/plugin_service.h"
     83 #include "content/public/browser/render_process_host.h"
     84 #include "content/public/browser/resource_dispatcher_host.h"
     85 #include "extensions/common/constants.h"
     86 #include "net/socket/client_socket_pool_manager.h"
     87 #include "net/url_request/url_request_context_getter.h"
     88 #include "ui/base/l10n/l10n_util.h"
     89 #include "ui/message_center/message_center.h"
     90 
     91 #if defined(ENABLE_CONFIGURATION_POLICY)
     92 #include "chrome/browser/policy/browser_policy_connector.h"
     93 #else
     94 #include "chrome/browser/policy/policy_service_stub.h"
     95 #endif  // defined(ENABLE_CONFIGURATION_POLICY)
     96 
     97 #if defined(OS_WIN)
     98 #include "base/win/windows_version.h"
     99 #include "ui/views/focus/view_storage.h"
    100 #elif defined(OS_MACOSX)
    101 #include "chrome/browser/chrome_browser_main_mac.h"
    102 #endif
    103 
    104 #if defined(USE_AURA)
    105 #include "ui/aura/env.h"
    106 #endif
    107 
    108 #if !defined(OS_ANDROID) && !defined(OS_IOS)
    109 #include "chrome/browser/media_galleries/media_file_system_registry.h"
    110 #endif
    111 
    112 #if defined(ENABLE_PLUGIN_INSTALLATION)
    113 #include "chrome/browser/plugins/plugins_resource_service.h"
    114 #endif
    115 
    116 #if defined(ENABLE_WEBRTC)
    117 #include "chrome/browser/media/webrtc_log_uploader.h"
    118 #endif
    119 
    120 #if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS)
    121 // How often to check if the persistent instance of Chrome needs to restart
    122 // to install an update.
    123 static const int kUpdateCheckIntervalHours = 6;
    124 #endif
    125 
    126 #if defined(OS_WIN)
    127 // Attest to the fact that the call to the file thread to save preferences has
    128 // run, and it is safe to terminate.  This avoids the potential of some other
    129 // task prematurely terminating our waiting message loop by posting a
    130 // QuitTask().
    131 static bool g_end_session_file_thread_has_completed = false;
    132 #endif
    133 
    134 #if defined(USE_X11)
    135 // How long to wait for the File thread to complete during EndSession, on
    136 // Linux. We have a timeout here because we're unable to run the UI messageloop
    137 // and there's some deadlock risk. Our only option is to exit anyway.
    138 static const int kEndSessionTimeoutSeconds = 10;
    139 #endif
    140 
    141 using content::BrowserThread;
    142 using content::ChildProcessSecurityPolicy;
    143 using content::PluginService;
    144 using content::ResourceDispatcherHost;
    145 
    146 BrowserProcessImpl::BrowserProcessImpl(
    147     base::SequencedTaskRunner* local_state_task_runner,
    148     const CommandLine& command_line)
    149     : created_metrics_service_(false),
    150       created_watchdog_thread_(false),
    151       created_browser_policy_connector_(false),
    152       created_profile_manager_(false),
    153       created_local_state_(false),
    154       created_icon_manager_(false),
    155       created_notification_ui_manager_(false),
    156       created_safe_browsing_service_(false),
    157       module_ref_count_(0),
    158       did_start_(false),
    159       checked_for_new_frames_(false),
    160       using_new_frames_(false),
    161       render_widget_snapshot_taker_(new RenderWidgetSnapshotTaker),
    162       download_status_updater_(new DownloadStatusUpdater),
    163       local_state_task_runner_(local_state_task_runner) {
    164   g_browser_process = this;
    165   platform_part_.reset(new BrowserProcessPlatformPart());
    166 
    167 #if defined(ENABLE_PRINTING)
    168   // Must be created after the NotificationService.
    169   print_job_manager_.reset(new printing::PrintJobManager);
    170 #endif
    171 
    172   net_log_.reset(new ChromeNetLog);
    173 
    174   ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(
    175       extensions::kExtensionScheme);
    176   ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(
    177       chrome::kExtensionResourceScheme);
    178   ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(
    179       chrome::kChromeSearchScheme);
    180 
    181 #if defined(OS_MACOSX)
    182   InitIdleMonitor();
    183 #endif
    184 
    185   extensions::ExtensionsClient::Set(
    186       extensions::ChromeExtensionsClient::GetInstance());
    187   extension_event_router_forwarder_ = new extensions::EventRouterForwarder;
    188   ExtensionRendererState::GetInstance()->Init();
    189 
    190   message_center::MessageCenter::Initialize();
    191 }
    192 
    193 BrowserProcessImpl::~BrowserProcessImpl() {
    194   tracked_objects::ThreadData::EnsureCleanupWasCalled(4);
    195 
    196   g_browser_process = NULL;
    197 }
    198 
    199 void BrowserProcessImpl::StartTearDown() {
    200 #if defined(ENABLE_AUTOMATION)
    201   // Delete the AutomationProviderList before NotificationService,
    202   // since it may try to unregister notifications
    203   // Both NotificationService and AutomationProvider are singleton instances in
    204   // the BrowserProcess. Since AutomationProvider may have some active
    205   // notification observers, it is essential that it gets destroyed before the
    206   // NotificationService. NotificationService won't be destroyed until after
    207   // this destructor is run.
    208   automation_provider_list_.reset();
    209 #endif
    210 
    211   // We need to shutdown the SdchDictionaryFetcher as it regularly holds
    212   // a pointer to a URLFetcher, and that URLFetcher (upon destruction) will do
    213   // a PostDelayedTask onto the IO thread.  This shutdown call will both discard
    214   // any pending URLFetchers, and avoid creating any more.
    215   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
    216                           base::Bind(&SdchDictionaryFetcher::Shutdown));
    217 
    218   // We need to destroy the MetricsService, VariationsService,
    219   // IntranetRedirectDetector, PromoResourceService, and SafeBrowsing
    220   // ClientSideDetectionService (owned by the SafeBrowsingService) before the
    221   // io_thread_ gets destroyed, since their destructors can call the URLFetcher
    222   // destructor, which does a PostDelayedTask operation on the IO thread. (The
    223   // IO thread will handle that URLFetcher operation before going away.)
    224   metrics_service_.reset();
    225   variations_service_.reset();
    226   intranet_redirect_detector_.reset();
    227 #if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING)
    228   if (safe_browsing_service_.get())
    229     safe_browsing_service()->ShutDown();
    230 #endif
    231 
    232   // Need to clear the desktop notification balloons before the io_thread_ and
    233   // before the profiles, since if there are any still showing we will access
    234   // those things during teardown.
    235   notification_ui_manager_.reset();
    236 
    237   // Need to clear profiles (download managers) before the io_thread_.
    238   profile_manager_.reset();
    239 
    240 #if !defined(OS_ANDROID)
    241   // Debugger must be cleaned up before IO thread and NotificationService.
    242   remote_debugging_server_.reset();
    243 #endif
    244 
    245   ExtensionRendererState::GetInstance()->Shutdown();
    246 
    247 #if !defined(OS_ANDROID) && !defined(OS_IOS)
    248   media_file_system_registry_.reset();
    249   // Delete |storage_monitor_| now. Otherwise the FILE thread would be gone
    250   // when we try to release it in the dtor and Valgrind would report a
    251   // leak on almost every single browser_test.
    252   // TODO(gbillock): Make this unnecessary.
    253   storage_monitor_.reset();
    254 #endif
    255 
    256   message_center::MessageCenter::Shutdown();
    257 
    258 #if defined(ENABLE_CONFIGURATION_POLICY)
    259   // The policy providers managed by |browser_policy_connector_| need to shut
    260   // down while the IO and FILE threads are still alive.
    261   if (browser_policy_connector_)
    262     browser_policy_connector_->Shutdown();
    263 #endif
    264 
    265   // Stop the watchdog thread before stopping other threads.
    266   watchdog_thread_.reset();
    267 
    268 #if defined(USE_AURA)
    269   // Delete aura after the metrics service has been deleted as it accesses
    270   // monitor information.
    271   aura::Env::DeleteInstance();
    272 #endif
    273 
    274   platform_part()->StartTearDown();
    275 }
    276 
    277 void BrowserProcessImpl::PostDestroyThreads() {
    278   // With the file_thread_ flushed, we can release any icon resources.
    279   icon_manager_.reset();
    280 
    281   // Reset associated state right after actual thread is stopped,
    282   // as io_thread_.global_ cleanup happens in CleanUp on the IO
    283   // thread, i.e. as the thread exits its message loop.
    284   //
    285   // This is important also because in various places, the
    286   // IOThread object being NULL is considered synonymous with the
    287   // IO thread having stopped.
    288   io_thread_.reset();
    289 }
    290 
    291 #if defined(OS_WIN)
    292 // Send a QuitTask to the given MessageLoop when the (file) thread has processed
    293 // our (other) recent requests (to save preferences).
    294 // Change the boolean so that the receiving thread will know that we did indeed
    295 // send the QuitTask that terminated the message loop.
    296 static void PostQuit(base::MessageLoop* message_loop) {
    297   g_end_session_file_thread_has_completed = true;
    298   message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
    299 }
    300 #elif defined(USE_X11)
    301 static void Signal(base::WaitableEvent* event) {
    302   event->Signal();
    303 }
    304 #endif
    305 
    306 unsigned int BrowserProcessImpl::AddRefModule() {
    307   DCHECK(CalledOnValidThread());
    308 
    309   // CHECK(!IsShuttingDown());
    310   if (IsShuttingDown()) {
    311     // Copy the stacktrace which released the final reference onto our stack so
    312     // it will be available in the crash report for inspection.
    313     base::debug::StackTrace callstack = release_last_reference_callstack_;
    314     base::debug::Alias(&callstack);
    315     CHECK(false);
    316   }
    317 
    318   did_start_ = true;
    319   module_ref_count_++;
    320   return module_ref_count_;
    321 }
    322 
    323 unsigned int BrowserProcessImpl::ReleaseModule() {
    324   DCHECK(CalledOnValidThread());
    325   DCHECK_NE(0u, module_ref_count_);
    326   module_ref_count_--;
    327   if (0 == module_ref_count_) {
    328     release_last_reference_callstack_ = base::debug::StackTrace();
    329 
    330 #if defined(ENABLE_PRINTING)
    331     // Wait for the pending print jobs to finish. Don't do this later, since
    332     // this might cause a nested message loop to run, and we don't want pending
    333     // tasks to run once teardown has started.
    334     print_job_manager_->OnQuit();
    335     print_job_manager_.reset();
    336 #endif
    337 
    338     CHECK(base::MessageLoop::current()->is_running());
    339 
    340 #if defined(OS_MACOSX)
    341     base::MessageLoop::current()->PostTask(
    342         FROM_HERE,
    343         base::Bind(ChromeBrowserMainPartsMac::DidEndMainMessageLoop));
    344 #endif
    345     base::MessageLoop::current()->Quit();
    346   }
    347   return module_ref_count_;
    348 }
    349 
    350 void BrowserProcessImpl::EndSession() {
    351   // Mark all the profiles as clean.
    352   ProfileManager* pm = profile_manager();
    353   std::vector<Profile*> profiles(pm->GetLoadedProfiles());
    354   for (size_t i = 0; i < profiles.size(); ++i)
    355     profiles[i]->SetExitType(Profile::EXIT_SESSION_ENDED);
    356 
    357   // Tell the metrics service it was cleanly shutdown.
    358   MetricsService* metrics = g_browser_process->metrics_service();
    359   if (metrics && local_state()) {
    360     metrics->RecordStartOfSessionEnd();
    361 
    362     // MetricsService lazily writes to prefs, force it to write now.
    363     local_state()->CommitPendingWrite();
    364   }
    365 
    366   // http://crbug.com/125207
    367   base::ThreadRestrictions::ScopedAllowWait allow_wait;
    368 
    369   // We must write that the profile and metrics service shutdown cleanly,
    370   // otherwise on startup we'll think we crashed. So we block until done and
    371   // then proceed with normal shutdown.
    372 #if defined(USE_X11)
    373   //  Can't run a local loop on linux. Instead create a waitable event.
    374   scoped_ptr<base::WaitableEvent> done_writing(
    375       new base::WaitableEvent(false, false));
    376   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
    377       base::Bind(Signal, done_writing.get()));
    378   // If all file writes haven't cleared in the timeout, leak the WaitableEvent
    379   // so that there's no race to reference it in Signal().
    380   if (!done_writing->TimedWait(
    381       base::TimeDelta::FromSeconds(kEndSessionTimeoutSeconds))) {
    382     ignore_result(done_writing.release());
    383   }
    384 
    385 #elif defined(OS_WIN)
    386   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
    387       base::Bind(PostQuit, base::MessageLoop::current()));
    388   int quits_received = 0;
    389   do {
    390     base::MessageLoop::current()->Run();
    391     ++quits_received;
    392   } while (!g_end_session_file_thread_has_completed);
    393   // If we did get extra quits, then we should re-post them to the message loop.
    394   while (--quits_received > 0) {
    395     base::MessageLoop::current()->PostTask(FROM_HERE,
    396                                            base::MessageLoop::QuitClosure());
    397   }
    398 #else
    399   NOTIMPLEMENTED();
    400 #endif
    401 }
    402 
    403 MetricsService* BrowserProcessImpl::metrics_service() {
    404   DCHECK(CalledOnValidThread());
    405   if (!created_metrics_service_)
    406     CreateMetricsService();
    407   return metrics_service_.get();
    408 }
    409 
    410 IOThread* BrowserProcessImpl::io_thread() {
    411   DCHECK(CalledOnValidThread());
    412   DCHECK(io_thread_.get());
    413   return io_thread_.get();
    414 }
    415 
    416 WatchDogThread* BrowserProcessImpl::watchdog_thread() {
    417   DCHECK(CalledOnValidThread());
    418   if (!created_watchdog_thread_)
    419     CreateWatchdogThread();
    420   DCHECK(watchdog_thread_.get() != NULL);
    421   return watchdog_thread_.get();
    422 }
    423 
    424 ProfileManager* BrowserProcessImpl::profile_manager() {
    425   DCHECK(CalledOnValidThread());
    426   if (!created_profile_manager_)
    427     CreateProfileManager();
    428   return profile_manager_.get();
    429 }
    430 
    431 PrefService* BrowserProcessImpl::local_state() {
    432   DCHECK(CalledOnValidThread());
    433   if (!created_local_state_)
    434     CreateLocalState();
    435   return local_state_.get();
    436 }
    437 
    438 net::URLRequestContextGetter* BrowserProcessImpl::system_request_context() {
    439   DCHECK(CalledOnValidThread());
    440   return io_thread()->system_url_request_context_getter();
    441 }
    442 
    443 chrome_variations::VariationsService* BrowserProcessImpl::variations_service() {
    444   DCHECK(CalledOnValidThread());
    445   if (!variations_service_.get()) {
    446     variations_service_.reset(
    447         chrome_variations::VariationsService::Create(local_state()));
    448   }
    449   return variations_service_.get();
    450 }
    451 
    452 BrowserProcessPlatformPart* BrowserProcessImpl::platform_part() {
    453   return platform_part_.get();
    454 }
    455 
    456 extensions::EventRouterForwarder*
    457 BrowserProcessImpl::extension_event_router_forwarder() {
    458   return extension_event_router_forwarder_.get();
    459 }
    460 
    461 NotificationUIManager* BrowserProcessImpl::notification_ui_manager() {
    462   DCHECK(CalledOnValidThread());
    463   if (!created_notification_ui_manager_)
    464     CreateNotificationUIManager();
    465   return notification_ui_manager_.get();
    466 }
    467 
    468 message_center::MessageCenter* BrowserProcessImpl::message_center() {
    469   DCHECK(CalledOnValidThread());
    470   return message_center::MessageCenter::Get();
    471 }
    472 
    473 policy::BrowserPolicyConnector* BrowserProcessImpl::browser_policy_connector() {
    474   DCHECK(CalledOnValidThread());
    475 #if defined(ENABLE_CONFIGURATION_POLICY)
    476   if (!created_browser_policy_connector_) {
    477     DCHECK(!browser_policy_connector_);
    478     browser_policy_connector_.reset(new policy::BrowserPolicyConnector());
    479     created_browser_policy_connector_ = true;
    480   }
    481   return browser_policy_connector_.get();
    482 #else
    483   return NULL;
    484 #endif
    485 }
    486 
    487 policy::PolicyService* BrowserProcessImpl::policy_service() {
    488 #if defined(ENABLE_CONFIGURATION_POLICY)
    489   return browser_policy_connector()->GetPolicyService();
    490 #else
    491   if (!policy_service_.get())
    492     policy_service_.reset(new policy::PolicyServiceStub());
    493   return policy_service_.get();
    494 #endif
    495 }
    496 
    497 IconManager* BrowserProcessImpl::icon_manager() {
    498   DCHECK(CalledOnValidThread());
    499   if (!created_icon_manager_)
    500     CreateIconManager();
    501   return icon_manager_.get();
    502 }
    503 
    504 GLStringManager* BrowserProcessImpl::gl_string_manager() {
    505   DCHECK(CalledOnValidThread());
    506   if (!gl_string_manager_.get())
    507     gl_string_manager_.reset(new GLStringManager());
    508   return gl_string_manager_.get();
    509 }
    510 
    511 GpuModeManager* BrowserProcessImpl::gpu_mode_manager() {
    512   DCHECK(CalledOnValidThread());
    513   if (!gpu_mode_manager_.get())
    514     gpu_mode_manager_.reset(new GpuModeManager());
    515   return gpu_mode_manager_.get();
    516 }
    517 
    518 RenderWidgetSnapshotTaker* BrowserProcessImpl::GetRenderWidgetSnapshotTaker() {
    519   return render_widget_snapshot_taker_.get();
    520 }
    521 
    522 AutomationProviderList* BrowserProcessImpl::GetAutomationProviderList() {
    523   DCHECK(CalledOnValidThread());
    524 #if defined(ENABLE_AUTOMATION)
    525   if (automation_provider_list_.get() == NULL)
    526     automation_provider_list_.reset(new AutomationProviderList());
    527   return automation_provider_list_.get();
    528 #else
    529   return NULL;
    530 #endif
    531 }
    532 
    533 void BrowserProcessImpl::CreateDevToolsHttpProtocolHandler(
    534     chrome::HostDesktopType host_desktop_type,
    535     const std::string& ip,
    536     int port,
    537     const std::string& frontend_url) {
    538   DCHECK(CalledOnValidThread());
    539 #if !defined(OS_ANDROID)
    540   // StartupBrowserCreator::LaunchBrowser can be run multiple times when browser
    541   // is started with several profiles or existing browser process is reused.
    542   if (!remote_debugging_server_.get()) {
    543     remote_debugging_server_.reset(
    544         new RemoteDebuggingServer(host_desktop_type, ip, port,
    545                                   frontend_url));
    546   }
    547 #endif
    548 }
    549 
    550 bool BrowserProcessImpl::IsShuttingDown() {
    551   DCHECK(CalledOnValidThread());
    552   return did_start_ && 0 == module_ref_count_;
    553 }
    554 
    555 printing::PrintJobManager* BrowserProcessImpl::print_job_manager() {
    556   // TODO(abarth): DCHECK(CalledOnValidThread());
    557   // http://code.google.com/p/chromium/issues/detail?id=6828
    558   // print_job_manager_ is initialized in the constructor and destroyed in the
    559   // destructor, so it should always be valid.
    560   DCHECK(print_job_manager_.get());
    561   return print_job_manager_.get();
    562 }
    563 
    564 printing::PrintPreviewDialogController*
    565     BrowserProcessImpl::print_preview_dialog_controller() {
    566 #if defined(ENABLE_FULL_PRINTING)
    567   DCHECK(CalledOnValidThread());
    568   if (!print_preview_dialog_controller_.get())
    569     CreatePrintPreviewDialogController();
    570   return print_preview_dialog_controller_.get();
    571 #else
    572   NOTIMPLEMENTED();
    573   return NULL;
    574 #endif
    575 }
    576 
    577 printing::BackgroundPrintingManager*
    578     BrowserProcessImpl::background_printing_manager() {
    579 #if defined(ENABLE_FULL_PRINTING)
    580   DCHECK(CalledOnValidThread());
    581   if (!background_printing_manager_.get())
    582     CreateBackgroundPrintingManager();
    583   return background_printing_manager_.get();
    584 #else
    585   NOTIMPLEMENTED();
    586   return NULL;
    587 #endif
    588 }
    589 
    590 IntranetRedirectDetector* BrowserProcessImpl::intranet_redirect_detector() {
    591   DCHECK(CalledOnValidThread());
    592   if (!intranet_redirect_detector_.get())
    593     CreateIntranetRedirectDetector();
    594   return intranet_redirect_detector_.get();
    595 }
    596 
    597 const std::string& BrowserProcessImpl::GetApplicationLocale() {
    598   DCHECK(!locale_.empty());
    599   return locale_;
    600 }
    601 
    602 void BrowserProcessImpl::SetApplicationLocale(const std::string& locale) {
    603   locale_ = locale;
    604   extension_l10n_util::SetProcessLocale(locale);
    605   chrome::ChromeContentBrowserClient::SetApplicationLocale(locale);
    606 }
    607 
    608 DownloadStatusUpdater* BrowserProcessImpl::download_status_updater() {
    609   return download_status_updater_.get();
    610 }
    611 
    612 BookmarkPromptController* BrowserProcessImpl::bookmark_prompt_controller() {
    613 #if defined(OS_ANDROID)
    614   return NULL;
    615 #else
    616   return bookmark_prompt_controller_.get();
    617 #endif
    618 }
    619 
    620 chrome::StorageMonitor* BrowserProcessImpl::storage_monitor() {
    621 #if defined(OS_ANDROID) || defined(OS_IOS)
    622   return NULL;
    623 #else
    624   return storage_monitor_.get();
    625 #endif
    626 }
    627 
    628 void BrowserProcessImpl::set_storage_monitor_for_test(
    629     scoped_ptr<chrome::StorageMonitor> monitor) {
    630 #if !defined(OS_ANDROID) && !defined(OS_IOS)
    631   storage_monitor_ = monitor.Pass();
    632 #endif
    633 }
    634 
    635 chrome::MediaFileSystemRegistry*
    636 BrowserProcessImpl::media_file_system_registry() {
    637 #if defined(OS_ANDROID) || defined(OS_IOS)
    638     return NULL;
    639 #else
    640   if (!media_file_system_registry_)
    641     media_file_system_registry_.reset(new chrome::MediaFileSystemRegistry());
    642   return media_file_system_registry_.get();
    643 #endif
    644 }
    645 
    646 bool BrowserProcessImpl::created_local_state() const {
    647     return created_local_state_;
    648 }
    649 
    650 #if defined(ENABLE_WEBRTC)
    651 WebRtcLogUploader* BrowserProcessImpl::webrtc_log_uploader() {
    652   if (!webrtc_log_uploader_.get())
    653     webrtc_log_uploader_.reset(new WebRtcLogUploader());
    654   return webrtc_log_uploader_.get();
    655 }
    656 #endif
    657 
    658 // static
    659 void BrowserProcessImpl::RegisterPrefs(PrefRegistrySimple* registry) {
    660   registry->RegisterBooleanPref(prefs::kDefaultBrowserSettingEnabled,
    661                                 false);
    662   // This policy needs to be defined before the net subsystem is initialized,
    663   // so we do it here.
    664   registry->RegisterIntegerPref(prefs::kMaxConnectionsPerProxy,
    665                                 net::kDefaultMaxSocketsPerProxyServer);
    666 
    667   registry->RegisterBooleanPref(prefs::kAllowCrossOriginAuthPrompt, false);
    668 
    669 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) || defined(OS_IOS)
    670   registry->RegisterBooleanPref(prefs::kEulaAccepted, false);
    671 #endif  // defined(OS_CHROMEOS) || defined(OS_ANDROID) || defined(OS_IOS)
    672 #if defined(OS_WIN)
    673   if (base::win::GetVersion() >= base::win::VERSION_WIN8)
    674     registry->RegisterBooleanPref(prefs::kRestartSwitchMode, false);
    675 #endif
    676 
    677   // TODO(brettw,*): this comment about ResourceBundle was here since
    678   // initial commit.  This comment seems unrelated, bit-rotten and
    679   // a candidate for removal.
    680   // Initialize ResourceBundle which handles files loaded from external
    681   // sources. This has to be done before uninstall code path and before prefs
    682   // are registered.
    683   registry->RegisterStringPref(prefs::kApplicationLocale, std::string());
    684 #if defined(OS_CHROMEOS)
    685   registry->RegisterStringPref(prefs::kOwnerLocale, std::string());
    686   registry->RegisterStringPref(prefs::kHardwareKeyboardLayout,
    687                                std::string());
    688 #endif  // defined(OS_CHROMEOS)
    689 #if !defined(OS_CHROMEOS)
    690   registry->RegisterBooleanPref(
    691       prefs::kMetricsReportingEnabled,
    692       GoogleUpdateSettings::GetCollectStatsConsent());
    693 #endif  // !defined(OS_CHROMEOS)
    694 
    695 #if defined(OS_ANDROID)
    696   registry->RegisterBooleanPref(
    697       prefs::kCrashReportingEnabled, false);
    698 #endif  // defined(OS_ANDROID)
    699 }
    700 
    701 DownloadRequestLimiter* BrowserProcessImpl::download_request_limiter() {
    702   DCHECK(CalledOnValidThread());
    703   if (!download_request_limiter_.get())
    704     download_request_limiter_ = new DownloadRequestLimiter();
    705   return download_request_limiter_.get();
    706 }
    707 
    708 BackgroundModeManager* BrowserProcessImpl::background_mode_manager() {
    709   DCHECK(CalledOnValidThread());
    710 #if defined(ENABLE_BACKGROUND)
    711   if (!background_mode_manager_.get())
    712     CreateBackgroundModeManager();
    713   return background_mode_manager_.get();
    714 #else
    715   NOTIMPLEMENTED();
    716   return NULL;
    717 #endif
    718 }
    719 
    720 void BrowserProcessImpl::set_background_mode_manager_for_test(
    721     scoped_ptr<BackgroundModeManager> manager) {
    722   background_mode_manager_ = manager.Pass();
    723 }
    724 
    725 StatusTray* BrowserProcessImpl::status_tray() {
    726   DCHECK(CalledOnValidThread());
    727   if (!status_tray_.get())
    728     CreateStatusTray();
    729   return status_tray_.get();
    730 }
    731 
    732 
    733 SafeBrowsingService* BrowserProcessImpl::safe_browsing_service() {
    734   DCHECK(CalledOnValidThread());
    735   if (!created_safe_browsing_service_)
    736     CreateSafeBrowsingService();
    737   return safe_browsing_service_.get();
    738 }
    739 
    740 safe_browsing::ClientSideDetectionService*
    741     BrowserProcessImpl::safe_browsing_detection_service() {
    742   DCHECK(CalledOnValidThread());
    743   if (safe_browsing_service())
    744     return safe_browsing_service()->safe_browsing_detection_service();
    745   return NULL;
    746 }
    747 
    748 #if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS)
    749 void BrowserProcessImpl::StartAutoupdateTimer() {
    750   autoupdate_timer_.Start(FROM_HERE,
    751       base::TimeDelta::FromHours(kUpdateCheckIntervalHours),
    752       this,
    753       &BrowserProcessImpl::OnAutoupdateTimer);
    754 }
    755 #endif
    756 
    757 ChromeNetLog* BrowserProcessImpl::net_log() {
    758   return net_log_.get();
    759 }
    760 
    761 prerender::PrerenderTracker* BrowserProcessImpl::prerender_tracker() {
    762   if (!prerender_tracker_.get())
    763     prerender_tracker_.reset(new prerender::PrerenderTracker);
    764 
    765   return prerender_tracker_.get();
    766 }
    767 
    768 ComponentUpdateService* BrowserProcessImpl::component_updater() {
    769   if (!component_updater_.get()) {
    770     ComponentUpdateService::Configurator* configurator =
    771         MakeChromeComponentUpdaterConfigurator(
    772             CommandLine::ForCurrentProcess(),
    773             io_thread()->system_url_request_context_getter());
    774     // Creating the component updater does not do anything, components
    775     // need to be registered and Start() needs to be called.
    776     component_updater_.reset(ComponentUpdateServiceFactory(configurator));
    777   }
    778   return component_updater_.get();
    779 }
    780 
    781 CRLSetFetcher* BrowserProcessImpl::crl_set_fetcher() {
    782   if (!crl_set_fetcher_.get())
    783     crl_set_fetcher_ = new CRLSetFetcher();
    784   return crl_set_fetcher_.get();
    785 }
    786 
    787 PnaclComponentInstaller* BrowserProcessImpl::pnacl_component_installer() {
    788   if (!pnacl_component_installer_.get())
    789     pnacl_component_installer_.reset(new PnaclComponentInstaller());
    790   return pnacl_component_installer_.get();
    791 }
    792 
    793 void BrowserProcessImpl::ResourceDispatcherHostCreated() {
    794   resource_dispatcher_host_delegate_.reset(
    795       new ChromeResourceDispatcherHostDelegate(prerender_tracker()));
    796   ResourceDispatcherHost::Get()->SetDelegate(
    797       resource_dispatcher_host_delegate_.get());
    798 
    799   pref_change_registrar_.Add(
    800       prefs::kAllowCrossOriginAuthPrompt,
    801       base::Bind(&BrowserProcessImpl::ApplyAllowCrossOriginAuthPromptPolicy,
    802                  base::Unretained(this)));
    803   ApplyAllowCrossOriginAuthPromptPolicy();
    804 }
    805 
    806 void BrowserProcessImpl::CreateMetricsService() {
    807   DCHECK(!created_metrics_service_ && metrics_service_.get() == NULL);
    808   created_metrics_service_ = true;
    809 
    810   metrics_service_.reset(new MetricsService);
    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   base::FilePath user_data_dir;
    828   PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
    829   profile_manager_.reset(new ProfileManager(user_data_dir));
    830 }
    831 
    832 void BrowserProcessImpl::CreateLocalState() {
    833   DCHECK(!created_local_state_ && local_state_.get() == NULL);
    834   created_local_state_ = true;
    835 
    836   base::FilePath local_state_path;
    837   CHECK(PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path));
    838   scoped_refptr<PrefRegistrySimple> pref_registry = new PrefRegistrySimple;
    839 
    840   // Register local state preferences.
    841   chrome::RegisterLocalState(pref_registry.get());
    842 
    843   local_state_.reset(
    844       chrome_prefs::CreateLocalState(local_state_path,
    845                                      local_state_task_runner_.get(),
    846                                      policy_service(),
    847                                      NULL,
    848                                      pref_registry,
    849                                      false));
    850 
    851   pref_change_registrar_.Init(local_state_.get());
    852 
    853   // Initialize the notification for the default browser setting policy.
    854   pref_change_registrar_.Add(
    855       prefs::kDefaultBrowserSettingEnabled,
    856       base::Bind(&BrowserProcessImpl::ApplyDefaultBrowserPolicy,
    857                  base::Unretained(this)));
    858 
    859   int max_per_proxy = local_state_->GetInteger(prefs::kMaxConnectionsPerProxy);
    860   net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(
    861       net::HttpNetworkSession::NORMAL_SOCKET_POOL,
    862       std::max(std::min(max_per_proxy, 99),
    863                net::ClientSocketPoolManager::max_sockets_per_group(
    864                    net::HttpNetworkSession::NORMAL_SOCKET_POOL)));
    865 }
    866 
    867 void BrowserProcessImpl::PreCreateThreads() {
    868   io_thread_.reset(new IOThread(local_state(), policy_service(), net_log_.get(),
    869                                 extension_event_router_forwarder_.get()));
    870 }
    871 
    872 void BrowserProcessImpl::PreMainMessageLoopRun() {
    873 #if defined(ENABLE_CONFIGURATION_POLICY)
    874   // browser_policy_connector() is created very early because local_state()
    875   // needs policy to be initialized with the managed preference values.
    876   // However, policy fetches from the network and loading of disk caches
    877   // requires that threads are running; this Init() call lets the connector
    878   // resume its initialization now that the loops are spinning and the
    879   // system request context is available for the fetchers.
    880   browser_policy_connector()->Init(local_state(), system_request_context());
    881 #endif
    882 
    883   if (local_state_->IsManagedPreference(prefs::kDefaultBrowserSettingEnabled))
    884     ApplyDefaultBrowserPolicy();
    885 
    886 #if defined(ENABLE_PLUGINS)
    887   PluginService* plugin_service = PluginService::GetInstance();
    888   plugin_service->SetFilter(ChromePluginServiceFilter::GetInstance());
    889   plugin_service->StartWatchingPlugins();
    890 
    891 #if defined(OS_POSIX)
    892   // Also find plugins in a user-specific plugins dir,
    893   // e.g. ~/.config/chromium/Plugins.
    894   const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
    895   if (!cmd_line.HasSwitch(switches::kDisablePluginsDiscovery)) {
    896     base::FilePath user_data_dir;
    897     if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
    898       plugin_service->AddExtraPluginDir(user_data_dir.Append("Plugins"));
    899   }
    900 #endif
    901 
    902   // Triggers initialization of the singleton instance on UI thread.
    903   PluginFinder::GetInstance()->Init();
    904 
    905 #if defined(ENABLE_PLUGIN_INSTALLATION)
    906   DCHECK(!plugins_resource_service_.get());
    907   plugins_resource_service_ = new PluginsResourceService(local_state());
    908   plugins_resource_service_->Init();
    909 #endif
    910 #endif  // defined(ENABLE_PLUGINS)
    911 
    912   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    913   if (!command_line.HasSwitch(switches::kDisableWebResources)) {
    914     DCHECK(!promo_resource_service_.get());
    915     promo_resource_service_ = new PromoResourceService;
    916     promo_resource_service_->StartAfterDelay();
    917   }
    918 
    919 #if !defined(OS_ANDROID)
    920   if (browser_defaults::bookmarks_enabled &&
    921       BookmarkPromptController::IsEnabled()) {
    922     bookmark_prompt_controller_.reset(new BookmarkPromptController());
    923   }
    924 #endif
    925 
    926 #if !defined(OS_ANDROID) && !defined(OS_IOS)
    927   storage_monitor_.reset(chrome::StorageMonitor::Create());
    928 #endif
    929 
    930   platform_part_->PreMainMessageLoopRun();
    931 }
    932 
    933 void BrowserProcessImpl::CreateIconManager() {
    934   DCHECK(!created_icon_manager_ && icon_manager_.get() == NULL);
    935   created_icon_manager_ = true;
    936   icon_manager_.reset(new IconManager);
    937 }
    938 
    939 void BrowserProcessImpl::CreateIntranetRedirectDetector() {
    940   DCHECK(intranet_redirect_detector_.get() == NULL);
    941   scoped_ptr<IntranetRedirectDetector> intranet_redirect_detector(
    942       new IntranetRedirectDetector);
    943   intranet_redirect_detector_.swap(intranet_redirect_detector);
    944 }
    945 
    946 void BrowserProcessImpl::CreateNotificationUIManager() {
    947 #if defined(ENABLE_NOTIFICATIONS)
    948   DCHECK(notification_ui_manager_.get() == NULL);
    949   notification_ui_manager_.reset(NotificationUIManager::Create(local_state()));
    950   created_notification_ui_manager_ = true;
    951 #endif
    952 }
    953 
    954 void BrowserProcessImpl::CreateBackgroundModeManager() {
    955   DCHECK(background_mode_manager_.get() == NULL);
    956   background_mode_manager_.reset(
    957       new BackgroundModeManager(CommandLine::ForCurrentProcess(),
    958                                 &profile_manager()->GetProfileInfoCache()));
    959 }
    960 
    961 void BrowserProcessImpl::CreateStatusTray() {
    962   DCHECK(status_tray_.get() == NULL);
    963   status_tray_.reset(StatusTray::Create());
    964 }
    965 
    966 void BrowserProcessImpl::CreatePrintPreviewDialogController() {
    967 #if defined(ENABLE_FULL_PRINTING)
    968   DCHECK(print_preview_dialog_controller_.get() == NULL);
    969   print_preview_dialog_controller_ =
    970       new printing::PrintPreviewDialogController();
    971 #else
    972   NOTIMPLEMENTED();
    973 #endif
    974 }
    975 
    976 void BrowserProcessImpl::CreateBackgroundPrintingManager() {
    977 #if defined(ENABLE_FULL_PRINTING)
    978   DCHECK(background_printing_manager_.get() == NULL);
    979   background_printing_manager_.reset(new printing::BackgroundPrintingManager());
    980 #else
    981   NOTIMPLEMENTED();
    982 #endif
    983 }
    984 
    985 void BrowserProcessImpl::CreateSafeBrowsingService() {
    986   DCHECK(safe_browsing_service_.get() == NULL);
    987   // Set this flag to true so that we don't retry indefinitely to
    988   // create the service class if there was an error.
    989   created_safe_browsing_service_ = true;
    990 #if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING)
    991   safe_browsing_service_ = SafeBrowsingService::CreateSafeBrowsingService();
    992   safe_browsing_service_->Initialize();
    993 #endif
    994 }
    995 
    996 void BrowserProcessImpl::ApplyDefaultBrowserPolicy() {
    997   if (local_state()->GetBoolean(prefs::kDefaultBrowserSettingEnabled)) {
    998     scoped_refptr<ShellIntegration::DefaultWebClientWorker>
    999         set_browser_worker = new ShellIntegration::DefaultBrowserWorker(NULL);
   1000     set_browser_worker->StartSetAsDefault();
   1001   }
   1002 }
   1003 
   1004 void BrowserProcessImpl::ApplyAllowCrossOriginAuthPromptPolicy() {
   1005   bool value = local_state()->GetBoolean(prefs::kAllowCrossOriginAuthPrompt);
   1006   ResourceDispatcherHost::Get()->SetAllowCrossOriginAuthPrompt(value);
   1007 }
   1008 
   1009 // Mac is currently not supported.
   1010 #if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS)
   1011 
   1012 bool BrowserProcessImpl::CanAutorestartForUpdate() const {
   1013   // Check if browser is in the background and if it needs to be restarted to
   1014   // apply a pending update.
   1015   return chrome::GetTotalBrowserCount() == 0 && chrome::WillKeepAlive() &&
   1016          upgrade_util::IsUpdatePendingRestart();
   1017 }
   1018 
   1019 // Switches to add when auto-restarting Chrome.
   1020 const char* const kSwitchesToAddOnAutorestart[] = {
   1021   switches::kNoStartupWindow
   1022 };
   1023 
   1024 void BrowserProcessImpl::RestartBackgroundInstance() {
   1025   CommandLine* old_cl = CommandLine::ForCurrentProcess();
   1026   scoped_ptr<CommandLine> new_cl(new CommandLine(old_cl->GetProgram()));
   1027 
   1028   std::map<std::string, CommandLine::StringType> switches =
   1029       old_cl->GetSwitches();
   1030 
   1031   switches::RemoveSwitchesForAutostart(&switches);
   1032 
   1033   // Append the rest of the switches (along with their values, if any)
   1034   // to the new command line
   1035   for (std::map<std::string, CommandLine::StringType>::const_iterator i =
   1036       switches.begin(); i != switches.end(); ++i) {
   1037       CommandLine::StringType switch_value = i->second;
   1038       if (switch_value.length() > 0) {
   1039         new_cl->AppendSwitchNative(i->first, i->second);
   1040       } else {
   1041         new_cl->AppendSwitch(i->first);
   1042       }
   1043   }
   1044 
   1045   // Ensure that our desired switches are set on the new process.
   1046   for (size_t i = 0; i < arraysize(kSwitchesToAddOnAutorestart); ++i) {
   1047     if (!new_cl->HasSwitch(kSwitchesToAddOnAutorestart[i]))
   1048       new_cl->AppendSwitch(kSwitchesToAddOnAutorestart[i]);
   1049   }
   1050 
   1051   DLOG(WARNING) << "Shutting down current instance of the browser.";
   1052   chrome::AttemptExit();
   1053 
   1054   // Transfer ownership to Upgrade.
   1055   upgrade_util::SetNewCommandLine(new_cl.release());
   1056 }
   1057 
   1058 void BrowserProcessImpl::OnAutoupdateTimer() {
   1059   if (CanAutorestartForUpdate()) {
   1060     DLOG(WARNING) << "Detected update.  Restarting browser.";
   1061     RestartBackgroundInstance();
   1062   }
   1063 }
   1064 
   1065 #endif  // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS)
   1066