| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright (c) 2010 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/profile_impl.h" |  | 
| 6 |  | 
| 7 #include "app/resource_bundle.h" |  | 
| 8 #include "base/command_line.h" |  | 
| 9 #include "base/environment.h" |  | 
| 10 #include "base/file_path.h" |  | 
| 11 #include "base/file_util.h" |  | 
| 12 #include "base/metrics/histogram.h" |  | 
| 13 #include "base/path_service.h" |  | 
| 14 #include "base/scoped_ptr.h" |  | 
| 15 #include "base/string_number_conversions.h" |  | 
| 16 #include "base/string_util.h" |  | 
| 17 #include "chrome/browser/about_flags.h" |  | 
| 18 #include "chrome/browser/appcache/chrome_appcache_service.h" |  | 
| 19 #include "chrome/browser/autocomplete/autocomplete_classifier.h" |  | 
| 20 #include "chrome/browser/autofill/personal_data_manager.h" |  | 
| 21 #include "chrome/browser/background_contents_service.h" |  | 
| 22 #include "chrome/browser/background_mode_manager.h" |  | 
| 23 #include "chrome/browser/bookmarks/bookmark_model.h" |  | 
| 24 #include "chrome/browser/browser_list.h" |  | 
| 25 #include "chrome/browser/browser_process.h" |  | 
| 26 #include "chrome/browser/browser_signin.h" |  | 
| 27 #include "chrome/browser/browser_thread.h" |  | 
| 28 #include "chrome/browser/chrome_blob_storage_context.h" |  | 
| 29 #include "chrome/browser/content_settings/host_content_settings_map.h" |  | 
| 30 #include "chrome/browser/dom_ui/ntp_resource_cache.h" |  | 
| 31 #include "chrome/browser/download/download_manager.h" |  | 
| 32 #include "chrome/browser/extensions/default_apps.h" |  | 
| 33 #include "chrome/browser/extensions/extension_devtools_manager.h" |  | 
| 34 #include "chrome/browser/extensions/extension_error_reporter.h" |  | 
| 35 #include "chrome/browser/extensions/extension_info_map.h" |  | 
| 36 #include "chrome/browser/extensions/extension_event_router.h" |  | 
| 37 #include "chrome/browser/extensions/extension_message_service.h" |  | 
| 38 #include "chrome/browser/extensions/extension_process_manager.h" |  | 
| 39 #include "chrome/browser/extensions/extensions_service.h" |  | 
| 40 #include "chrome/browser/extensions/user_script_master.h" |  | 
| 41 #include "chrome/browser/favicon_service.h" |  | 
| 42 #include "chrome/browser/file_system/browser_file_system_context.h" |  | 
| 43 #include "chrome/browser/geolocation/geolocation_content_settings_map.h" |  | 
| 44 #include "chrome/browser/geolocation/geolocation_permission_context.h" |  | 
| 45 #include "chrome/browser/history/history.h" |  | 
| 46 #include "chrome/browser/history/top_sites.h" |  | 
| 47 #include "chrome/browser/host_zoom_map.h" |  | 
| 48 #include "chrome/browser/instant/instant_controller.h" |  | 
| 49 #include "chrome/browser/in_process_webkit/webkit_context.h" |  | 
| 50 #include "chrome/browser/net/chrome_url_request_context.h" |  | 
| 51 #include "chrome/browser/net/gaia/token_service.h" |  | 
| 52 #include "chrome/browser/net/net_pref_observer.h" |  | 
| 53 #include "chrome/browser/net/pref_proxy_config_service.h" |  | 
| 54 #include "chrome/browser/net/ssl_config_service_manager.h" |  | 
| 55 #include "chrome/browser/notifications/desktop_notification_service.h" |  | 
| 56 #include "chrome/browser/password_manager/password_store_default.h" |  | 
| 57 #include "chrome/browser/policy/configuration_policy_provider.h" |  | 
| 58 #include "chrome/browser/policy/configuration_policy_pref_store.h" |  | 
| 59 #include "chrome/browser/policy/profile_policy_context.h" |  | 
| 60 #include "chrome/browser/prefs/browser_prefs.h" |  | 
| 61 #include "chrome/browser/prefs/pref_value_store.h" |  | 
| 62 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" |  | 
| 63 #include "chrome/browser/profile_manager.h" |  | 
| 64 #include "chrome/browser/renderer_host/render_process_host.h" |  | 
| 65 #include "chrome/browser/search_engines/template_url_fetcher.h" |  | 
| 66 #include "chrome/browser/search_engines/template_url_model.h" |  | 
| 67 #include "chrome/browser/sessions/session_service.h" |  | 
| 68 #include "chrome/browser/sessions/tab_restore_service.h" |  | 
| 69 #include "chrome/browser/spellcheck_host.h" |  | 
| 70 #include "chrome/browser/ssl/ssl_host_state.h" |  | 
| 71 #include "chrome/browser/status_icons/status_tray.h" |  | 
| 72 #include "chrome/browser/sync/profile_sync_factory_impl.h" |  | 
| 73 #include "chrome/browser/sync/profile_sync_service.h" |  | 
| 74 #include "chrome/browser/tabs/pinned_tab_service.h" |  | 
| 75 #include "chrome/browser/themes/browser_theme_provider.h" |  | 
| 76 #include "chrome/browser/transport_security_persister.h" |  | 
| 77 #include "chrome/browser/ui/find_bar/find_bar_state.h" |  | 
| 78 #include "chrome/browser/user_style_sheet_watcher.h" |  | 
| 79 #include "chrome/browser/visitedlink_event_listener.h" |  | 
| 80 #include "chrome/browser/visitedlink_master.h" |  | 
| 81 #include "chrome/browser/web_resource/web_resource_service.h" |  | 
| 82 #include "chrome/browser/webdata/web_data_service.h" |  | 
| 83 #include "chrome/common/chrome_constants.h" |  | 
| 84 #include "chrome/common/chrome_paths.h" |  | 
| 85 #include "chrome/common/chrome_paths_internal.h" |  | 
| 86 #include "chrome/common/chrome_switches.h" |  | 
| 87 #include "chrome/common/json_pref_store.h" |  | 
| 88 #include "chrome/common/notification_service.h" |  | 
| 89 #include "chrome/common/pref_names.h" |  | 
| 90 #include "chrome/common/render_messages.h" |  | 
| 91 #include "grit/browser_resources.h" |  | 
| 92 #include "grit/locale_settings.h" |  | 
| 93 #include "net/base/transport_security_state.h" |  | 
| 94 #include "webkit/database/database_tracker.h" |  | 
| 95 |  | 
| 96 #if defined(TOOLKIT_USES_GTK) |  | 
| 97 #include "chrome/browser/gtk/gtk_theme_provider.h" |  | 
| 98 #endif |  | 
| 99 |  | 
| 100 #if defined(OS_WIN) |  | 
| 101 #include "chrome/browser/instant/promo_counter.h" |  | 
| 102 #include "chrome/browser/password_manager/password_store_win.h" |  | 
| 103 #include "chrome/installer/util/install_util.h" |  | 
| 104 #elif defined(OS_MACOSX) |  | 
| 105 #include "chrome/browser/keychain_mac.h" |  | 
| 106 #include "chrome/browser/password_manager/password_store_mac.h" |  | 
| 107 #elif defined(OS_CHROMEOS) |  | 
| 108 #include "chrome/browser/chromeos/enterprise_extension_observer.h" |  | 
| 109 #include "chrome/browser/chromeos/proxy_config_service_impl.h" |  | 
| 110 #elif defined(OS_POSIX) && !defined(OS_CHROMEOS) |  | 
| 111 #include "base/nix/xdg_util.h" |  | 
| 112 #if defined(USE_GNOME_KEYRING) |  | 
| 113 #include "chrome/browser/password_manager/native_backend_gnome_x.h" |  | 
| 114 #endif |  | 
| 115 #include "chrome/browser/password_manager/native_backend_kwallet_x.h" |  | 
| 116 #include "chrome/browser/password_manager/password_store_x.h" |  | 
| 117 #endif |  | 
| 118 |  | 
| 119 #if defined(OS_CHROMEOS) |  | 
| 120 #include "chrome/browser/chromeos/preferences.h" |  | 
| 121 #endif |  | 
| 122 |  | 
| 123 using base::Time; |  | 
| 124 using base::TimeDelta; |  | 
| 125 |  | 
| 126 namespace { |  | 
| 127 |  | 
| 128 void CleanupRequestContext(ChromeURLRequestContextGetter* context) { |  | 
| 129   if (context) |  | 
| 130     context->CleanupOnUIThread(); |  | 
| 131 } |  | 
| 132 |  | 
| 133 // Delay, in milliseconds, before we explicitly create the SessionService. |  | 
| 134 static const int kCreateSessionServiceDelayMS = 500; |  | 
| 135 |  | 
| 136 enum ContextType { |  | 
| 137   kNormalContext, |  | 
| 138   kMediaContext |  | 
| 139 }; |  | 
| 140 |  | 
| 141 // Gets the cache parameters from the command line. |type| is the type of |  | 
| 142 // request context that we need, |cache_path| will be set to the user provided |  | 
| 143 // path, or will not be touched if there is not an argument. |max_size| will |  | 
| 144 // be the user provided value or zero by default. |  | 
| 145 void GetCacheParameters(ContextType type, FilePath* cache_path, |  | 
| 146                         int* max_size) { |  | 
| 147   DCHECK(cache_path); |  | 
| 148   DCHECK(max_size); |  | 
| 149 |  | 
| 150   // Override the cache location if specified by the user. |  | 
| 151   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDiskCacheDir)) { |  | 
| 152     *cache_path = CommandLine::ForCurrentProcess()->GetSwitchValuePath( |  | 
| 153         switches::kDiskCacheDir); |  | 
| 154   } |  | 
| 155 |  | 
| 156   const char* arg = kNormalContext == type ? switches::kDiskCacheSize : |  | 
| 157                                              switches::kMediaCacheSize; |  | 
| 158   std::string value = |  | 
| 159       CommandLine::ForCurrentProcess()->GetSwitchValueASCII(arg); |  | 
| 160 |  | 
| 161   // By default we let the cache determine the right size. |  | 
| 162   *max_size = 0; |  | 
| 163   if (!base::StringToInt(value, max_size)) { |  | 
| 164     *max_size = 0; |  | 
| 165   } else if (max_size < 0) { |  | 
| 166     *max_size = 0; |  | 
| 167   } |  | 
| 168 } |  | 
| 169 |  | 
| 170 FilePath GetCachePath(const FilePath& base) { |  | 
| 171   return base.Append(chrome::kCacheDirname); |  | 
| 172 } |  | 
| 173 |  | 
| 174 FilePath GetMediaCachePath(const FilePath& base) { |  | 
| 175   return base.Append(chrome::kMediaCacheDirname); |  | 
| 176 } |  | 
| 177 |  | 
| 178 // Simple task to log the size of the current profile. |  | 
| 179 class ProfileSizeTask : public Task { |  | 
| 180  public: |  | 
| 181   explicit ProfileSizeTask(const FilePath& path) : path_(path) {} |  | 
| 182   virtual ~ProfileSizeTask() {} |  | 
| 183 |  | 
| 184   virtual void Run(); |  | 
| 185  private: |  | 
| 186   FilePath path_; |  | 
| 187 }; |  | 
| 188 |  | 
| 189 void ProfileSizeTask::Run() { |  | 
| 190   int64 size = file_util::ComputeFilesSize(path_, FILE_PATH_LITERAL("*")); |  | 
| 191   int size_MB = static_cast<int>(size  / (1024 * 1024)); |  | 
| 192   UMA_HISTOGRAM_COUNTS_10000("Profile.TotalSize", size_MB); |  | 
| 193 |  | 
| 194   size = file_util::ComputeFilesSize(path_, FILE_PATH_LITERAL("History")); |  | 
| 195   size_MB = static_cast<int>(size  / (1024 * 1024)); |  | 
| 196   UMA_HISTOGRAM_COUNTS_10000("Profile.HistorySize", size_MB); |  | 
| 197 |  | 
| 198   size = file_util::ComputeFilesSize(path_, FILE_PATH_LITERAL("History*")); |  | 
| 199   size_MB = static_cast<int>(size  / (1024 * 1024)); |  | 
| 200   UMA_HISTOGRAM_COUNTS_10000("Profile.TotalHistorySize", size_MB); |  | 
| 201 |  | 
| 202   size = file_util::ComputeFilesSize(path_, FILE_PATH_LITERAL("Cookies")); |  | 
| 203   size_MB = static_cast<int>(size  / (1024 * 1024)); |  | 
| 204   UMA_HISTOGRAM_COUNTS_10000("Profile.CookiesSize", size_MB); |  | 
| 205 |  | 
| 206   size = file_util::ComputeFilesSize(path_, FILE_PATH_LITERAL("Bookmarks")); |  | 
| 207   size_MB = static_cast<int>(size  / (1024 * 1024)); |  | 
| 208   UMA_HISTOGRAM_COUNTS_10000("Profile.BookmarksSize", size_MB); |  | 
| 209 |  | 
| 210   size = file_util::ComputeFilesSize(path_, FILE_PATH_LITERAL("Favicons")); |  | 
| 211   size_MB = static_cast<int>(size  / (1024 * 1024)); |  | 
| 212   UMA_HISTOGRAM_COUNTS_10000("Profile.FaviconsSize", size_MB); |  | 
| 213 |  | 
| 214   size = file_util::ComputeFilesSize(path_, FILE_PATH_LITERAL("Top Sites")); |  | 
| 215   size_MB = static_cast<int>(size  / (1024 * 1024)); |  | 
| 216   UMA_HISTOGRAM_COUNTS_10000("Profile.TopSitesSize", size_MB); |  | 
| 217 |  | 
| 218   size = file_util::ComputeFilesSize(path_, FILE_PATH_LITERAL("Visited Links")); |  | 
| 219   size_MB = static_cast<int>(size  / (1024 * 1024)); |  | 
| 220   UMA_HISTOGRAM_COUNTS_10000("Profile.VisitedLinksSize", size_MB); |  | 
| 221 |  | 
| 222   size = file_util::ComputeFilesSize(path_, FILE_PATH_LITERAL("Web Data")); |  | 
| 223   size_MB = static_cast<int>(size  / (1024 * 1024)); |  | 
| 224   UMA_HISTOGRAM_COUNTS_10000("Profile.WebDataSize", size_MB); |  | 
| 225 |  | 
| 226   size = file_util::ComputeFilesSize(path_, FILE_PATH_LITERAL("Extension*")); |  | 
| 227   size_MB = static_cast<int>(size  / (1024 * 1024)); |  | 
| 228   UMA_HISTOGRAM_COUNTS_10000("Profile.ExtensionSize", size_MB); |  | 
| 229 } |  | 
| 230 |  | 
| 231 }  // namespace |  | 
| 232 |  | 
| 233 // static |  | 
| 234 Profile* Profile::CreateProfile(const FilePath& path) { |  | 
| 235   return new ProfileImpl(path); |  | 
| 236 } |  | 
| 237 |  | 
| 238 // static |  | 
| 239 void ProfileImpl::RegisterUserPrefs(PrefService* prefs) { |  | 
| 240   prefs->RegisterBooleanPref(prefs::kSavingBrowserHistoryDisabled, false); |  | 
| 241   DefaultApps::RegisterUserPrefs(prefs); |  | 
| 242 } |  | 
| 243 |  | 
| 244 ProfileImpl::ProfileImpl(const FilePath& path) |  | 
| 245     : path_(path), |  | 
| 246       visited_link_event_listener_(new VisitedLinkEventListener()), |  | 
| 247       extension_devtools_manager_(NULL), |  | 
| 248       request_context_(NULL), |  | 
| 249       media_request_context_(NULL), |  | 
| 250       extensions_request_context_(NULL), |  | 
| 251       host_content_settings_map_(NULL), |  | 
| 252       host_zoom_map_(NULL), |  | 
| 253       history_service_created_(false), |  | 
| 254       favicon_service_created_(false), |  | 
| 255       created_web_data_service_(false), |  | 
| 256       created_password_store_(false), |  | 
| 257       created_download_manager_(false), |  | 
| 258       created_theme_provider_(false), |  | 
| 259       start_time_(Time::Now()), |  | 
| 260       spellcheck_host_(NULL), |  | 
| 261       spellcheck_host_ready_(false), |  | 
| 262 #if defined(OS_WIN) |  | 
| 263       checked_instant_promo_(false), |  | 
| 264 #endif |  | 
| 265       shutdown_session_service_(false) { |  | 
| 266   DCHECK(!path.empty()) << "Using an empty path will attempt to write " << |  | 
| 267                             "profile files to the root directory!"; |  | 
| 268   create_session_service_timer_.Start( |  | 
| 269       TimeDelta::FromMilliseconds(kCreateSessionServiceDelayMS), this, |  | 
| 270       &ProfileImpl::EnsureSessionServiceCreated); |  | 
| 271 |  | 
| 272   PrefService* prefs = GetPrefs(); |  | 
| 273   pref_change_registrar_.Init(prefs); |  | 
| 274   pref_change_registrar_.Add(prefs::kSpellCheckDictionary, this); |  | 
| 275   pref_change_registrar_.Add(prefs::kEnableSpellCheck, this); |  | 
| 276   pref_change_registrar_.Add(prefs::kEnableAutoSpellCorrect, this); |  | 
| 277   pref_change_registrar_.Add(prefs::kClearSiteDataOnExit, this); |  | 
| 278 |  | 
| 279   // Convert active labs into switches. Modifies the current command line. |  | 
| 280   about_flags::ConvertFlagsToSwitches(prefs, CommandLine::ForCurrentProcess()); |  | 
| 281 |  | 
| 282   // It would be nice to use PathService for fetching this directory, but |  | 
| 283   // the cache directory depends on the profile directory, which isn't available |  | 
| 284   // to PathService. |  | 
| 285   chrome::GetUserCacheDirectory(path_, &base_cache_path_); |  | 
| 286   file_util::CreateDirectory(base_cache_path_); |  | 
| 287 |  | 
| 288   // Listen for theme installations from our original profile. |  | 
| 289   registrar_.Add(this, NotificationType::THEME_INSTALLED, |  | 
| 290                  Source<Profile>(GetOriginalProfile())); |  | 
| 291 |  | 
| 292   // Listen for bookmark model load, to bootstrap the sync service. |  | 
| 293   registrar_.Add(this, NotificationType::BOOKMARK_MODEL_LOADED, |  | 
| 294                  Source<Profile>(this)); |  | 
| 295 |  | 
| 296   ssl_config_service_manager_.reset( |  | 
| 297       SSLConfigServiceManager::CreateDefaultManager(this)); |  | 
| 298 |  | 
| 299 #if defined(OS_CHROMEOS) |  | 
| 300   chromeos_preferences_.reset(new chromeos::Preferences()); |  | 
| 301   chromeos_preferences_->Init(prefs); |  | 
| 302 #endif |  | 
| 303 |  | 
| 304   pinned_tab_service_.reset(new PinnedTabService(this)); |  | 
| 305 |  | 
| 306   // Initialize the BackgroundModeManager - this has to be done here before |  | 
| 307   // InitExtensions() is called because it relies on receiving notifications |  | 
| 308   // when extensions are loaded. BackgroundModeManager is not needed under |  | 
| 309   // ChromeOS because Chrome is always running (no need for special keep-alive |  | 
| 310   // or launch-on-startup support). |  | 
| 311 #if !defined(OS_CHROMEOS) |  | 
| 312   background_mode_manager_.reset(new BackgroundModeManager(this, |  | 
| 313       CommandLine::ForCurrentProcess())); |  | 
| 314 #endif |  | 
| 315 |  | 
| 316   background_contents_service_.reset( |  | 
| 317       new BackgroundContentsService(this, CommandLine::ForCurrentProcess())); |  | 
| 318 |  | 
| 319   extension_info_map_ = new ExtensionInfoMap(); |  | 
| 320 |  | 
| 321   GetPolicyContext()->Initialize(); |  | 
| 322 |  | 
| 323   clear_local_state_on_exit_ = prefs->GetBoolean(prefs::kClearSiteDataOnExit); |  | 
| 324 |  | 
| 325   // Log the profile size after a reasonable startup delay. |  | 
| 326   BrowserThread::PostDelayedTask(BrowserThread::FILE, FROM_HERE, |  | 
| 327                                  new ProfileSizeTask(path_), 112000); |  | 
| 328 |  | 
| 329   InstantController::RecordMetrics(this); |  | 
| 330 } |  | 
| 331 |  | 
| 332 void ProfileImpl::InitExtensions() { |  | 
| 333   if (user_script_master_ || extensions_service_) |  | 
| 334     return;  // Already initialized. |  | 
| 335 |  | 
| 336   const CommandLine* command_line = CommandLine::ForCurrentProcess(); |  | 
| 337   if (command_line->HasSwitch( |  | 
| 338       switches::kEnableExtensionTimelineApi)) { |  | 
| 339     extension_devtools_manager_ = new ExtensionDevToolsManager(this); |  | 
| 340   } |  | 
| 341 |  | 
| 342   extension_process_manager_.reset(ExtensionProcessManager::Create(this)); |  | 
| 343   extension_event_router_.reset(new ExtensionEventRouter(this)); |  | 
| 344   extension_message_service_ = new ExtensionMessageService(this); |  | 
| 345 |  | 
| 346   ExtensionErrorReporter::Init(true);  // allow noisy errors. |  | 
| 347 |  | 
| 348   FilePath script_dir;  // Don't look for user scripts in any directory. |  | 
| 349                         // TODO(aa): We should just remove this functionality, |  | 
| 350                         // since it isn't used anymore. |  | 
| 351   user_script_master_ = new UserScriptMaster(script_dir, this); |  | 
| 352 |  | 
| 353   extensions_service_ = new ExtensionsService( |  | 
| 354       this, |  | 
| 355       CommandLine::ForCurrentProcess(), |  | 
| 356       GetPath().AppendASCII(ExtensionsService::kInstallDirectoryName), |  | 
| 357       true); |  | 
| 358 |  | 
| 359   RegisterComponentExtensions(); |  | 
| 360   extensions_service_->Init(); |  | 
| 361   InstallDefaultApps(); |  | 
| 362 |  | 
| 363   // Load any extensions specified with --load-extension. |  | 
| 364   if (command_line->HasSwitch(switches::kLoadExtension)) { |  | 
| 365     FilePath path = command_line->GetSwitchValuePath(switches::kLoadExtension); |  | 
| 366     extensions_service_->LoadExtension(path); |  | 
| 367   } |  | 
| 368 } |  | 
| 369 |  | 
| 370 void ProfileImpl::RegisterComponentExtensions() { |  | 
| 371   // Register the component extensions. |  | 
| 372   typedef std::list<std::pair<std::string, int> > ComponentExtensionList; |  | 
| 373   ComponentExtensionList component_extensions; |  | 
| 374 |  | 
| 375   // Bookmark manager. |  | 
| 376   component_extensions.push_back( |  | 
| 377       std::make_pair("bookmark_manager", IDR_BOOKMARKS_MANIFEST)); |  | 
| 378 |  | 
| 379 #if defined(TOUCH_UI) |  | 
| 380   component_extensions.push_back( |  | 
| 381       std::make_pair("keyboard", IDR_KEYBOARD_MANIFEST)); |  | 
| 382 #endif |  | 
| 383 |  | 
| 384   // Web Store. |  | 
| 385   component_extensions.push_back( |  | 
| 386       std::make_pair("web_store", IDR_WEBSTORE_MANIFEST)); |  | 
| 387 |  | 
| 388   for (ComponentExtensionList::iterator iter = component_extensions.begin(); |  | 
| 389     iter != component_extensions.end(); ++iter) { |  | 
| 390     FilePath path; |  | 
| 391     if (PathService::Get(chrome::DIR_RESOURCES, &path)) { |  | 
| 392       path = path.AppendASCII(iter->first); |  | 
| 393     } else { |  | 
| 394       NOTREACHED(); |  | 
| 395     } |  | 
| 396 |  | 
| 397     std::string manifest = |  | 
| 398         ResourceBundle::GetSharedInstance().GetRawDataResource( |  | 
| 399             iter->second).as_string(); |  | 
| 400     extensions_service_->register_component_extension( |  | 
| 401         ExtensionsService::ComponentExtensionInfo(manifest, path)); |  | 
| 402   } |  | 
| 403 } |  | 
| 404 |  | 
| 405 void ProfileImpl::InstallDefaultApps() { |  | 
| 406 #if !defined(OS_CHROMEOS) |  | 
| 407   // On desktop Chrome, we don't have default apps on by, err, default yet. |  | 
| 408   if (!CommandLine::ForCurrentProcess()->HasSwitch( |  | 
| 409           switches::kEnableDefaultApps)) { |  | 
| 410     return; |  | 
| 411   } |  | 
| 412 #endif |  | 
| 413 |  | 
| 414   // The web store only supports en-US at the moment, so we don't install |  | 
| 415   // default apps in other locales. |  | 
| 416   if (g_browser_process->GetApplicationLocale() != "en-US") |  | 
| 417     return; |  | 
| 418 |  | 
| 419   ExtensionsService* extensions_service = GetExtensionsService(); |  | 
| 420   const ExtensionIdSet* app_ids = |  | 
| 421       extensions_service->default_apps()->GetAppsToInstall(); |  | 
| 422   if (!app_ids) |  | 
| 423     return; |  | 
| 424 |  | 
| 425   for (ExtensionIdSet::const_iterator iter = app_ids->begin(); |  | 
| 426        iter != app_ids->end(); ++iter) { |  | 
| 427     extensions_service->AddPendingExtensionFromDefaultAppList(*iter); |  | 
| 428   } |  | 
| 429 } |  | 
| 430 |  | 
| 431 void ProfileImpl::InitWebResources() { |  | 
| 432   if (web_resource_service_) |  | 
| 433     return; |  | 
| 434 |  | 
| 435   web_resource_service_ = new WebResourceService(this); |  | 
| 436   web_resource_service_->StartAfterDelay(); |  | 
| 437 } |  | 
| 438 |  | 
| 439 NTPResourceCache* ProfileImpl::GetNTPResourceCache() { |  | 
| 440   if (!ntp_resource_cache_.get()) |  | 
| 441     ntp_resource_cache_.reset(new NTPResourceCache(this)); |  | 
| 442   return ntp_resource_cache_.get(); |  | 
| 443 } |  | 
| 444 |  | 
| 445 FilePath ProfileImpl::last_selected_directory() { |  | 
| 446   return GetPrefs()->GetFilePath(prefs::kSelectFileLastDirectory); |  | 
| 447 } |  | 
| 448 |  | 
| 449 void ProfileImpl::set_last_selected_directory(const FilePath& path) { |  | 
| 450   GetPrefs()->SetFilePath(prefs::kSelectFileLastDirectory, path); |  | 
| 451 } |  | 
| 452 |  | 
| 453 ProfileImpl::~ProfileImpl() { |  | 
| 454   NotificationService::current()->Notify( |  | 
| 455       NotificationType::PROFILE_DESTROYED, |  | 
| 456       Source<Profile>(this), |  | 
| 457       NotificationService::NoDetails()); |  | 
| 458 |  | 
| 459   GetPolicyContext()->Shutdown(); |  | 
| 460 |  | 
| 461   tab_restore_service_ = NULL; |  | 
| 462 |  | 
| 463   StopCreateSessionServiceTimer(); |  | 
| 464   // TemplateURLModel schedules a task on the WebDataService from its |  | 
| 465   // destructor. Delete it first to ensure the task gets scheduled before we |  | 
| 466   // shut down the database. |  | 
| 467   template_url_model_.reset(); |  | 
| 468 |  | 
| 469   // DownloadManager is lazily created, so check before accessing it. |  | 
| 470   if (download_manager_.get()) { |  | 
| 471     // The download manager queries the history system and should be shutdown |  | 
| 472     // before the history is shutdown so it can properly cancel all requests. |  | 
| 473     download_manager_->Shutdown(); |  | 
| 474     download_manager_ = NULL; |  | 
| 475   } |  | 
| 476 |  | 
| 477   // The theme provider provides bitmaps to whoever wants them. |  | 
| 478   theme_provider_.reset(); |  | 
| 479 |  | 
| 480   // Remove pref observers |  | 
| 481   pref_change_registrar_.RemoveAll(); |  | 
| 482 |  | 
| 483   // Delete the NTP resource cache so we can unregister pref observers. |  | 
| 484   ntp_resource_cache_.reset(); |  | 
| 485 |  | 
| 486   // The sync service needs to be deleted before the services it calls. |  | 
| 487   sync_service_.reset(); |  | 
| 488 |  | 
| 489   // Both HistoryService and WebDataService maintain threads for background |  | 
| 490   // processing. Its possible each thread still has tasks on it that have |  | 
| 491   // increased the ref count of the service. In such a situation, when we |  | 
| 492   // decrement the refcount, it won't be 0, and the threads/databases aren't |  | 
| 493   // properly shut down. By explicitly calling Cleanup/Shutdown we ensure the |  | 
| 494   // databases are properly closed. |  | 
| 495   if (web_data_service_.get()) |  | 
| 496     web_data_service_->Shutdown(); |  | 
| 497 |  | 
| 498   if (top_sites_.get()) |  | 
| 499     top_sites_->Shutdown(); |  | 
| 500 |  | 
| 501   if (history_service_.get()) |  | 
| 502     history_service_->Cleanup(); |  | 
| 503 |  | 
| 504   if (spellcheck_host_.get()) |  | 
| 505     spellcheck_host_->UnsetObserver(); |  | 
| 506 |  | 
| 507   if (default_request_context_ == request_context_) |  | 
| 508     default_request_context_ = NULL; |  | 
| 509 |  | 
| 510   CleanupRequestContext(request_context_); |  | 
| 511   CleanupRequestContext(media_request_context_); |  | 
| 512   CleanupRequestContext(extensions_request_context_); |  | 
| 513 |  | 
| 514   // HistoryService may call into the BookmarkModel, as such we need to |  | 
| 515   // delete HistoryService before the BookmarkModel. The destructor for |  | 
| 516   // HistoryService will join with HistoryService's backend thread so that |  | 
| 517   // by the time the destructor has finished we're sure it will no longer call |  | 
| 518   // into the BookmarkModel. |  | 
| 519   history_service_ = NULL; |  | 
| 520   bookmark_bar_model_.reset(); |  | 
| 521 |  | 
| 522   // FaviconService depends on HistoryServce so make sure we delete |  | 
| 523   // HistoryService first. |  | 
| 524   favicon_service_ = NULL; |  | 
| 525 |  | 
| 526   if (extension_message_service_) |  | 
| 527     extension_message_service_->DestroyingProfile(); |  | 
| 528 |  | 
| 529   if (extensions_service_) |  | 
| 530     extensions_service_->DestroyingProfile(); |  | 
| 531 |  | 
| 532   if (pref_proxy_config_tracker_) |  | 
| 533     pref_proxy_config_tracker_->DetachFromPrefService(); |  | 
| 534 |  | 
| 535   // This causes the Preferences file to be written to disk. |  | 
| 536   MarkAsCleanShutdown(); |  | 
| 537 } |  | 
| 538 |  | 
| 539 ProfileId ProfileImpl::GetRuntimeId() { |  | 
| 540   return reinterpret_cast<ProfileId>(this); |  | 
| 541 } |  | 
| 542 |  | 
| 543 FilePath ProfileImpl::GetPath() { |  | 
| 544   return path_; |  | 
| 545 } |  | 
| 546 |  | 
| 547 bool ProfileImpl::IsOffTheRecord() { |  | 
| 548   return false; |  | 
| 549 } |  | 
| 550 |  | 
| 551 Profile* ProfileImpl::GetOffTheRecordProfile() { |  | 
| 552   if (!off_the_record_profile_.get()) { |  | 
| 553     scoped_ptr<Profile> p(CreateOffTheRecordProfile()); |  | 
| 554     off_the_record_profile_.swap(p); |  | 
| 555 |  | 
| 556     NotificationService::current()->Notify( |  | 
| 557         NotificationType::OTR_PROFILE_CREATED, |  | 
| 558         Source<Profile>(off_the_record_profile_.get()), |  | 
| 559         NotificationService::NoDetails()); |  | 
| 560   } |  | 
| 561   return off_the_record_profile_.get(); |  | 
| 562 } |  | 
| 563 |  | 
| 564 void ProfileImpl::DestroyOffTheRecordProfile() { |  | 
| 565   off_the_record_profile_.reset(); |  | 
| 566 } |  | 
| 567 |  | 
| 568 bool ProfileImpl::HasOffTheRecordProfile() { |  | 
| 569   return off_the_record_profile_.get() != NULL; |  | 
| 570 } |  | 
| 571 |  | 
| 572 Profile* ProfileImpl::GetOriginalProfile() { |  | 
| 573   return this; |  | 
| 574 } |  | 
| 575 |  | 
| 576 ChromeAppCacheService* ProfileImpl::GetAppCacheService() { |  | 
| 577   if (!appcache_service_) { |  | 
| 578     appcache_service_ = new ChromeAppCacheService; |  | 
| 579     BrowserThread::PostTask( |  | 
| 580         BrowserThread::IO, FROM_HERE, |  | 
| 581         NewRunnableMethod(appcache_service_.get(), |  | 
| 582                           &ChromeAppCacheService::InitializeOnIOThread, |  | 
| 583                           GetPath(), IsOffTheRecord(), |  | 
| 584                           make_scoped_refptr(GetHostContentSettingsMap()))); |  | 
| 585   } |  | 
| 586   return appcache_service_; |  | 
| 587 } |  | 
| 588 |  | 
| 589 webkit_database::DatabaseTracker* ProfileImpl::GetDatabaseTracker() { |  | 
| 590   if (!db_tracker_) { |  | 
| 591     db_tracker_ = new webkit_database::DatabaseTracker( |  | 
| 592         GetPath(), IsOffTheRecord()); |  | 
| 593   } |  | 
| 594   return db_tracker_; |  | 
| 595 } |  | 
| 596 |  | 
| 597 VisitedLinkMaster* ProfileImpl::GetVisitedLinkMaster() { |  | 
| 598   if (!visited_link_master_.get()) { |  | 
| 599     scoped_ptr<VisitedLinkMaster> visited_links( |  | 
| 600       new VisitedLinkMaster(visited_link_event_listener_.get(), this)); |  | 
| 601     if (!visited_links->Init()) |  | 
| 602       return NULL; |  | 
| 603     visited_link_master_.swap(visited_links); |  | 
| 604   } |  | 
| 605 |  | 
| 606   return visited_link_master_.get(); |  | 
| 607 } |  | 
| 608 |  | 
| 609 ExtensionsService* ProfileImpl::GetExtensionsService() { |  | 
| 610   return extensions_service_.get(); |  | 
| 611 } |  | 
| 612 |  | 
| 613 BackgroundContentsService* ProfileImpl::GetBackgroundContentsService() const { |  | 
| 614   return background_contents_service_.get(); |  | 
| 615 } |  | 
| 616 |  | 
| 617 StatusTray* ProfileImpl::GetStatusTray() { |  | 
| 618   if (!status_tray_.get()) |  | 
| 619     status_tray_.reset(StatusTray::Create()); |  | 
| 620   return status_tray_.get(); |  | 
| 621 } |  | 
| 622 |  | 
| 623 UserScriptMaster* ProfileImpl::GetUserScriptMaster() { |  | 
| 624   return user_script_master_.get(); |  | 
| 625 } |  | 
| 626 |  | 
| 627 ExtensionDevToolsManager* ProfileImpl::GetExtensionDevToolsManager() { |  | 
| 628   return extension_devtools_manager_.get(); |  | 
| 629 } |  | 
| 630 |  | 
| 631 ExtensionProcessManager* ProfileImpl::GetExtensionProcessManager() { |  | 
| 632   return extension_process_manager_.get(); |  | 
| 633 } |  | 
| 634 |  | 
| 635 ExtensionMessageService* ProfileImpl::GetExtensionMessageService() { |  | 
| 636   return extension_message_service_.get(); |  | 
| 637 } |  | 
| 638 |  | 
| 639 ExtensionEventRouter* ProfileImpl::GetExtensionEventRouter() { |  | 
| 640   return extension_event_router_.get(); |  | 
| 641 } |  | 
| 642 |  | 
| 643 SSLHostState* ProfileImpl::GetSSLHostState() { |  | 
| 644   if (!ssl_host_state_.get()) |  | 
| 645     ssl_host_state_.reset(new SSLHostState()); |  | 
| 646 |  | 
| 647   DCHECK(ssl_host_state_->CalledOnValidThread()); |  | 
| 648   return ssl_host_state_.get(); |  | 
| 649 } |  | 
| 650 |  | 
| 651 net::TransportSecurityState* |  | 
| 652     ProfileImpl::GetTransportSecurityState() { |  | 
| 653   if (!transport_security_state_.get()) { |  | 
| 654     transport_security_state_ = new net::TransportSecurityState(); |  | 
| 655     transport_security_persister_ = |  | 
| 656         new TransportSecurityPersister(); |  | 
| 657     transport_security_persister_->Initialize( |  | 
| 658         transport_security_state_.get(), path_); |  | 
| 659   } |  | 
| 660 |  | 
| 661   return transport_security_state_.get(); |  | 
| 662 } |  | 
| 663 |  | 
| 664 PrefService* ProfileImpl::GetPrefs() { |  | 
| 665   if (!prefs_.get()) { |  | 
| 666     prefs_.reset(PrefService::CreatePrefService(GetPrefFilePath(), |  | 
| 667                                                 GetOriginalProfile())); |  | 
| 668 |  | 
| 669     // The Profile class and ProfileManager class may read some prefs so |  | 
| 670     // register known prefs as soon as possible. |  | 
| 671     Profile::RegisterUserPrefs(prefs_.get()); |  | 
| 672     browser::RegisterUserPrefs(prefs_.get()); |  | 
| 673 |  | 
| 674     // The last session exited cleanly if there is no pref for |  | 
| 675     // kSessionExitedCleanly or the value for kSessionExitedCleanly is true. |  | 
| 676     last_session_exited_cleanly_ = |  | 
| 677         prefs_->GetBoolean(prefs::kSessionExitedCleanly); |  | 
| 678     // Mark the session as open. |  | 
| 679     prefs_->SetBoolean(prefs::kSessionExitedCleanly, false); |  | 
| 680     // Make sure we save to disk that the session has opened. |  | 
| 681     prefs_->ScheduleSavePersistentPrefs(); |  | 
| 682 |  | 
| 683     DCHECK(!net_pref_observer_.get()); |  | 
| 684     net_pref_observer_.reset(new NetPrefObserver(prefs_.get())); |  | 
| 685   } |  | 
| 686 |  | 
| 687   return prefs_.get(); |  | 
| 688 } |  | 
| 689 |  | 
| 690 FilePath ProfileImpl::GetPrefFilePath() { |  | 
| 691   FilePath pref_file_path = path_; |  | 
| 692   pref_file_path = pref_file_path.Append(chrome::kPreferencesFilename); |  | 
| 693   return pref_file_path; |  | 
| 694 } |  | 
| 695 |  | 
| 696 URLRequestContextGetter* ProfileImpl::GetRequestContext() { |  | 
| 697   if (!request_context_) { |  | 
| 698     FilePath cookie_path = GetPath(); |  | 
| 699     cookie_path = cookie_path.Append(chrome::kCookieFilename); |  | 
| 700     FilePath cache_path = base_cache_path_; |  | 
| 701     int max_size; |  | 
| 702     GetCacheParameters(kNormalContext, &cache_path, &max_size); |  | 
| 703 |  | 
| 704     cache_path = GetCachePath(cache_path); |  | 
| 705     request_context_ = ChromeURLRequestContextGetter::CreateOriginal( |  | 
| 706         this, cookie_path, cache_path, max_size); |  | 
| 707 |  | 
| 708     // The first request context is always a normal (non-OTR) request context. |  | 
| 709     // Even when Chromium is started in OTR mode, a normal profile is always |  | 
| 710     // created first. |  | 
| 711     if (!default_request_context_) { |  | 
| 712       default_request_context_ = request_context_; |  | 
| 713       request_context_->set_is_main(true); |  | 
| 714       // TODO(eroman): this isn't terribly useful anymore now that the |  | 
| 715       // URLRequestContext is constructed by the IO thread... |  | 
| 716       NotificationService::current()->Notify( |  | 
| 717           NotificationType::DEFAULT_REQUEST_CONTEXT_AVAILABLE, |  | 
| 718           NotificationService::AllSources(), NotificationService::NoDetails()); |  | 
| 719     } |  | 
| 720   } |  | 
| 721 |  | 
| 722   return request_context_; |  | 
| 723 } |  | 
| 724 |  | 
| 725 URLRequestContextGetter* ProfileImpl::GetRequestContextForMedia() { |  | 
| 726   if (!media_request_context_) { |  | 
| 727     FilePath cache_path = base_cache_path_; |  | 
| 728     int max_size; |  | 
| 729     GetCacheParameters(kMediaContext, &cache_path, &max_size); |  | 
| 730 |  | 
| 731     cache_path = GetMediaCachePath(cache_path); |  | 
| 732     media_request_context_ = |  | 
| 733         ChromeURLRequestContextGetter::CreateOriginalForMedia( |  | 
| 734             this, cache_path, max_size); |  | 
| 735   } |  | 
| 736 |  | 
| 737   return media_request_context_; |  | 
| 738 } |  | 
| 739 |  | 
| 740 FaviconService* ProfileImpl::GetFaviconService(ServiceAccessType sat) { |  | 
| 741   if (!favicon_service_created_) { |  | 
| 742     favicon_service_created_ = true; |  | 
| 743     scoped_refptr<FaviconService> service(new FaviconService(this)); |  | 
| 744     favicon_service_.swap(service); |  | 
| 745   } |  | 
| 746   return favicon_service_.get(); |  | 
| 747 } |  | 
| 748 |  | 
| 749 URLRequestContextGetter* ProfileImpl::GetRequestContextForExtensions() { |  | 
| 750   if (!extensions_request_context_) { |  | 
| 751     FilePath cookie_path = GetPath(); |  | 
| 752     cookie_path = cookie_path.Append(chrome::kExtensionsCookieFilename); |  | 
| 753 |  | 
| 754     extensions_request_context_ = |  | 
| 755         ChromeURLRequestContextGetter::CreateOriginalForExtensions( |  | 
| 756             this, cookie_path); |  | 
| 757   } |  | 
| 758 |  | 
| 759   return extensions_request_context_; |  | 
| 760 } |  | 
| 761 |  | 
| 762 void ProfileImpl::RegisterExtensionWithRequestContexts( |  | 
| 763     const Extension* extension) { |  | 
| 764   // AddRef to ensure the data lives until the other thread gets it. Balanced in |  | 
| 765   // OnNewExtensions. |  | 
| 766   extension->AddRef(); |  | 
| 767   BrowserThread::PostTask( |  | 
| 768       BrowserThread::IO, FROM_HERE, |  | 
| 769       NewRunnableMethod(extension_info_map_.get(), |  | 
| 770                         &ExtensionInfoMap::AddExtension, |  | 
| 771                         extension)); |  | 
| 772 } |  | 
| 773 |  | 
| 774 void ProfileImpl::UnregisterExtensionWithRequestContexts( |  | 
| 775     const Extension* extension) { |  | 
| 776   BrowserThread::PostTask( |  | 
| 777       BrowserThread::IO, FROM_HERE, |  | 
| 778       NewRunnableMethod(extension_info_map_.get(), |  | 
| 779                         &ExtensionInfoMap::RemoveExtension, |  | 
| 780                         extension->id())); |  | 
| 781 } |  | 
| 782 |  | 
| 783 net::SSLConfigService* ProfileImpl::GetSSLConfigService() { |  | 
| 784   return ssl_config_service_manager_->Get(); |  | 
| 785 } |  | 
| 786 |  | 
| 787 HostContentSettingsMap* ProfileImpl::GetHostContentSettingsMap() { |  | 
| 788   if (!host_content_settings_map_.get()) |  | 
| 789     host_content_settings_map_ = new HostContentSettingsMap(this); |  | 
| 790   return host_content_settings_map_.get(); |  | 
| 791 } |  | 
| 792 |  | 
| 793 HostZoomMap* ProfileImpl::GetHostZoomMap() { |  | 
| 794   if (!host_zoom_map_) |  | 
| 795     host_zoom_map_ = new HostZoomMap(this); |  | 
| 796   return host_zoom_map_.get(); |  | 
| 797 } |  | 
| 798 |  | 
| 799 GeolocationContentSettingsMap* ProfileImpl::GetGeolocationContentSettingsMap() { |  | 
| 800   if (!geolocation_content_settings_map_.get()) |  | 
| 801     geolocation_content_settings_map_ = new GeolocationContentSettingsMap(this); |  | 
| 802   return geolocation_content_settings_map_.get(); |  | 
| 803 } |  | 
| 804 |  | 
| 805 GeolocationPermissionContext* ProfileImpl::GetGeolocationPermissionContext() { |  | 
| 806   if (!geolocation_permission_context_.get()) |  | 
| 807     geolocation_permission_context_ = new GeolocationPermissionContext(this); |  | 
| 808   return geolocation_permission_context_.get(); |  | 
| 809 } |  | 
| 810 |  | 
| 811 UserStyleSheetWatcher* ProfileImpl::GetUserStyleSheetWatcher() { |  | 
| 812   if (!user_style_sheet_watcher_.get()) { |  | 
| 813     user_style_sheet_watcher_ = new UserStyleSheetWatcher(GetPath()); |  | 
| 814     user_style_sheet_watcher_->Init(); |  | 
| 815   } |  | 
| 816   return user_style_sheet_watcher_.get(); |  | 
| 817 } |  | 
| 818 |  | 
| 819 FindBarState* ProfileImpl::GetFindBarState() { |  | 
| 820   if (!find_bar_state_.get()) { |  | 
| 821     find_bar_state_.reset(new FindBarState()); |  | 
| 822   } |  | 
| 823   return find_bar_state_.get(); |  | 
| 824 } |  | 
| 825 |  | 
| 826 HistoryService* ProfileImpl::GetHistoryService(ServiceAccessType sat) { |  | 
| 827   // If saving history is disabled, only allow explicit access. |  | 
| 828   if (GetPrefs()->GetBoolean(prefs::kSavingBrowserHistoryDisabled) && |  | 
| 829       sat != EXPLICIT_ACCESS) |  | 
| 830     return NULL; |  | 
| 831 |  | 
| 832   if (!history_service_created_) { |  | 
| 833     history_service_created_ = true; |  | 
| 834     scoped_refptr<HistoryService> history(new HistoryService(this)); |  | 
| 835     if (!history->Init(GetPath(), GetBookmarkModel())) |  | 
| 836       return NULL; |  | 
| 837     history_service_.swap(history); |  | 
| 838 |  | 
| 839     // Send out the notification that the history service was created. |  | 
| 840     NotificationService::current()-> |  | 
| 841         Notify(NotificationType::HISTORY_CREATED, Source<Profile>(this), |  | 
| 842                Details<HistoryService>(history_service_.get())); |  | 
| 843   } |  | 
| 844   return history_service_.get(); |  | 
| 845 } |  | 
| 846 |  | 
| 847 HistoryService* ProfileImpl::GetHistoryServiceWithoutCreating() { |  | 
| 848   return history_service_.get(); |  | 
| 849 } |  | 
| 850 |  | 
| 851 TemplateURLModel* ProfileImpl::GetTemplateURLModel() { |  | 
| 852   if (!template_url_model_.get()) |  | 
| 853     template_url_model_.reset(new TemplateURLModel(this)); |  | 
| 854   return template_url_model_.get(); |  | 
| 855 } |  | 
| 856 |  | 
| 857 TemplateURLFetcher* ProfileImpl::GetTemplateURLFetcher() { |  | 
| 858   if (!template_url_fetcher_.get()) |  | 
| 859     template_url_fetcher_.reset(new TemplateURLFetcher(this)); |  | 
| 860   return template_url_fetcher_.get(); |  | 
| 861 } |  | 
| 862 |  | 
| 863 AutocompleteClassifier* ProfileImpl::GetAutocompleteClassifier() { |  | 
| 864   if (!autocomplete_classifier_.get()) |  | 
| 865     autocomplete_classifier_.reset(new AutocompleteClassifier(this)); |  | 
| 866   return autocomplete_classifier_.get(); |  | 
| 867 } |  | 
| 868 |  | 
| 869 WebDataService* ProfileImpl::GetWebDataService(ServiceAccessType sat) { |  | 
| 870   if (!created_web_data_service_) |  | 
| 871     CreateWebDataService(); |  | 
| 872   return web_data_service_.get(); |  | 
| 873 } |  | 
| 874 |  | 
| 875 WebDataService* ProfileImpl::GetWebDataServiceWithoutCreating() { |  | 
| 876   return web_data_service_.get(); |  | 
| 877 } |  | 
| 878 |  | 
| 879 void ProfileImpl::CreateWebDataService() { |  | 
| 880   DCHECK(!created_web_data_service_ && web_data_service_.get() == NULL); |  | 
| 881   created_web_data_service_ = true; |  | 
| 882   scoped_refptr<WebDataService> wds(new WebDataService()); |  | 
| 883   if (!wds->Init(GetPath())) |  | 
| 884     return; |  | 
| 885   web_data_service_.swap(wds); |  | 
| 886 } |  | 
| 887 |  | 
| 888 PasswordStore* ProfileImpl::GetPasswordStore(ServiceAccessType sat) { |  | 
| 889   if (!created_password_store_) |  | 
| 890     CreatePasswordStore(); |  | 
| 891   return password_store_.get(); |  | 
| 892 } |  | 
| 893 |  | 
| 894 void ProfileImpl::CreatePasswordStore() { |  | 
| 895   DCHECK(!created_password_store_ && password_store_.get() == NULL); |  | 
| 896   created_password_store_ = true; |  | 
| 897   scoped_refptr<PasswordStore> ps; |  | 
| 898   FilePath login_db_file_path = GetPath(); |  | 
| 899   login_db_file_path = login_db_file_path.Append(chrome::kLoginDataFileName); |  | 
| 900   LoginDatabase* login_db = new LoginDatabase(); |  | 
| 901   if (!login_db->Init(login_db_file_path)) { |  | 
| 902     LOG(ERROR) << "Could not initialize login database."; |  | 
| 903     delete login_db; |  | 
| 904     return; |  | 
| 905   } |  | 
| 906 #if defined(OS_WIN) |  | 
| 907   ps = new PasswordStoreWin(login_db, this, |  | 
| 908                             GetWebDataService(Profile::IMPLICIT_ACCESS)); |  | 
| 909 #elif defined(OS_MACOSX) |  | 
| 910   ps = new PasswordStoreMac(new MacKeychain(), login_db); |  | 
| 911 #elif defined(OS_CHROMEOS) |  | 
| 912   // For now, we use PasswordStoreDefault. We might want to make a native |  | 
| 913   // backend for PasswordStoreX (see below) in the future though. |  | 
| 914   ps = new PasswordStoreDefault(login_db, this, |  | 
| 915                                 GetWebDataService(Profile::IMPLICIT_ACCESS)); |  | 
| 916 #elif defined(OS_POSIX) |  | 
| 917   // On POSIX systems, we try to use the "native" password management system of |  | 
| 918   // the desktop environment currently running, allowing GNOME Keyring in XFCE. |  | 
| 919   // (In all cases we fall back on the default store in case of failure.) |  | 
| 920   base::nix::DesktopEnvironment desktop_env; |  | 
| 921   std::string store_type = |  | 
| 922       CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |  | 
| 923           switches::kPasswordStore); |  | 
| 924   if (store_type == "kwallet") { |  | 
| 925     desktop_env = base::nix::DESKTOP_ENVIRONMENT_KDE4; |  | 
| 926   } else if (store_type == "gnome") { |  | 
| 927     desktop_env = base::nix::DESKTOP_ENVIRONMENT_GNOME; |  | 
| 928   } else if (store_type == "detect") { |  | 
| 929     scoped_ptr<base::Environment> env(base::Environment::Create()); |  | 
| 930     desktop_env = base::nix::GetDesktopEnvironment(env.get()); |  | 
| 931     VLOG(1) << "Password storage detected desktop environment: " |  | 
| 932             << base::nix::GetDesktopEnvironmentName(desktop_env); |  | 
| 933   } else { |  | 
| 934     // TODO(mdm): If the flag is not given, or has an unknown value, use the |  | 
| 935     // default store for now. Once we're confident in the other stores, we can |  | 
| 936     // default to detecting the desktop environment instead. |  | 
| 937     desktop_env = base::nix::DESKTOP_ENVIRONMENT_OTHER; |  | 
| 938   } |  | 
| 939 |  | 
| 940   scoped_ptr<PasswordStoreX::NativeBackend> backend; |  | 
| 941   if (desktop_env == base::nix::DESKTOP_ENVIRONMENT_KDE4) { |  | 
| 942     // KDE3 didn't use DBus, which our KWallet store uses. |  | 
| 943     VLOG(1) << "Trying KWallet for password storage."; |  | 
| 944     backend.reset(new NativeBackendKWallet()); |  | 
| 945     if (backend->Init()) |  | 
| 946       VLOG(1) << "Using KWallet for password storage."; |  | 
| 947     else |  | 
| 948       backend.reset(); |  | 
| 949   } else if (desktop_env == base::nix::DESKTOP_ENVIRONMENT_GNOME || |  | 
| 950              desktop_env == base::nix::DESKTOP_ENVIRONMENT_XFCE) { |  | 
| 951 #if defined(USE_GNOME_KEYRING) |  | 
| 952     VLOG(1) << "Trying GNOME keyring for password storage."; |  | 
| 953     backend.reset(new NativeBackendGnome()); |  | 
| 954     if (backend->Init()) |  | 
| 955       VLOG(1) << "Using GNOME keyring for password storage."; |  | 
| 956     else |  | 
| 957       backend.reset(); |  | 
| 958 #endif  // defined(USE_GNOME_KEYRING) |  | 
| 959   } |  | 
| 960   // TODO(mdm): this can change to a WARNING when we detect by default. |  | 
| 961   if (!backend.get()) |  | 
| 962     VLOG(1) << "Using default (unencrypted) store for password storage."; |  | 
| 963 |  | 
| 964   ps = new PasswordStoreX(login_db, this, |  | 
| 965                           GetWebDataService(Profile::IMPLICIT_ACCESS), |  | 
| 966                           backend.release()); |  | 
| 967 #else |  | 
| 968   NOTIMPLEMENTED(); |  | 
| 969 #endif |  | 
| 970   if (!ps) |  | 
| 971     delete login_db; |  | 
| 972 |  | 
| 973   if (!ps || !ps->Init()) { |  | 
| 974     NOTREACHED() << "Could not initialize password manager."; |  | 
| 975     return; |  | 
| 976   } |  | 
| 977   password_store_.swap(ps); |  | 
| 978 } |  | 
| 979 |  | 
| 980 DownloadManager* ProfileImpl::GetDownloadManager() { |  | 
| 981   if (!created_download_manager_) { |  | 
| 982     scoped_refptr<DownloadManager> dlm( |  | 
| 983         new DownloadManager(g_browser_process->download_status_updater())); |  | 
| 984     dlm->Init(this); |  | 
| 985     created_download_manager_ = true; |  | 
| 986     download_manager_.swap(dlm); |  | 
| 987   } |  | 
| 988   return download_manager_.get(); |  | 
| 989 } |  | 
| 990 |  | 
| 991 bool ProfileImpl::HasCreatedDownloadManager() const { |  | 
| 992   return created_download_manager_; |  | 
| 993 } |  | 
| 994 |  | 
| 995 PersonalDataManager* ProfileImpl::GetPersonalDataManager() { |  | 
| 996   if (!personal_data_manager_.get()) { |  | 
| 997     personal_data_manager_ = new PersonalDataManager(); |  | 
| 998     personal_data_manager_->Init(this); |  | 
| 999   } |  | 
| 1000   return personal_data_manager_.get(); |  | 
| 1001 } |  | 
| 1002 |  | 
| 1003 BrowserFileSystemContext* ProfileImpl::GetFileSystemContext() { |  | 
| 1004   if (!browser_file_system_context_.get()) |  | 
| 1005     browser_file_system_context_ = new BrowserFileSystemContext( |  | 
| 1006         GetPath(), IsOffTheRecord()); |  | 
| 1007   DCHECK(browser_file_system_context_.get()); |  | 
| 1008   return browser_file_system_context_.get(); |  | 
| 1009 } |  | 
| 1010 |  | 
| 1011 void ProfileImpl::InitThemes() { |  | 
| 1012   if (!created_theme_provider_) { |  | 
| 1013 #if defined(TOOLKIT_USES_GTK) |  | 
| 1014     theme_provider_.reset(new GtkThemeProvider); |  | 
| 1015 #else |  | 
| 1016     theme_provider_.reset(new BrowserThemeProvider); |  | 
| 1017 #endif |  | 
| 1018     theme_provider_->Init(this); |  | 
| 1019     created_theme_provider_ = true; |  | 
| 1020   } |  | 
| 1021 } |  | 
| 1022 |  | 
| 1023 void ProfileImpl::SetTheme(const Extension* extension) { |  | 
| 1024   InitThemes(); |  | 
| 1025   theme_provider_.get()->SetTheme(extension); |  | 
| 1026 } |  | 
| 1027 |  | 
| 1028 void ProfileImpl::SetNativeTheme() { |  | 
| 1029   InitThemes(); |  | 
| 1030   theme_provider_.get()->SetNativeTheme(); |  | 
| 1031 } |  | 
| 1032 |  | 
| 1033 void ProfileImpl::ClearTheme() { |  | 
| 1034   InitThemes(); |  | 
| 1035   theme_provider_.get()->UseDefaultTheme(); |  | 
| 1036 } |  | 
| 1037 |  | 
| 1038 const Extension* ProfileImpl::GetTheme() { |  | 
| 1039   InitThemes(); |  | 
| 1040 |  | 
| 1041   std::string id = theme_provider_.get()->GetThemeID(); |  | 
| 1042   if (id == BrowserThemeProvider::kDefaultThemeID) |  | 
| 1043     return NULL; |  | 
| 1044 |  | 
| 1045   return extensions_service_->GetExtensionById(id, false); |  | 
| 1046 } |  | 
| 1047 |  | 
| 1048 BrowserThemeProvider* ProfileImpl::GetThemeProvider() { |  | 
| 1049   InitThemes(); |  | 
| 1050   return theme_provider_.get(); |  | 
| 1051 } |  | 
| 1052 |  | 
| 1053 SessionService* ProfileImpl::GetSessionService() { |  | 
| 1054   if (!session_service_.get() && !shutdown_session_service_) { |  | 
| 1055     session_service_ = new SessionService(this); |  | 
| 1056     session_service_->ResetFromCurrentBrowsers(); |  | 
| 1057   } |  | 
| 1058   return session_service_.get(); |  | 
| 1059 } |  | 
| 1060 |  | 
| 1061 void ProfileImpl::ShutdownSessionService() { |  | 
| 1062   if (shutdown_session_service_) |  | 
| 1063     return; |  | 
| 1064 |  | 
| 1065   // We're about to exit, force creation of the session service if it hasn't |  | 
| 1066   // been created yet. We do this to ensure session state matches the point in |  | 
| 1067   // time the user exited. |  | 
| 1068   GetSessionService(); |  | 
| 1069   shutdown_session_service_ = true; |  | 
| 1070   session_service_ = NULL; |  | 
| 1071 } |  | 
| 1072 |  | 
| 1073 bool ProfileImpl::HasSessionService() const { |  | 
| 1074   return (session_service_.get() != NULL); |  | 
| 1075 } |  | 
| 1076 |  | 
| 1077 bool ProfileImpl::HasProfileSyncService() const { |  | 
| 1078   return (sync_service_.get() != NULL); |  | 
| 1079 } |  | 
| 1080 |  | 
| 1081 bool ProfileImpl::DidLastSessionExitCleanly() { |  | 
| 1082   // last_session_exited_cleanly_ is set when the preferences are loaded. Force |  | 
| 1083   // it to be set by asking for the prefs. |  | 
| 1084   GetPrefs(); |  | 
| 1085   return last_session_exited_cleanly_; |  | 
| 1086 } |  | 
| 1087 |  | 
| 1088 BookmarkModel* ProfileImpl::GetBookmarkModel() { |  | 
| 1089   if (!bookmark_bar_model_.get()) { |  | 
| 1090     bookmark_bar_model_.reset(new BookmarkModel(this)); |  | 
| 1091     bookmark_bar_model_->Load(); |  | 
| 1092   } |  | 
| 1093   return bookmark_bar_model_.get(); |  | 
| 1094 } |  | 
| 1095 |  | 
| 1096 bool ProfileImpl::IsSameProfile(Profile* profile) { |  | 
| 1097   if (profile == static_cast<Profile*>(this)) |  | 
| 1098     return true; |  | 
| 1099   Profile* otr_profile = off_the_record_profile_.get(); |  | 
| 1100   return otr_profile && profile == otr_profile; |  | 
| 1101 } |  | 
| 1102 |  | 
| 1103 Time ProfileImpl::GetStartTime() const { |  | 
| 1104   return start_time_; |  | 
| 1105 } |  | 
| 1106 |  | 
| 1107 TabRestoreService* ProfileImpl::GetTabRestoreService() { |  | 
| 1108   if (!tab_restore_service_.get()) |  | 
| 1109     tab_restore_service_ = new TabRestoreService(this); |  | 
| 1110   return tab_restore_service_.get(); |  | 
| 1111 } |  | 
| 1112 |  | 
| 1113 history::TopSites* ProfileImpl::GetTopSites() { |  | 
| 1114   if (!top_sites_.get()) { |  | 
| 1115     top_sites_ = new history::TopSites(this); |  | 
| 1116     top_sites_->Init(GetPath().Append(chrome::kTopSitesFilename)); |  | 
| 1117   } |  | 
| 1118   return top_sites_; |  | 
| 1119 } |  | 
| 1120 |  | 
| 1121 history::TopSites* ProfileImpl::GetTopSitesWithoutCreating() { |  | 
| 1122   return top_sites_; |  | 
| 1123 } |  | 
| 1124 |  | 
| 1125 void ProfileImpl::ResetTabRestoreService() { |  | 
| 1126   tab_restore_service_ = NULL; |  | 
| 1127 } |  | 
| 1128 |  | 
| 1129 SpellCheckHost* ProfileImpl::GetSpellCheckHost() { |  | 
| 1130   return spellcheck_host_ready_ ? spellcheck_host_.get() : NULL; |  | 
| 1131 } |  | 
| 1132 |  | 
| 1133 void ProfileImpl::ReinitializeSpellCheckHost(bool force) { |  | 
| 1134   // If we are already loading the spellchecker, and this is just a hint to |  | 
| 1135   // load the spellchecker, do nothing. |  | 
| 1136   if (!force && spellcheck_host_.get()) |  | 
| 1137     return; |  | 
| 1138 |  | 
| 1139   spellcheck_host_ready_ = false; |  | 
| 1140 |  | 
| 1141   bool notify = false; |  | 
| 1142   if (spellcheck_host_.get()) { |  | 
| 1143     spellcheck_host_->UnsetObserver(); |  | 
| 1144     spellcheck_host_ = NULL; |  | 
| 1145     notify = true; |  | 
| 1146   } |  | 
| 1147 |  | 
| 1148   PrefService* prefs = GetPrefs(); |  | 
| 1149   if (prefs->GetBoolean(prefs::kEnableSpellCheck)) { |  | 
| 1150     // Retrieve the (perhaps updated recently) dictionary name from preferences. |  | 
| 1151     spellcheck_host_ = new SpellCheckHost( |  | 
| 1152         this, |  | 
| 1153         prefs->GetString(prefs::kSpellCheckDictionary), |  | 
| 1154         GetRequestContext()); |  | 
| 1155     spellcheck_host_->Initialize(); |  | 
| 1156   } else if (notify) { |  | 
| 1157     // The spellchecker has been disabled. |  | 
| 1158     SpellCheckHostInitialized(); |  | 
| 1159   } |  | 
| 1160 } |  | 
| 1161 |  | 
| 1162 void ProfileImpl::SpellCheckHostInitialized() { |  | 
| 1163   spellcheck_host_ready_ = spellcheck_host_ && |  | 
| 1164       (spellcheck_host_->bdict_file() != base::kInvalidPlatformFileValue || |  | 
| 1165        spellcheck_host_->use_platform_spellchecker()); |  | 
| 1166   NotificationService::current()->Notify( |  | 
| 1167       NotificationType::SPELLCHECK_HOST_REINITIALIZED, |  | 
| 1168           Source<Profile>(this), NotificationService::NoDetails()); |  | 
| 1169 } |  | 
| 1170 |  | 
| 1171 WebKitContext* ProfileImpl::GetWebKitContext() { |  | 
| 1172   if (!webkit_context_.get()) |  | 
| 1173     webkit_context_ = new WebKitContext(this, clear_local_state_on_exit_); |  | 
| 1174   DCHECK(webkit_context_.get()); |  | 
| 1175   return webkit_context_.get(); |  | 
| 1176 } |  | 
| 1177 |  | 
| 1178 DesktopNotificationService* ProfileImpl::GetDesktopNotificationService() { |  | 
| 1179   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |  | 
| 1180   if (!desktop_notification_service_.get()) { |  | 
| 1181      desktop_notification_service_.reset(new DesktopNotificationService( |  | 
| 1182          this, g_browser_process->notification_ui_manager())); |  | 
| 1183   } |  | 
| 1184   return desktop_notification_service_.get(); |  | 
| 1185 } |  | 
| 1186 |  | 
| 1187 void ProfileImpl::MarkAsCleanShutdown() { |  | 
| 1188   if (prefs_.get()) { |  | 
| 1189     // The session cleanly exited, set kSessionExitedCleanly appropriately. |  | 
| 1190     prefs_->SetBoolean(prefs::kSessionExitedCleanly, true); |  | 
| 1191 |  | 
| 1192     // NOTE: If you change what thread this writes on, be sure and update |  | 
| 1193     // ChromeFrame::EndSession(). |  | 
| 1194     prefs_->SavePersistentPrefs(); |  | 
| 1195   } |  | 
| 1196 } |  | 
| 1197 |  | 
| 1198 void ProfileImpl::Observe(NotificationType type, |  | 
| 1199                           const NotificationSource& source, |  | 
| 1200                           const NotificationDetails& details) { |  | 
| 1201   if (NotificationType::PREF_CHANGED == type) { |  | 
| 1202     std::string* pref_name_in = Details<std::string>(details).ptr(); |  | 
| 1203     PrefService* prefs = Source<PrefService>(source).ptr(); |  | 
| 1204     DCHECK(pref_name_in && prefs); |  | 
| 1205     if (*pref_name_in == prefs::kSpellCheckDictionary || |  | 
| 1206         *pref_name_in == prefs::kEnableSpellCheck) { |  | 
| 1207       ReinitializeSpellCheckHost(true); |  | 
| 1208     } else if (*pref_name_in == prefs::kEnableAutoSpellCorrect) { |  | 
| 1209       NotificationService::current()->Notify( |  | 
| 1210           NotificationType::SPELLCHECK_AUTOSPELL_TOGGLED, |  | 
| 1211               Source<Profile>(this), NotificationService::NoDetails()); |  | 
| 1212     } else if (*pref_name_in == prefs::kClearSiteDataOnExit) { |  | 
| 1213       clear_local_state_on_exit_ = |  | 
| 1214           prefs->GetBoolean(prefs::kClearSiteDataOnExit); |  | 
| 1215       if (webkit_context_) |  | 
| 1216         webkit_context_->set_clear_local_state_on_exit( |  | 
| 1217             clear_local_state_on_exit_); |  | 
| 1218     } |  | 
| 1219   } else if (NotificationType::THEME_INSTALLED == type) { |  | 
| 1220     DCHECK_EQ(Source<Profile>(source).ptr(), GetOriginalProfile()); |  | 
| 1221     const Extension* extension = Details<const Extension>(details).ptr(); |  | 
| 1222     SetTheme(extension); |  | 
| 1223   } else if (NotificationType::BOOKMARK_MODEL_LOADED == type) { |  | 
| 1224     GetProfileSyncService();  // Causes lazy-load if sync is enabled. |  | 
| 1225     registrar_.Remove(this, NotificationType::BOOKMARK_MODEL_LOADED, |  | 
| 1226                       Source<Profile>(this)); |  | 
| 1227   } |  | 
| 1228 } |  | 
| 1229 |  | 
| 1230 void ProfileImpl::StopCreateSessionServiceTimer() { |  | 
| 1231   create_session_service_timer_.Stop(); |  | 
| 1232 } |  | 
| 1233 |  | 
| 1234 TokenService* ProfileImpl::GetTokenService() { |  | 
| 1235   if (!token_service_.get()) { |  | 
| 1236     token_service_.reset(new TokenService()); |  | 
| 1237   } |  | 
| 1238   return token_service_.get(); |  | 
| 1239 } |  | 
| 1240 |  | 
| 1241 ProfileSyncService* ProfileImpl::GetProfileSyncService() { |  | 
| 1242   return GetProfileSyncService(""); |  | 
| 1243 } |  | 
| 1244 |  | 
| 1245 ProfileSyncService* ProfileImpl::GetProfileSyncService( |  | 
| 1246     const std::string& cros_user) { |  | 
| 1247 |  | 
| 1248   if (!ProfileSyncService::IsSyncEnabled()) |  | 
| 1249     return NULL; |  | 
| 1250   if (!sync_service_.get()) |  | 
| 1251     InitSyncService(cros_user); |  | 
| 1252   return sync_service_.get(); |  | 
| 1253 } |  | 
| 1254 |  | 
| 1255 BrowserSignin* ProfileImpl::GetBrowserSignin() { |  | 
| 1256   if (!browser_signin_.get()) { |  | 
| 1257     browser_signin_.reset(new BrowserSignin(this)); |  | 
| 1258   } |  | 
| 1259   return browser_signin_.get(); |  | 
| 1260 } |  | 
| 1261 |  | 
| 1262 CloudPrintProxyService* ProfileImpl::GetCloudPrintProxyService() { |  | 
| 1263   if (!cloud_print_proxy_service_.get()) |  | 
| 1264     InitCloudPrintProxyService(); |  | 
| 1265   return cloud_print_proxy_service_.get(); |  | 
| 1266 } |  | 
| 1267 |  | 
| 1268 void ProfileImpl::InitSyncService(const std::string& cros_user) { |  | 
| 1269   profile_sync_factory_.reset( |  | 
| 1270       new ProfileSyncFactoryImpl(this, CommandLine::ForCurrentProcess())); |  | 
| 1271   sync_service_.reset( |  | 
| 1272       profile_sync_factory_->CreateProfileSyncService(cros_user)); |  | 
| 1273   sync_service_->Initialize(); |  | 
| 1274 } |  | 
| 1275 |  | 
| 1276 void ProfileImpl::InitCloudPrintProxyService() { |  | 
| 1277   cloud_print_proxy_service_ = new CloudPrintProxyService(this); |  | 
| 1278   cloud_print_proxy_service_->Initialize(); |  | 
| 1279 } |  | 
| 1280 |  | 
| 1281 ChromeBlobStorageContext* ProfileImpl::GetBlobStorageContext() { |  | 
| 1282   if (!blob_storage_context_) { |  | 
| 1283     blob_storage_context_ = new ChromeBlobStorageContext(); |  | 
| 1284     BrowserThread::PostTask( |  | 
| 1285         BrowserThread::IO, FROM_HERE, |  | 
| 1286         NewRunnableMethod(blob_storage_context_.get(), |  | 
| 1287                           &ChromeBlobStorageContext::InitializeOnIOThread)); |  | 
| 1288   } |  | 
| 1289   return blob_storage_context_; |  | 
| 1290 } |  | 
| 1291 |  | 
| 1292 ExtensionInfoMap* ProfileImpl::GetExtensionInfoMap() { |  | 
| 1293   return extension_info_map_.get(); |  | 
| 1294 } |  | 
| 1295 |  | 
| 1296 policy::ProfilePolicyContext* ProfileImpl::GetPolicyContext() { |  | 
| 1297   if (!profile_policy_context_.get()) |  | 
| 1298     profile_policy_context_.reset(new policy::ProfilePolicyContext(this)); |  | 
| 1299 |  | 
| 1300   return profile_policy_context_.get(); |  | 
| 1301 } |  | 
| 1302 |  | 
| 1303 PromoCounter* ProfileImpl::GetInstantPromoCounter() { |  | 
| 1304 #if defined(OS_WIN) |  | 
| 1305   // TODO: enable this when we're ready to turn on the promo. |  | 
| 1306   /* |  | 
| 1307   if (!checked_instant_promo_) { |  | 
| 1308     checked_instant_promo_ = true; |  | 
| 1309     PrefService* prefs = GetPrefs(); |  | 
| 1310     if (!prefs->GetBoolean(prefs::kInstantEnabledOnce) && |  | 
| 1311         !InstantController::IsEnabled(this) && |  | 
| 1312         InstallUtil::IsChromeSxSProcess()) { |  | 
| 1313       DCHECK(!instant_promo_counter_.get()); |  | 
| 1314       instant_promo_counter_.reset( |  | 
| 1315           new PromoCounter(this, prefs::kInstantPromo, "Instant.Promo", 3, 3)); |  | 
| 1316     } |  | 
| 1317   } |  | 
| 1318   */ |  | 
| 1319   return instant_promo_counter_.get(); |  | 
| 1320 #else |  | 
| 1321   return NULL; |  | 
| 1322 #endif |  | 
| 1323 } |  | 
| 1324 |  | 
| 1325 #if defined(OS_CHROMEOS) |  | 
| 1326 chromeos::ProxyConfigServiceImpl* |  | 
| 1327     ProfileImpl::GetChromeOSProxyConfigServiceImpl() { |  | 
| 1328   if (!chromeos_proxy_config_service_impl_) { |  | 
| 1329     chromeos_proxy_config_service_impl_ = |  | 
| 1330         new chromeos::ProxyConfigServiceImpl(); |  | 
| 1331   } |  | 
| 1332   return chromeos_proxy_config_service_impl_; |  | 
| 1333 } |  | 
| 1334 |  | 
| 1335 void ProfileImpl::SetupChromeOSEnterpriseExtensionObserver() { |  | 
| 1336   DCHECK(!chromeos_enterprise_extension_observer_.get()); |  | 
| 1337   chromeos_enterprise_extension_observer_.reset( |  | 
| 1338       new chromeos::EnterpriseExtensionObserver(this)); |  | 
| 1339 } |  | 
| 1340 #endif  // defined(OS_CHROMEOS) |  | 
| 1341 |  | 
| 1342 PrefProxyConfigTracker* ProfileImpl::GetProxyConfigTracker() { |  | 
| 1343   if (!pref_proxy_config_tracker_) |  | 
| 1344     pref_proxy_config_tracker_ = new PrefProxyConfigTracker(GetPrefs()); |  | 
| 1345 |  | 
| 1346   return pref_proxy_config_tracker_; |  | 
| 1347 } |  | 
| OLD | NEW | 
|---|