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