// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_PROFILES_PROFILE_IO_DATA_H_ #define CHROME_BROWSER_PROFILES_PROFILE_IO_DATA_H_ #include #include #include #include "base/basictypes.h" #include "base/callback_forward.h" #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/prefs/pref_member.h" #include "base/synchronization/lock.h" #include "chrome/browser/custom_handlers/protocol_handler_registry.h" #include "chrome/browser/io_thread.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/storage_partition_descriptor.h" #include "components/content_settings/core/common/content_settings_types.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/resource_context.h" #include "net/cookies/cookie_monster.h" #include "net/http/http_cache.h" #include "net/http/http_network_session.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_interceptor.h" #include "net/url_request/url_request_job_factory.h" class ChromeHttpUserAgentSettings; class ChromeNetworkDelegate; class ChromeURLRequestContextGetter; class CookieSettings; class DevToolsNetworkController; class HostContentSettingsMap; class MediaDeviceIDSalt; class ProtocolHandlerRegistry; class SigninNamesOnIOThread; class SupervisedUserURLFilter; namespace chrome_browser_net { class ResourcePrefetchPredictorObserver; } namespace data_reduction_proxy { class DataReductionProxyIOData; } namespace extensions { class InfoMap; } namespace net { class CertVerifier; class ChannelIDService; class CookieStore; class FraudulentCertificateReporter; class FtpTransactionFactory; class HttpServerProperties; class HttpTransactionFactory; class ProxyConfigService; class ProxyService; class SSLConfigService; class TransportSecurityPersister; class TransportSecurityState; class URLRequestJobFactoryImpl; } // namespace net namespace policy { class PolicyCertVerifier; class PolicyHeaderIOHelper; class URLBlacklistManager; } // namespace policy // Conceptually speaking, the ProfileIOData represents data that lives on the IO // thread that is owned by a Profile, such as, but not limited to, network // objects like CookieMonster, HttpTransactionFactory, etc. Profile owns // ProfileIOData, but will make sure to delete it on the IO thread (except // possibly in unit tests where there is no IO thread). class ProfileIOData { public: typedef std::vector> ChromeURLRequestContextGetterVector; virtual ~ProfileIOData(); static ProfileIOData* FromResourceContext(content::ResourceContext* rc); // Returns true if |scheme| is handled in Chrome, or by default handlers in // net::URLRequest. static bool IsHandledProtocol(const std::string& scheme); // Returns true if |url| is handled in Chrome, or by default handlers in // net::URLRequest. static bool IsHandledURL(const GURL& url); // Utility to install additional WebUI handlers into the |job_factory|. // Ownership of the handlers is transfered from |protocol_handlers| // to the |job_factory|. static void InstallProtocolHandlers( net::URLRequestJobFactoryImpl* job_factory, content::ProtocolHandlerMap* protocol_handlers); // Called by Profile. content::ResourceContext* GetResourceContext() const; // Initializes the ProfileIOData object and primes the RequestContext // generation. Must be called prior to any of the Get*() methods other than // GetResouceContext or GetMetricsEnabledStateOnIOThread. void Init( content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) const; net::URLRequestContext* GetMainRequestContext() const; net::URLRequestContext* GetMediaRequestContext() const; net::URLRequestContext* GetExtensionsRequestContext() const; net::URLRequestContext* GetIsolatedAppRequestContext( net::URLRequestContext* main_context, const StoragePartitionDescriptor& partition_descriptor, scoped_ptr protocol_handler_interceptor, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) const; net::URLRequestContext* GetIsolatedMediaRequestContext( net::URLRequestContext* app_context, const StoragePartitionDescriptor& partition_descriptor) const; // These are useful when the Chrome layer is called from the content layer // with a content::ResourceContext, and they want access to Chrome data for // that profile. extensions::InfoMap* GetExtensionInfoMap() const; CookieSettings* GetCookieSettings() const; HostContentSettingsMap* GetHostContentSettingsMap() const; IntegerPrefMember* session_startup_pref() const { return &session_startup_pref_; } SigninNamesOnIOThread* signin_names() const { return signin_names_.get(); } StringPrefMember* google_services_account_id() const { return &google_services_user_account_id_; } net::URLRequestContext* extensions_request_context() const { return extensions_request_context_.get(); } BooleanPrefMember* safe_browsing_enabled() const { return &safe_browsing_enabled_; } BooleanPrefMember* sync_disabled() const { return &sync_disabled_; } BooleanPrefMember* signin_allowed() const { return &signin_allowed_; } IntegerPrefMember* network_prediction_options() const { return &network_prediction_options_; } content::ResourceContext::SaltCallback GetMediaDeviceIDSalt() const; DevToolsNetworkController* network_controller() const { return network_controller_.get(); } net::TransportSecurityState* transport_security_state() const { return transport_security_state_.get(); } #if defined(OS_CHROMEOS) std::string username_hash() const { return username_hash_; } bool use_system_key_slot() const { return use_system_key_slot_; } #endif Profile::ProfileType profile_type() const { return profile_type_; } bool IsOffTheRecord() const; IntegerPrefMember* incognito_availibility() const { return &incognito_availibility_pref_; } chrome_browser_net::ResourcePrefetchPredictorObserver* resource_prefetch_predictor_observer() const { return resource_prefetch_predictor_observer_.get(); } #if defined(ENABLE_CONFIGURATION_POLICY) policy::PolicyHeaderIOHelper* policy_header_helper() const { return policy_header_helper_.get(); } #endif #if defined(ENABLE_SUPERVISED_USERS) const SupervisedUserURLFilter* supervised_user_url_filter() const { return supervised_user_url_filter_.get(); } #endif // Initialize the member needed to track the metrics enabled state. This is // only to be called on the UI thread. void InitializeMetricsEnabledStateOnUIThread(); // Returns whether or not metrics reporting is enabled in the browser instance // on which this profile resides. This is safe for use from the IO thread, and // should only be called from there. bool GetMetricsEnabledStateOnIOThread() const; void set_client_cert_store_factory_for_testing( const base::Callback()>& factory) { client_cert_store_factory_ = factory; } bool IsDataReductionProxyEnabled() const; data_reduction_proxy::DataReductionProxyIOData* data_reduction_proxy_io_data() const { return data_reduction_proxy_io_data_.get(); } protected: // A URLRequestContext for media that owns its HTTP factory, to ensure // it is deleted. class MediaRequestContext : public net::URLRequestContext { public: MediaRequestContext(); void SetHttpTransactionFactory( scoped_ptr http_factory); private: ~MediaRequestContext() override; scoped_ptr http_factory_; }; // A URLRequestContext for apps that owns its cookie store and HTTP factory, // to ensure they are deleted. class AppRequestContext : public net::URLRequestContext { public: AppRequestContext(); void SetCookieStore(net::CookieStore* cookie_store); void SetHttpTransactionFactory( scoped_ptr http_factory); void SetJobFactory(scoped_ptr job_factory); private: ~AppRequestContext() override; scoped_refptr cookie_store_; scoped_ptr http_factory_; scoped_ptr job_factory_; }; // Created on the UI thread, read on the IO thread during ProfileIOData lazy // initialization. struct ProfileParams { ProfileParams(); ~ProfileParams(); base::FilePath path; IOThread* io_thread; scoped_refptr cookie_settings; scoped_refptr host_content_settings_map; scoped_refptr ssl_config_service; scoped_refptr cookie_monster_delegate; #if defined(ENABLE_EXTENSIONS) scoped_refptr extension_info_map; #endif scoped_ptr resource_prefetch_predictor_observer_; // This pointer exists only as a means of conveying a url job factory // pointer from the protocol handler registry on the UI thread to the // the URLRequestContext on the IO thread. The consumer MUST take // ownership of the object by calling release() on this pointer. scoped_ptr protocol_handler_interceptor; // Holds the URLRequestInterceptor pointer that is created on the UI thread // and then passed to the list of request_interceptors on the IO thread. scoped_ptr new_tab_page_interceptor; // We need to initialize the ProxyConfigService from the UI thread // because on linux it relies on initializing things through gconf, // and needs to be on the main thread. scoped_ptr proxy_config_service; #if defined(ENABLE_SUPERVISED_USERS) scoped_refptr supervised_user_url_filter; #endif #if defined(OS_CHROMEOS) std::string username_hash; bool use_system_key_slot; #endif // The profile this struct was populated from. It's passed as a void* to // ensure it's not accidently used on the IO thread. Before using it on the // UI thread, call ProfileManager::IsValidProfile to ensure it's alive. void* profile; }; explicit ProfileIOData(Profile::ProfileType profile_type); static std::string GetSSLSessionCacheShard(); void InitializeOnUIThread(Profile* profile); void ApplyProfileParamsToContext(net::URLRequestContext* context) const; scoped_ptr SetUpJobFactoryDefaults( scoped_ptr job_factory, content::URLRequestInterceptorScopedVector request_interceptors, scoped_ptr protocol_handler_interceptor, net::NetworkDelegate* network_delegate, net::FtpTransactionFactory* ftp_transaction_factory) const; // Called when the profile is destroyed. void ShutdownOnUIThread( scoped_ptr context_getters); // A ChannelIDService object is created by a derived class of // ProfileIOData, and the derived class calls this method to set the // channel_id_service_ member and transfers ownership to the base // class. void set_channel_id_service( net::ChannelIDService* channel_id_service) const; void set_data_reduction_proxy_io_data( scoped_ptr data_reduction_proxy_io_data) const; net::FraudulentCertificateReporter* fraudulent_certificate_reporter() const { return fraudulent_certificate_reporter_.get(); } net::ProxyService* proxy_service() const { return proxy_service_.get(); } base::WeakPtr http_server_properties() const; void set_http_server_properties( scoped_ptr http_server_properties) const; net::URLRequestContext* main_request_context() const { return main_request_context_.get(); } bool initialized() const { return initialized_; } // Destroys the ResourceContext first, to cancel any URLRequests that are // using it still, before we destroy the member variables that those // URLRequests may be accessing. void DestroyResourceContext(); // Creates network session and main network transaction factory. scoped_ptr CreateMainHttpFactory( const ProfileParams* profile_params, net::HttpCache::BackendFactory* main_backend) const; // Creates network transaction factory. scoped_ptr CreateHttpFactory( net::HttpNetworkSession* shared_session, net::HttpCache::BackendFactory* backend) const; void SetCookieSettingsForTesting(CookieSettings* cookie_settings); void set_signin_names_for_testing(SigninNamesOnIOThread* signin_names); private: class ResourceContext : public content::ResourceContext { public: explicit ResourceContext(ProfileIOData* io_data); ~ResourceContext() override; // ResourceContext implementation: net::HostResolver* GetHostResolver() override; net::URLRequestContext* GetRequestContext() override; scoped_ptr CreateClientCertStore() override; void CreateKeygenHandler( uint32 key_size_in_bits, const std::string& challenge_string, const GURL& url, const base::Callback)>& callback) override; SaltCallback GetMediaDeviceIDSalt() override; private: friend class ProfileIOData; ProfileIOData* const io_data_; net::HostResolver* host_resolver_; net::URLRequestContext* request_context_; }; typedef std::map URLRequestContextMap; // -------------------------------------------- // Virtual interface for subtypes to implement: // -------------------------------------------- // Does the actual initialization of the ProfileIOData subtype. Subtypes // should use the static helper functions above to implement this. virtual void InitializeInternal( scoped_ptr chrome_network_delegate, ProfileParams* profile_params, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) const = 0; // Initializes the RequestContext for extensions. virtual void InitializeExtensionsRequestContext( ProfileParams* profile_params) const = 0; // Does an on-demand initialization of a RequestContext for the given // isolated app. virtual net::URLRequestContext* InitializeAppRequestContext( net::URLRequestContext* main_context, const StoragePartitionDescriptor& details, scoped_ptr protocol_handler_interceptor, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) const = 0; // Does an on-demand initialization of a media RequestContext for the given // isolated app. virtual net::URLRequestContext* InitializeMediaRequestContext( net::URLRequestContext* original_context, const StoragePartitionDescriptor& details) const = 0; // These functions are used to transfer ownership of the lazily initialized // context from ProfileIOData to the URLRequestContextGetter. virtual net::URLRequestContext* AcquireMediaRequestContext() const = 0; virtual net::URLRequestContext* AcquireIsolatedAppRequestContext( net::URLRequestContext* main_context, const StoragePartitionDescriptor& partition_descriptor, scoped_ptr protocol_handler_interceptor, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) const = 0; virtual net::URLRequestContext* AcquireIsolatedMediaRequestContext( net::URLRequestContext* app_context, const StoragePartitionDescriptor& partition_descriptor) const = 0; // The order *DOES* matter for the majority of these member variables, so // don't move them around unless you know what you're doing! // General rules: // * ResourceContext references the URLRequestContexts, so // URLRequestContexts must outlive ResourceContext, hence ResourceContext // should be destroyed first. // * URLRequestContexts reference a whole bunch of members, so // URLRequestContext needs to be destroyed before them. // * Therefore, ResourceContext should be listed last, and then the // URLRequestContexts, and then the URLRequestContext members. // * Note that URLRequestContext members have a directed dependency graph // too, so they must themselves be ordered correctly. // Tracks whether or not we've been lazily initialized. mutable bool initialized_; // Data from the UI thread from the Profile, used to initialize ProfileIOData. // Deleted after lazy initialization. mutable scoped_ptr profile_params_; // Provides access to the email addresses of all signed in profiles. mutable scoped_ptr signin_names_; // Used for testing. mutable base::Callback()> client_cert_store_factory_; mutable StringPrefMember google_services_user_account_id_; mutable scoped_refptr media_device_id_salt_; // Member variables which are pointed to by the various context objects. mutable BooleanPrefMember enable_referrers_; mutable BooleanPrefMember enable_do_not_track_; mutable BooleanPrefMember force_google_safesearch_; mutable BooleanPrefMember force_youtube_safety_mode_; mutable BooleanPrefMember safe_browsing_enabled_; mutable BooleanPrefMember sync_disabled_; mutable BooleanPrefMember signin_allowed_; mutable IntegerPrefMember network_prediction_options_; // TODO(marja): Remove session_startup_pref_ if no longer needed. mutable IntegerPrefMember session_startup_pref_; mutable BooleanPrefMember quick_check_enabled_; mutable IntegerPrefMember incognito_availibility_pref_; // The state of metrics reporting in the browser that this profile runs on. // Unfortunately, since ChromeOS has a separate representation of this state, // we need to make one available based on the platform. #if defined(OS_CHROMEOS) bool enable_metrics_; #else BooleanPrefMember enable_metrics_; #endif #if defined(ENABLE_CONFIGURATION_POLICY) // Pointed to by NetworkDelegate. mutable scoped_ptr url_blacklist_manager_; mutable scoped_ptr policy_header_helper_; #endif // Pointed to by URLRequestContext. #if defined(ENABLE_EXTENSIONS) mutable scoped_refptr extension_info_map_; #endif mutable scoped_ptr channel_id_service_; mutable scoped_ptr data_reduction_proxy_io_data_; mutable scoped_ptr fraudulent_certificate_reporter_; mutable scoped_ptr proxy_service_; mutable scoped_ptr transport_security_state_; mutable scoped_ptr http_server_properties_; #if defined(OS_CHROMEOS) // Set to |cert_verifier_| if it references a PolicyCertVerifier. In that // case, the verifier is owned by |cert_verifier_|. Otherwise, set to NULL. mutable policy::PolicyCertVerifier* policy_cert_verifier_; mutable scoped_ptr cert_verifier_; mutable std::string username_hash_; mutable bool use_system_key_slot_; #endif mutable scoped_ptr transport_security_persister_; // These are only valid in between LazyInitialize() and their accessor being // called. mutable scoped_ptr main_request_context_; mutable scoped_ptr extensions_request_context_; // One URLRequestContext per isolated app for main and media requests. mutable URLRequestContextMap app_request_context_map_; mutable URLRequestContextMap isolated_media_request_context_map_; mutable scoped_ptr resource_context_; mutable scoped_refptr cookie_settings_; mutable scoped_refptr host_content_settings_map_; mutable scoped_ptr resource_prefetch_predictor_observer_; mutable scoped_ptr chrome_http_user_agent_settings_; #if defined(ENABLE_SUPERVISED_USERS) mutable scoped_refptr supervised_user_url_filter_; #endif mutable scoped_ptr network_controller_; // TODO(jhawkins): Remove once crbug.com/102004 is fixed. bool initialized_on_UI_thread_; const Profile::ProfileType profile_type_; DISALLOW_COPY_AND_ASSIGN(ProfileIOData); }; #endif // CHROME_BROWSER_PROFILES_PROFILE_IO_DATA_H_