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.
5 #include "chrome/browser/profiles/off_the_record_profile_impl.h"
8 #include "base/command_line.h"
9 #include "base/compiler_specific.h"
10 #include "base/files/file_path.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/path_service.h"
13 #include "base/prefs/json_pref_store.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h"
16 #include "build/build_config.h"
17 #include "chrome/browser/background/background_contents_service_factory.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/content_settings/host_content_settings_map.h"
20 #include "chrome/browser/download/chrome_download_manager_delegate.h"
21 #include "chrome/browser/download/download_service.h"
22 #include "chrome/browser/download/download_service_factory.h"
23 #include "chrome/browser/extensions/extension_service.h"
24 #include "chrome/browser/extensions/extension_special_storage_policy.h"
25 #include "chrome/browser/io_thread.h"
26 #include "chrome/browser/net/pref_proxy_config_tracker.h"
27 #include "chrome/browser/net/proxy_service_factory.h"
28 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
29 #include "chrome/browser/plugins/plugin_prefs.h"
30 #include "chrome/browser/prefs/incognito_mode_prefs.h"
31 #include "chrome/browser/prefs/pref_service_syncable.h"
32 #include "chrome/browser/themes/theme_service.h"
33 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
34 #include "chrome/common/chrome_constants.h"
35 #include "chrome/common/chrome_paths.h"
36 #include "chrome/common/chrome_switches.h"
37 #include "chrome/common/pref_names.h"
38 #include "chrome/common/render_messages.h"
39 #include "components/keyed_service/content/browser_context_dependency_manager.h"
40 #include "components/user_prefs/user_prefs.h"
41 #include "content/public/browser/browser_thread.h"
42 #include "content/public/browser/host_zoom_map.h"
43 #include "content/public/browser/render_process_host.h"
44 #include "content/public/browser/storage_partition.h"
45 #include "content/public/browser/url_data_source.h"
46 #include "content/public/browser/web_contents.h"
47 #include "extensions/browser/extension_system.h"
48 #include "extensions/common/extension.h"
49 #include "net/http/http_server_properties.h"
50 #include "net/http/transport_security_state.h"
51 #include "webkit/browser/database/database_tracker.h"
53 #if defined(OS_ANDROID)
54 #include "chrome/browser/media/protected_media_identifier_permission_context.h"
55 #include "chrome/browser/media/protected_media_identifier_permission_context_factory.h"
56 #endif // defined(OS_ANDROID)
58 #if defined(OS_ANDROID) || defined(OS_IOS)
59 #include "base/prefs/scoped_user_pref_update.h"
60 #include "chrome/browser/prefs/proxy_prefs.h"
61 #endif // defined(OS_ANDROID) || defined(OS_IOS)
63 #if defined(OS_CHROMEOS)
64 #include "chrome/browser/chromeos/preferences.h"
65 #include "chrome/browser/chromeos/profiles/profile_helper.h"
68 #if defined(ENABLE_CONFIGURATION_POLICY) && !defined(OS_CHROMEOS)
69 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
72 #if defined(ENABLE_EXTENSIONS)
73 #include "chrome/browser/guest_view/guest_view_manager.h"
76 #if defined(ENABLE_EXTENSIONS)
77 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
80 using content::BrowserThread;
81 using content::DownloadManagerDelegate;
82 using content::HostZoomMap;
84 #if defined(ENABLE_EXTENSIONS)
87 void NotifyOTRProfileCreatedOnIOThread(void* original_profile,
89 ExtensionWebRequestEventRouter::GetInstance()->OnOTRProfileCreated(
90 original_profile, otr_profile);
93 void NotifyOTRProfileDestroyedOnIOThread(void* original_profile,
95 ExtensionWebRequestEventRouter::GetInstance()->OnOTRProfileDestroyed(
96 original_profile, otr_profile);
102 OffTheRecordProfileImpl::OffTheRecordProfileImpl(Profile* real_profile)
103 : profile_(real_profile),
104 prefs_(PrefServiceSyncable::IncognitoFromProfile(real_profile)),
105 start_time_(Time::Now()) {
106 // Register on BrowserContext.
107 user_prefs::UserPrefs::Set(this, prefs_);
110 void OffTheRecordProfileImpl::Init() {
111 // The construction of OffTheRecordProfileIOData::Handle needs the profile
112 // type returned by this->GetProfileType(). Since GetProfileType() is a
113 // virtual member function, we cannot call the function defined in the most
114 // derived class (e.g. GuestSessionProfile) until a ctor finishes. Thus,
115 // we have to instantiate OffTheRecordProfileIOData::Handle here after a ctor.
118 #if defined(ENABLE_CONFIGURATION_POLICY) && !defined(OS_CHROMEOS)
119 // Because UserCloudPolicyManager is in a component, it cannot access
120 // GetOriginalProfile. Instead, we have to inject this relation here.
121 policy::UserCloudPolicyManagerFactory::RegisterForOffTheRecordBrowserContext(
122 this->GetOriginalProfile(), this);
125 BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
128 DCHECK_NE(IncognitoModePrefs::DISABLED,
129 IncognitoModePrefs::GetAvailability(profile_->GetPrefs()));
131 #if defined(OS_ANDROID) || defined(OS_IOS)
133 #endif // defined(OS_ANDROID) || defined(OS_IOS)
135 // TODO(oshima): Remove the need to eagerly initialize the request context
136 // getter. chromeos::OnlineAttempt is illegally trying to access this
137 // Profile member from a thread other than the UI thread, so we need to
139 #if defined(OS_CHROMEOS)
141 #endif // defined(OS_CHROMEOS)
145 // Make the chrome//extension-icon/ resource available.
146 extensions::ExtensionIconSource* icon_source =
147 new extensions::ExtensionIconSource(profile_);
148 content::URLDataSource::Add(this, icon_source);
150 #if defined(ENABLE_PLUGINS)
151 ChromePluginServiceFilter::GetInstance()->RegisterResourceContext(
152 PluginPrefs::GetForProfile(this).get(),
153 io_data_->GetResourceContextNoInit());
156 #if defined(ENABLE_EXTENSIONS)
157 BrowserThread::PostTask(
158 BrowserThread::IO, FROM_HERE,
159 base::Bind(&NotifyOTRProfileCreatedOnIOThread, profile_, this));
163 OffTheRecordProfileImpl::~OffTheRecordProfileImpl() {
164 MaybeSendDestroyedNotification();
166 #if defined(ENABLE_PLUGINS)
167 ChromePluginServiceFilter::GetInstance()->UnregisterResourceContext(
168 io_data_->GetResourceContextNoInit());
171 BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
174 #if defined(ENABLE_EXTENSIONS)
175 BrowserThread::PostTask(
176 BrowserThread::IO, FROM_HERE,
177 base::Bind(&NotifyOTRProfileDestroyedOnIOThread, profile_, this));
180 if (host_content_settings_map_.get())
181 host_content_settings_map_->ShutdownOnUIThread();
183 if (pref_proxy_config_tracker_)
184 pref_proxy_config_tracker_->DetachFromPrefService();
186 // Clears any data the network stack contains that may be related to the
188 g_browser_process->io_thread()->ChangedToOnTheRecord();
191 void OffTheRecordProfileImpl::InitIoData() {
192 io_data_.reset(new OffTheRecordProfileIOData::Handle(this));
195 void OffTheRecordProfileImpl::InitHostZoomMap() {
196 HostZoomMap* host_zoom_map = HostZoomMap::GetForBrowserContext(this);
197 HostZoomMap* parent_host_zoom_map =
198 HostZoomMap::GetForBrowserContext(profile_);
199 host_zoom_map->CopyFrom(parent_host_zoom_map);
200 // Observe parent's HZM change for propagating change of parent's
201 // change to this HZM.
202 zoom_subscription_ = parent_host_zoom_map->AddZoomLevelChangedCallback(
203 base::Bind(&OffTheRecordProfileImpl::OnZoomLevelChanged,
204 base::Unretained(this)));
207 #if defined(OS_ANDROID) || defined(OS_IOS)
208 void OffTheRecordProfileImpl::UseSystemProxy() {
209 // Force the use of the system-assigned proxy when off the record.
210 const char kProxyMode[] = "mode";
211 const char kProxyServer[] = "server";
212 const char kProxyBypassList[] = "bypass_list";
213 const char kProxyPacUrl[] = "pac_url";
214 DictionaryPrefUpdate update(prefs_, prefs::kProxy);
215 base::DictionaryValue* dict = update.Get();
216 dict->SetString(kProxyMode, ProxyModeToString(ProxyPrefs::MODE_SYSTEM));
217 dict->SetString(kProxyPacUrl, "");
218 dict->SetString(kProxyServer, "");
219 dict->SetString(kProxyBypassList, "");
221 #endif // defined(OS_ANDROID) || defined(OS_IOS)
223 std::string OffTheRecordProfileImpl::GetProfileName() {
224 // Incognito profile should not return the profile name.
225 return std::string();
228 Profile::ProfileType OffTheRecordProfileImpl::GetProfileType() const {
229 return INCOGNITO_PROFILE;
232 base::FilePath OffTheRecordProfileImpl::GetPath() const {
233 return profile_->GetPath();
236 scoped_refptr<base::SequencedTaskRunner>
237 OffTheRecordProfileImpl::GetIOTaskRunner() {
238 return profile_->GetIOTaskRunner();
241 bool OffTheRecordProfileImpl::IsOffTheRecord() const {
245 Profile* OffTheRecordProfileImpl::GetOffTheRecordProfile() {
249 void OffTheRecordProfileImpl::DestroyOffTheRecordProfile() {
254 bool OffTheRecordProfileImpl::HasOffTheRecordProfile() {
258 Profile* OffTheRecordProfileImpl::GetOriginalProfile() {
262 ExtensionService* OffTheRecordProfileImpl::GetExtensionService() {
263 return extensions::ExtensionSystem::Get(this)->extension_service();
266 ExtensionSpecialStoragePolicy*
267 OffTheRecordProfileImpl::GetExtensionSpecialStoragePolicy() {
268 return GetOriginalProfile()->GetExtensionSpecialStoragePolicy();
271 bool OffTheRecordProfileImpl::IsSupervised() {
272 return GetOriginalProfile()->IsSupervised();
275 PrefService* OffTheRecordProfileImpl::GetPrefs() {
279 PrefService* OffTheRecordProfileImpl::GetOffTheRecordPrefs() {
283 DownloadManagerDelegate* OffTheRecordProfileImpl::GetDownloadManagerDelegate() {
284 return DownloadServiceFactory::GetForBrowserContext(this)->
285 GetDownloadManagerDelegate();
288 net::URLRequestContextGetter* OffTheRecordProfileImpl::GetRequestContext() {
289 return GetDefaultStoragePartition(this)->GetURLRequestContext();
292 net::URLRequestContextGetter* OffTheRecordProfileImpl::CreateRequestContext(
293 content::ProtocolHandlerMap* protocol_handlers,
294 content::URLRequestInterceptorScopedVector request_interceptors) {
295 return io_data_->CreateMainRequestContextGetter(
296 protocol_handlers, request_interceptors.Pass()).get();
299 net::URLRequestContextGetter*
300 OffTheRecordProfileImpl::GetRequestContextForRenderProcess(
301 int renderer_child_id) {
302 content::RenderProcessHost* rph = content::RenderProcessHost::FromID(
304 return rph->GetStoragePartition()->GetURLRequestContext();
307 net::URLRequestContextGetter*
308 OffTheRecordProfileImpl::GetMediaRequestContext() {
309 // In OTR mode, media request context is the same as the original one.
310 return GetRequestContext();
313 net::URLRequestContextGetter*
314 OffTheRecordProfileImpl::GetMediaRequestContextForRenderProcess(
315 int renderer_child_id) {
316 // In OTR mode, media request context is the same as the original one.
317 return GetRequestContextForRenderProcess(renderer_child_id);
320 net::URLRequestContextGetter*
321 OffTheRecordProfileImpl::GetMediaRequestContextForStoragePartition(
322 const base::FilePath& partition_path,
324 return io_data_->GetIsolatedAppRequestContextGetter(partition_path, in_memory)
328 net::URLRequestContextGetter*
329 OffTheRecordProfileImpl::GetRequestContextForExtensions() {
330 return io_data_->GetExtensionsRequestContextGetter().get();
333 net::URLRequestContextGetter*
334 OffTheRecordProfileImpl::CreateRequestContextForStoragePartition(
335 const base::FilePath& partition_path,
337 content::ProtocolHandlerMap* protocol_handlers,
338 content::URLRequestInterceptorScopedVector request_interceptors) {
339 return io_data_->CreateIsolatedAppRequestContextGetter(
343 request_interceptors.Pass()).get();
346 content::ResourceContext* OffTheRecordProfileImpl::GetResourceContext() {
347 return io_data_->GetResourceContext();
350 net::SSLConfigService* OffTheRecordProfileImpl::GetSSLConfigService() {
351 return profile_->GetSSLConfigService();
354 HostContentSettingsMap* OffTheRecordProfileImpl::GetHostContentSettingsMap() {
355 // Retrieve the host content settings map of the parent profile in order to
356 // ensure the preferences have been migrated.
357 profile_->GetHostContentSettingsMap();
358 if (!host_content_settings_map_.get()) {
359 host_content_settings_map_ = new HostContentSettingsMap(GetPrefs(), true);
360 #if defined(ENABLE_EXTENSIONS)
361 ExtensionService* extension_service = GetExtensionService();
362 if (extension_service)
363 host_content_settings_map_->RegisterExtensionService(extension_service);
366 return host_content_settings_map_.get();
369 content::BrowserPluginGuestManager*
370 OffTheRecordProfileImpl::GetGuestManager() {
371 #if defined(ENABLE_EXTENSIONS)
372 return GuestViewManager::FromBrowserContext(this);
378 quota::SpecialStoragePolicy*
379 OffTheRecordProfileImpl::GetSpecialStoragePolicy() {
380 return GetExtensionSpecialStoragePolicy();
383 content::PushMessagingService*
384 OffTheRecordProfileImpl::GetPushMessagingService() {
385 // TODO(johnme): Support push messaging in incognito if possible.
389 bool OffTheRecordProfileImpl::IsSameProfile(Profile* profile) {
390 return (profile == this) || (profile == profile_);
393 Time OffTheRecordProfileImpl::GetStartTime() const {
397 history::TopSites* OffTheRecordProfileImpl::GetTopSitesWithoutCreating() {
401 history::TopSites* OffTheRecordProfileImpl::GetTopSites() {
405 void OffTheRecordProfileImpl::SetExitType(ExitType exit_type) {
408 base::FilePath OffTheRecordProfileImpl::last_selected_directory() {
409 const base::FilePath& directory = last_selected_directory_;
410 if (directory.empty()) {
411 return profile_->last_selected_directory();
416 void OffTheRecordProfileImpl::set_last_selected_directory(
417 const base::FilePath& path) {
418 last_selected_directory_ = path;
421 bool OffTheRecordProfileImpl::WasCreatedByVersionOrLater(
422 const std::string& version) {
423 return profile_->WasCreatedByVersionOrLater(version);
426 Profile::ExitType OffTheRecordProfileImpl::GetLastSessionExitType() {
427 return profile_->GetLastSessionExitType();
430 #if defined(OS_CHROMEOS)
431 void OffTheRecordProfileImpl::ChangeAppLocale(const std::string& locale,
432 AppLocaleChangedVia) {
435 void OffTheRecordProfileImpl::OnLogin() {
438 void OffTheRecordProfileImpl::InitChromeOSPreferences() {
439 // The incognito profile shouldn't have Chrome OS's preferences.
440 // The preferences are associated with the regular user profile.
442 #endif // defined(OS_CHROMEOS)
444 PrefProxyConfigTracker* OffTheRecordProfileImpl::GetProxyConfigTracker() {
445 if (!pref_proxy_config_tracker_)
446 pref_proxy_config_tracker_.reset(CreateProxyConfigTracker());
447 return pref_proxy_config_tracker_.get();
450 chrome_browser_net::Predictor* OffTheRecordProfileImpl::GetNetworkPredictor() {
451 // We do not store information about websites visited in OTR profiles which
452 // is necessary for a Predictor, so we do not have a Predictor at all.
456 DevToolsNetworkController*
457 OffTheRecordProfileImpl::GetDevToolsNetworkController() {
458 return io_data_->GetDevToolsNetworkController();
461 void OffTheRecordProfileImpl::ClearNetworkingHistorySince(
463 const base::Closure& completion) {
464 // Nothing to do here, our transport security state is read-only.
465 // Still, fire the callback to indicate we have finished, otherwise the
466 // BrowsingDataRemover will never be destroyed and the dialog will never be
467 // closed. We must do this asynchronously in order to avoid reentrancy issues.
468 if (!completion.is_null()) {
469 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, completion);
473 void OffTheRecordProfileImpl::ClearDomainReliabilityMonitor(
474 domain_reliability::DomainReliabilityClearMode mode,
475 const base::Closure& completion) {
476 // Incognito profiles don't have Domain Reliability Monitors, so there's
477 // nothing to do here.
478 if (!completion.is_null()) {
479 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, completion);
483 GURL OffTheRecordProfileImpl::GetHomePage() {
484 return profile_->GetHomePage();
487 #if defined(OS_CHROMEOS)
488 // Special case of the OffTheRecordProfileImpl which is used while Guest
490 class GuestSessionProfile : public OffTheRecordProfileImpl {
492 explicit GuestSessionProfile(Profile* real_profile)
493 : OffTheRecordProfileImpl(real_profile) {
496 virtual ProfileType GetProfileType() const OVERRIDE {
497 return GUEST_PROFILE;
500 virtual void InitChromeOSPreferences() OVERRIDE {
501 chromeos_preferences_.reset(new chromeos::Preferences());
502 chromeos_preferences_->Init(static_cast<PrefServiceSyncable*>(GetPrefs()),
503 chromeos::UserManager::Get()->GetActiveUser());
507 // The guest user should be able to customize Chrome OS preferences.
508 scoped_ptr<chromeos::Preferences> chromeos_preferences_;
512 Profile* Profile::CreateOffTheRecordProfile() {
513 OffTheRecordProfileImpl* profile = NULL;
514 #if defined(OS_CHROMEOS)
515 if (IsGuestSession())
516 profile = new GuestSessionProfile(this);
519 profile = new OffTheRecordProfileImpl(this);
524 void OffTheRecordProfileImpl::OnZoomLevelChanged(
525 const HostZoomMap::ZoomLevelChange& change) {
526 HostZoomMap* host_zoom_map = HostZoomMap::GetForBrowserContext(this);
527 switch (change.mode) {
528 case HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM:
530 case HostZoomMap::ZOOM_CHANGED_FOR_HOST:
531 host_zoom_map->SetZoomLevelForHost(change.host, change.zoom_level);
533 case HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST:
534 host_zoom_map->SetZoomLevelForHostAndScheme(change.scheme,
541 PrefProxyConfigTracker* OffTheRecordProfileImpl::CreateProxyConfigTracker() {
542 #if defined(OS_CHROMEOS)
543 if (chromeos::ProfileHelper::IsSigninProfile(this)) {
544 return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
545 g_browser_process->local_state());
547 #endif // defined(OS_CHROMEOS)
548 return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
549 GetPrefs(), g_browser_process->local_state());