Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / profiles / off_the_record_profile_impl.cc
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 #include "chrome/browser/profiles/off_the_record_profile_impl.h"
6
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/geolocation/chrome_geolocation_permission_context.h"
27 #include "chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h"
28 #include "chrome/browser/io_thread.h"
29 #include "chrome/browser/media/chrome_midi_permission_context.h"
30 #include "chrome/browser/media/chrome_midi_permission_context_factory.h"
31 #include "chrome/browser/net/pref_proxy_config_tracker.h"
32 #include "chrome/browser/net/proxy_service_factory.h"
33 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
34 #include "chrome/browser/plugins/plugin_prefs.h"
35 #include "chrome/browser/prefs/incognito_mode_prefs.h"
36 #include "chrome/browser/prefs/pref_service_syncable.h"
37 #include "chrome/browser/themes/theme_service.h"
38 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
39 #include "chrome/common/chrome_constants.h"
40 #include "chrome/common/chrome_paths.h"
41 #include "chrome/common/chrome_switches.h"
42 #include "chrome/common/pref_names.h"
43 #include "chrome/common/render_messages.h"
44 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
45 #include "components/user_prefs/user_prefs.h"
46 #include "content/public/browser/browser_thread.h"
47 #include "content/public/browser/host_zoom_map.h"
48 #include "content/public/browser/render_process_host.h"
49 #include "content/public/browser/storage_partition.h"
50 #include "content/public/browser/url_data_source.h"
51 #include "content/public/browser/web_contents.h"
52 #include "extensions/browser/extension_system.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"
57
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)
62
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)
67
68 #if defined(OS_CHROMEOS)
69 #include "chrome/browser/chromeos/preferences.h"
70 #include "chrome/browser/chromeos/profiles/profile_helper.h"
71 #endif
72
73 #if defined(ENABLE_CONFIGURATION_POLICY) && !defined(OS_CHROMEOS)
74 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
75 #endif
76
77 using content::BrowserThread;
78 using content::DownloadManagerDelegate;
79 using content::HostZoomMap;
80
81 namespace {
82
83 void NotifyOTRProfileCreatedOnIOThread(void* original_profile,
84                                        void* otr_profile) {
85   ExtensionWebRequestEventRouter::GetInstance()->OnOTRProfileCreated(
86       original_profile, otr_profile);
87 }
88
89 void NotifyOTRProfileDestroyedOnIOThread(void* original_profile,
90                                          void* otr_profile) {
91   ExtensionWebRequestEventRouter::GetInstance()->OnOTRProfileDestroyed(
92       original_profile, otr_profile);
93 }
94
95 }  // namespace
96
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_);
104 }
105
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
113
114   BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
115       this);
116
117   DCHECK_NE(IncognitoModePrefs::DISABLED,
118             IncognitoModePrefs::GetAvailability(profile_->GetPrefs()));
119
120 #if defined(OS_ANDROID) || defined(OS_IOS)
121   UseSystemProxy();
122 #endif  // defined(OS_ANDROID) || defined(OS_IOS)
123
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)
131
132   InitHostZoomMap();
133
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);
138
139 #if defined(ENABLE_PLUGINS)
140   ChromePluginServiceFilter::GetInstance()->RegisterResourceContext(
141       PluginPrefs::GetForProfile(this).get(),
142       io_data_.GetResourceContextNoInit());
143 #endif
144
145   BrowserThread::PostTask(
146       BrowserThread::IO, FROM_HERE,
147       base::Bind(&NotifyOTRProfileCreatedOnIOThread, profile_, this));
148 }
149
150 OffTheRecordProfileImpl::~OffTheRecordProfileImpl() {
151   MaybeSendDestroyedNotification();
152
153 #if defined(ENABLE_PLUGINS)
154   ChromePluginServiceFilter::GetInstance()->UnregisterResourceContext(
155     io_data_.GetResourceContextNoInit());
156 #endif
157
158   BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
159       this);
160
161   BrowserThread::PostTask(
162       BrowserThread::IO, FROM_HERE,
163       base::Bind(&NotifyOTRProfileDestroyedOnIOThread, profile_, this));
164
165   if (host_content_settings_map_.get())
166     host_content_settings_map_->ShutdownOnUIThread();
167
168   if (pref_proxy_config_tracker_)
169     pref_proxy_config_tracker_->DetachFromPrefService();
170
171   // Clears any data the network stack contains that may be related to the
172   // OTR session.
173   g_browser_process->io_thread()->ChangedToOnTheRecord();
174 }
175
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)));
186 }
187
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, "");
201 }
202 #endif  // defined(OS_ANDROID) || defined(OS_IOS)
203
204 std::string OffTheRecordProfileImpl::GetProfileName() {
205   // Incognito profile should not return the profile name.
206   return std::string();
207 }
208
209 base::FilePath OffTheRecordProfileImpl::GetPath() const {
210   return profile_->GetPath();
211 }
212
213 scoped_refptr<base::SequencedTaskRunner>
214 OffTheRecordProfileImpl::GetIOTaskRunner() {
215   return profile_->GetIOTaskRunner();
216 }
217
218 bool OffTheRecordProfileImpl::IsOffTheRecord() const {
219   return true;
220 }
221
222 Profile* OffTheRecordProfileImpl::GetOffTheRecordProfile() {
223   return this;
224 }
225
226 void OffTheRecordProfileImpl::DestroyOffTheRecordProfile() {
227   // Suicide is bad!
228   NOTREACHED();
229 }
230
231 bool OffTheRecordProfileImpl::HasOffTheRecordProfile() {
232   return true;
233 }
234
235 Profile* OffTheRecordProfileImpl::GetOriginalProfile() {
236   return profile_;
237 }
238
239 ExtensionService* OffTheRecordProfileImpl::GetExtensionService() {
240   return extensions::ExtensionSystem::Get(this)->extension_service();
241 }
242
243 ExtensionSpecialStoragePolicy*
244     OffTheRecordProfileImpl::GetExtensionSpecialStoragePolicy() {
245   return GetOriginalProfile()->GetExtensionSpecialStoragePolicy();
246 }
247
248 bool OffTheRecordProfileImpl::IsManaged() {
249   return GetOriginalProfile()->IsManaged();
250 }
251
252 PrefService* OffTheRecordProfileImpl::GetPrefs() {
253   return prefs_;
254 }
255
256 PrefService* OffTheRecordProfileImpl::GetOffTheRecordPrefs() {
257   return prefs_;
258 }
259
260 DownloadManagerDelegate* OffTheRecordProfileImpl::GetDownloadManagerDelegate() {
261   return DownloadServiceFactory::GetForBrowserContext(this)->
262       GetDownloadManagerDelegate();
263 }
264
265 net::URLRequestContextGetter* OffTheRecordProfileImpl::GetRequestContext() {
266   return GetDefaultStoragePartition(this)->GetURLRequestContext();
267 }
268
269 net::URLRequestContextGetter* OffTheRecordProfileImpl::CreateRequestContext(
270     content::ProtocolHandlerMap* protocol_handlers) {
271   return io_data_.CreateMainRequestContextGetter(protocol_handlers).get();
272 }
273
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();
280 }
281
282 net::URLRequestContextGetter*
283     OffTheRecordProfileImpl::GetMediaRequestContext() {
284   // In OTR mode, media request context is the same as the original one.
285   return GetRequestContext();
286 }
287
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);
293 }
294
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();
301 }
302
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);
316 }
317
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);
327 }
328
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)
349 }
350
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)
360 }
361
362 net::URLRequestContextGetter*
363     OffTheRecordProfileImpl::GetRequestContextForExtensions() {
364   return io_data_.GetExtensionsRequestContextGetter().get();
365 }
366
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();
374 }
375
376 content::ResourceContext* OffTheRecordProfileImpl::GetResourceContext() {
377   return io_data_.GetResourceContext();
378 }
379
380 net::SSLConfigService* OffTheRecordProfileImpl::GetSSLConfigService() {
381   return profile_->GetSSLConfigService();
382 }
383
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
395   }
396   return host_content_settings_map_.get();
397 }
398
399 content::GeolocationPermissionContext*
400     OffTheRecordProfileImpl::GetGeolocationPermissionContext() {
401   return ChromeGeolocationPermissionContextFactory::GetForProfile(this);
402 }
403
404 quota::SpecialStoragePolicy*
405     OffTheRecordProfileImpl::GetSpecialStoragePolicy() {
406   return GetExtensionSpecialStoragePolicy();
407 }
408
409 bool OffTheRecordProfileImpl::IsSameProfile(Profile* profile) {
410   return (profile == this) || (profile == profile_);
411 }
412
413 Time OffTheRecordProfileImpl::GetStartTime() const {
414   return start_time_;
415 }
416
417 history::TopSites* OffTheRecordProfileImpl::GetTopSitesWithoutCreating() {
418   return NULL;
419 }
420
421 history::TopSites* OffTheRecordProfileImpl::GetTopSites() {
422   return NULL;
423 }
424
425 void OffTheRecordProfileImpl::SetExitType(ExitType exit_type) {
426 }
427
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();
432   }
433   return directory;
434 }
435
436 void OffTheRecordProfileImpl::set_last_selected_directory(
437     const base::FilePath& path) {
438   last_selected_directory_ = path;
439 }
440
441 bool OffTheRecordProfileImpl::WasCreatedByVersionOrLater(
442     const std::string& version) {
443   return profile_->WasCreatedByVersionOrLater(version);
444 }
445
446 Profile::ExitType OffTheRecordProfileImpl::GetLastSessionExitType() {
447   return profile_->GetLastSessionExitType();
448 }
449
450 #if defined(OS_CHROMEOS)
451 void OffTheRecordProfileImpl::ChangeAppLocale(const std::string& locale,
452                                               AppLocaleChangedVia) {
453 }
454
455 void OffTheRecordProfileImpl::OnLogin() {
456 }
457
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.
461 }
462 #endif  // defined(OS_CHROMEOS)
463
464 PrefProxyConfigTracker* OffTheRecordProfileImpl::GetProxyConfigTracker() {
465   if (!pref_proxy_config_tracker_)
466     pref_proxy_config_tracker_.reset(CreateProxyConfigTracker());
467   return pref_proxy_config_tracker_.get();
468 }
469
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;
474 }
475
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);
485   }
486 }
487
488 GURL OffTheRecordProfileImpl::GetHomePage() {
489   return profile_->GetHomePage();
490 }
491
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) {
499   }
500
501   virtual void InitChromeOSPreferences() OVERRIDE {
502     chromeos_preferences_.reset(new chromeos::Preferences());
503     chromeos_preferences_->Init(static_cast<PrefServiceSyncable*>(GetPrefs()),
504                                 chromeos::UserManager::Get()->GetActiveUser());
505   }
506
507  private:
508   // The guest user should be able to customize Chrome OS preferences.
509   scoped_ptr<chromeos::Preferences> chromeos_preferences_;
510 };
511 #endif
512
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;
523 }
524
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;
539   }
540 }
541
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());
547   }
548 #endif  // defined(OS_CHROMEOS)
549   return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
550       GetPrefs(), g_browser_process->local_state());
551 }