Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / profiles / off_the_record_profile_impl.cc
blob3fd940a667dcd165d73c07b79e218f34c707500e
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"
7 #include "base/bind.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/api/web_request/web_request_api.h"
24 #include "chrome/browser/extensions/extension_service.h"
25 #include "chrome/browser/extensions/extension_special_storage_policy.h"
26 #include "chrome/browser/extensions/extension_system.h"
27 #include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
28 #include "chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h"
29 #include "chrome/browser/io_thread.h"
30 #include "chrome/browser/media/chrome_midi_permission_context.h"
31 #include "chrome/browser/media/chrome_midi_permission_context_factory.h"
32 #include "chrome/browser/net/pref_proxy_config_tracker.h"
33 #include "chrome/browser/net/proxy_service_factory.h"
34 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
35 #include "chrome/browser/plugins/plugin_prefs.h"
36 #include "chrome/browser/prefs/incognito_mode_prefs.h"
37 #include "chrome/browser/prefs/pref_service_syncable.h"
38 #include "chrome/browser/themes/theme_service.h"
39 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
40 #include "chrome/common/chrome_constants.h"
41 #include "chrome/common/chrome_paths.h"
42 #include "chrome/common/chrome_switches.h"
43 #include "chrome/common/pref_names.h"
44 #include "chrome/common/render_messages.h"
45 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
46 #include "components/user_prefs/user_prefs.h"
47 #include "content/public/browser/browser_thread.h"
48 #include "content/public/browser/host_zoom_map.h"
49 #include "content/public/browser/render_process_host.h"
50 #include "content/public/browser/storage_partition.h"
51 #include "content/public/browser/url_data_source.h"
52 #include "content/public/browser/web_contents.h"
53 #include "extensions/common/extension.h"
54 #include "net/http/http_server_properties.h"
55 #include "net/http/transport_security_state.h"
56 #include "webkit/browser/database/database_tracker.h"
58 #if defined(OS_ANDROID)
59 #include "chrome/browser/media/protected_media_identifier_permission_context.h"
60 #include "chrome/browser/media/protected_media_identifier_permission_context_factory.h"
61 #endif // defined(OS_ANDROID)
63 #if defined(OS_ANDROID) || defined(OS_IOS)
64 #include "base/prefs/scoped_user_pref_update.h"
65 #include "chrome/browser/prefs/proxy_prefs.h"
66 #endif // defined(OS_ANDROID) || defined(OS_IOS)
68 #if defined(OS_CHROMEOS)
69 #include "chrome/browser/chromeos/preferences.h"
70 #include "chrome/browser/chromeos/profiles/profile_helper.h"
71 #endif
73 #if defined(ENABLE_CONFIGURATION_POLICY) && !defined(OS_CHROMEOS)
74 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
75 #endif
77 using content::BrowserThread;
78 using content::DownloadManagerDelegate;
79 using content::HostZoomMap;
81 namespace {
83 void NotifyOTRProfileCreatedOnIOThread(void* original_profile,
84 void* otr_profile) {
85 ExtensionWebRequestEventRouter::GetInstance()->OnOTRProfileCreated(
86 original_profile, otr_profile);
89 void NotifyOTRProfileDestroyedOnIOThread(void* original_profile,
90 void* otr_profile) {
91 ExtensionWebRequestEventRouter::GetInstance()->OnOTRProfileDestroyed(
92 original_profile, otr_profile);
95 } // namespace
97 OffTheRecordProfileImpl::OffTheRecordProfileImpl(Profile* real_profile)
98 : profile_(real_profile),
99 prefs_(PrefServiceSyncable::IncognitoFromProfile(real_profile)),
100 io_data_(this),
101 start_time_(Time::Now()) {
102 // Register on BrowserContext.
103 user_prefs::UserPrefs::Set(this, prefs_);
106 void OffTheRecordProfileImpl::Init() {
107 #if defined(ENABLE_CONFIGURATION_POLICY) && !defined(OS_CHROMEOS)
108 // Because UserCloudPolicyManager is in a component, it cannot access
109 // GetOriginalProfile. Instead, we have to inject this relation here.
110 policy::UserCloudPolicyManagerFactory::RegisterForOffTheRecordBrowserContext(
111 this->GetOriginalProfile(), this);
112 #endif
114 BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
115 this);
117 DCHECK_NE(IncognitoModePrefs::DISABLED,
118 IncognitoModePrefs::GetAvailability(profile_->GetPrefs()));
120 #if defined(OS_ANDROID) || defined(OS_IOS)
121 UseSystemProxy();
122 #endif // defined(OS_ANDROID) || defined(OS_IOS)
124 // TODO(oshima): Remove the need to eagerly initialize the request context
125 // getter. chromeos::OnlineAttempt is illegally trying to access this
126 // Profile member from a thread other than the UI thread, so we need to
127 // prevent a race.
128 #if defined(OS_CHROMEOS)
129 GetRequestContext();
130 #endif // defined(OS_CHROMEOS)
132 InitHostZoomMap();
134 // Make the chrome//extension-icon/ resource available.
135 extensions::ExtensionIconSource* icon_source =
136 new extensions::ExtensionIconSource(profile_);
137 content::URLDataSource::Add(this, icon_source);
139 #if defined(ENABLE_PLUGINS)
140 ChromePluginServiceFilter::GetInstance()->RegisterResourceContext(
141 PluginPrefs::GetForProfile(this).get(),
142 io_data_.GetResourceContextNoInit());
143 #endif
145 BrowserThread::PostTask(
146 BrowserThread::IO, FROM_HERE,
147 base::Bind(&NotifyOTRProfileCreatedOnIOThread, profile_, this));
150 OffTheRecordProfileImpl::~OffTheRecordProfileImpl() {
151 MaybeSendDestroyedNotification();
153 #if defined(ENABLE_PLUGINS)
154 ChromePluginServiceFilter::GetInstance()->UnregisterResourceContext(
155 io_data_.GetResourceContextNoInit());
156 #endif
158 BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
159 this);
161 BrowserThread::PostTask(
162 BrowserThread::IO, FROM_HERE,
163 base::Bind(&NotifyOTRProfileDestroyedOnIOThread, profile_, this));
165 if (host_content_settings_map_.get())
166 host_content_settings_map_->ShutdownOnUIThread();
168 if (pref_proxy_config_tracker_)
169 pref_proxy_config_tracker_->DetachFromPrefService();
171 // Clears any data the network stack contains that may be related to the
172 // OTR session.
173 g_browser_process->io_thread()->ChangedToOnTheRecord();
176 void OffTheRecordProfileImpl::InitHostZoomMap() {
177 HostZoomMap* host_zoom_map = HostZoomMap::GetForBrowserContext(this);
178 HostZoomMap* parent_host_zoom_map =
179 HostZoomMap::GetForBrowserContext(profile_);
180 host_zoom_map->CopyFrom(parent_host_zoom_map);
181 // Observe parent's HZM change for propagating change of parent's
182 // change to this HZM.
183 zoom_subscription_ = parent_host_zoom_map->AddZoomLevelChangedCallback(
184 base::Bind(&OffTheRecordProfileImpl::OnZoomLevelChanged,
185 base::Unretained(this)));
188 #if defined(OS_ANDROID) || defined(OS_IOS)
189 void OffTheRecordProfileImpl::UseSystemProxy() {
190 // Force the use of the system-assigned proxy when off the record.
191 const char kProxyMode[] = "mode";
192 const char kProxyServer[] = "server";
193 const char kProxyBypassList[] = "bypass_list";
194 const char kProxyPacUrl[] = "pac_url";
195 DictionaryPrefUpdate update(prefs_, prefs::kProxy);
196 base::DictionaryValue* dict = update.Get();
197 dict->SetString(kProxyMode, ProxyModeToString(ProxyPrefs::MODE_SYSTEM));
198 dict->SetString(kProxyPacUrl, "");
199 dict->SetString(kProxyServer, "");
200 dict->SetString(kProxyBypassList, "");
202 #endif // defined(OS_ANDROID) || defined(OS_IOS)
204 std::string OffTheRecordProfileImpl::GetProfileName() {
205 // Incognito profile should not return the profile name.
206 return std::string();
209 base::FilePath OffTheRecordProfileImpl::GetPath() const {
210 return profile_->GetPath();
213 scoped_refptr<base::SequencedTaskRunner>
214 OffTheRecordProfileImpl::GetIOTaskRunner() {
215 return profile_->GetIOTaskRunner();
218 bool OffTheRecordProfileImpl::IsOffTheRecord() const {
219 return true;
222 Profile* OffTheRecordProfileImpl::GetOffTheRecordProfile() {
223 return this;
226 void OffTheRecordProfileImpl::DestroyOffTheRecordProfile() {
227 // Suicide is bad!
228 NOTREACHED();
231 bool OffTheRecordProfileImpl::HasOffTheRecordProfile() {
232 return true;
235 Profile* OffTheRecordProfileImpl::GetOriginalProfile() {
236 return profile_;
239 ExtensionService* OffTheRecordProfileImpl::GetExtensionService() {
240 return extensions::ExtensionSystem::Get(this)->extension_service();
243 ExtensionSpecialStoragePolicy*
244 OffTheRecordProfileImpl::GetExtensionSpecialStoragePolicy() {
245 return GetOriginalProfile()->GetExtensionSpecialStoragePolicy();
248 bool OffTheRecordProfileImpl::IsManaged() {
249 return GetOriginalProfile()->IsManaged();
252 PrefService* OffTheRecordProfileImpl::GetPrefs() {
253 return prefs_;
256 PrefService* OffTheRecordProfileImpl::GetOffTheRecordPrefs() {
257 return prefs_;
260 DownloadManagerDelegate* OffTheRecordProfileImpl::GetDownloadManagerDelegate() {
261 return DownloadServiceFactory::GetForBrowserContext(this)->
262 GetDownloadManagerDelegate();
265 net::URLRequestContextGetter* OffTheRecordProfileImpl::GetRequestContext() {
266 return GetDefaultStoragePartition(this)->GetURLRequestContext();
269 net::URLRequestContextGetter* OffTheRecordProfileImpl::CreateRequestContext(
270 content::ProtocolHandlerMap* protocol_handlers) {
271 return io_data_.CreateMainRequestContextGetter(protocol_handlers).get();
274 net::URLRequestContextGetter*
275 OffTheRecordProfileImpl::GetRequestContextForRenderProcess(
276 int renderer_child_id) {
277 content::RenderProcessHost* rph = content::RenderProcessHost::FromID(
278 renderer_child_id);
279 return rph->GetStoragePartition()->GetURLRequestContext();
282 net::URLRequestContextGetter*
283 OffTheRecordProfileImpl::GetMediaRequestContext() {
284 // In OTR mode, media request context is the same as the original one.
285 return GetRequestContext();
288 net::URLRequestContextGetter*
289 OffTheRecordProfileImpl::GetMediaRequestContextForRenderProcess(
290 int renderer_child_id) {
291 // In OTR mode, media request context is the same as the original one.
292 return GetRequestContextForRenderProcess(renderer_child_id);
295 net::URLRequestContextGetter*
296 OffTheRecordProfileImpl::GetMediaRequestContextForStoragePartition(
297 const base::FilePath& partition_path,
298 bool in_memory) {
299 return io_data_.GetIsolatedAppRequestContextGetter(partition_path, in_memory)
300 .get();
303 void OffTheRecordProfileImpl::RequestMIDISysExPermission(
304 int render_process_id,
305 int render_view_id,
306 int bridge_id,
307 const GURL& requesting_frame,
308 const MIDISysExPermissionCallback& callback) {
309 ChromeMIDIPermissionContext* context =
310 ChromeMIDIPermissionContextFactory::GetForProfile(this);
311 context->RequestMIDISysExPermission(render_process_id,
312 render_view_id,
313 bridge_id,
314 requesting_frame,
315 callback);
318 void OffTheRecordProfileImpl::CancelMIDISysExPermissionRequest(
319 int render_process_id,
320 int render_view_id,
321 int bridge_id,
322 const GURL& requesting_frame) {
323 ChromeMIDIPermissionContext* context =
324 ChromeMIDIPermissionContextFactory::GetForProfile(this);
325 context->CancelMIDISysExPermissionRequest(
326 render_process_id, render_view_id, bridge_id, requesting_frame);
329 void OffTheRecordProfileImpl::RequestProtectedMediaIdentifierPermission(
330 int render_process_id,
331 int render_view_id,
332 int bridge_id,
333 int group_id,
334 const GURL& requesting_frame,
335 const ProtectedMediaIdentifierPermissionCallback& callback) {
336 #if defined(OS_ANDROID)
337 ProtectedMediaIdentifierPermissionContext* context =
338 ProtectedMediaIdentifierPermissionContextFactory::GetForProfile(this);
339 context->RequestProtectedMediaIdentifierPermission(render_process_id,
340 render_view_id,
341 bridge_id,
342 group_id,
343 requesting_frame,
344 callback);
345 #else
346 NOTIMPLEMENTED();
347 callback.Run(false);
348 #endif // defined(OS_ANDROID)
351 void OffTheRecordProfileImpl::CancelProtectedMediaIdentifierPermissionRequests(
352 int group_id) {
353 #if defined(OS_ANDROID)
354 ProtectedMediaIdentifierPermissionContext* context =
355 ProtectedMediaIdentifierPermissionContextFactory::GetForProfile(this);
356 context->CancelProtectedMediaIdentifierPermissionRequests(group_id);
357 #else
358 NOTIMPLEMENTED();
359 #endif // defined(OS_ANDROID)
362 net::URLRequestContextGetter*
363 OffTheRecordProfileImpl::GetRequestContextForExtensions() {
364 return io_data_.GetExtensionsRequestContextGetter().get();
367 net::URLRequestContextGetter*
368 OffTheRecordProfileImpl::CreateRequestContextForStoragePartition(
369 const base::FilePath& partition_path,
370 bool in_memory,
371 content::ProtocolHandlerMap* protocol_handlers) {
372 return io_data_.CreateIsolatedAppRequestContextGetter(
373 partition_path, in_memory, protocol_handlers).get();
376 content::ResourceContext* OffTheRecordProfileImpl::GetResourceContext() {
377 return io_data_.GetResourceContext();
380 net::SSLConfigService* OffTheRecordProfileImpl::GetSSLConfigService() {
381 return profile_->GetSSLConfigService();
384 HostContentSettingsMap* OffTheRecordProfileImpl::GetHostContentSettingsMap() {
385 // Retrieve the host content settings map of the parent profile in order to
386 // ensure the preferences have been migrated.
387 profile_->GetHostContentSettingsMap();
388 if (!host_content_settings_map_.get()) {
389 host_content_settings_map_ = new HostContentSettingsMap(GetPrefs(), true);
390 #if defined(ENABLE_EXTENSIONS)
391 ExtensionService* extension_service = GetExtensionService();
392 if (extension_service)
393 host_content_settings_map_->RegisterExtensionService(extension_service);
394 #endif
396 return host_content_settings_map_.get();
399 content::GeolocationPermissionContext*
400 OffTheRecordProfileImpl::GetGeolocationPermissionContext() {
401 return ChromeGeolocationPermissionContextFactory::GetForProfile(this);
404 quota::SpecialStoragePolicy*
405 OffTheRecordProfileImpl::GetSpecialStoragePolicy() {
406 return GetExtensionSpecialStoragePolicy();
409 bool OffTheRecordProfileImpl::IsSameProfile(Profile* profile) {
410 return (profile == this) || (profile == profile_);
413 Time OffTheRecordProfileImpl::GetStartTime() const {
414 return start_time_;
417 history::TopSites* OffTheRecordProfileImpl::GetTopSitesWithoutCreating() {
418 return NULL;
421 history::TopSites* OffTheRecordProfileImpl::GetTopSites() {
422 return NULL;
425 void OffTheRecordProfileImpl::SetExitType(ExitType exit_type) {
428 base::FilePath OffTheRecordProfileImpl::last_selected_directory() {
429 const base::FilePath& directory = last_selected_directory_;
430 if (directory.empty()) {
431 return profile_->last_selected_directory();
433 return directory;
436 void OffTheRecordProfileImpl::set_last_selected_directory(
437 const base::FilePath& path) {
438 last_selected_directory_ = path;
441 bool OffTheRecordProfileImpl::WasCreatedByVersionOrLater(
442 const std::string& version) {
443 return profile_->WasCreatedByVersionOrLater(version);
446 Profile::ExitType OffTheRecordProfileImpl::GetLastSessionExitType() {
447 return profile_->GetLastSessionExitType();
450 #if defined(OS_CHROMEOS)
451 void OffTheRecordProfileImpl::ChangeAppLocale(const std::string& locale,
452 AppLocaleChangedVia) {
455 void OffTheRecordProfileImpl::OnLogin() {
458 void OffTheRecordProfileImpl::InitChromeOSPreferences() {
459 // The incognito profile shouldn't have Chrome OS's preferences.
460 // The preferences are associated with the regular user profile.
462 #endif // defined(OS_CHROMEOS)
464 PrefProxyConfigTracker* OffTheRecordProfileImpl::GetProxyConfigTracker() {
465 if (!pref_proxy_config_tracker_)
466 pref_proxy_config_tracker_.reset(CreateProxyConfigTracker());
467 return pref_proxy_config_tracker_.get();
470 chrome_browser_net::Predictor* OffTheRecordProfileImpl::GetNetworkPredictor() {
471 // We do not store information about websites visited in OTR profiles which
472 // is necessary for a Predictor, so we do not have a Predictor at all.
473 return NULL;
476 void OffTheRecordProfileImpl::ClearNetworkingHistorySince(
477 base::Time time,
478 const base::Closure& completion) {
479 // Nothing to do here, our transport security state is read-only.
480 // Still, fire the callback to indicate we have finished, otherwise the
481 // BrowsingDataRemover will never be destroyed and the dialog will never be
482 // closed. We must do this asynchronously in order to avoid reentrancy issues.
483 if (!completion.is_null()) {
484 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, completion);
488 GURL OffTheRecordProfileImpl::GetHomePage() {
489 return profile_->GetHomePage();
492 #if defined(OS_CHROMEOS)
493 // Special case of the OffTheRecordProfileImpl which is used while Guest
494 // session in CrOS.
495 class GuestSessionProfile : public OffTheRecordProfileImpl {
496 public:
497 explicit GuestSessionProfile(Profile* real_profile)
498 : OffTheRecordProfileImpl(real_profile) {
501 virtual void InitChromeOSPreferences() OVERRIDE {
502 chromeos_preferences_.reset(new chromeos::Preferences());
503 chromeos_preferences_->Init(static_cast<PrefServiceSyncable*>(GetPrefs()),
504 true /* is_primary_profile */);
507 private:
508 // The guest user should be able to customize Chrome OS preferences.
509 scoped_ptr<chromeos::Preferences> chromeos_preferences_;
511 #endif
513 Profile* Profile::CreateOffTheRecordProfile() {
514 OffTheRecordProfileImpl* profile = NULL;
515 #if defined(OS_CHROMEOS)
516 if (IsGuestSession())
517 profile = new GuestSessionProfile(this);
518 #endif
519 if (!profile)
520 profile = new OffTheRecordProfileImpl(this);
521 profile->Init();
522 return profile;
525 void OffTheRecordProfileImpl::OnZoomLevelChanged(
526 const HostZoomMap::ZoomLevelChange& change) {
527 HostZoomMap* host_zoom_map = HostZoomMap::GetForBrowserContext(this);
528 switch (change.mode) {
529 case HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM:
530 return;
531 case HostZoomMap::ZOOM_CHANGED_FOR_HOST:
532 host_zoom_map->SetZoomLevelForHost(change.host, change.zoom_level);
533 return;
534 case HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST:
535 host_zoom_map->SetZoomLevelForHostAndScheme(change.scheme,
536 change.host,
537 change.zoom_level);
538 return;
542 PrefProxyConfigTracker* OffTheRecordProfileImpl::CreateProxyConfigTracker() {
543 #if defined(OS_CHROMEOS)
544 if (chromeos::ProfileHelper::IsSigninProfile(this)) {
545 return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
546 g_browser_process->local_state());
548 #endif // defined(OS_CHROMEOS)
549 return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
550 GetPrefs(), g_browser_process->local_state());