1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_PROFILES_PROFILE_IO_DATA_H_
6#define CHROME_BROWSER_PROFILES_PROFILE_IO_DATA_H_
7#pragma once
8
9#include <set>
10#include "base/basictypes.h"
11#include "base/debug/stack_trace.h"
12#include "base/file_path.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/synchronization/lock.h"
16#include "chrome/browser/net/chrome_url_request_context.h"
17#include "chrome/browser/prefs/pref_member.h"
18#include "chrome/browser/profiles/profile.h"
19#include "content/browser/resource_context.h"
20#include "net/base/cookie_monster.h"
21
22class CommandLine;
23class ChromeAppCacheService;
24class ChromeBlobStorageContext;
25class ExtensionInfoMap;
26namespace fileapi {
27class FileSystemContext;
28}  // namespace fileapi
29class HostContentSettingsMap;
30class HostZoomMap;
31class IOThread;
32namespace net {
33class DnsCertProvenanceChecker;
34class NetLog;
35class ProxyConfigService;
36class ProxyService;
37class SSLConfigService;
38class TransportSecurityState;
39}  // namespace net
40namespace prerender {
41class PrerenderManager;
42};  // namespace prerender
43class ProtocolHandlerRegistry;
44namespace webkit_database {
45class DatabaseTracker;
46}  // webkit_database
47
48// Conceptually speaking, the ProfileIOData represents data that lives on the IO
49// thread that is owned by a Profile, such as, but not limited to, network
50// objects like CookieMonster, HttpTransactionFactory, etc. The Profile
51// implementation will maintain a reference to the ProfileIOData. The
52// ProfileIOData will originally own a reference to the ChromeURLRequestContexts
53// that reference its members. When an accessor for a ChromeURLRequestContext is
54// invoked, then ProfileIOData will release its reference to the
55// ChromeURLRequestContext and the ChromeURLRequestContext will acquire a
56// reference to the ProfileIOData, so they exchange ownership. This is done
57// because it's possible for a context's accessor never to be invoked, so this
58// ownership reversal prevents shutdown leaks. ProfileIOData will lazily
59// initialize its members on the first invocation of a ChromeURLRequestContext
60// accessor.
61class ProfileIOData : public base::RefCountedThreadSafe<ProfileIOData> {
62 public:
63  // These should only be called at most once each. Ownership is reversed when
64  // they get called, from ProfileIOData owning ChromeURLRequestContext to vice
65  // versa.
66  scoped_refptr<ChromeURLRequestContext> GetMainRequestContext() const;
67  scoped_refptr<ChromeURLRequestContext> GetMediaRequestContext() const;
68  scoped_refptr<ChromeURLRequestContext> GetExtensionsRequestContext() const;
69  scoped_refptr<ChromeURLRequestContext> GetIsolatedAppRequestContext(
70      scoped_refptr<ChromeURLRequestContext> main_context,
71      const std::string& app_id) const;
72  const content::ResourceContext& GetResourceContext() const;
73
74 protected:
75  friend class base::RefCountedThreadSafe<ProfileIOData>;
76
77  class RequestContext : public ChromeURLRequestContext {
78   public:
79    RequestContext();
80    ~RequestContext();
81
82    // Setter is used to transfer ownership of the ProfileIOData to the context.
83    void set_profile_io_data(const ProfileIOData* profile_io_data) {
84      profile_io_data_ = profile_io_data;
85    }
86
87   private:
88    scoped_refptr<const ProfileIOData> profile_io_data_;
89  };
90
91  // Created on the UI thread, read on the IO thread during ProfileIOData lazy
92  // initialization.
93  struct ProfileParams {
94    ProfileParams();
95    ~ProfileParams();
96
97    bool is_incognito;
98    bool clear_local_state_on_exit;
99    std::string accept_language;
100    std::string accept_charset;
101    std::string referrer_charset;
102    FilePath user_script_dir_path;
103    IOThread* io_thread;
104    scoped_refptr<HostContentSettingsMap> host_content_settings_map;
105    scoped_refptr<HostZoomMap> host_zoom_map;
106    scoped_refptr<net::TransportSecurityState> transport_security_state;
107    scoped_refptr<net::SSLConfigService> ssl_config_service;
108    scoped_refptr<net::CookieMonster::Delegate> cookie_monster_delegate;
109    scoped_refptr<webkit_database::DatabaseTracker> database_tracker;
110    scoped_refptr<ChromeAppCacheService> appcache_service;
111    scoped_refptr<ChromeBlobStorageContext> blob_storage_context;
112    scoped_refptr<fileapi::FileSystemContext> file_system_context;
113    scoped_refptr<ExtensionInfoMap> extension_info_map;
114    scoped_refptr<prerender::PrerenderManager> prerender_manager;
115    scoped_refptr<ProtocolHandlerRegistry> protocol_handler_registry;
116    // We need to initialize the ProxyConfigService from the UI thread
117    // because on linux it relies on initializing things through gconf,
118    // and needs to be on the main thread.
119    scoped_ptr<net::ProxyConfigService> proxy_config_service;
120    // The profile this struct was populated from.
121    ProfileId profile_id;
122  };
123
124  explicit ProfileIOData(bool is_incognito);
125  virtual ~ProfileIOData();
126
127  void InitializeProfileParams(Profile* profile);
128  void ApplyProfileParamsToContext(ChromeURLRequestContext* context) const;
129
130  // Lazy initializes the ProfileIOData object the first time a request context
131  // is requested. The lazy logic is implemented here. The actual initialization
132  // is done in LazyInitializeInternal(), implemented by subtypes. Static helper
133  // functions have been provided to assist in common operations.
134  void LazyInitialize() const;
135
136  // Called when the profile is destroyed.
137  void ShutdownOnUIThread();
138
139  BooleanPrefMember* enable_referrers() const {
140    return &enable_referrers_;
141  }
142
143  net::NetworkDelegate* network_delegate() const {
144    return network_delegate_.get();
145  }
146
147  net::DnsCertProvenanceChecker* dns_cert_checker() const {
148    return dns_cert_checker_.get();
149  }
150
151  net::ProxyService* proxy_service() const {
152    return proxy_service_.get();
153  }
154
155  net::CookiePolicy* cookie_policy() const {
156    return cookie_policy_.get();
157  }
158
159  ChromeURLRequestContext* main_request_context() const {
160    return main_request_context_;
161  }
162
163  ChromeURLRequestContext* extensions_request_context() const {
164    return extensions_request_context_;
165  }
166
167 private:
168  class ResourceContext : public content::ResourceContext {
169   public:
170    explicit ResourceContext(const ProfileIOData* io_data);
171    virtual ~ResourceContext();
172
173   private:
174    virtual void EnsureInitialized() const;
175
176    const ProfileIOData* const io_data_;
177  };
178
179  // --------------------------------------------
180  // Virtual interface for subtypes to implement:
181  // --------------------------------------------
182
183  // Does the actual initialization of the ProfileIOData subtype. Subtypes
184  // should use the static helper functions above to implement this.
185  virtual void LazyInitializeInternal(ProfileParams* profile_params) const = 0;
186
187  // Does an on-demand initialization of a RequestContext for the given
188  // isolated app.
189  virtual scoped_refptr<RequestContext> InitializeAppRequestContext(
190      scoped_refptr<ChromeURLRequestContext> main_context,
191      const std::string& app_id) const = 0;
192
193  // These functions are used to transfer ownership of the lazily initialized
194  // context from ProfileIOData to the URLRequestContextGetter.
195  virtual scoped_refptr<ChromeURLRequestContext>
196      AcquireMediaRequestContext() const = 0;
197  virtual scoped_refptr<ChromeURLRequestContext>
198      AcquireIsolatedAppRequestContext(
199          scoped_refptr<ChromeURLRequestContext> main_context,
200          const std::string& app_id) const = 0;
201
202  // Tracks whether or not we've been lazily initialized.
203  mutable bool initialized_;
204
205  // Data from the UI thread from the Profile, used to initialize ProfileIOData.
206  // Deleted after lazy initialization.
207  mutable scoped_ptr<ProfileParams> profile_params_;
208
209  // Member variables which are pointed to by the various context objects.
210  mutable BooleanPrefMember enable_referrers_;
211
212  // Pointed to by URLRequestContext.
213  mutable scoped_ptr<net::NetworkDelegate> network_delegate_;
214  mutable scoped_ptr<net::DnsCertProvenanceChecker> dns_cert_checker_;
215  mutable scoped_refptr<net::ProxyService> proxy_service_;
216  mutable scoped_ptr<net::CookiePolicy> cookie_policy_;
217
218  // Pointed to by ResourceContext.
219  mutable scoped_refptr<webkit_database::DatabaseTracker> database_tracker_;
220  mutable scoped_refptr<ChromeAppCacheService> appcache_service_;
221  mutable scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
222  mutable scoped_refptr<fileapi::FileSystemContext> file_system_context_;
223
224  mutable ResourceContext resource_context_;
225
226  // These are only valid in between LazyInitialize() and their accessor being
227  // called.
228  mutable scoped_refptr<RequestContext> main_request_context_;
229  mutable scoped_refptr<RequestContext> extensions_request_context_;
230
231  DISALLOW_COPY_AND_ASSIGN(ProfileIOData);
232};
233
234#endif  // CHROME_BROWSER_PROFILES_PROFILE_IO_DATA_H_
235