profile_io_data.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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/callback.h" 13#include "base/command_line.h" 14#include "base/compiler_specific.h" 15#include "base/debug/alias.h" 16#include "base/logging.h" 17#include "base/path_service.h" 18#include "base/prefs/pref_service.h" 19#include "base/stl_util.h" 20#include "base/strings/string_number_conversions.h" 21#include "base/strings/string_util.h" 22#include "base/strings/stringprintf.h" 23#include "base/threading/sequenced_worker_pool.h" 24#include "chrome/browser/browser_process.h" 25#include "chrome/browser/chrome_notification_types.h" 26#include "chrome/browser/content_settings/content_settings_provider.h" 27#include "chrome/browser/content_settings/cookie_settings.h" 28#include "chrome/browser/content_settings/host_content_settings_map.h" 29#include "chrome/browser/custom_handlers/protocol_handler_registry.h" 30#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" 31#include "chrome/browser/devtools/devtools_network_controller.h" 32#include "chrome/browser/devtools/devtools_network_transaction_factory.h" 33#include "chrome/browser/download/download_service.h" 34#include "chrome/browser/download/download_service_factory.h" 35#include "chrome/browser/extensions/extension_resource_protocols.h" 36#include "chrome/browser/io_thread.h" 37#include "chrome/browser/media/media_device_id_salt.h" 38#include "chrome/browser/net/about_protocol_handler.h" 39#include "chrome/browser/net/chrome_fraudulent_certificate_reporter.h" 40#include "chrome/browser/net/chrome_http_user_agent_settings.h" 41#include "chrome/browser/net/chrome_net_log.h" 42#include "chrome/browser/net/chrome_network_delegate.h" 43#include "chrome/browser/net/cookie_store_util.h" 44#include "chrome/browser/net/proxy_service_factory.h" 45#include "chrome/browser/profiles/profile.h" 46#include "chrome/browser/profiles/profile_manager.h" 47#include "chrome/browser/signin/signin_names_io_thread.h" 48#include "chrome/common/chrome_paths.h" 49#include "chrome/common/chrome_switches.h" 50#include "chrome/common/pref_names.h" 51#include "chrome/common/url_constants.h" 52#include "components/startup_metric_utils/startup_metric_utils.h" 53#include "components/sync_driver/pref_names.h" 54#include "components/url_fixer/url_fixer.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 "extensions/browser/extension_protocols.h" 60#include "extensions/browser/extension_system.h" 61#include "extensions/browser/info_map.h" 62#include "extensions/common/constants.h" 63#include "net/base/keygen_handler.h" 64#include "net/cookies/canonical_cookie.h" 65#include "net/http/http_transaction_factory.h" 66#include "net/http/http_util.h" 67#include "net/http/transport_security_persister.h" 68#include "net/proxy/proxy_config_service_fixed.h" 69#include "net/proxy/proxy_script_fetcher_impl.h" 70#include "net/proxy/proxy_service.h" 71#include "net/ssl/client_cert_store.h" 72#include "net/ssl/server_bound_cert_service.h" 73#include "net/url_request/data_protocol_handler.h" 74#include "net/url_request/file_protocol_handler.h" 75#include "net/url_request/ftp_protocol_handler.h" 76#include "net/url_request/url_request.h" 77#include "net/url_request/url_request_file_job.h" 78#include "net/url_request/url_request_intercepting_job_factory.h" 79#include "net/url_request/url_request_interceptor.h" 80#include "net/url_request/url_request_job_factory_impl.h" 81 82#if defined(ENABLE_CONFIGURATION_POLICY) 83#include "chrome/browser/policy/cloud/policy_header_service_factory.h" 84#include "chrome/browser/policy/policy_helpers.h" 85#include "components/policy/core/browser/url_blacklist_manager.h" 86#include "components/policy/core/common/cloud/policy_header_io_helper.h" 87#include "components/policy/core/common/cloud/policy_header_service.h" 88#include "components/policy/core/common/cloud/user_cloud_policy_manager.h" 89#endif 90 91#if defined(ENABLE_MANAGED_USERS) 92#include "chrome/browser/supervised_user/supervised_user_service.h" 93#include "chrome/browser/supervised_user/supervised_user_service_factory.h" 94#include "chrome/browser/supervised_user/supervised_user_url_filter.h" 95#endif 96 97#if defined(OS_ANDROID) 98#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h" 99#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_factory_android.h" 100#include "components/data_reduction_proxy/common/data_reduction_proxy_switches.h" 101#endif // defined(OS_ANDROID) 102 103#if defined(OS_CHROMEOS) 104#include "chrome/browser/chromeos/drive/drive_protocol_handler.h" 105#include "chrome/browser/chromeos/login/startup_utils.h" 106#include "chrome/browser/chromeos/login/users/user.h" 107#include "chrome/browser/chromeos/login/users/user_manager.h" 108#include "chrome/browser/chromeos/net/cert_verify_proc_chromeos.h" 109#include "chrome/browser/chromeos/policy/policy_cert_service.h" 110#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h" 111#include "chrome/browser/chromeos/policy/policy_cert_verifier.h" 112#include "chrome/browser/chromeos/profiles/profile_helper.h" 113#include "chrome/browser/chromeos/settings/cros_settings.h" 114#include "chromeos/dbus/cryptohome_client.h" 115#include "chromeos/dbus/dbus_thread_manager.h" 116#include "chromeos/settings/cros_settings_names.h" 117#include "crypto/nss_util.h" 118#include "crypto/nss_util_internal.h" 119#include "net/cert/multi_threaded_cert_verifier.h" 120#include "net/ssl/client_cert_store_chromeos.h" 121#endif // defined(OS_CHROMEOS) 122 123#if defined(USE_NSS) 124#include "chrome/browser/ui/crypto_module_delegate_nss.h" 125#include "net/ssl/client_cert_store_nss.h" 126#endif 127 128#if defined(OS_WIN) 129#include "net/ssl/client_cert_store_win.h" 130#endif 131 132#if defined(OS_MACOSX) 133#include "net/ssl/client_cert_store_mac.h" 134#endif 135 136using content::BrowserContext; 137using content::BrowserThread; 138using content::ResourceContext; 139using data_reduction_proxy::DataReductionProxyUsageStats; 140 141namespace { 142 143#if defined(DEBUG_DEVTOOLS) 144bool IsSupportedDevToolsURL(const GURL& url, base::FilePath* path) { 145 std::string bundled_path_prefix(chrome::kChromeUIDevToolsBundledPath); 146 bundled_path_prefix = "/" + bundled_path_prefix + "/"; 147 148 if (!url.SchemeIs(content::kChromeDevToolsScheme) || 149 url.host() != chrome::kChromeUIDevToolsHost || 150 !StartsWithASCII(url.path(), bundled_path_prefix, false)) { 151 return false; 152 } 153 154 if (!url.is_valid()) { 155 NOTREACHED(); 156 return false; 157 } 158 159 // Remove Query and Ref from URL. 160 GURL stripped_url; 161 GURL::Replacements replacements; 162 replacements.ClearQuery(); 163 replacements.ClearRef(); 164 stripped_url = url.ReplaceComponents(replacements); 165 166 std::string relative_path; 167 const std::string& spec = stripped_url.possibly_invalid_spec(); 168 const url::Parsed& parsed = stripped_url.parsed_for_possibly_invalid_spec(); 169 int offset = parsed.CountCharactersBefore(url::Parsed::PATH, false); 170 if (offset < static_cast<int>(spec.size())) 171 relative_path.assign(spec.substr(offset + bundled_path_prefix.length())); 172 173 // Check that |relative_path| is not an absolute path (otherwise 174 // AppendASCII() will DCHECK). The awkward use of StringType is because on 175 // some systems FilePath expects a std::string, but on others a std::wstring. 176 base::FilePath p( 177 base::FilePath::StringType(relative_path.begin(), relative_path.end())); 178 if (p.IsAbsolute()) 179 return false; 180 181 base::FilePath inspector_dir; 182 if (!PathService::Get(chrome::DIR_INSPECTOR, &inspector_dir)) 183 return false; 184 185 if (inspector_dir.empty()) 186 return false; 187 188 *path = inspector_dir.AppendASCII(relative_path); 189 return true; 190} 191 192class DebugDevToolsInterceptor : public net::URLRequestInterceptor { 193 public: 194 DebugDevToolsInterceptor() {} 195 virtual ~DebugDevToolsInterceptor() {} 196 197 // net::URLRequestInterceptor implementation. 198 virtual net::URLRequestJob* MaybeInterceptRequest( 199 net::URLRequest* request, 200 net::NetworkDelegate* network_delegate) const OVERRIDE { 201 base::FilePath path; 202 if (IsSupportedDevToolsURL(request->url(), &path)) 203 return new net::URLRequestFileJob( 204 request, network_delegate, path, 205 content::BrowserThread::GetBlockingPool()-> 206 GetTaskRunnerWithShutdownBehavior( 207 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); 208 209 return NULL; 210 } 211}; 212#endif // defined(DEBUG_DEVTOOLS) 213 214#if defined(OS_CHROMEOS) 215// The following four functions are responsible for initializing NSS for each 216// profile on ChromeOS, which has a separate NSS database and TPM slot 217// per-profile. 218// 219// Initialization basically follows these steps: 220// 1) Get some info from chromeos::UserManager about the User for this profile. 221// 2) Tell nss_util to initialize the software slot for this profile. 222// 3) Wait for the TPM module to be loaded by nss_util if it isn't already. 223// 4) Ask CryptohomeClient which TPM slot id corresponds to this profile. 224// 5) Tell nss_util to use that slot id on the TPM module. 225// 226// Some of these steps must happen on the UI thread, others must happen on the 227// IO thread: 228// UI thread IO Thread 229// 230// ProfileIOData::InitializeOnUIThread 231// | 232// ProfileHelper::Get()->GetUserByProfile() 233// \---------------------------------------v 234// StartNSSInitOnIOThread 235// | 236// crypto::InitializeNSSForChromeOSUser 237// | 238// crypto::IsTPMTokenReady 239// | 240// StartTPMSlotInitializationOnIOThread 241// v---------------------------------------/ 242// GetTPMInfoForUserOnUIThread 243// | 244// CryptohomeClient::Pkcs11GetTpmTokenInfoForUser 245// | 246// DidGetTPMInfoForUserOnUIThread 247// \---------------------------------------v 248// crypto::InitializeTPMForChromeOSUser 249 250void DidGetTPMInfoForUserOnUIThread(const std::string& username_hash, 251 chromeos::DBusMethodCallStatus call_status, 252 const std::string& label, 253 const std::string& user_pin, 254 int slot_id) { 255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 256 if (call_status == chromeos::DBUS_METHOD_CALL_FAILURE) { 257 NOTREACHED() << "dbus error getting TPM info for " << username_hash; 258 return; 259 } 260 DVLOG(1) << "Got TPM slot for " << username_hash << ": " << slot_id; 261 BrowserThread::PostTask( 262 BrowserThread::IO, 263 FROM_HERE, 264 base::Bind( 265 &crypto::InitializeTPMForChromeOSUser, username_hash, slot_id)); 266} 267 268void GetTPMInfoForUserOnUIThread(const std::string& username, 269 const std::string& username_hash) { 270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 271 DVLOG(1) << "Getting TPM info from cryptohome for " 272 << " " << username << " " << username_hash; 273 chromeos::DBusThreadManager::Get() 274 ->GetCryptohomeClient() 275 ->Pkcs11GetTpmTokenInfoForUser( 276 username, 277 base::Bind(&DidGetTPMInfoForUserOnUIThread, username_hash)); 278} 279 280void StartTPMSlotInitializationOnIOThread(const std::string& username, 281 const std::string& username_hash) { 282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 283 284 BrowserThread::PostTask( 285 BrowserThread::UI, 286 FROM_HERE, 287 base::Bind(&GetTPMInfoForUserOnUIThread, username, username_hash)); 288} 289 290void StartNSSInitOnIOThread(const std::string& username, 291 const std::string& username_hash, 292 const base::FilePath& path) { 293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 294 DVLOG(1) << "Starting NSS init for " << username 295 << " hash:" << username_hash; 296 297 // Make sure NSS is initialized for the user. 298 crypto::InitializeNSSForChromeOSUser(username, username_hash, path); 299 300 // Check if it's OK to initialize TPM for the user before continuing. This 301 // may not be the case if the TPM slot initialization was previously 302 // requested for the same user. 303 if (!crypto::ShouldInitializeTPMForChromeOSUser(username_hash)) 304 return; 305 306 crypto::WillInitializeTPMForChromeOSUser(username_hash); 307 308 if (crypto::IsTPMTokenEnabledForNSS()) { 309 if (crypto::IsTPMTokenReady(base::Bind( 310 &StartTPMSlotInitializationOnIOThread, username, username_hash))) { 311 StartTPMSlotInitializationOnIOThread(username, username_hash); 312 } else { 313 DVLOG(1) << "Waiting for tpm ready ..."; 314 } 315 } else { 316 crypto::InitializePrivateSoftwareSlotForChromeOSUser(username_hash); 317 } 318} 319#endif // defined(OS_CHROMEOS) 320 321} // namespace 322 323void ProfileIOData::InitializeOnUIThread(Profile* profile) { 324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 325 PrefService* pref_service = profile->GetPrefs(); 326 PrefService* local_state_pref_service = g_browser_process->local_state(); 327 328 scoped_ptr<ProfileParams> params(new ProfileParams); 329 params->path = profile->GetPath(); 330 331 params->io_thread = g_browser_process->io_thread(); 332 333 params->cookie_settings = CookieSettings::Factory::GetForProfile(profile); 334 params->host_content_settings_map = profile->GetHostContentSettingsMap(); 335 params->ssl_config_service = profile->GetSSLConfigService(); 336 params->cookie_monster_delegate = 337 chrome_browser_net::CreateCookieDelegate(profile); 338 params->extension_info_map = 339 extensions::ExtensionSystem::Get(profile)->info_map(); 340 341 ProtocolHandlerRegistry* protocol_handler_registry = 342 ProtocolHandlerRegistryFactory::GetForProfile(profile); 343 DCHECK(protocol_handler_registry); 344 345 // The profile instance is only available here in the InitializeOnUIThread 346 // method, so we create the url job factory here, then save it for 347 // later delivery to the job factory in Init(). 348 params->protocol_handler_interceptor = 349 protocol_handler_registry->CreateJobInterceptorFactory(); 350 351 params->proxy_config_service 352 .reset(ProxyServiceFactory::CreateProxyConfigService( 353 profile->GetProxyConfigTracker())); 354#if defined(ENABLE_MANAGED_USERS) 355 SupervisedUserService* supervised_user_service = 356 SupervisedUserServiceFactory::GetForProfile(profile); 357 params->supervised_user_url_filter = 358 supervised_user_service->GetURLFilterForIOThread(); 359#endif 360#if defined(OS_CHROMEOS) 361 chromeos::UserManager* user_manager = chromeos::UserManager::Get(); 362 if (user_manager) { 363 chromeos::User* user = 364 chromeos::ProfileHelper::Get()->GetUserByProfile(profile); 365 // No need to initialize NSS for users with empty username hash: 366 // Getters for a user's NSS slots always return NULL slot if the user's 367 // username hash is empty, even when the NSS is not initialized for the 368 // user. 369 if (user && !user->username_hash().empty()) { 370 params->username_hash = user->username_hash(); 371 DCHECK(!params->username_hash.empty()); 372 BrowserThread::PostTask(BrowserThread::IO, 373 FROM_HERE, 374 base::Bind(&StartNSSInitOnIOThread, 375 user->email(), 376 user->username_hash(), 377 profile->GetPath())); 378 } 379 } 380#endif 381 382 params->profile = profile; 383 params->prerender_tracker = g_browser_process->prerender_tracker(); 384 profile_params_.reset(params.release()); 385 386 ChromeNetworkDelegate::InitializePrefsOnUIThread( 387 &enable_referrers_, 388 &enable_do_not_track_, 389 &force_safesearch_, 390 pref_service); 391 392 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy = 393 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); 394#if defined(ENABLE_PRINTING) 395 printing_enabled_.Init(prefs::kPrintingEnabled, pref_service); 396 printing_enabled_.MoveToThread(io_message_loop_proxy); 397#endif 398 399 chrome_http_user_agent_settings_.reset( 400 new ChromeHttpUserAgentSettings(pref_service)); 401 402 // These members are used only for one click sign in, which is not enabled 403 // in incognito mode. So no need to initialize them. 404 if (!IsOffTheRecord()) { 405 signin_names_.reset(new SigninNamesOnIOThread()); 406 407 google_services_user_account_id_.Init( 408 prefs::kGoogleServicesUserAccountId, pref_service); 409 google_services_user_account_id_.MoveToThread(io_message_loop_proxy); 410 411 google_services_username_.Init( 412 prefs::kGoogleServicesUsername, pref_service); 413 google_services_username_.MoveToThread(io_message_loop_proxy); 414 415 google_services_username_pattern_.Init( 416 prefs::kGoogleServicesUsernamePattern, local_state_pref_service); 417 google_services_username_pattern_.MoveToThread(io_message_loop_proxy); 418 419 reverse_autologin_enabled_.Init( 420 prefs::kReverseAutologinEnabled, pref_service); 421 reverse_autologin_enabled_.MoveToThread(io_message_loop_proxy); 422 423 one_click_signin_rejected_email_list_.Init( 424 prefs::kReverseAutologinRejectedEmailList, pref_service); 425 one_click_signin_rejected_email_list_.MoveToThread(io_message_loop_proxy); 426 427 sync_disabled_.Init(sync_driver::prefs::kSyncManaged, pref_service); 428 sync_disabled_.MoveToThread(io_message_loop_proxy); 429 430 signin_allowed_.Init(prefs::kSigninAllowed, pref_service); 431 signin_allowed_.MoveToThread(io_message_loop_proxy); 432 } 433 434 quick_check_enabled_.Init(prefs::kQuickCheckEnabled, 435 local_state_pref_service); 436 quick_check_enabled_.MoveToThread(io_message_loop_proxy); 437 438 media_device_id_salt_ = new MediaDeviceIDSalt(pref_service, IsOffTheRecord()); 439 440 // TODO(bnc): remove per https://crbug.com/334602. 441 network_prediction_enabled_.Init(prefs::kNetworkPredictionEnabled, 442 pref_service); 443 network_prediction_enabled_.MoveToThread(io_message_loop_proxy); 444 445 network_prediction_options_.Init(prefs::kNetworkPredictionOptions, 446 pref_service); 447 448 network_prediction_options_.MoveToThread(io_message_loop_proxy); 449 450#if defined(OS_CHROMEOS) 451 cert_verifier_ = policy::PolicyCertServiceFactory::CreateForProfile(profile); 452#endif 453 // The URLBlacklistManager has to be created on the UI thread to register 454 // observers of |pref_service|, and it also has to clean up on 455 // ShutdownOnUIThread to release these observers on the right thread. 456 // Don't pass it in |profile_params_| to make sure it is correctly cleaned up, 457 // in particular when this ProfileIOData isn't |initialized_| during deletion. 458#if defined(ENABLE_CONFIGURATION_POLICY) 459 policy::URLBlacklist::SegmentURLCallback callback = 460 static_cast<policy::URLBlacklist::SegmentURLCallback>( 461 url_fixer::SegmentURL); 462 base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); 463 scoped_refptr<base::SequencedTaskRunner> background_task_runner = 464 pool->GetSequencedTaskRunner(pool->GetSequenceToken()); 465 url_blacklist_manager_.reset( 466 new policy::URLBlacklistManager( 467 pref_service, 468 background_task_runner, 469 io_message_loop_proxy, 470 callback, 471 base::Bind(policy::OverrideBlacklistForURL))); 472 473 if (!IsOffTheRecord()) { 474 // Add policy headers for non-incognito requests. 475 policy::PolicyHeaderService* policy_header_service = 476 policy::PolicyHeaderServiceFactory::GetForBrowserContext(profile); 477 if (policy_header_service) { 478 policy_header_helper_ = policy_header_service->CreatePolicyHeaderIOHelper( 479 io_message_loop_proxy); 480 } 481 } 482#endif 483 484 incognito_availibility_pref_.Init( 485 prefs::kIncognitoModeAvailability, pref_service); 486 incognito_availibility_pref_.MoveToThread(io_message_loop_proxy); 487 488 initialized_on_UI_thread_ = true; 489 490#if defined(OS_ANDROID) 491#if defined(SPDY_PROXY_AUTH_ORIGIN) 492 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 493 base::Bind(&ProfileIOData::SetDataReductionProxyUsageStatsOnIOThread, 494 base::Unretained(this), g_browser_process->io_thread(), profile)); 495#endif 496#endif 497 498 // We need to make sure that content initializes its own data structures that 499 // are associated with each ResourceContext because we might post this 500 // object to the IO thread after this function. 501 BrowserContext::EnsureResourceContextInitialized(profile); 502} 503 504#if defined(OS_ANDROID) 505#if defined(SPDY_PROXY_AUTH_ORIGIN) 506void ProfileIOData::SetDataReductionProxyUsageStatsOnIOThread( 507 IOThread* io_thread, Profile* profile) { 508 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 509 IOThread::Globals* globals = io_thread->globals(); 510 DataReductionProxyUsageStats* usage_stats = 511 globals->data_reduction_proxy_usage_stats.get(); 512 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 513 base::Bind(&ProfileIOData::SetDataReductionProxyUsageStatsOnUIThread, 514 base::Unretained(this), profile, usage_stats)); 515} 516 517void ProfileIOData::SetDataReductionProxyUsageStatsOnUIThread( 518 Profile* profile, 519 DataReductionProxyUsageStats* usage_stats) { 520 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 521 if (g_browser_process->profile_manager()->IsValidProfile(profile)) { 522 DataReductionProxySettingsAndroid* proxySettingsAndroid = 523 DataReductionProxySettingsFactoryAndroid::GetForBrowserContext(profile); 524 if (proxySettingsAndroid) 525 proxySettingsAndroid->SetDataReductionProxyUsageStats(usage_stats); 526 } 527} 528#endif 529#endif 530 531ProfileIOData::MediaRequestContext::MediaRequestContext() { 532} 533 534void ProfileIOData::MediaRequestContext::SetHttpTransactionFactory( 535 scoped_ptr<net::HttpTransactionFactory> http_factory) { 536 http_factory_ = http_factory.Pass(); 537 set_http_transaction_factory(http_factory_.get()); 538} 539 540ProfileIOData::MediaRequestContext::~MediaRequestContext() {} 541 542ProfileIOData::AppRequestContext::AppRequestContext() { 543} 544 545void ProfileIOData::AppRequestContext::SetCookieStore( 546 net::CookieStore* cookie_store) { 547 cookie_store_ = cookie_store; 548 set_cookie_store(cookie_store); 549} 550 551void ProfileIOData::AppRequestContext::SetHttpTransactionFactory( 552 scoped_ptr<net::HttpTransactionFactory> http_factory) { 553 http_factory_ = http_factory.Pass(); 554 set_http_transaction_factory(http_factory_.get()); 555} 556 557void ProfileIOData::AppRequestContext::SetJobFactory( 558 scoped_ptr<net::URLRequestJobFactory> job_factory) { 559 job_factory_ = job_factory.Pass(); 560 set_job_factory(job_factory_.get()); 561} 562 563ProfileIOData::AppRequestContext::~AppRequestContext() {} 564 565ProfileIOData::ProfileParams::ProfileParams() 566 : io_thread(NULL), 567 profile(NULL) { 568} 569 570ProfileIOData::ProfileParams::~ProfileParams() {} 571 572ProfileIOData::ProfileIOData(Profile::ProfileType profile_type) 573 : initialized_(false), 574 resource_context_(new ResourceContext(this)), 575 initialized_on_UI_thread_(false), 576 profile_type_(profile_type) { 577 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 578} 579 580ProfileIOData::~ProfileIOData() { 581 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) 582 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 583 584 // Pull the contents of the request context maps onto the stack for sanity 585 // checking of values in a minidump. http://crbug.com/260425 586 size_t num_app_contexts = app_request_context_map_.size(); 587 size_t num_media_contexts = isolated_media_request_context_map_.size(); 588 size_t current_context = 0; 589 static const size_t kMaxCachedContexts = 20; 590 ChromeURLRequestContext* app_context_cache[kMaxCachedContexts] = {0}; 591 void* app_context_vtable_cache[kMaxCachedContexts] = {0}; 592 ChromeURLRequestContext* media_context_cache[kMaxCachedContexts] = {0}; 593 void* media_context_vtable_cache[kMaxCachedContexts] = {0}; 594 void* tmp_vtable = NULL; 595 base::debug::Alias(&num_app_contexts); 596 base::debug::Alias(&num_media_contexts); 597 base::debug::Alias(¤t_context); 598 base::debug::Alias(app_context_cache); 599 base::debug::Alias(app_context_vtable_cache); 600 base::debug::Alias(media_context_cache); 601 base::debug::Alias(media_context_vtable_cache); 602 base::debug::Alias(&tmp_vtable); 603 604 current_context = 0; 605 for (URLRequestContextMap::const_iterator it = 606 app_request_context_map_.begin(); 607 current_context < kMaxCachedContexts && 608 it != app_request_context_map_.end(); 609 ++it, ++current_context) { 610 app_context_cache[current_context] = it->second; 611 memcpy(&app_context_vtable_cache[current_context], 612 static_cast<void*>(it->second), sizeof(void*)); 613 } 614 615 current_context = 0; 616 for (URLRequestContextMap::const_iterator it = 617 isolated_media_request_context_map_.begin(); 618 current_context < kMaxCachedContexts && 619 it != isolated_media_request_context_map_.end(); 620 ++it, ++current_context) { 621 media_context_cache[current_context] = it->second; 622 memcpy(&media_context_vtable_cache[current_context], 623 static_cast<void*>(it->second), sizeof(void*)); 624 } 625 626 // TODO(ajwong): These AssertNoURLRequests() calls are unnecessary since they 627 // are already done in the URLRequestContext destructor. 628 if (main_request_context_) 629 main_request_context_->AssertNoURLRequests(); 630 if (extensions_request_context_) 631 extensions_request_context_->AssertNoURLRequests(); 632 633 current_context = 0; 634 for (URLRequestContextMap::iterator it = app_request_context_map_.begin(); 635 it != app_request_context_map_.end(); ++it) { 636 if (current_context < kMaxCachedContexts) { 637 CHECK_EQ(app_context_cache[current_context], it->second); 638 memcpy(&tmp_vtable, static_cast<void*>(it->second), sizeof(void*)); 639 CHECK_EQ(app_context_vtable_cache[current_context], tmp_vtable); 640 } 641 it->second->AssertNoURLRequests(); 642 delete it->second; 643 current_context++; 644 } 645 646 current_context = 0; 647 for (URLRequestContextMap::iterator it = 648 isolated_media_request_context_map_.begin(); 649 it != isolated_media_request_context_map_.end(); ++it) { 650 if (current_context < kMaxCachedContexts) { 651 CHECK_EQ(media_context_cache[current_context], it->second); 652 memcpy(&tmp_vtable, static_cast<void*>(it->second), sizeof(void*)); 653 CHECK_EQ(media_context_vtable_cache[current_context], tmp_vtable); 654 } 655 it->second->AssertNoURLRequests(); 656 delete it->second; 657 current_context++; 658 } 659} 660 661// static 662ProfileIOData* ProfileIOData::FromResourceContext( 663 content::ResourceContext* rc) { 664 return (static_cast<ResourceContext*>(rc))->io_data_; 665} 666 667// static 668bool ProfileIOData::IsHandledProtocol(const std::string& scheme) { 669 DCHECK_EQ(scheme, StringToLowerASCII(scheme)); 670 static const char* const kProtocolList[] = { 671 url::kFileScheme, 672 content::kChromeDevToolsScheme, 673 chrome::kDomDistillerScheme, 674 extensions::kExtensionScheme, 675 extensions::kExtensionResourceScheme, 676 content::kChromeUIScheme, 677 url::kDataScheme, 678#if defined(OS_CHROMEOS) 679 chrome::kDriveScheme, 680#endif // defined(OS_CHROMEOS) 681 url::kAboutScheme, 682#if !defined(DISABLE_FTP_SUPPORT) 683 url::kFtpScheme, 684#endif // !defined(DISABLE_FTP_SUPPORT) 685 url::kBlobScheme, 686 url::kFileSystemScheme, 687 chrome::kChromeSearchScheme, 688 }; 689 for (size_t i = 0; i < arraysize(kProtocolList); ++i) { 690 if (scheme == kProtocolList[i]) 691 return true; 692 } 693 return net::URLRequest::IsHandledProtocol(scheme); 694} 695 696// static 697bool ProfileIOData::IsHandledURL(const GURL& url) { 698 if (!url.is_valid()) { 699 // We handle error cases. 700 return true; 701 } 702 703 return IsHandledProtocol(url.scheme()); 704} 705 706// static 707void ProfileIOData::InstallProtocolHandlers( 708 net::URLRequestJobFactoryImpl* job_factory, 709 content::ProtocolHandlerMap* protocol_handlers) { 710 for (content::ProtocolHandlerMap::iterator it = 711 protocol_handlers->begin(); 712 it != protocol_handlers->end(); 713 ++it) { 714 bool set_protocol = job_factory->SetProtocolHandler( 715 it->first, it->second.release()); 716 DCHECK(set_protocol); 717 } 718 protocol_handlers->clear(); 719} 720 721content::ResourceContext* ProfileIOData::GetResourceContext() const { 722 return resource_context_.get(); 723} 724 725ChromeURLRequestContext* ProfileIOData::GetMainRequestContext() const { 726 DCHECK(initialized_); 727 return main_request_context_.get(); 728} 729 730ChromeURLRequestContext* ProfileIOData::GetMediaRequestContext() const { 731 DCHECK(initialized_); 732 ChromeURLRequestContext* context = AcquireMediaRequestContext(); 733 DCHECK(context); 734 return context; 735} 736 737ChromeURLRequestContext* ProfileIOData::GetExtensionsRequestContext() const { 738 DCHECK(initialized_); 739 return extensions_request_context_.get(); 740} 741 742ChromeURLRequestContext* ProfileIOData::GetIsolatedAppRequestContext( 743 ChromeURLRequestContext* main_context, 744 const StoragePartitionDescriptor& partition_descriptor, 745 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> 746 protocol_handler_interceptor, 747 content::ProtocolHandlerMap* protocol_handlers, 748 content::URLRequestInterceptorScopedVector request_interceptors) const { 749 DCHECK(initialized_); 750 ChromeURLRequestContext* context = NULL; 751 if (ContainsKey(app_request_context_map_, partition_descriptor)) { 752 context = app_request_context_map_[partition_descriptor]; 753 } else { 754 context = 755 AcquireIsolatedAppRequestContext(main_context, 756 partition_descriptor, 757 protocol_handler_interceptor.Pass(), 758 protocol_handlers, 759 request_interceptors.Pass()); 760 app_request_context_map_[partition_descriptor] = context; 761 } 762 DCHECK(context); 763 return context; 764} 765 766ChromeURLRequestContext* ProfileIOData::GetIsolatedMediaRequestContext( 767 ChromeURLRequestContext* app_context, 768 const StoragePartitionDescriptor& partition_descriptor) const { 769 DCHECK(initialized_); 770 ChromeURLRequestContext* context = NULL; 771 if (ContainsKey(isolated_media_request_context_map_, partition_descriptor)) { 772 context = isolated_media_request_context_map_[partition_descriptor]; 773 } else { 774 context = AcquireIsolatedMediaRequestContext(app_context, 775 partition_descriptor); 776 isolated_media_request_context_map_[partition_descriptor] = context; 777 } 778 DCHECK(context); 779 return context; 780} 781 782extensions::InfoMap* ProfileIOData::GetExtensionInfoMap() const { 783 DCHECK(initialized_) << "ExtensionSystem not initialized"; 784 return extension_info_map_.get(); 785} 786 787CookieSettings* ProfileIOData::GetCookieSettings() const { 788 // Allow either Init() or SetCookieSettingsForTesting() to initialize. 789 DCHECK(initialized_ || cookie_settings_.get()); 790 return cookie_settings_.get(); 791} 792 793HostContentSettingsMap* ProfileIOData::GetHostContentSettingsMap() const { 794 DCHECK(initialized_); 795 return host_content_settings_map_.get(); 796} 797 798ResourceContext::SaltCallback ProfileIOData::GetMediaDeviceIDSalt() const { 799 return base::Bind(&MediaDeviceIDSalt::GetSalt, media_device_id_salt_); 800} 801 802bool ProfileIOData::IsOffTheRecord() const { 803 return profile_type() == Profile::INCOGNITO_PROFILE 804 || profile_type() == Profile::GUEST_PROFILE; 805} 806 807void ProfileIOData::InitializeMetricsEnabledStateOnUIThread() { 808 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 809#if defined(OS_CHROMEOS) 810 // Just fetch the value from ChromeOS' settings while we're on the UI thread. 811 // TODO(stevet): For now, this value is only set on profile initialization. 812 // We will want to do something similar to the PrefMember method below in the 813 // future to more accurately capture this state. 814 chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref, 815 &enable_metrics_); 816#elif defined(OS_ANDROID) 817 // TODO(dwkang): rename or unify the pref for UMA once we have conclusion 818 // in crbugs.com/246495. 819 // Android has it's own preferences for metrics / crash uploading. 820 enable_metrics_.Init(prefs::kCrashReportingEnabled, 821 g_browser_process->local_state()); 822 enable_metrics_.MoveToThread( 823 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); 824#else 825 // Prep the PrefMember and send it to the IO thread, since this value will be 826 // read from there. 827 enable_metrics_.Init(prefs::kMetricsReportingEnabled, 828 g_browser_process->local_state()); 829 enable_metrics_.MoveToThread( 830 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); 831#endif // defined(OS_CHROMEOS) 832} 833 834bool ProfileIOData::GetMetricsEnabledStateOnIOThread() const { 835 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 836#if defined(OS_CHROMEOS) 837 return enable_metrics_; 838#else 839 return enable_metrics_.GetValue(); 840#endif // defined(OS_CHROMEOS) 841} 842 843#if defined(OS_ANDROID) 844bool ProfileIOData::IsDataReductionProxyEnabled() const { 845 return data_reduction_proxy_enabled_.GetValue() || 846 CommandLine::ForCurrentProcess()->HasSwitch( 847 data_reduction_proxy::switches::kEnableDataReductionProxy); 848} 849#endif 850 851base::WeakPtr<net::HttpServerProperties> 852ProfileIOData::http_server_properties() const { 853 return http_server_properties_->GetWeakPtr(); 854} 855 856void ProfileIOData::set_http_server_properties( 857 scoped_ptr<net::HttpServerProperties> http_server_properties) const { 858 http_server_properties_ = http_server_properties.Pass(); 859} 860 861ProfileIOData::ResourceContext::ResourceContext(ProfileIOData* io_data) 862 : io_data_(io_data), 863 host_resolver_(NULL), 864 request_context_(NULL) { 865 DCHECK(io_data); 866} 867 868ProfileIOData::ResourceContext::~ResourceContext() {} 869 870net::HostResolver* ProfileIOData::ResourceContext::GetHostResolver() { 871 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 872 DCHECK(io_data_->initialized_); 873 return host_resolver_; 874} 875 876net::URLRequestContext* ProfileIOData::ResourceContext::GetRequestContext() { 877 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 878 DCHECK(io_data_->initialized_); 879 return request_context_; 880} 881 882scoped_ptr<net::ClientCertStore> 883ProfileIOData::ResourceContext::CreateClientCertStore() { 884 if (!io_data_->client_cert_store_factory_.is_null()) 885 return io_data_->client_cert_store_factory_.Run(); 886#if defined(OS_CHROMEOS) 887 return scoped_ptr<net::ClientCertStore>(new net::ClientCertStoreChromeOS( 888 io_data_->username_hash(), 889 base::Bind(&CreateCryptoModuleBlockingPasswordDelegate, 890 chrome::kCryptoModulePasswordClientAuth))); 891#elif defined(USE_NSS) 892 return scoped_ptr<net::ClientCertStore>(new net::ClientCertStoreNSS( 893 base::Bind(&CreateCryptoModuleBlockingPasswordDelegate, 894 chrome::kCryptoModulePasswordClientAuth))); 895#elif defined(OS_WIN) 896 return scoped_ptr<net::ClientCertStore>(new net::ClientCertStoreWin()); 897#elif defined(OS_MACOSX) 898 return scoped_ptr<net::ClientCertStore>(new net::ClientCertStoreMac()); 899#elif defined(USE_OPENSSL) 900 // OpenSSL does not use the ClientCertStore infrastructure. On Android client 901 // cert matching is done by the OS as part of the call to show the cert 902 // selection dialog. 903 return scoped_ptr<net::ClientCertStore>(); 904#else 905#error Unknown platform. 906#endif 907} 908 909void ProfileIOData::ResourceContext::CreateKeygenHandler( 910 uint32 key_size_in_bits, 911 const std::string& challenge_string, 912 const GURL& url, 913 const base::Callback<void(scoped_ptr<net::KeygenHandler>)>& callback) { 914 DCHECK(!callback.is_null()); 915#if defined(USE_NSS) 916 scoped_ptr<net::KeygenHandler> keygen_handler( 917 new net::KeygenHandler(key_size_in_bits, challenge_string, url)); 918 919 scoped_ptr<ChromeNSSCryptoModuleDelegate> delegate( 920 new ChromeNSSCryptoModuleDelegate(chrome::kCryptoModulePasswordKeygen, 921 net::HostPortPair::FromURL(url))); 922 ChromeNSSCryptoModuleDelegate* delegate_ptr = delegate.get(); 923 keygen_handler->set_crypto_module_delegate( 924 delegate.PassAs<crypto::NSSCryptoModuleDelegate>()); 925 926 base::Closure bound_callback = 927 base::Bind(callback, base::Passed(&keygen_handler)); 928 if (delegate_ptr->InitializeSlot(this, bound_callback)) { 929 // Initialization complete, run the callback synchronously. 930 bound_callback.Run(); 931 return; 932 } 933 // Otherwise, the InitializeSlot will run the callback asynchronously. 934#else 935 callback.Run(make_scoped_ptr( 936 new net::KeygenHandler(key_size_in_bits, challenge_string, url))); 937#endif 938} 939 940bool ProfileIOData::ResourceContext::AllowMicAccess(const GURL& origin) { 941 return AllowContentAccess(origin, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); 942} 943 944bool ProfileIOData::ResourceContext::AllowCameraAccess(const GURL& origin) { 945 return AllowContentAccess(origin, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); 946} 947 948bool ProfileIOData::ResourceContext::AllowContentAccess( 949 const GURL& origin, ContentSettingsType type) { 950 HostContentSettingsMap* content_settings = 951 io_data_->GetHostContentSettingsMap(); 952 ContentSetting setting = content_settings->GetContentSetting( 953 origin, origin, type, NO_RESOURCE_IDENTIFIER); 954 return setting == CONTENT_SETTING_ALLOW; 955} 956 957ResourceContext::SaltCallback 958ProfileIOData::ResourceContext::GetMediaDeviceIDSalt() { 959 return io_data_->GetMediaDeviceIDSalt(); 960} 961 962// static 963std::string ProfileIOData::GetSSLSessionCacheShard() { 964 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 965 // The SSL session cache is partitioned by setting a string. This returns a 966 // unique string to partition the SSL session cache. Each time we create a 967 // new profile, we'll get a fresh SSL session cache which is separate from 968 // the other profiles. 969 static unsigned ssl_session_cache_instance = 0; 970 return base::StringPrintf("profile/%u", ssl_session_cache_instance++); 971} 972 973void ProfileIOData::Init( 974 content::ProtocolHandlerMap* protocol_handlers, 975 content::URLRequestInterceptorScopedVector request_interceptors) const { 976 // The basic logic is implemented here. The specific initialization 977 // is done in InitializeInternal(), implemented by subtypes. Static helper 978 // functions have been provided to assist in common operations. 979 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 980 DCHECK(!initialized_); 981 982 startup_metric_utils::ScopedSlowStartupUMA 983 scoped_timer("Startup.SlowStartupProfileIODataInit"); 984 985 // TODO(jhawkins): Remove once crbug.com/102004 is fixed. 986 CHECK(initialized_on_UI_thread_); 987 988 // TODO(jhawkins): Return to DCHECK once crbug.com/102004 is fixed. 989 CHECK(profile_params_.get()); 990 991 IOThread* const io_thread = profile_params_->io_thread; 992 IOThread::Globals* const io_thread_globals = io_thread->globals(); 993 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 994 995 // Create the common request contexts. 996 main_request_context_.reset(new ChromeURLRequestContext()); 997 extensions_request_context_.reset(new ChromeURLRequestContext()); 998 999 ChromeNetworkDelegate* network_delegate = 1000 new ChromeNetworkDelegate( 1001 io_thread_globals->extension_event_router_forwarder.get(), 1002 &enable_referrers_); 1003 network_delegate->set_data_reduction_proxy_params( 1004 io_thread_globals->data_reduction_proxy_params.get()); 1005 network_delegate->set_data_reduction_proxy_usage_stats( 1006 io_thread_globals->data_reduction_proxy_usage_stats.get()); 1007 network_delegate->set_data_reduction_proxy_auth_request_handler( 1008 io_thread_globals->data_reduction_proxy_auth_request_handler.get()); 1009 network_delegate->set_on_resolve_proxy_handler( 1010 io_thread_globals->on_resolve_proxy_handler); 1011 if (command_line.HasSwitch(switches::kEnableClientHints)) 1012 network_delegate->SetEnableClientHints(); 1013 network_delegate->set_extension_info_map( 1014 profile_params_->extension_info_map.get()); 1015#if defined(ENABLE_CONFIGURATION_POLICY) 1016 network_delegate->set_url_blacklist_manager(url_blacklist_manager_.get()); 1017#endif 1018 network_delegate->set_profile(profile_params_->profile); 1019 network_delegate->set_profile_path(profile_params_->path); 1020 network_delegate->set_cookie_settings(profile_params_->cookie_settings.get()); 1021 network_delegate->set_enable_do_not_track(&enable_do_not_track_); 1022 network_delegate->set_force_google_safe_search(&force_safesearch_); 1023 network_delegate->set_prerender_tracker(profile_params_->prerender_tracker); 1024 network_delegate_.reset(network_delegate); 1025 1026 fraudulent_certificate_reporter_.reset( 1027 new chrome_browser_net::ChromeFraudulentCertificateReporter( 1028 main_request_context_.get())); 1029 1030 // NOTE: Proxy service uses the default io thread network delegate, not the 1031 // delegate just created. 1032 proxy_service_.reset( 1033 ProxyServiceFactory::CreateProxyService( 1034 io_thread->net_log(), 1035 io_thread_globals->proxy_script_fetcher_context.get(), 1036 io_thread_globals->system_network_delegate.get(), 1037 profile_params_->proxy_config_service.release(), 1038 command_line, 1039 quick_check_enabled_.GetValue())); 1040 1041 transport_security_state_.reset(new net::TransportSecurityState()); 1042 transport_security_persister_.reset( 1043 new net::TransportSecurityPersister( 1044 transport_security_state_.get(), 1045 profile_params_->path, 1046 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE), 1047 IsOffTheRecord())); 1048 1049 // Take ownership over these parameters. 1050 cookie_settings_ = profile_params_->cookie_settings; 1051 host_content_settings_map_ = profile_params_->host_content_settings_map; 1052 extension_info_map_ = profile_params_->extension_info_map; 1053 1054 resource_context_->host_resolver_ = io_thread_globals->host_resolver.get(); 1055 resource_context_->request_context_ = main_request_context_.get(); 1056 1057#if defined(ENABLE_MANAGED_USERS) 1058 supervised_user_url_filter_ = profile_params_->supervised_user_url_filter; 1059#endif 1060 1061#if defined(OS_CHROMEOS) 1062 username_hash_ = profile_params_->username_hash; 1063 scoped_refptr<net::CertVerifyProc> verify_proc; 1064 crypto::ScopedPK11Slot public_slot = 1065 crypto::GetPublicSlotForChromeOSUser(username_hash_); 1066 // The private slot won't be ready by this point. It shouldn't be necessary 1067 // for cert trust purposes anyway. 1068 verify_proc = new chromeos::CertVerifyProcChromeOS(public_slot.Pass()); 1069 if (cert_verifier_) { 1070 cert_verifier_->InitializeOnIOThread(verify_proc); 1071 main_request_context_->set_cert_verifier(cert_verifier_.get()); 1072 } else { 1073 main_request_context_->set_cert_verifier( 1074 new net::MultiThreadedCertVerifier(verify_proc.get())); 1075 } 1076#else 1077 main_request_context_->set_cert_verifier( 1078 io_thread_globals->cert_verifier.get()); 1079#endif 1080 1081 InitializeInternal( 1082 profile_params_.get(), protocol_handlers, request_interceptors.Pass()); 1083 1084 profile_params_.reset(); 1085 initialized_ = true; 1086} 1087 1088void ProfileIOData::ApplyProfileParamsToContext( 1089 ChromeURLRequestContext* context) const { 1090 context->set_http_user_agent_settings( 1091 chrome_http_user_agent_settings_.get()); 1092 context->set_ssl_config_service(profile_params_->ssl_config_service.get()); 1093} 1094 1095scoped_ptr<net::URLRequestJobFactory> ProfileIOData::SetUpJobFactoryDefaults( 1096 scoped_ptr<net::URLRequestJobFactoryImpl> job_factory, 1097 content::URLRequestInterceptorScopedVector request_interceptors, 1098 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> 1099 protocol_handler_interceptor, 1100 net::NetworkDelegate* network_delegate, 1101 net::FtpTransactionFactory* ftp_transaction_factory) const { 1102 // NOTE(willchan): Keep these protocol handlers in sync with 1103 // ProfileIOData::IsHandledProtocol(). 1104 bool set_protocol = job_factory->SetProtocolHandler( 1105 url::kFileScheme, 1106 new net::FileProtocolHandler( 1107 content::BrowserThread::GetBlockingPool()-> 1108 GetTaskRunnerWithShutdownBehavior( 1109 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN))); 1110 DCHECK(set_protocol); 1111 1112 DCHECK(extension_info_map_.get()); 1113 // Check only for incognito (and not Chrome OS guest mode GUEST_PROFILE). 1114 bool is_incognito = profile_type() == Profile::INCOGNITO_PROFILE; 1115 set_protocol = job_factory->SetProtocolHandler( 1116 extensions::kExtensionScheme, 1117 extensions::CreateExtensionProtocolHandler(is_incognito, 1118 extension_info_map_.get())); 1119 DCHECK(set_protocol); 1120 set_protocol = job_factory->SetProtocolHandler( 1121 extensions::kExtensionResourceScheme, 1122 CreateExtensionResourceProtocolHandler()); 1123 DCHECK(set_protocol); 1124 set_protocol = job_factory->SetProtocolHandler( 1125 url::kDataScheme, new net::DataProtocolHandler()); 1126 DCHECK(set_protocol); 1127#if defined(OS_CHROMEOS) 1128 if (profile_params_) { 1129 set_protocol = job_factory->SetProtocolHandler( 1130 chrome::kDriveScheme, 1131 new drive::DriveProtocolHandler(profile_params_->profile)); 1132 DCHECK(set_protocol); 1133 } 1134#endif // defined(OS_CHROMEOS) 1135 1136 job_factory->SetProtocolHandler( 1137 url::kAboutScheme, new chrome_browser_net::AboutProtocolHandler()); 1138#if !defined(DISABLE_FTP_SUPPORT) 1139 DCHECK(ftp_transaction_factory); 1140 job_factory->SetProtocolHandler( 1141 url::kFtpScheme, 1142 new net::FtpProtocolHandler(ftp_transaction_factory)); 1143#endif // !defined(DISABLE_FTP_SUPPORT) 1144 1145#if defined(DEBUG_DEVTOOLS) 1146 request_interceptors.push_back(new DebugDevToolsInterceptor); 1147#endif 1148 1149 // Set up interceptors in the reverse order. 1150 scoped_ptr<net::URLRequestJobFactory> top_job_factory = 1151 job_factory.PassAs<net::URLRequestJobFactory>(); 1152 for (content::URLRequestInterceptorScopedVector::reverse_iterator i = 1153 request_interceptors.rbegin(); 1154 i != request_interceptors.rend(); 1155 ++i) { 1156 top_job_factory.reset(new net::URLRequestInterceptingJobFactory( 1157 top_job_factory.Pass(), make_scoped_ptr(*i))); 1158 } 1159 request_interceptors.weak_clear(); 1160 1161 if (protocol_handler_interceptor) { 1162 protocol_handler_interceptor->Chain(top_job_factory.Pass()); 1163 return protocol_handler_interceptor.PassAs<net::URLRequestJobFactory>(); 1164 } else { 1165 return top_job_factory.Pass(); 1166 } 1167} 1168 1169void ProfileIOData::ShutdownOnUIThread() { 1170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1171 1172 if (signin_names_) 1173 signin_names_->ReleaseResourcesOnUIThread(); 1174 1175 google_services_user_account_id_.Destroy(); 1176 google_services_username_.Destroy(); 1177 google_services_username_pattern_.Destroy(); 1178 reverse_autologin_enabled_.Destroy(); 1179 one_click_signin_rejected_email_list_.Destroy(); 1180 enable_referrers_.Destroy(); 1181 enable_do_not_track_.Destroy(); 1182 force_safesearch_.Destroy(); 1183#if !defined(OS_CHROMEOS) 1184 enable_metrics_.Destroy(); 1185#endif 1186 safe_browsing_enabled_.Destroy(); 1187#if defined(OS_ANDROID) 1188 data_reduction_proxy_enabled_.Destroy(); 1189#endif 1190 printing_enabled_.Destroy(); 1191 sync_disabled_.Destroy(); 1192 signin_allowed_.Destroy(); 1193 // TODO(bnc): remove per https://crbug.com/334602. 1194 network_prediction_enabled_.Destroy(); 1195 network_prediction_options_.Destroy(); 1196 quick_check_enabled_.Destroy(); 1197 if (media_device_id_salt_) 1198 media_device_id_salt_->ShutdownOnUIThread(); 1199 session_startup_pref_.Destroy(); 1200#if defined(ENABLE_CONFIGURATION_POLICY) 1201 if (url_blacklist_manager_) 1202 url_blacklist_manager_->ShutdownOnUIThread(); 1203#endif 1204 if (chrome_http_user_agent_settings_) 1205 chrome_http_user_agent_settings_->CleanupOnUIThread(); 1206 incognito_availibility_pref_.Destroy(); 1207 bool posted = BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this); 1208 if (!posted) 1209 delete this; 1210} 1211 1212void ProfileIOData::set_server_bound_cert_service( 1213 net::ServerBoundCertService* server_bound_cert_service) const { 1214 server_bound_cert_service_.reset(server_bound_cert_service); 1215} 1216 1217void ProfileIOData::DestroyResourceContext() { 1218 resource_context_.reset(); 1219} 1220 1221scoped_ptr<net::HttpCache> ProfileIOData::CreateMainHttpFactory( 1222 const ProfileParams* profile_params, 1223 net::HttpCache::BackendFactory* main_backend) const { 1224 net::HttpNetworkSession::Params params; 1225 ChromeURLRequestContext* context = main_request_context(); 1226 1227 IOThread* const io_thread = profile_params->io_thread; 1228 1229 io_thread->InitializeNetworkSessionParams(¶ms); 1230 1231 params.host_resolver = context->host_resolver(); 1232 params.cert_verifier = context->cert_verifier(); 1233 params.server_bound_cert_service = context->server_bound_cert_service(); 1234 params.transport_security_state = context->transport_security_state(); 1235 params.cert_transparency_verifier = context->cert_transparency_verifier(); 1236 params.proxy_service = context->proxy_service(); 1237 params.ssl_session_cache_shard = GetSSLSessionCacheShard(); 1238 params.ssl_config_service = context->ssl_config_service(); 1239 params.http_auth_handler_factory = context->http_auth_handler_factory(); 1240 params.network_delegate = network_delegate(); 1241 params.http_server_properties = context->http_server_properties(); 1242 params.net_log = context->net_log(); 1243 1244 network_controller_.reset(new DevToolsNetworkController()); 1245 1246 net::HttpNetworkSession* session = new net::HttpNetworkSession(params); 1247 return scoped_ptr<net::HttpCache>(new net::HttpCache( 1248 new DevToolsNetworkTransactionFactory(network_controller_.get(), session), 1249 context->net_log(), main_backend)); 1250} 1251 1252scoped_ptr<net::HttpCache> ProfileIOData::CreateHttpFactory( 1253 net::HttpNetworkSession* shared_session, 1254 net::HttpCache::BackendFactory* backend) const { 1255 return scoped_ptr<net::HttpCache>(new net::HttpCache( 1256 new DevToolsNetworkTransactionFactory( 1257 network_controller_.get(), shared_session), 1258 shared_session->net_log(), backend)); 1259} 1260 1261void ProfileIOData::SetCookieSettingsForTesting( 1262 CookieSettings* cookie_settings) { 1263 DCHECK(!cookie_settings_.get()); 1264 cookie_settings_ = cookie_settings; 1265} 1266 1267void ProfileIOData::set_signin_names_for_testing( 1268 SigninNamesOnIOThread* signin_names) { 1269 signin_names_.reset(signin_names); 1270} 1271