// Copyright (c) 2011 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_ #pragma once #include <set> #include "base/basictypes.h" #include "base/debug/stack_trace.h" #include "base/file_path.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/synchronization/lock.h" #include "chrome/browser/net/chrome_url_request_context.h" #include "chrome/browser/prefs/pref_member.h" #include "chrome/browser/profiles/profile.h" #include "content/browser/resource_context.h" #include "net/base/cookie_monster.h" class CommandLine; class ChromeAppCacheService; class ChromeBlobStorageContext; class ExtensionInfoMap; namespace fileapi { class FileSystemContext; } // namespace fileapi class HostContentSettingsMap; class HostZoomMap; class IOThread; namespace net { class DnsCertProvenanceChecker; class NetLog; class ProxyConfigService; class ProxyService; class SSLConfigService; class TransportSecurityState; } // namespace net namespace prerender { class PrerenderManager; }; // namespace prerender class ProtocolHandlerRegistry; namespace webkit_database { class DatabaseTracker; } // webkit_database // 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. The Profile // implementation will maintain a reference to the ProfileIOData. The // ProfileIOData will originally own a reference to the ChromeURLRequestContexts // that reference its members. When an accessor for a ChromeURLRequestContext is // invoked, then ProfileIOData will release its reference to the // ChromeURLRequestContext and the ChromeURLRequestContext will acquire a // reference to the ProfileIOData, so they exchange ownership. This is done // because it's possible for a context's accessor never to be invoked, so this // ownership reversal prevents shutdown leaks. ProfileIOData will lazily // initialize its members on the first invocation of a ChromeURLRequestContext // accessor. class ProfileIOData : public base::RefCountedThreadSafe<ProfileIOData> { public: // These should only be called at most once each. Ownership is reversed when // they get called, from ProfileIOData owning ChromeURLRequestContext to vice // versa. scoped_refptr<ChromeURLRequestContext> GetMainRequestContext() const; scoped_refptr<ChromeURLRequestContext> GetMediaRequestContext() const; scoped_refptr<ChromeURLRequestContext> GetExtensionsRequestContext() const; scoped_refptr<ChromeURLRequestContext> GetIsolatedAppRequestContext( scoped_refptr<ChromeURLRequestContext> main_context, const std::string& app_id) const; const content::ResourceContext& GetResourceContext() const; protected: friend class base::RefCountedThreadSafe<ProfileIOData>; class RequestContext : public ChromeURLRequestContext { public: RequestContext(); ~RequestContext(); // Setter is used to transfer ownership of the ProfileIOData to the context. void set_profile_io_data(const ProfileIOData* profile_io_data) { profile_io_data_ = profile_io_data; } private: scoped_refptr<const ProfileIOData> profile_io_data_; }; // Created on the UI thread, read on the IO thread during ProfileIOData lazy // initialization. struct ProfileParams { ProfileParams(); ~ProfileParams(); bool is_incognito; bool clear_local_state_on_exit; std::string accept_language; std::string accept_charset; std::string referrer_charset; FilePath user_script_dir_path; IOThread* io_thread; scoped_refptr<HostContentSettingsMap> host_content_settings_map; scoped_refptr<HostZoomMap> host_zoom_map; scoped_refptr<net::TransportSecurityState> transport_security_state; scoped_refptr<net::SSLConfigService> ssl_config_service; scoped_refptr<net::CookieMonster::Delegate> cookie_monster_delegate; scoped_refptr<webkit_database::DatabaseTracker> database_tracker; scoped_refptr<ChromeAppCacheService> appcache_service; scoped_refptr<ChromeBlobStorageContext> blob_storage_context; scoped_refptr<fileapi::FileSystemContext> file_system_context; scoped_refptr<ExtensionInfoMap> extension_info_map; scoped_refptr<prerender::PrerenderManager> prerender_manager; scoped_refptr<ProtocolHandlerRegistry> protocol_handler_registry; // 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<net::ProxyConfigService> proxy_config_service; // The profile this struct was populated from. ProfileId profile_id; }; explicit ProfileIOData(bool is_incognito); virtual ~ProfileIOData(); void InitializeProfileParams(Profile* profile); void ApplyProfileParamsToContext(ChromeURLRequestContext* context) const; // Lazy initializes the ProfileIOData object the first time a request context // is requested. The lazy logic is implemented here. The actual initialization // is done in LazyInitializeInternal(), implemented by subtypes. Static helper // functions have been provided to assist in common operations. void LazyInitialize() const; // Called when the profile is destroyed. void ShutdownOnUIThread(); BooleanPrefMember* enable_referrers() const { return &enable_referrers_; } net::NetworkDelegate* network_delegate() const { return network_delegate_.get(); } net::DnsCertProvenanceChecker* dns_cert_checker() const { return dns_cert_checker_.get(); } net::ProxyService* proxy_service() const { return proxy_service_.get(); } net::CookiePolicy* cookie_policy() const { return cookie_policy_.get(); } ChromeURLRequestContext* main_request_context() const { return main_request_context_; } ChromeURLRequestContext* extensions_request_context() const { return extensions_request_context_; } private: class ResourceContext : public content::ResourceContext { public: explicit ResourceContext(const ProfileIOData* io_data); virtual ~ResourceContext(); private: virtual void EnsureInitialized() const; const ProfileIOData* const io_data_; }; // -------------------------------------------- // 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 LazyInitializeInternal(ProfileParams* profile_params) const = 0; // Does an on-demand initialization of a RequestContext for the given // isolated app. virtual scoped_refptr<RequestContext> InitializeAppRequestContext( scoped_refptr<ChromeURLRequestContext> main_context, const std::string& app_id) const = 0; // These functions are used to transfer ownership of the lazily initialized // context from ProfileIOData to the URLRequestContextGetter. virtual scoped_refptr<ChromeURLRequestContext> AcquireMediaRequestContext() const = 0; virtual scoped_refptr<ChromeURLRequestContext> AcquireIsolatedAppRequestContext( scoped_refptr<ChromeURLRequestContext> main_context, const std::string& app_id) const = 0; // 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<ProfileParams> profile_params_; // Member variables which are pointed to by the various context objects. mutable BooleanPrefMember enable_referrers_; // Pointed to by URLRequestContext. mutable scoped_ptr<net::NetworkDelegate> network_delegate_; mutable scoped_ptr<net::DnsCertProvenanceChecker> dns_cert_checker_; mutable scoped_refptr<net::ProxyService> proxy_service_; mutable scoped_ptr<net::CookiePolicy> cookie_policy_; // Pointed to by ResourceContext. mutable scoped_refptr<webkit_database::DatabaseTracker> database_tracker_; mutable scoped_refptr<ChromeAppCacheService> appcache_service_; mutable scoped_refptr<ChromeBlobStorageContext> blob_storage_context_; mutable scoped_refptr<fileapi::FileSystemContext> file_system_context_; mutable ResourceContext resource_context_; // These are only valid in between LazyInitialize() and their accessor being // called. mutable scoped_refptr<RequestContext> main_request_context_; mutable scoped_refptr<RequestContext> extensions_request_context_; DISALLOW_COPY_AND_ASSIGN(ProfileIOData); }; #endif // CHROME_BROWSER_PROFILES_PROFILE_IO_DATA_H_