profile_io_data.h 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#ifndef CHROME_BROWSER_PROFILES_PROFILE_IO_DATA_H_
6#define CHROME_BROWSER_PROFILES_PROFILE_IO_DATA_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/callback_forward.h"
12#include "base/file_path.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/weak_ptr.h"
16#include "base/synchronization/lock.h"
17#include "chrome/browser/api/prefs/pref_member.h"
18#include "chrome/browser/io_thread.h"
19#include "chrome/browser/net/chrome_url_request_context.h"
20#include "chrome/browser/profiles/storage_partition_descriptor.h"
21#include "content/public/browser/resource_context.h"
22#include "net/cookies/cookie_monster.h"
23#include "net/http/http_network_session.h"
24#include "net/url_request/url_request_job_factory.h"
25
26class ChromeHttpUserAgentSettings;
27class CookieSettings;
28class DesktopNotificationService;
29class ExtensionInfoMap;
30class HostContentSettingsMap;
31class Profile;
32class ProtocolHandlerRegistry;
33class SigninNamesOnIOThread;
34class TransportSecurityPersister;
35
36namespace chrome_browser_net {
37class LoadTimeStats;
38class HttpServerPropertiesManager;
39class ResourcePrefetchPredictorObserver;
40}
41
42namespace net {
43class CookieStore;
44class FraudulentCertificateReporter;
45class HttpTransactionFactory;
46class ServerBoundCertService;
47class ProxyConfigService;
48class ProxyService;
49class SSLConfigService;
50class TransportSecurityState;
51class URLRequestJobFactoryImpl;
52}  // namespace net
53
54namespace policy {
55class URLBlacklistManager;
56}  // namespace policy
57
58// Conceptually speaking, the ProfileIOData represents data that lives on the IO
59// thread that is owned by a Profile, such as, but not limited to, network
60// objects like CookieMonster, HttpTransactionFactory, etc.  Profile owns
61// ProfileIOData, but will make sure to delete it on the IO thread (except
62// possibly in unit tests where there is no IO thread).
63class ProfileIOData {
64 public:
65  virtual ~ProfileIOData();
66
67  static ProfileIOData* FromResourceContext(content::ResourceContext* rc);
68
69  // Returns true if |scheme| is handled in Chrome, or by default handlers in
70  // net::URLRequest.
71  static bool IsHandledProtocol(const std::string& scheme);
72
73  // Returns true if |url| is handled in Chrome, or by default handlers in
74  // net::URLRequest.
75  static bool IsHandledURL(const GURL& url);
76
77  // Called by Profile.
78  content::ResourceContext* GetResourceContext() const;
79  ChromeURLDataManagerBackend* GetChromeURLDataManagerBackend() const;
80
81  // These should only be called at most once each. Ownership is reversed when
82  // they get called, from ProfileIOData owning ChromeURLRequestContext to vice
83  // versa.
84  ChromeURLRequestContext* GetMainRequestContext() const;
85  ChromeURLRequestContext* GetMediaRequestContext() const;
86  ChromeURLRequestContext* GetExtensionsRequestContext() const;
87  ChromeURLRequestContext* GetIsolatedAppRequestContext(
88      ChromeURLRequestContext* main_context,
89      const StoragePartitionDescriptor& partition_descriptor,
90      scoped_ptr<net::URLRequestJobFactory::Interceptor>
91          protocol_handler_interceptor) const;
92  ChromeURLRequestContext* GetIsolatedMediaRequestContext(
93      ChromeURLRequestContext* app_context,
94      const StoragePartitionDescriptor& partition_descriptor) const;
95
96  // These are useful when the Chrome layer is called from the content layer
97  // with a content::ResourceContext, and they want access to Chrome data for
98  // that profile.
99  ExtensionInfoMap* GetExtensionInfoMap() const;
100  CookieSettings* GetCookieSettings() const;
101
102#if defined(ENABLE_NOTIFICATIONS)
103  DesktopNotificationService* GetNotificationService() const;
104#endif
105
106  IntegerPrefMember* session_startup_pref() const {
107    return &session_startup_pref_;
108  }
109
110  SigninNamesOnIOThread* signin_names() const {
111    return signin_names_.get();
112  }
113
114  StringPrefMember* google_services_username() const {
115    return &google_services_username_;
116  }
117
118  StringPrefMember* google_services_username_pattern() const {
119    return &google_services_username_pattern_;
120  }
121
122  BooleanPrefMember* reverse_autologin_enabled() const {
123    return &reverse_autologin_enabled_;
124  }
125
126  StringListPrefMember* one_click_signin_rejected_email_list() const {
127    return &one_click_signin_rejected_email_list_;
128  }
129
130  ChromeURLRequestContext* extensions_request_context() const {
131    return extensions_request_context_.get();
132  }
133
134  BooleanPrefMember* safe_browsing_enabled() const {
135    return &safe_browsing_enabled_;
136  }
137
138  BooleanPrefMember* printing_enabled() const {
139    return &printing_enabled_;
140  }
141
142  net::TransportSecurityState* transport_security_state() const {
143    return transport_security_state_.get();
144  }
145
146  chrome_browser_net::HttpServerPropertiesManager*
147      http_server_properties_manager() const;
148
149  bool is_incognito() const {
150    return is_incognito_;
151  }
152
153  chrome_browser_net::ResourcePrefetchPredictorObserver*
154      resource_prefetch_predictor_observer() const {
155    return resource_prefetch_predictor_observer_.get();
156  }
157
158  // Initialize the member needed to track the metrics enabled state. This is
159  // only to be called on the UI thread.
160  void InitializeMetricsEnabledStateOnUIThread();
161
162  // Returns whether or not metrics reporting is enabled in the browser instance
163  // on which this profile resides. This is safe for use from the IO thread, and
164  // should only be called from there.
165  bool GetMetricsEnabledStateOnIOThread() const;
166
167 protected:
168  // A URLRequestContext for media that owns its HTTP factory, to ensure
169  // it is deleted.
170  class MediaRequestContext : public ChromeURLRequestContext {
171   public:
172    explicit MediaRequestContext(
173        chrome_browser_net::LoadTimeStats* load_time_stats);
174
175    void SetHttpTransactionFactory(
176        scoped_ptr<net::HttpTransactionFactory> http_factory);
177
178   private:
179    virtual ~MediaRequestContext();
180
181    scoped_ptr<net::HttpTransactionFactory> http_factory_;
182  };
183
184  // A URLRequestContext for apps that owns its cookie store and HTTP factory,
185  // to ensure they are deleted.
186  class AppRequestContext : public ChromeURLRequestContext {
187   public:
188    explicit AppRequestContext(
189        chrome_browser_net::LoadTimeStats* load_time_stats);
190
191    void SetCookieStore(net::CookieStore* cookie_store);
192    void SetHttpTransactionFactory(
193        scoped_ptr<net::HttpTransactionFactory> http_factory);
194    void SetJobFactory(scoped_ptr<net::URLRequestJobFactory> job_factory);
195
196   private:
197    virtual ~AppRequestContext();
198
199    scoped_refptr<net::CookieStore> cookie_store_;
200    scoped_ptr<net::HttpTransactionFactory> http_factory_;
201    scoped_ptr<net::URLRequestJobFactory> job_factory_;
202  };
203
204  // Created on the UI thread, read on the IO thread during ProfileIOData lazy
205  // initialization.
206  struct ProfileParams {
207    ProfileParams();
208    ~ProfileParams();
209
210    FilePath path;
211    IOThread* io_thread;
212    scoped_refptr<CookieSettings> cookie_settings;
213    scoped_refptr<net::SSLConfigService> ssl_config_service;
214    scoped_refptr<net::CookieMonster::Delegate> cookie_monster_delegate;
215    scoped_refptr<ExtensionInfoMap> extension_info_map;
216    scoped_ptr<chrome_browser_net::ResourcePrefetchPredictorObserver>
217        resource_prefetch_predictor_observer_;
218
219#if defined(ENABLE_NOTIFICATIONS)
220    DesktopNotificationService* notification_service;
221#endif
222
223    // This pointer exists only as a means of conveying a url interceptor
224    // pointer from the protocol handler registry on the UI thread to the
225    // the URLRequestJobFactory on the IO thread. The consumer MUST take
226    // ownership of the object by calling release() on this pointer.
227    scoped_ptr<net::URLRequestJobFactory::Interceptor>
228        protocol_handler_interceptor;
229
230    // We need to initialize the ProxyConfigService from the UI thread
231    // because on linux it relies on initializing things through gconf,
232    // and needs to be on the main thread.
233    scoped_ptr<net::ProxyConfigService> proxy_config_service;
234    // The profile this struct was populated from. It's passed as a void* to
235    // ensure it's not accidently used on the IO thread. Before using it on the
236    // UI thread, call ProfileManager::IsValidProfile to ensure it's alive.
237    void* profile;
238  };
239
240  explicit ProfileIOData(bool is_incognito);
241
242  static std::string GetSSLSessionCacheShard();
243
244  void InitializeOnUIThread(Profile* profile);
245  void ApplyProfileParamsToContext(ChromeURLRequestContext* context) const;
246
247  void SetUpJobFactoryDefaults(
248      net::URLRequestJobFactoryImpl* job_factory,
249      scoped_ptr<net::URLRequestJobFactory::Interceptor>
250          protocol_handler_interceptor,
251      net::NetworkDelegate* network_delegate,
252      net::FtpTransactionFactory* ftp_transaction_factory,
253      net::FtpAuthCache* ftp_auth_cache) const;
254
255  // Lazy initializes the ProfileIOData object the first time a request context
256  // is requested. The lazy logic is implemented here. The actual initialization
257  // is done in LazyInitializeInternal(), implemented by subtypes. Static helper
258  // functions have been provided to assist in common operations.
259  void LazyInitialize() const;
260
261  // Called when the profile is destroyed.
262  void ShutdownOnUIThread();
263
264  ChromeURLDataManagerBackend* chrome_url_data_manager_backend() const {
265    return chrome_url_data_manager_backend_.get();
266  }
267
268  // A ServerBoundCertService object is created by a derived class of
269  // ProfileIOData, and the derived class calls this method to set the
270  // server_bound_cert_service_ member and transfers ownership to the base
271  // class.
272  void set_server_bound_cert_service(
273      net::ServerBoundCertService* server_bound_cert_service) const;
274
275  net::NetworkDelegate* network_delegate() const {
276    return network_delegate_.get();
277  }
278
279  net::FraudulentCertificateReporter* fraudulent_certificate_reporter() const {
280    return fraudulent_certificate_reporter_.get();
281  }
282
283  net::ProxyService* proxy_service() const {
284    return proxy_service_.get();
285  }
286
287  void set_http_server_properties_manager(
288      chrome_browser_net::HttpServerPropertiesManager* manager) const;
289
290  ChromeURLRequestContext* main_request_context() const {
291    return main_request_context_.get();
292  }
293
294  chrome_browser_net::LoadTimeStats* load_time_stats() const {
295    return load_time_stats_;
296  }
297
298  // Destroys the ResourceContext first, to cancel any URLRequests that are
299  // using it still, before we destroy the member variables that those
300  // URLRequests may be accessing.
301  void DestroyResourceContext();
302
303  // Fills in fields of params using values from main_request_context_ and the
304  // IOThread associated with profile_params.
305  void PopulateNetworkSessionParams(
306      const ProfileParams* profile_params,
307      net::HttpNetworkSession::Params* params) const;
308
309  void SetCookieSettingsForTesting(CookieSettings* cookie_settings);
310
311  void set_signin_names_for_testing(SigninNamesOnIOThread* signin_names);
312
313 private:
314  class ResourceContext : public content::ResourceContext {
315   public:
316    explicit ResourceContext(ProfileIOData* io_data);
317    virtual ~ResourceContext();
318
319    // ResourceContext implementation:
320    virtual net::HostResolver* GetHostResolver() OVERRIDE;
321    virtual net::URLRequestContext* GetRequestContext() OVERRIDE;
322
323   private:
324    friend class ProfileIOData;
325
326    void EnsureInitialized();
327
328    ProfileIOData* const io_data_;
329
330    net::HostResolver* host_resolver_;
331    net::URLRequestContext* request_context_;
332  };
333
334  typedef std::map<StoragePartitionDescriptor,
335                   ChromeURLRequestContext*,
336                   StoragePartitionDescriptorLess>
337      URLRequestContextMap;
338
339  // --------------------------------------------
340  // Virtual interface for subtypes to implement:
341  // --------------------------------------------
342
343  // Does the actual initialization of the ProfileIOData subtype. Subtypes
344  // should use the static helper functions above to implement this.
345  virtual void LazyInitializeInternal(ProfileParams* profile_params) const = 0;
346
347  // Does an on-demand initialization of a RequestContext for the given
348  // isolated app.
349  virtual ChromeURLRequestContext* InitializeAppRequestContext(
350      ChromeURLRequestContext* main_context,
351      const StoragePartitionDescriptor& details,
352      scoped_ptr<net::URLRequestJobFactory::Interceptor>
353          protocol_handler_interceptor) const = 0;
354
355  // Does an on-demand initialization of a media RequestContext for the given
356  // isolated app.
357  virtual ChromeURLRequestContext* InitializeMediaRequestContext(
358      ChromeURLRequestContext* original_context,
359      const StoragePartitionDescriptor& details) const = 0;
360
361  // These functions are used to transfer ownership of the lazily initialized
362  // context from ProfileIOData to the URLRequestContextGetter.
363  virtual ChromeURLRequestContext*
364      AcquireMediaRequestContext() const = 0;
365  virtual ChromeURLRequestContext*
366      AcquireIsolatedAppRequestContext(
367          ChromeURLRequestContext* main_context,
368          const StoragePartitionDescriptor& partition_descriptor,
369          scoped_ptr<net::URLRequestJobFactory::Interceptor>
370              protocol_handler_interceptor) const = 0;
371  virtual ChromeURLRequestContext*
372      AcquireIsolatedMediaRequestContext(
373          ChromeURLRequestContext* app_context,
374          const StoragePartitionDescriptor& partition_descriptor) const = 0;
375
376  // Returns the LoadTimeStats object to be used for this profile.
377  virtual chrome_browser_net::LoadTimeStats* GetLoadTimeStats(
378      IOThread::Globals* io_thread_globals) const = 0;
379
380  // The order *DOES* matter for the majority of these member variables, so
381  // don't move them around unless you know what you're doing!
382  // General rules:
383  //   * ResourceContext references the URLRequestContexts, so
384  //   URLRequestContexts must outlive ResourceContext, hence ResourceContext
385  //   should be destroyed first.
386  //   * URLRequestContexts reference a whole bunch of members, so
387  //   URLRequestContext needs to be destroyed before them.
388  //   * Therefore, ResourceContext should be listed last, and then the
389  //   URLRequestContexts, and then the URLRequestContext members.
390  //   * Note that URLRequestContext members have a directed dependency graph
391  //   too, so they must themselves be ordered correctly.
392
393  // Tracks whether or not we've been lazily initialized.
394  mutable bool initialized_;
395
396  // Data from the UI thread from the Profile, used to initialize ProfileIOData.
397  // Deleted after lazy initialization.
398  mutable scoped_ptr<ProfileParams> profile_params_;
399
400  // Provides access to the email addresses of all signed in profiles.
401  mutable scoped_ptr<SigninNamesOnIOThread> signin_names_;
402
403  mutable StringPrefMember google_services_username_;
404  mutable StringPrefMember google_services_username_pattern_;
405  mutable BooleanPrefMember reverse_autologin_enabled_;
406  mutable StringListPrefMember one_click_signin_rejected_email_list_;
407
408  // Member variables which are pointed to by the various context objects.
409  mutable BooleanPrefMember enable_referrers_;
410  mutable BooleanPrefMember enable_do_not_track_;
411  mutable BooleanPrefMember force_safesearch_;
412  mutable BooleanPrefMember safe_browsing_enabled_;
413  mutable BooleanPrefMember printing_enabled_;
414  // TODO(marja): Remove session_startup_pref_ if no longer needed.
415  mutable IntegerPrefMember session_startup_pref_;
416
417  // The state of metrics reporting in the browser that this profile runs on.
418  // Unfortunately, since ChromeOS has a separate representation of this state,
419  // we need to make one available based on the platform.
420#if defined(OS_CHROMEOS)
421  bool enable_metrics_;
422#else
423  BooleanPrefMember enable_metrics_;
424#endif
425
426  // Pointed to by NetworkDelegate.
427  mutable scoped_ptr<policy::URLBlacklistManager> url_blacklist_manager_;
428
429  // Pointed to by URLRequestContext.
430  mutable scoped_refptr<ExtensionInfoMap> extension_info_map_;
431  mutable scoped_ptr<ChromeURLDataManagerBackend>
432      chrome_url_data_manager_backend_;
433  mutable scoped_ptr<net::ServerBoundCertService> server_bound_cert_service_;
434  mutable scoped_ptr<net::NetworkDelegate> network_delegate_;
435  mutable scoped_ptr<net::FraudulentCertificateReporter>
436      fraudulent_certificate_reporter_;
437  mutable scoped_ptr<net::ProxyService> proxy_service_;
438  mutable scoped_ptr<net::TransportSecurityState> transport_security_state_;
439  mutable scoped_ptr<chrome_browser_net::HttpServerPropertiesManager>
440      http_server_properties_manager_;
441
442#if defined(ENABLE_NOTIFICATIONS)
443  mutable DesktopNotificationService* notification_service_;
444#endif
445
446  mutable scoped_ptr<TransportSecurityPersister>
447      transport_security_persister_;
448
449  // These are only valid in between LazyInitialize() and their accessor being
450  // called.
451  mutable scoped_ptr<ChromeURLRequestContext> main_request_context_;
452  mutable scoped_ptr<ChromeURLRequestContext> extensions_request_context_;
453  // One URLRequestContext per isolated app for main and media requests.
454  mutable URLRequestContextMap app_request_context_map_;
455  mutable URLRequestContextMap isolated_media_request_context_map_;
456
457  mutable scoped_ptr<ResourceContext> resource_context_;
458
459  mutable scoped_refptr<CookieSettings> cookie_settings_;
460
461  mutable scoped_ptr<chrome_browser_net::ResourcePrefetchPredictorObserver>
462      resource_prefetch_predictor_observer_;
463
464  mutable scoped_ptr<ChromeHttpUserAgentSettings>
465      chrome_http_user_agent_settings_;
466
467  mutable chrome_browser_net::LoadTimeStats* load_time_stats_;
468
469  // TODO(jhawkins): Remove once crbug.com/102004 is fixed.
470  bool initialized_on_UI_thread_;
471
472  bool is_incognito_;
473
474  DISALLOW_COPY_AND_ASSIGN(ProfileIOData);
475};
476
477#endif  // CHROME_BROWSER_PROFILES_PROFILE_IO_DATA_H_
478