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
BrowserProcessImpl(const CommandLine & command_line)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
~BrowserProcessImpl()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.
PostQuit(MessageLoop * message_loop)287 static void PostQuit(MessageLoop* message_loop) {
288 message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask());
289 }
290 #elif defined(USE_X11)
Signal(base::WaitableEvent * event)291 static void Signal(base::WaitableEvent* event) {
292 event->Signal();
293 }
294 #endif
295
AddRefModule()296 unsigned int BrowserProcessImpl::AddRefModule() {
297 DCHECK(CalledOnValidThread());
298 did_start_ = true;
299 module_ref_count_++;
300 return module_ref_count_;
301 }
302
ReleaseModule()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
EndSession()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
resource_dispatcher_host()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
metrics_service()368 MetricsService* BrowserProcessImpl::metrics_service() {
369 DCHECK(CalledOnValidThread());
370 if (!created_metrics_service_)
371 CreateMetricsService();
372 return metrics_service_.get();
373 }
374
io_thread()375 IOThread* BrowserProcessImpl::io_thread() {
376 DCHECK(CalledOnValidThread());
377 if (!created_io_thread_)
378 CreateIOThread();
379 return io_thread_.get();
380 }
381
file_thread()382 base::Thread* BrowserProcessImpl::file_thread() {
383 DCHECK(CalledOnValidThread());
384 if (!created_file_thread_)
385 CreateFileThread();
386 return file_thread_.get();
387 }
388
db_thread()389 base::Thread* BrowserProcessImpl::db_thread() {
390 DCHECK(CalledOnValidThread());
391 if (!created_db_thread_)
392 CreateDBThread();
393 return db_thread_.get();
394 }
395
process_launcher_thread()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
cache_thread()403 base::Thread* BrowserProcessImpl::cache_thread() {
404 DCHECK(CalledOnValidThread());
405 if (!created_cache_thread_)
406 CreateCacheThread();
407 return cache_thread_.get();
408 }
409
gpu_thread()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)
background_x11_thread()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
watchdog_thread()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
profile_manager()435 ProfileManager* BrowserProcessImpl::profile_manager() {
436 DCHECK(CalledOnValidThread());
437 if (!created_profile_manager_)
438 CreateProfileManager();
439 return profile_manager_.get();
440 }
441
local_state()442 PrefService* BrowserProcessImpl::local_state() {
443 DCHECK(CalledOnValidThread());
444 if (!created_local_state_)
445 CreateLocalState();
446 return local_state_.get();
447 }
448
devtools_manager()449 DevToolsManager* BrowserProcessImpl::devtools_manager() {
450 DCHECK(CalledOnValidThread());
451 if (!created_devtools_manager_)
452 CreateDevToolsManager();
453 return devtools_manager_.get();
454 }
455
sidebar_manager()456 SidebarManager* BrowserProcessImpl::sidebar_manager() {
457 DCHECK(CalledOnValidThread());
458 if (!created_sidebar_manager_)
459 CreateSidebarManager();
460 return sidebar_manager_.get();
461 }
462
clipboard()463 ui::Clipboard* BrowserProcessImpl::clipboard() {
464 DCHECK(CalledOnValidThread());
465 return clipboard_.get();
466 }
467
system_request_context()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*
chromeos_proxy_config_service_impl()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*
extension_event_router_forwarder()486 BrowserProcessImpl::extension_event_router_forwarder() {
487 return extension_event_router_forwarder_.get();
488 }
489
notification_ui_manager()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
browser_policy_connector()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
icon_manager()507 IconManager* BrowserProcessImpl::icon_manager() {
508 DCHECK(CalledOnValidThread());
509 if (!created_icon_manager_)
510 CreateIconManager();
511 return icon_manager_.get();
512 }
513
GetThumbnailGenerator()514 ThumbnailGenerator* BrowserProcessImpl::GetThumbnailGenerator() {
515 return &thumbnail_generator_;
516 }
517
InitAutomationProviderList()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
InitDevToolsHttpProtocolHandler(const std::string & ip,int port,const std::string & frontend_url)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
InitDevToolsLegacyProtocolHandler(int port)538 void BrowserProcessImpl::InitDevToolsLegacyProtocolHandler(int port) {
539 DCHECK(CalledOnValidThread());
540 devtools_legacy_handler_ = DevToolsProtocolHandler::Start(port);
541 }
542
IsShuttingDown()543 bool BrowserProcessImpl::IsShuttingDown() {
544 DCHECK(CalledOnValidThread());
545 return did_start_ && 0 == module_ref_count_;
546 }
547
print_job_manager()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*
print_preview_tab_controller()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
google_url_tracker()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
intranet_redirect_detector()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
GetApplicationLocale()579 const std::string& BrowserProcessImpl::GetApplicationLocale() {
580 DCHECK(!locale_.empty());
581 return locale_;
582 }
583
SetApplicationLocale(const std::string & locale)584 void BrowserProcessImpl::SetApplicationLocale(const std::string& locale) {
585 locale_ = locale;
586 extension_l10n_util::SetProcessLocale(locale);
587 }
588
download_status_updater()589 DownloadStatusUpdater* BrowserProcessImpl::download_status_updater() {
590 return &download_status_updater_;
591 }
592
shutdown_event()593 base::WaitableEvent* BrowserProcessImpl::shutdown_event() {
594 return shutdown_event_.get();
595 }
596
tab_closeable_state_watcher()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*
safe_browsing_detection_service()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
plugin_finder_disabled() const613 bool BrowserProcessImpl::plugin_finder_disabled() const {
614 return *plugin_finder_disabled_pref_;
615 }
616
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)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
WaitForPluginDataRemoverToFinish()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)
StartAutoupdateTimer()651 void BrowserProcessImpl::StartAutoupdateTimer() {
652 autoupdate_timer_.Start(
653 base::TimeDelta::FromHours(kUpdateCheckIntervalHours),
654 this,
655 &BrowserProcessImpl::OnAutoupdateTimer);
656 }
657 #endif
658
net_log()659 ChromeNetLog* BrowserProcessImpl::net_log() {
660 return net_log_.get();
661 }
662
ClearLocalState(const FilePath & profile_path)663 void BrowserProcessImpl::ClearLocalState(const FilePath& profile_path) {
664 webkit_database::DatabaseTracker::ClearLocalState(profile_path);
665 }
666
ShouldClearLocalState(FilePath * profile_path)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
CreateResourceDispatcherHost()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
CreateMetricsService()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
CreateIOThread()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
CreateFileThread()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
CreateDBThread()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
CreateProcessLauncherThread()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
CreateCacheThread()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
CreateGpuThread()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
CreateWatchdogThread()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
CreateProfileManager()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
CreateLocalState()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
CreateIconManager()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
CreateDevToolsManager()892 void BrowserProcessImpl::CreateDevToolsManager() {
893 DCHECK(devtools_manager_.get() == NULL);
894 created_devtools_manager_ = true;
895 devtools_manager_ = new DevToolsManager();
896 }
897
CreateSidebarManager()898 void BrowserProcessImpl::CreateSidebarManager() {
899 DCHECK(sidebar_manager_.get() == NULL);
900 created_sidebar_manager_ = true;
901 sidebar_manager_ = new SidebarManager();
902 }
903
CreateGoogleURLTracker()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
CreateIntranetRedirectDetector()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
CreateNotificationUIManager()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
CreateTabCloseableStateWatcher()924 void BrowserProcessImpl::CreateTabCloseableStateWatcher() {
925 DCHECK(tab_closeable_state_watcher_.get() == NULL);
926 tab_closeable_state_watcher_.reset(TabCloseableStateWatcher::Create());
927 }
928
CreatePrintPreviewTabController()929 void BrowserProcessImpl::CreatePrintPreviewTabController() {
930 DCHECK(print_preview_tab_controller_.get() == NULL);
931 print_preview_tab_controller_ = new printing::PrintPreviewTabController();
932 }
933
CreateSafeBrowsingDetectionService()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
IsSafeBrowsingDetectionServiceEnabled()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
ApplyDisabledSchemesPolicy()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
SetIPCLoggingEnabled(bool enable)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.
SetIPCLoggingEnabledForChildProcesses(bool enabled)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
CanAutorestartForUpdate() const1030 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
RestartPersistentInstance()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
OnAutoupdateTimer()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