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 |