| 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 |