profile_io_data.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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/profiles/profile_io_data.h"
6
7#include <string>
8
9#include "base/basictypes.h"
10#include "base/bind.h"
11#include "base/bind_helpers.h"
12#include "base/command_line.h"
13#include "base/compiler_specific.h"
14#include "base/logging.h"
15#include "base/stl_util.h"
16#include "base/string_number_conversions.h"
17#include "base/string_util.h"
18#include "base/stringprintf.h"
19#include "chrome/browser/browser_process.h"
20#include "chrome/browser/net/about_protocol_handler.h"
21#include "chrome/browser/content_settings/cookie_settings.h"
22#include "chrome/browser/content_settings/host_content_settings_map.h"
23#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
24#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
25#include "chrome/browser/download/download_service.h"
26#include "chrome/browser/download/download_service_factory.h"
27#include "chrome/browser/extensions/extension_info_map.h"
28#include "chrome/browser/extensions/extension_protocols.h"
29#include "chrome/browser/extensions/extension_resource_protocols.h"
30#include "chrome/browser/extensions/extension_system.h"
31#include "chrome/browser/io_thread.h"
32#include "chrome/browser/net/chrome_cookie_notification_details.h"
33#include "chrome/browser/net/chrome_fraudulent_certificate_reporter.h"
34#include "chrome/browser/net/chrome_http_user_agent_settings.h"
35#include "chrome/browser/net/chrome_net_log.h"
36#include "chrome/browser/net/chrome_network_delegate.h"
37#include "chrome/browser/net/http_server_properties_manager.h"
38#include "chrome/browser/net/load_time_stats.h"
39#include "chrome/browser/net/proxy_service_factory.h"
40#include "chrome/browser/net/resource_prefetch_predictor_observer.h"
41#include "chrome/browser/net/transport_security_persister.h"
42#include "chrome/browser/notifications/desktop_notification_service_factory.h"
43#include "chrome/browser/policy/url_blacklist_manager.h"
44#include "chrome/browser/predictors/resource_prefetch_predictor.h"
45#include "chrome/browser/predictors/resource_prefetch_predictor_factory.h"
46#include "chrome/browser/prefs/pref_service.h"
47#include "chrome/browser/profiles/profile.h"
48#include "chrome/browser/profiles/profile_manager.h"
49#include "chrome/browser/signin/signin_names_io_thread.h"
50#include "chrome/browser/ui/webui/chrome_url_data_manager_backend.h"
51#include "chrome/common/chrome_notification_types.h"
52#include "chrome/common/chrome_switches.h"
53#include "chrome/common/pref_names.h"
54#include "chrome/common/url_constants.h"
55#include "content/public/browser/browser_thread.h"
56#include "content/public/browser/host_zoom_map.h"
57#include "content/public/browser/notification_service.h"
58#include "content/public/browser/resource_context.h"
59#include "net/base/server_bound_cert_service.h"
60#include "net/cookies/canonical_cookie.h"
61#include "net/cookies/cookie_monster.h"
62#include "net/http/http_transaction_factory.h"
63#include "net/http/http_util.h"
64#include "net/proxy/proxy_config_service_fixed.h"
65#include "net/proxy/proxy_script_fetcher_impl.h"
66#include "net/proxy/proxy_service.h"
67#include "net/url_request/data_protocol_handler.h"
68#include "net/url_request/file_protocol_handler.h"
69#include "net/url_request/ftp_protocol_handler.h"
70#include "net/url_request/url_request.h"
71#include "net/url_request/url_request_job_factory_impl.h"
72
73#if !defined(OS_ANDROID)
74#include "chrome/browser/managed_mode/managed_mode.h"
75#endif
76
77#if defined(OS_CHROMEOS)
78#include "chrome/browser/chromeos/drive/drive_protocol_handler.h"
79#include "chrome/browser/chromeos/gview_request_interceptor.h"
80#include "chrome/browser/chromeos/proxy_config_service_impl.h"
81#include "chrome/browser/chromeos/settings/cros_settings.h"
82#include "chrome/browser/chromeos/settings/cros_settings_names.h"
83#endif  // defined(OS_CHROMEOS)
84
85using content::BrowserContext;
86using content::BrowserThread;
87using content::ResourceContext;
88
89namespace {
90
91// ----------------------------------------------------------------------------
92// CookieMonster::Delegate implementation
93// ----------------------------------------------------------------------------
94class ChromeCookieMonsterDelegate : public net::CookieMonster::Delegate {
95 public:
96  explicit ChromeCookieMonsterDelegate(
97      const base::Callback<Profile*(void)>& profile_getter)
98      : profile_getter_(profile_getter) {
99    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
100  }
101
102  // net::CookieMonster::Delegate implementation.
103  virtual void OnCookieChanged(
104      const net::CanonicalCookie& cookie,
105      bool removed,
106      net::CookieMonster::Delegate::ChangeCause cause) {
107    BrowserThread::PostTask(
108        BrowserThread::UI, FROM_HERE,
109        base::Bind(&ChromeCookieMonsterDelegate::OnCookieChangedAsyncHelper,
110                   this, cookie, removed, cause));
111  }
112
113 private:
114  virtual ~ChromeCookieMonsterDelegate() {}
115
116  void OnCookieChangedAsyncHelper(
117      const net::CanonicalCookie& cookie,
118      bool removed,
119      net::CookieMonster::Delegate::ChangeCause cause) {
120    Profile* profile = profile_getter_.Run();
121    if (profile) {
122      ChromeCookieDetails cookie_details(&cookie, removed, cause);
123      content::NotificationService::current()->Notify(
124          chrome::NOTIFICATION_COOKIE_CHANGED,
125          content::Source<Profile>(profile),
126          content::Details<ChromeCookieDetails>(&cookie_details));
127    }
128  }
129
130  const base::Callback<Profile*(void)> profile_getter_;
131};
132
133Profile* GetProfileOnUI(ProfileManager* profile_manager, Profile* profile) {
134  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
135  DCHECK(profile);
136  if (profile_manager->IsValidProfile(profile))
137    return profile;
138  return NULL;
139}
140
141}  // namespace
142
143void ProfileIOData::InitializeOnUIThread(Profile* profile) {
144  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
145  PrefService* pref_service = profile->GetPrefs();
146  PrefService* local_state_pref_service = g_browser_process->local_state();
147
148  scoped_ptr<ProfileParams> params(new ProfileParams);
149  params->path = profile->GetPath();
150
151  params->io_thread = g_browser_process->io_thread();
152
153  params->cookie_settings = CookieSettings::Factory::GetForProfile(profile);
154  params->ssl_config_service = profile->GetSSLConfigService();
155  base::Callback<Profile*(void)> profile_getter =
156      base::Bind(&GetProfileOnUI, g_browser_process->profile_manager(),
157                 profile);
158  params->cookie_monster_delegate =
159      new ChromeCookieMonsterDelegate(profile_getter);
160  params->extension_info_map =
161      extensions::ExtensionSystem::Get(profile)->info_map();
162
163  if (predictors::ResourcePrefetchPredictor* predictor =
164          predictors::ResourcePrefetchPredictorFactory::GetForProfile(
165              profile)) {
166    resource_prefetch_predictor_observer_.reset(
167        new chrome_browser_net::ResourcePrefetchPredictorObserver(predictor));
168  }
169
170#if defined(ENABLE_NOTIFICATIONS)
171  params->notification_service =
172      DesktopNotificationServiceFactory::GetForProfile(profile);
173#endif
174
175  ProtocolHandlerRegistry* protocol_handler_registry =
176      ProtocolHandlerRegistryFactory::GetForProfile(profile);
177  DCHECK(protocol_handler_registry);
178
179  // The profile instance is only available here in the InitializeOnUIThread
180  // method, so we create the url interceptor here, then save it for
181  // later delivery to the job factory in LazyInitialize.
182  params->protocol_handler_interceptor.reset(
183      protocol_handler_registry->CreateURLInterceptor());
184
185  ChromeProxyConfigService* proxy_config_service =
186      ProxyServiceFactory::CreateProxyConfigService(true);
187  params->proxy_config_service.reset(proxy_config_service);
188  profile->GetProxyConfigTracker()->SetChromeProxyConfigService(
189      proxy_config_service);
190  params->profile = profile;
191  profile_params_.reset(params.release());
192
193  ChromeNetworkDelegate::InitializePrefsOnUIThread(
194      &enable_referrers_,
195      &enable_do_not_track_,
196      &force_safesearch_,
197      pref_service);
198
199#if defined(ENABLE_PRINTING)
200  printing_enabled_.Init(prefs::kPrintingEnabled, pref_service, NULL);
201  printing_enabled_.MoveToThread(
202      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
203#endif
204  chrome_http_user_agent_settings_.reset(
205      new ChromeHttpUserAgentSettings(pref_service));
206
207  // These members are used only for one click sign in, which is not enabled
208  // in incognito mode.  So no need to initialize them.
209  if (!is_incognito()) {
210    signin_names_.reset(new SigninNamesOnIOThread());
211
212    google_services_username_.Init(prefs::kGoogleServicesUsername, pref_service,
213                                   NULL);
214    google_services_username_.MoveToThread(
215        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
216
217    google_services_username_pattern_.Init(
218        prefs::kGoogleServicesUsernamePattern, local_state_pref_service, NULL);
219    google_services_username_pattern_.MoveToThread(
220        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
221
222    reverse_autologin_enabled_.Init(
223        prefs::kReverseAutologinEnabled, pref_service, NULL);
224    reverse_autologin_enabled_.MoveToThread(
225        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
226
227    one_click_signin_rejected_email_list_.Init(
228        prefs::kReverseAutologinRejectedEmailList, pref_service, NULL);
229    one_click_signin_rejected_email_list_.MoveToThread(
230        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
231  }
232
233  // The URLBlacklistManager has to be created on the UI thread to register
234  // observers of |pref_service|, and it also has to clean up on
235  // ShutdownOnUIThread to release these observers on the right thread.
236  // Don't pass it in |profile_params_| to make sure it is correctly cleaned up,
237  // in particular when this ProfileIOData isn't |initialized_| during deletion.
238#if defined(ENABLE_CONFIGURATION_POLICY)
239  url_blacklist_manager_.reset(new policy::URLBlacklistManager(pref_service));
240#endif
241
242  initialized_on_UI_thread_ = true;
243
244  // We need to make sure that content initializes its own data structures that
245  // are associated with each ResourceContext because we might post this
246  // object to the IO thread after this function.
247  BrowserContext::EnsureResourceContextInitialized(profile);
248}
249
250ProfileIOData::MediaRequestContext::MediaRequestContext(
251    chrome_browser_net::LoadTimeStats* load_time_stats)
252    : ChromeURLRequestContext(ChromeURLRequestContext::CONTEXT_TYPE_MEDIA,
253                              load_time_stats) {
254}
255
256void ProfileIOData::MediaRequestContext::SetHttpTransactionFactory(
257    scoped_ptr<net::HttpTransactionFactory> http_factory) {
258  http_factory_ = http_factory.Pass();
259  set_http_transaction_factory(http_factory_.get());
260}
261
262ProfileIOData::MediaRequestContext::~MediaRequestContext() {}
263
264ProfileIOData::AppRequestContext::AppRequestContext(
265    chrome_browser_net::LoadTimeStats* load_time_stats)
266    : ChromeURLRequestContext(ChromeURLRequestContext::CONTEXT_TYPE_APP,
267                              load_time_stats) {
268}
269
270void ProfileIOData::AppRequestContext::SetCookieStore(
271    net::CookieStore* cookie_store) {
272  cookie_store_ = cookie_store;
273  set_cookie_store(cookie_store);
274}
275
276void ProfileIOData::AppRequestContext::SetHttpTransactionFactory(
277    scoped_ptr<net::HttpTransactionFactory> http_factory) {
278  http_factory_ = http_factory.Pass();
279  set_http_transaction_factory(http_factory_.get());
280}
281
282void ProfileIOData::AppRequestContext::SetJobFactory(
283    scoped_ptr<net::URLRequestJobFactory> job_factory) {
284  job_factory_ = job_factory.Pass();
285  set_job_factory(job_factory_.get());
286}
287
288ProfileIOData::AppRequestContext::~AppRequestContext() {}
289
290ProfileIOData::ProfileParams::ProfileParams()
291    : io_thread(NULL),
292#if defined(ENABLE_NOTIFICATIONS)
293      notification_service(NULL),
294#endif
295      profile(NULL) {
296}
297
298ProfileIOData::ProfileParams::~ProfileParams() {}
299
300ProfileIOData::ProfileIOData(bool is_incognito)
301    : initialized_(false),
302      ALLOW_THIS_IN_INITIALIZER_LIST(
303          resource_context_(new ResourceContext(this))),
304      initialized_on_UI_thread_(false),
305      is_incognito_(is_incognito) {
306  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
307}
308
309ProfileIOData::~ProfileIOData() {
310  if (BrowserThread::IsMessageLoopValid(BrowserThread::IO))
311    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
312
313  if (main_request_context_.get())
314    main_request_context_->AssertNoURLRequests();
315  if (extensions_request_context_.get())
316    extensions_request_context_->AssertNoURLRequests();
317  for (URLRequestContextMap::iterator it = app_request_context_map_.begin();
318       it != app_request_context_map_.end(); ++it) {
319    it->second->AssertNoURLRequests();
320    delete it->second;
321  }
322  for (URLRequestContextMap::iterator it =
323           isolated_media_request_context_map_.begin();
324       it != isolated_media_request_context_map_.end(); ++it) {
325    it->second->AssertNoURLRequests();
326    delete it->second;
327  }
328}
329
330// static
331ProfileIOData* ProfileIOData::FromResourceContext(
332    content::ResourceContext* rc) {
333  return (static_cast<ResourceContext*>(rc))->io_data_;
334}
335
336// static
337bool ProfileIOData::IsHandledProtocol(const std::string& scheme) {
338  DCHECK_EQ(scheme, StringToLowerASCII(scheme));
339  static const char* const kProtocolList[] = {
340    chrome::kExtensionScheme,
341    chrome::kChromeUIScheme,
342    chrome::kChromeDevToolsScheme,
343#if defined(OS_CHROMEOS)
344    chrome::kMetadataScheme,
345    chrome::kDriveScheme,
346#endif  // defined(OS_CHROMEOS)
347    chrome::kBlobScheme,
348    chrome::kFileSystemScheme,
349    chrome::kExtensionResourceScheme,
350  };
351  for (size_t i = 0; i < arraysize(kProtocolList); ++i) {
352    if (scheme == kProtocolList[i])
353      return true;
354  }
355  return net::URLRequest::IsHandledProtocol(scheme);
356}
357
358bool ProfileIOData::IsHandledURL(const GURL& url) {
359  if (!url.is_valid()) {
360    // We handle error cases.
361    return true;
362  }
363
364  return IsHandledProtocol(url.scheme());
365}
366
367content::ResourceContext* ProfileIOData::GetResourceContext() const {
368  return resource_context_.get();
369}
370
371ChromeURLDataManagerBackend*
372ProfileIOData::GetChromeURLDataManagerBackend() const {
373  LazyInitialize();
374  return chrome_url_data_manager_backend_.get();
375}
376
377ChromeURLRequestContext*
378ProfileIOData::GetMainRequestContext() const {
379  LazyInitialize();
380  return main_request_context_.get();
381}
382
383ChromeURLRequestContext*
384ProfileIOData::GetMediaRequestContext() const {
385  LazyInitialize();
386  ChromeURLRequestContext* context =
387      AcquireMediaRequestContext();
388  DCHECK(context);
389  return context;
390}
391
392ChromeURLRequestContext*
393ProfileIOData::GetExtensionsRequestContext() const {
394  LazyInitialize();
395  return extensions_request_context_.get();
396}
397
398ChromeURLRequestContext*
399ProfileIOData::GetIsolatedAppRequestContext(
400    ChromeURLRequestContext* main_context,
401    const StoragePartitionDescriptor& partition_descriptor,
402    scoped_ptr<net::URLRequestJobFactory::Interceptor>
403        protocol_handler_interceptor) const {
404  LazyInitialize();
405  ChromeURLRequestContext* context = NULL;
406  if (ContainsKey(app_request_context_map_, partition_descriptor)) {
407    context = app_request_context_map_[partition_descriptor];
408  } else {
409    context = AcquireIsolatedAppRequestContext(
410        main_context, partition_descriptor,
411        protocol_handler_interceptor.Pass());
412    app_request_context_map_[partition_descriptor] = context;
413  }
414  DCHECK(context);
415  return context;
416}
417
418ChromeURLRequestContext*
419ProfileIOData::GetIsolatedMediaRequestContext(
420    ChromeURLRequestContext* app_context,
421    const StoragePartitionDescriptor& partition_descriptor) const {
422  LazyInitialize();
423  ChromeURLRequestContext* context = NULL;
424  if (ContainsKey(isolated_media_request_context_map_, partition_descriptor)) {
425    context = isolated_media_request_context_map_[partition_descriptor];
426  } else {
427    context = AcquireIsolatedMediaRequestContext(app_context,
428                                                 partition_descriptor);
429    isolated_media_request_context_map_[partition_descriptor] = context;
430  }
431  DCHECK(context);
432  return context;
433}
434
435ExtensionInfoMap* ProfileIOData::GetExtensionInfoMap() const {
436  DCHECK(extension_info_map_) << "ExtensionSystem not initialized";
437  return extension_info_map_;
438}
439
440CookieSettings* ProfileIOData::GetCookieSettings() const {
441  return cookie_settings_;
442}
443
444#if defined(ENABLE_NOTIFICATIONS)
445DesktopNotificationService* ProfileIOData::GetNotificationService() const {
446  return notification_service_;
447}
448#endif
449
450void ProfileIOData::InitializeMetricsEnabledStateOnUIThread() {
451  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
452#if defined(OS_CHROMEOS)
453  // Just fetch the value from ChromeOS' settings while we're on the UI thread.
454  // TODO(stevet): For now, this value is only set on profile initialization.
455  // We will want to do something similar to the PrefMember method below in the
456  // future to more accurately capture this state.
457  chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref,
458                                            &enable_metrics_);
459#else
460  // Prep the PrefMember and send it to the IO thread, since this value will be
461  // read from there.
462  enable_metrics_.Init(prefs::kMetricsReportingEnabled,
463                       g_browser_process->local_state(),
464                       NULL);
465  enable_metrics_.MoveToThread(
466      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
467#endif  // defined(OS_CHROMEOS)
468}
469
470bool ProfileIOData::GetMetricsEnabledStateOnIOThread() const {
471  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
472#if defined(OS_CHROMEOS)
473  return enable_metrics_;
474#else
475  return enable_metrics_.GetValue();
476#endif  // defined(OS_CHROMEOS)
477}
478
479chrome_browser_net::HttpServerPropertiesManager*
480    ProfileIOData::http_server_properties_manager() const {
481  return http_server_properties_manager_.get();
482}
483
484void ProfileIOData::set_http_server_properties_manager(
485    chrome_browser_net::HttpServerPropertiesManager* manager) const {
486  http_server_properties_manager_.reset(manager);
487}
488
489ProfileIOData::ResourceContext::ResourceContext(ProfileIOData* io_data)
490    : io_data_(io_data),
491      host_resolver_(NULL),
492      request_context_(NULL) {
493  DCHECK(io_data);
494}
495
496ProfileIOData::ResourceContext::~ResourceContext() {}
497
498void ProfileIOData::ResourceContext::EnsureInitialized() {
499  io_data_->LazyInitialize();
500}
501
502net::HostResolver* ProfileIOData::ResourceContext::GetHostResolver()  {
503  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
504  EnsureInitialized();
505  return host_resolver_;
506}
507
508net::URLRequestContext* ProfileIOData::ResourceContext::GetRequestContext()  {
509  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
510  EnsureInitialized();
511  return request_context_;
512}
513
514// static
515std::string ProfileIOData::GetSSLSessionCacheShard() {
516  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
517  // The SSL session cache is partitioned by setting a string. This returns a
518  // unique string to partition the SSL session cache. Each time we create a
519  // new profile, we'll get a fresh SSL session cache which is separate from
520  // the other profiles.
521  static unsigned ssl_session_cache_instance = 0;
522  return StringPrintf("profile/%u", ssl_session_cache_instance++);
523}
524
525void ProfileIOData::LazyInitialize() const {
526  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
527  if (initialized_)
528    return;
529
530  // TODO(jhawkins): Remove once crbug.com/102004 is fixed.
531  CHECK(initialized_on_UI_thread_);
532
533  // TODO(jhawkins): Return to DCHECK once crbug.com/102004 is fixed.
534  CHECK(profile_params_.get());
535
536  IOThread* const io_thread = profile_params_->io_thread;
537  IOThread::Globals* const io_thread_globals = io_thread->globals();
538  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
539  load_time_stats_ = GetLoadTimeStats(io_thread_globals);
540
541  // Create the common request contexts.
542  main_request_context_.reset(
543      new ChromeURLRequestContext(ChromeURLRequestContext::CONTEXT_TYPE_MAIN,
544                                  load_time_stats_));
545  extensions_request_context_.reset(
546      new ChromeURLRequestContext(
547          ChromeURLRequestContext::CONTEXT_TYPE_EXTENSIONS,
548          load_time_stats_));
549
550  chrome_url_data_manager_backend_.reset(new ChromeURLDataManagerBackend);
551
552  network_delegate_.reset(new ChromeNetworkDelegate(
553        io_thread_globals->extension_event_router_forwarder.get(),
554        profile_params_->extension_info_map,
555        url_blacklist_manager_.get(),
556#if !defined(OS_ANDROID)
557        ManagedMode::GetURLFilter(),
558#else
559        NULL,
560#endif
561        profile_params_->profile,
562        profile_params_->cookie_settings,
563        &enable_referrers_,
564        &enable_do_not_track_,
565        &force_safesearch_,
566        load_time_stats_));
567
568  fraudulent_certificate_reporter_.reset(
569      new chrome_browser_net::ChromeFraudulentCertificateReporter(
570          main_request_context_.get()));
571
572  proxy_service_.reset(
573      ProxyServiceFactory::CreateProxyService(
574          io_thread->net_log(),
575          io_thread_globals->proxy_script_fetcher_context.get(),
576          profile_params_->proxy_config_service.release(),
577          command_line));
578
579  transport_security_state_.reset(new net::TransportSecurityState());
580  transport_security_persister_.reset(
581      new TransportSecurityPersister(transport_security_state_.get(),
582                                     profile_params_->path,
583                                     is_incognito()));
584  const std::string& serialized =
585      command_line.GetSwitchValueASCII(switches::kHstsHosts);
586  transport_security_persister_.get()->DeserializeFromCommandLine(serialized);
587
588  // Take ownership over these parameters.
589  cookie_settings_ = profile_params_->cookie_settings;
590#if defined(ENABLE_NOTIFICATIONS)
591  notification_service_ = profile_params_->notification_service;
592#endif
593  extension_info_map_ = profile_params_->extension_info_map;
594
595  resource_context_->host_resolver_ = io_thread_globals->host_resolver.get();
596  resource_context_->request_context_ = main_request_context_.get();
597
598  if (profile_params_->resource_prefetch_predictor_observer_.get()) {
599    resource_prefetch_predictor_observer_.reset(
600        profile_params_->resource_prefetch_predictor_observer_.release());
601  }
602
603  LazyInitializeInternal(profile_params_.get());
604
605  profile_params_.reset();
606  initialized_ = true;
607}
608
609void ProfileIOData::ApplyProfileParamsToContext(
610    ChromeURLRequestContext* context) const {
611  context->set_is_incognito(is_incognito());
612  context->set_http_user_agent_settings(
613      chrome_http_user_agent_settings_.get());
614  context->set_ssl_config_service(profile_params_->ssl_config_service);
615}
616
617void ProfileIOData::SetUpJobFactoryDefaults(
618    net::URLRequestJobFactoryImpl* job_factory,
619    scoped_ptr<net::URLRequestJobFactory::Interceptor>
620        protocol_handler_interceptor,
621    net::NetworkDelegate* network_delegate,
622    net::FtpTransactionFactory* ftp_transaction_factory,
623    net::FtpAuthCache* ftp_auth_cache) const {
624  // NOTE(willchan): Keep these protocol handlers in sync with
625  // ProfileIOData::IsHandledProtocol().
626  bool set_protocol = job_factory->SetProtocolHandler(
627      chrome::kFileScheme, new net::FileProtocolHandler());
628  DCHECK(set_protocol);
629
630  set_protocol = job_factory->SetProtocolHandler(
631      chrome::kChromeDevToolsScheme,
632      CreateDevToolsProtocolHandler(chrome_url_data_manager_backend(),
633                                    network_delegate));
634  DCHECK(set_protocol);
635
636  if (protocol_handler_interceptor.get()) {
637    job_factory->AddInterceptor(protocol_handler_interceptor.release());
638  }
639
640  set_protocol = job_factory->SetProtocolHandler(
641      chrome::kExtensionScheme,
642      CreateExtensionProtocolHandler(is_incognito(), GetExtensionInfoMap()));
643  DCHECK(set_protocol);
644  set_protocol = job_factory->SetProtocolHandler(
645      chrome::kExtensionResourceScheme,
646      CreateExtensionResourceProtocolHandler());
647  DCHECK(set_protocol);
648  set_protocol = job_factory->SetProtocolHandler(
649      chrome::kChromeUIScheme,
650      ChromeURLDataManagerBackend::CreateProtocolHandler(
651          chrome_url_data_manager_backend_.get()));
652  DCHECK(set_protocol);
653  set_protocol = job_factory->SetProtocolHandler(
654      chrome::kDataScheme, new net::DataProtocolHandler());
655  DCHECK(set_protocol);
656#if defined(OS_CHROMEOS)
657  if (!is_incognito()) {
658    set_protocol = job_factory->SetProtocolHandler(
659        chrome::kDriveScheme, new drive::DriveProtocolHandler());
660    DCHECK(set_protocol);
661  }
662#if !defined(GOOGLE_CHROME_BUILD)
663  // Install the GView request interceptor that will redirect requests
664  // of compatible documents (PDF, etc) to the GView document viewer.
665  const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
666  if (parsed_command_line.HasSwitch(switches::kEnableGView))
667    job_factory->AddInterceptor(new chromeos::GViewRequestInterceptor);
668#endif  // !defined(GOOGLE_CHROME_BUILD)
669#endif  // defined(OS_CHROMEOS)
670
671  job_factory->SetProtocolHandler(
672      chrome::kAboutScheme,
673      new chrome_browser_net::AboutProtocolHandler());
674#if !defined(DISABLE_FTP_SUPPORT)
675  DCHECK(ftp_transaction_factory);
676  job_factory->SetProtocolHandler(
677      chrome::kFtpScheme,
678      new net::FtpProtocolHandler(ftp_transaction_factory,
679                                  ftp_auth_cache));
680#endif  // !defined(DISABLE_FTP_SUPPORT)
681}
682
683void ProfileIOData::ShutdownOnUIThread() {
684  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
685
686  if (signin_names_)
687    signin_names_->ReleaseResourcesOnUIThread();
688
689  google_services_username_.Destroy();
690  google_services_username_pattern_.Destroy();
691  reverse_autologin_enabled_.Destroy();
692  one_click_signin_rejected_email_list_.Destroy();
693  enable_referrers_.Destroy();
694  enable_do_not_track_.Destroy();
695  force_safesearch_.Destroy();
696#if !defined(OS_CHROMEOS)
697  enable_metrics_.Destroy();
698#endif
699  safe_browsing_enabled_.Destroy();
700  printing_enabled_.Destroy();
701  session_startup_pref_.Destroy();
702#if defined(ENABLE_CONFIGURATION_POLICY)
703  if (url_blacklist_manager_.get())
704    url_blacklist_manager_->ShutdownOnUIThread();
705#endif
706  if (chrome_http_user_agent_settings_.get())
707    chrome_http_user_agent_settings_->CleanupOnUIThread();
708  bool posted = BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this);
709  if (!posted)
710    delete this;
711}
712
713void ProfileIOData::set_server_bound_cert_service(
714    net::ServerBoundCertService* server_bound_cert_service) const {
715  server_bound_cert_service_.reset(server_bound_cert_service);
716}
717
718void ProfileIOData::DestroyResourceContext() {
719  resource_context_.reset();
720}
721
722void ProfileIOData::PopulateNetworkSessionParams(
723    const ProfileParams* profile_params,
724    net::HttpNetworkSession::Params* params) const {
725
726  ChromeURLRequestContext* context = main_request_context();
727
728  IOThread* const io_thread = profile_params->io_thread;
729  IOThread::Globals* const globals = io_thread->globals();
730
731  params->host_resolver = context->host_resolver();
732  params->cert_verifier = context->cert_verifier();
733  params->server_bound_cert_service = context->server_bound_cert_service();
734  params->transport_security_state = context->transport_security_state();
735  params->proxy_service = context->proxy_service();
736  params->ssl_session_cache_shard = GetSSLSessionCacheShard();
737  params->ssl_config_service = context->ssl_config_service();
738  params->http_auth_handler_factory = context->http_auth_handler_factory();
739  params->network_delegate = context->network_delegate();
740  params->http_server_properties = context->http_server_properties();
741  params->net_log = context->net_log();
742  params->host_mapping_rules = globals->host_mapping_rules.get();
743  params->ignore_certificate_errors = globals->ignore_certificate_errors;
744  params->http_pipelining_enabled = globals->http_pipelining_enabled;
745  params->testing_fixed_http_port = globals->testing_fixed_http_port;
746  params->testing_fixed_https_port = globals->testing_fixed_https_port;
747
748  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
749  if (command_line.HasSwitch(switches::kTrustedSpdyProxy)) {
750    params->trusted_spdy_proxy = command_line.GetSwitchValueASCII(
751        switches::kTrustedSpdyProxy);
752  }
753}
754
755void ProfileIOData::SetCookieSettingsForTesting(
756    CookieSettings* cookie_settings) {
757  DCHECK(!cookie_settings_.get());
758  cookie_settings_ = cookie_settings;
759}
760
761void ProfileIOData::set_signin_names_for_testing(
762    SigninNamesOnIOThread* signin_names) {
763  signin_names_.reset(signin_names);
764}
765