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