Home | History | Annotate | Download | only in profiles
      1 // Copyright (c) 2011 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/profile.h"
      6 
      7 #include <string>
      8 
      9 #include "base/command_line.h"
     10 #include "base/compiler_specific.h"
     11 #include "base/file_path.h"
     12 #include "base/file_util.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/path_service.h"
     15 #include "base/string_util.h"
     16 #include "build/build_config.h"
     17 #include "chrome/browser/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/download_manager.h"
     21 #include "chrome/browser/extensions/extension_message_service.h"
     22 #include "chrome/browser/extensions/extension_pref_store.h"
     23 #include "chrome/browser/extensions/extension_process_manager.h"
     24 #include "chrome/browser/extensions/extension_special_storage_policy.h"
     25 #include "chrome/browser/net/pref_proxy_config_service.h"
     26 #include "chrome/browser/prefs/pref_service.h"
     27 #include "chrome/browser/profiles/off_the_record_profile_io_data.h"
     28 #include "chrome/browser/profiles/profile_dependency_manager.h"
     29 #include "chrome/browser/ssl/ssl_host_state.h"
     30 #include "chrome/browser/sync/profile_sync_service.h"
     31 #include "chrome/browser/themes/theme_service.h"
     32 #include "chrome/browser/transport_security_persister.h"
     33 #include "chrome/browser/ui/browser_list.h"
     34 #include "chrome/browser/ui/find_bar/find_bar_state.h"
     35 #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
     36 #include "chrome/browser/ui/webui/extension_icon_source.h"
     37 #include "chrome/common/chrome_constants.h"
     38 #include "chrome/common/chrome_paths.h"
     39 #include "chrome/common/chrome_switches.h"
     40 #include "chrome/common/extensions/extension.h"
     41 #include "chrome/common/json_pref_store.h"
     42 #include "chrome/common/pref_names.h"
     43 #include "chrome/common/render_messages.h"
     44 #include "content/browser/appcache/chrome_appcache_service.h"
     45 #include "content/browser/browser_thread.h"
     46 #include "content/browser/chrome_blob_storage_context.h"
     47 #include "content/browser/file_system/browser_file_system_helper.h"
     48 #include "content/browser/host_zoom_map.h"
     49 #include "content/browser/in_process_webkit/webkit_context.h"
     50 #include "content/common/notification_service.h"
     51 #include "grit/locale_settings.h"
     52 #include "net/base/transport_security_state.h"
     53 #include "ui/base/resource/resource_bundle.h"
     54 #include "webkit/database/database_tracker.h"
     55 
     56 #if defined(TOOLKIT_USES_GTK)
     57 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
     58 #endif
     59 
     60 #if defined(OS_WIN)
     61 #include "chrome/browser/password_manager/password_store_win.h"
     62 #elif defined(OS_MACOSX)
     63 #include "chrome/browser/keychain_mac.h"
     64 #include "chrome/browser/password_manager/password_store_mac.h"
     65 #elif defined(OS_POSIX) && !defined(OS_CHROMEOS)
     66 #include "chrome/browser/password_manager/native_backend_gnome_x.h"
     67 #include "chrome/browser/password_manager/native_backend_kwallet_x.h"
     68 #include "chrome/browser/password_manager/password_store_x.h"
     69 #elif defined(OS_CHROMEOS)
     70 #include "chrome/browser/chromeos/preferences.h"
     71 #endif
     72 
     73 using base::Time;
     74 using base::TimeDelta;
     75 
     76 // A pointer to the request context for the default profile.  See comments on
     77 // Profile::GetDefaultRequestContext.
     78 net::URLRequestContextGetter* Profile::default_request_context_;
     79 
     80 namespace {
     81 
     82 }  // namespace
     83 
     84 #ifdef ANDROID
     85 // Android moved this to profile_android.cc to avoid compiling this file.
     86 #endif
     87 Profile::Profile()
     88     : restored_last_session_(false),
     89       accessibility_pause_level_(0) {
     90 }
     91 
     92 // static
     93 const char* Profile::kProfileKey = "__PROFILE__";
     94 
     95 // static
     96 const ProfileId Profile::kInvalidProfileId = static_cast<ProfileId>(0);
     97 
     98 // static
     99 void Profile::RegisterUserPrefs(PrefService* prefs) {
    100   prefs->RegisterBooleanPref(prefs::kSearchSuggestEnabled, true);
    101   prefs->RegisterBooleanPref(prefs::kSessionExitedCleanly, true);
    102   prefs->RegisterBooleanPref(prefs::kSafeBrowsingEnabled, true);
    103   prefs->RegisterBooleanPref(prefs::kSafeBrowsingReportingEnabled, false);
    104   // TODO(estade): IDS_SPELLCHECK_DICTIONARY should be an ASCII string.
    105   prefs->RegisterLocalizedStringPref(prefs::kSpellCheckDictionary,
    106       IDS_SPELLCHECK_DICTIONARY);
    107   prefs->RegisterBooleanPref(prefs::kEnableSpellCheck, true);
    108   prefs->RegisterBooleanPref(prefs::kEnableAutoSpellCorrect, true);
    109 #if defined(TOOLKIT_USES_GTK)
    110   prefs->RegisterBooleanPref(prefs::kUsesSystemTheme,
    111                              GtkThemeService::DefaultUsesSystemTheme());
    112 #endif
    113   prefs->RegisterFilePathPref(prefs::kCurrentThemePackFilename, FilePath());
    114   prefs->RegisterStringPref(prefs::kCurrentThemeID,
    115                             ThemeService::kDefaultThemeID);
    116   prefs->RegisterDictionaryPref(prefs::kCurrentThemeImages);
    117   prefs->RegisterDictionaryPref(prefs::kCurrentThemeColors);
    118   prefs->RegisterDictionaryPref(prefs::kCurrentThemeTints);
    119   prefs->RegisterDictionaryPref(prefs::kCurrentThemeDisplayProperties);
    120   prefs->RegisterBooleanPref(prefs::kDisableExtensions, false);
    121   prefs->RegisterStringPref(prefs::kSelectFileLastDirectory, "");
    122 #if defined(OS_CHROMEOS)
    123   // TODO(dilmah): For OS_CHROMEOS we maintain kApplicationLocale in both
    124   // local state and user's profile.  For other platforms we maintain
    125   // kApplicationLocale only in local state.
    126   // In the future we may want to maintain kApplicationLocale
    127   // in user's profile for other platforms as well.
    128   prefs->RegisterStringPref(prefs::kApplicationLocale, "");
    129   prefs->RegisterStringPref(prefs::kApplicationLocaleBackup, "");
    130   prefs->RegisterStringPref(prefs::kApplicationLocaleAccepted, "");
    131 #endif
    132 }
    133 
    134 // static
    135 net::URLRequestContextGetter* Profile::GetDefaultRequestContext() {
    136   return default_request_context_;
    137 }
    138 
    139 bool Profile::IsGuestSession() {
    140 #if defined(OS_CHROMEOS)
    141   static bool is_guest_session =
    142       CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession);
    143   return is_guest_session;
    144 #else
    145   return false;
    146 #endif
    147 }
    148 
    149 bool Profile::IsSyncAccessible() {
    150   ProfileSyncService* syncService = GetProfileSyncService();
    151   return syncService && !syncService->IsManaged();
    152 }
    153 
    154 ////////////////////////////////////////////////////////////////////////////////
    155 //
    156 // OffTheRecordProfileImpl is a profile subclass that wraps an existing profile
    157 // to make it suitable for the incognito mode.
    158 //
    159 ////////////////////////////////////////////////////////////////////////////////
    160 class OffTheRecordProfileImpl : public Profile,
    161                                 public BrowserList::Observer {
    162  public:
    163   explicit OffTheRecordProfileImpl(Profile* real_profile)
    164       : profile_(real_profile),
    165         prefs_(real_profile->GetOffTheRecordPrefs()),
    166         ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)),
    167         start_time_(Time::Now()) {
    168     extension_process_manager_.reset(ExtensionProcessManager::Create(this));
    169 
    170     BrowserList::AddObserver(this);
    171 
    172     BackgroundContentsServiceFactory::GetForProfile(this);
    173 
    174     DCHECK(real_profile->GetPrefs()->GetBoolean(prefs::kIncognitoEnabled));
    175 
    176     // TODO(oshima): Remove the need to eagerly initialize the request context
    177     // getter. chromeos::OnlineAttempt is illegally trying to access this
    178     // Profile member from a thread other than the UI thread, so we need to
    179     // prevent a race.
    180 #if defined(OS_CHROMEOS)
    181     GetRequestContext();
    182 #endif  // defined(OS_CHROMEOS)
    183 
    184     // Make the chrome//extension-icon/ resource available.
    185     ExtensionIconSource* icon_source = new ExtensionIconSource(real_profile);
    186     GetChromeURLDataManager()->AddDataSource(icon_source);
    187   }
    188 
    189   virtual ~OffTheRecordProfileImpl() {
    190     NotificationService::current()->Notify(NotificationType::PROFILE_DESTROYED,
    191                                            Source<Profile>(this),
    192                                            NotificationService::NoDetails());
    193 
    194     ProfileDependencyManager::GetInstance()->DestroyProfileServices(this);
    195 
    196     // Clean up all DB files/directories
    197     if (db_tracker_)
    198       BrowserThread::PostTask(
    199           BrowserThread::FILE, FROM_HERE,
    200           NewRunnableMethod(
    201               db_tracker_.get(),
    202               &webkit_database::DatabaseTracker::DeleteIncognitoDBDirectory));
    203 
    204     BrowserList::RemoveObserver(this);
    205 
    206     if (pref_proxy_config_tracker_)
    207       pref_proxy_config_tracker_->DetachFromPrefService();
    208   }
    209 
    210   virtual ProfileId GetRuntimeId() {
    211     return reinterpret_cast<ProfileId>(this);
    212   }
    213 
    214   virtual FilePath GetPath() { return profile_->GetPath(); }
    215 
    216   virtual bool IsOffTheRecord() {
    217     return true;
    218   }
    219 
    220   virtual Profile* GetOffTheRecordProfile() {
    221     return this;
    222   }
    223 
    224   virtual void DestroyOffTheRecordProfile() {
    225     // Suicide is bad!
    226     NOTREACHED();
    227   }
    228 
    229   virtual bool HasOffTheRecordProfile() {
    230     return true;
    231   }
    232 
    233   virtual Profile* GetOriginalProfile() {
    234     return profile_;
    235   }
    236 
    237   virtual ChromeAppCacheService* GetAppCacheService() {
    238     if (!appcache_service_) {
    239       appcache_service_ = new ChromeAppCacheService;
    240       BrowserThread::PostTask(
    241           BrowserThread::IO, FROM_HERE,
    242           NewRunnableMethod(
    243               appcache_service_.get(),
    244               &ChromeAppCacheService::InitializeOnIOThread,
    245               IsOffTheRecord()
    246                   ? FilePath() : GetPath().Append(chrome::kAppCacheDirname),
    247               make_scoped_refptr(GetHostContentSettingsMap()),
    248               make_scoped_refptr(GetExtensionSpecialStoragePolicy()),
    249               false));
    250     }
    251     return appcache_service_;
    252   }
    253 
    254   virtual webkit_database::DatabaseTracker* GetDatabaseTracker() {
    255     if (!db_tracker_.get()) {
    256       db_tracker_ = new webkit_database::DatabaseTracker(
    257           GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy());
    258     }
    259     return db_tracker_;
    260   }
    261 
    262   virtual VisitedLinkMaster* GetVisitedLinkMaster() {
    263     // We don't provide access to the VisitedLinkMaster when we're OffTheRecord
    264     // because we don't want to leak the sites that the user has visited before.
    265     return NULL;
    266   }
    267 
    268   virtual ExtensionService* GetExtensionService() {
    269     return GetOriginalProfile()->GetExtensionService();
    270   }
    271 
    272   virtual StatusTray* GetStatusTray() {
    273     return GetOriginalProfile()->GetStatusTray();
    274   }
    275 
    276   virtual UserScriptMaster* GetUserScriptMaster() {
    277     return GetOriginalProfile()->GetUserScriptMaster();
    278   }
    279 
    280   virtual ExtensionDevToolsManager* GetExtensionDevToolsManager() {
    281     // TODO(mpcomplete): figure out whether we should return the original
    282     // profile's version.
    283     return NULL;
    284   }
    285 
    286   virtual ExtensionProcessManager* GetExtensionProcessManager() {
    287     return extension_process_manager_.get();
    288   }
    289 
    290   virtual ExtensionMessageService* GetExtensionMessageService() {
    291     return GetOriginalProfile()->GetExtensionMessageService();
    292   }
    293 
    294   virtual ExtensionEventRouter* GetExtensionEventRouter() {
    295     return GetOriginalProfile()->GetExtensionEventRouter();
    296   }
    297 
    298   virtual ExtensionSpecialStoragePolicy* GetExtensionSpecialStoragePolicy() {
    299     return GetOriginalProfile()->GetExtensionSpecialStoragePolicy();
    300   }
    301 
    302   virtual SSLHostState* GetSSLHostState() {
    303     if (!ssl_host_state_.get())
    304       ssl_host_state_.reset(new SSLHostState());
    305 
    306     DCHECK(ssl_host_state_->CalledOnValidThread());
    307     return ssl_host_state_.get();
    308   }
    309 
    310   virtual net::TransportSecurityState* GetTransportSecurityState() {
    311     if (!transport_security_state_.get()) {
    312       transport_security_state_ = new net::TransportSecurityState();
    313       transport_security_loader_ =
    314           new TransportSecurityPersister(true /* readonly */);
    315       transport_security_loader_->Initialize(transport_security_state_.get(),
    316                                              GetOriginalProfile()->GetPath());
    317     }
    318 
    319     return transport_security_state_.get();
    320   }
    321 
    322   virtual HistoryService* GetHistoryService(ServiceAccessType sat) {
    323     if (sat == EXPLICIT_ACCESS)
    324       return profile_->GetHistoryService(sat);
    325 
    326     NOTREACHED() << "This profile is OffTheRecord";
    327     return NULL;
    328   }
    329 
    330   virtual HistoryService* GetHistoryServiceWithoutCreating() {
    331     return profile_->GetHistoryServiceWithoutCreating();
    332   }
    333 
    334   virtual FaviconService* GetFaviconService(ServiceAccessType sat) {
    335     if (sat == EXPLICIT_ACCESS)
    336       return profile_->GetFaviconService(sat);
    337 
    338     NOTREACHED() << "This profile is OffTheRecord";
    339     return NULL;
    340   }
    341 
    342   virtual AutocompleteClassifier* GetAutocompleteClassifier() {
    343     return profile_->GetAutocompleteClassifier();
    344   }
    345 
    346   virtual WebDataService* GetWebDataService(ServiceAccessType sat) {
    347     if (sat == EXPLICIT_ACCESS)
    348       return profile_->GetWebDataService(sat);
    349 
    350     NOTREACHED() << "This profile is OffTheRecord";
    351     return NULL;
    352   }
    353 
    354   virtual WebDataService* GetWebDataServiceWithoutCreating() {
    355     return profile_->GetWebDataServiceWithoutCreating();
    356   }
    357 
    358   virtual PasswordStore* GetPasswordStore(ServiceAccessType sat) {
    359     if (sat == EXPLICIT_ACCESS)
    360       return profile_->GetPasswordStore(sat);
    361 
    362     NOTREACHED() << "This profile is OffTheRecord";
    363     return NULL;
    364   }
    365 
    366   virtual PrefService* GetPrefs() {
    367     return prefs_;
    368   }
    369 
    370   virtual PrefService* GetOffTheRecordPrefs() {
    371     return prefs_;
    372   }
    373 
    374   virtual TemplateURLModel* GetTemplateURLModel() {
    375     return profile_->GetTemplateURLModel();
    376   }
    377 
    378   virtual TemplateURLFetcher* GetTemplateURLFetcher() {
    379     return profile_->GetTemplateURLFetcher();
    380   }
    381 
    382   virtual DownloadManager* GetDownloadManager() {
    383     if (!download_manager_.get()) {
    384       scoped_refptr<DownloadManager> dlm(
    385           new DownloadManager(g_browser_process->download_status_updater()));
    386       dlm->Init(this);
    387       download_manager_.swap(dlm);
    388     }
    389     return download_manager_.get();
    390   }
    391 
    392   virtual bool HasCreatedDownloadManager() const {
    393     return (download_manager_.get() != NULL);
    394   }
    395 
    396   virtual PersonalDataManager* GetPersonalDataManager() {
    397     return NULL;
    398   }
    399 
    400   virtual fileapi::FileSystemContext* GetFileSystemContext() {
    401     if (!file_system_context_)
    402       file_system_context_ = CreateFileSystemContext(
    403           GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy());
    404     DCHECK(file_system_context_.get());
    405     return file_system_context_.get();
    406   }
    407 
    408   virtual net::URLRequestContextGetter* GetRequestContext() {
    409     return io_data_.GetMainRequestContextGetter();
    410   }
    411 
    412   virtual net::URLRequestContextGetter* GetRequestContextForPossibleApp(
    413       const Extension* installed_app) {
    414     if (CommandLine::ForCurrentProcess()->HasSwitch(
    415             switches::kEnableExperimentalAppManifests) &&
    416         installed_app != NULL &&
    417         installed_app->is_storage_isolated())
    418       return GetRequestContextForIsolatedApp(installed_app->id());
    419 
    420     return GetRequestContext();
    421   }
    422 
    423   virtual net::URLRequestContextGetter* GetRequestContextForMedia() {
    424     // In OTR mode, media request context is the same as the original one.
    425     return io_data_.GetMainRequestContextGetter();
    426   }
    427 
    428   virtual net::URLRequestContextGetter* GetRequestContextForExtensions() {
    429     return io_data_.GetExtensionsRequestContextGetter();
    430   }
    431 
    432   virtual net::URLRequestContextGetter* GetRequestContextForIsolatedApp(
    433       const std::string& app_id) {
    434     return io_data_.GetIsolatedAppRequestContextGetter(app_id);
    435   }
    436 
    437   virtual const content::ResourceContext& GetResourceContext() {
    438     return io_data_.GetResourceContext();
    439   }
    440 
    441   virtual net::SSLConfigService* GetSSLConfigService() {
    442     return profile_->GetSSLConfigService();
    443   }
    444 
    445   virtual HostContentSettingsMap* GetHostContentSettingsMap() {
    446     // Retrieve the host content settings map of the parent profile in order to
    447     // ensure the preferences have been migrated.
    448     profile_->GetHostContentSettingsMap();
    449     if (!host_content_settings_map_.get())
    450       host_content_settings_map_ = new HostContentSettingsMap(this);
    451     return host_content_settings_map_.get();
    452   }
    453 
    454   virtual HostZoomMap* GetHostZoomMap() {
    455     if (!host_zoom_map_)
    456       host_zoom_map_ = new HostZoomMap(this);
    457     return host_zoom_map_.get();
    458   }
    459 
    460   virtual GeolocationContentSettingsMap* GetGeolocationContentSettingsMap() {
    461     return profile_->GetGeolocationContentSettingsMap();
    462   }
    463 
    464   virtual GeolocationPermissionContext* GetGeolocationPermissionContext() {
    465     return profile_->GetGeolocationPermissionContext();
    466   }
    467 
    468   virtual UserStyleSheetWatcher* GetUserStyleSheetWatcher() {
    469     return profile_->GetUserStyleSheetWatcher();
    470   }
    471 
    472   virtual FindBarState* GetFindBarState() {
    473     if (!find_bar_state_.get())
    474       find_bar_state_.reset(new FindBarState());
    475     return find_bar_state_.get();
    476   }
    477 
    478   virtual SessionService* GetSessionService() {
    479     // Don't save any sessions when incognito.
    480     return NULL;
    481   }
    482 
    483   virtual void ShutdownSessionService() {
    484     // We don't allow a session service, nothing to do.
    485   }
    486 
    487   virtual bool HasSessionService() const {
    488     // We never have a session service.
    489     return false;
    490   }
    491 
    492   virtual bool HasProfileSyncService() const {
    493     // We never have a profile sync service.
    494     return false;
    495   }
    496 
    497   virtual bool DidLastSessionExitCleanly() {
    498     return profile_->DidLastSessionExitCleanly();
    499   }
    500 
    501   virtual BookmarkModel* GetBookmarkModel() {
    502     return profile_->GetBookmarkModel();
    503   }
    504 
    505   virtual ProtocolHandlerRegistry* GetProtocolHandlerRegistry() {
    506     return profile_->GetProtocolHandlerRegistry();
    507   }
    508 
    509   virtual TokenService* GetTokenService() {
    510     return NULL;
    511   }
    512 
    513   virtual ProfileSyncService* GetProfileSyncService() {
    514     return NULL;
    515   }
    516 
    517   virtual ProfileSyncService* GetProfileSyncService(
    518       const std::string& cros_user) {
    519     return NULL;
    520   }
    521 
    522   virtual BrowserSignin* GetBrowserSignin() {
    523     return profile_->GetBrowserSignin();
    524   }
    525 
    526   virtual CloudPrintProxyService* GetCloudPrintProxyService() {
    527     return NULL;
    528   }
    529 
    530   virtual bool IsSameProfile(Profile* profile) {
    531     return (profile == this) || (profile == profile_);
    532   }
    533 
    534   virtual Time GetStartTime() const {
    535     return start_time_;
    536   }
    537 
    538   virtual TabRestoreService* GetTabRestoreService() {
    539     return NULL;
    540   }
    541 
    542   virtual void ResetTabRestoreService() {
    543   }
    544 
    545   virtual SpellCheckHost* GetSpellCheckHost() {
    546     return profile_->GetSpellCheckHost();
    547   }
    548 
    549   virtual void ReinitializeSpellCheckHost(bool force) {
    550     profile_->ReinitializeSpellCheckHost(force);
    551   }
    552 
    553   virtual WebKitContext* GetWebKitContext() {
    554     if (!webkit_context_.get()) {
    555       webkit_context_ = new WebKitContext(
    556           IsOffTheRecord(), GetPath(), GetExtensionSpecialStoragePolicy(),
    557           false);
    558     }
    559     return webkit_context_.get();
    560   }
    561 
    562   virtual history::TopSites* GetTopSitesWithoutCreating() {
    563     return NULL;
    564   }
    565 
    566   virtual history::TopSites* GetTopSites() {
    567     return NULL;
    568   }
    569 
    570   virtual void MarkAsCleanShutdown() {
    571   }
    572 
    573   virtual void InitExtensions(bool extensions_enabled) {
    574     NOTREACHED();
    575   }
    576 
    577   virtual void InitPromoResources() {
    578     NOTREACHED();
    579   }
    580 
    581   virtual void InitRegisteredProtocolHandlers() {
    582     NOTREACHED();
    583   }
    584 
    585   virtual NTPResourceCache* GetNTPResourceCache() {
    586     // Just return the real profile resource cache.
    587     return profile_->GetNTPResourceCache();
    588   }
    589 
    590   virtual FilePath last_selected_directory() {
    591     const FilePath& directory = last_selected_directory_;
    592     if (directory.empty()) {
    593       return profile_->last_selected_directory();
    594     }
    595     return directory;
    596   }
    597 
    598   virtual void set_last_selected_directory(const FilePath& path) {
    599     last_selected_directory_ = path;
    600   }
    601 
    602 #if defined(OS_CHROMEOS)
    603   virtual void SetupChromeOSEnterpriseExtensionObserver() {
    604     profile_->SetupChromeOSEnterpriseExtensionObserver();
    605   }
    606 
    607   virtual void InitChromeOSPreferences() {
    608     // The incognito profile shouldn't have Chrome OS's preferences.
    609     // The preferences are associated with the regular user profile.
    610   }
    611 #endif  // defined(OS_CHROMEOS)
    612 
    613   virtual void ExitedOffTheRecordMode() {
    614     // DownloadManager is lazily created, so check before accessing it.
    615     if (download_manager_.get()) {
    616       // Drop our download manager so we forget about all the downloads made
    617       // in incognito mode.
    618       download_manager_->Shutdown();
    619       download_manager_ = NULL;
    620     }
    621   }
    622 
    623   virtual void OnBrowserAdded(const Browser* browser) {
    624   }
    625 
    626   virtual void OnBrowserRemoved(const Browser* browser) {
    627     if (BrowserList::GetBrowserCount(this) == 0)
    628       ExitedOffTheRecordMode();
    629   }
    630 
    631   virtual ChromeBlobStorageContext* GetBlobStorageContext() {
    632     if (!blob_storage_context_) {
    633       blob_storage_context_ = new ChromeBlobStorageContext();
    634       BrowserThread::PostTask(
    635           BrowserThread::IO, FROM_HERE,
    636           NewRunnableMethod(
    637               blob_storage_context_.get(),
    638               &ChromeBlobStorageContext::InitializeOnIOThread));
    639     }
    640     return blob_storage_context_;
    641   }
    642 
    643   virtual ExtensionInfoMap* GetExtensionInfoMap() {
    644     return profile_->GetExtensionInfoMap();
    645   }
    646 
    647   virtual policy::ProfilePolicyConnector* GetPolicyConnector() {
    648     return NULL;
    649   }
    650 
    651   virtual ChromeURLDataManager* GetChromeURLDataManager() {
    652     if (!chrome_url_data_manager_.get())
    653       chrome_url_data_manager_.reset(new ChromeURLDataManager(this));
    654     return chrome_url_data_manager_.get();
    655   }
    656 
    657   virtual PromoCounter* GetInstantPromoCounter() {
    658     return NULL;
    659   }
    660 
    661 #if defined(OS_CHROMEOS)
    662   virtual void ChangeAppLocale(const std::string& locale, AppLocaleChangedVia) {
    663   }
    664   virtual void OnLogin() {
    665   }
    666 #endif  // defined(OS_CHROMEOS)
    667 
    668   virtual PrefProxyConfigTracker* GetProxyConfigTracker() {
    669     if (!pref_proxy_config_tracker_)
    670       pref_proxy_config_tracker_ = new PrefProxyConfigTracker(GetPrefs());
    671 
    672     return pref_proxy_config_tracker_;
    673   }
    674 
    675   virtual prerender::PrerenderManager* GetPrerenderManager() {
    676     // We do not allow prerendering in OTR profiles at this point.
    677     // TODO(tburkard): Figure out if we want to support this, and how, at some
    678     // point in the future.
    679     return NULL;
    680   }
    681 
    682  private:
    683   NotificationRegistrar registrar_;
    684 
    685   // The real underlying profile.
    686   Profile* profile_;
    687 
    688   // Weak pointer owned by |profile_|.
    689   PrefService* prefs_;
    690 
    691   scoped_ptr<ExtensionProcessManager> extension_process_manager_;
    692 
    693   OffTheRecordProfileIOData::Handle io_data_;
    694 
    695   // The download manager that only stores downloaded items in memory.
    696   scoped_refptr<DownloadManager> download_manager_;
    697 
    698   // We use a non-writable content settings map for OTR.
    699   scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
    700 
    701   // Use a separate zoom map for OTR.
    702   scoped_refptr<HostZoomMap> host_zoom_map_;
    703 
    704   // Use a special WebKit context for OTR browsing.
    705   scoped_refptr<WebKitContext> webkit_context_;
    706 
    707   // We don't want SSLHostState from the OTR profile to leak back to the main
    708   // profile because then the main profile would learn some of the host names
    709   // the user visited while OTR.
    710   scoped_ptr<SSLHostState> ssl_host_state_;
    711 
    712   // Use a separate FindBarState so search terms do not leak back to the main
    713   // profile.
    714   scoped_ptr<FindBarState> find_bar_state_;
    715 
    716   // The TransportSecurityState that only stores enabled sites in memory.
    717   scoped_refptr<net::TransportSecurityState>
    718       transport_security_state_;
    719 
    720   // Time we were started.
    721   Time start_time_;
    722 
    723   scoped_refptr<ChromeAppCacheService> appcache_service_;
    724 
    725   // The main database tracker for this profile.
    726   // Should be used only on the file thread.
    727   scoped_refptr<webkit_database::DatabaseTracker> db_tracker_;
    728 
    729   FilePath last_selected_directory_;
    730 
    731   scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
    732 
    733   // The file_system context for this profile.
    734   scoped_refptr<fileapi::FileSystemContext> file_system_context_;
    735 
    736   scoped_refptr<PrefProxyConfigTracker> pref_proxy_config_tracker_;
    737 
    738   scoped_ptr<ChromeURLDataManager> chrome_url_data_manager_;
    739 
    740   // Used read-only.
    741   scoped_refptr<TransportSecurityPersister> transport_security_loader_;
    742 
    743   DISALLOW_COPY_AND_ASSIGN(OffTheRecordProfileImpl);
    744 };
    745 
    746 #if defined(OS_CHROMEOS)
    747 // Special case of the OffTheRecordProfileImpl which is used while Guest
    748 // session in CrOS.
    749 class GuestSessionProfile : public OffTheRecordProfileImpl {
    750  public:
    751   explicit GuestSessionProfile(Profile* real_profile)
    752       : OffTheRecordProfileImpl(real_profile) {
    753   }
    754 
    755   virtual PersonalDataManager* GetPersonalDataManager() {
    756     return GetOriginalProfile()->GetPersonalDataManager();
    757   }
    758 
    759   virtual void InitChromeOSPreferences() {
    760     chromeos_preferences_.reset(new chromeos::Preferences());
    761     chromeos_preferences_->Init(GetPrefs());
    762   }
    763 
    764  private:
    765   // The guest user should be able to customize Chrome OS preferences.
    766   scoped_ptr<chromeos::Preferences> chromeos_preferences_;
    767 };
    768 #endif
    769 
    770 Profile* Profile::CreateOffTheRecordProfile() {
    771 #if defined(OS_CHROMEOS)
    772   if (Profile::IsGuestSession())
    773     return new GuestSessionProfile(this);
    774 #endif
    775   return new OffTheRecordProfileImpl(this);
    776 }
    777