diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-08 22:34:29 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-08 22:34:29 +0000 |
commit | 0850fa6b9e60e7b925ba516d8cf563fcb18eb23a (patch) | |
tree | b269d0c9180761ab39a046ebda1e34355d78c9ab /chrome/browser | |
parent | 0b081d53f118869541d28139353457bd7aec32e5 (diff) | |
download | chromium_src-0850fa6b9e60e7b925ba516d8cf563fcb18eb23a.zip chromium_src-0850fa6b9e60e7b925ba516d8cf563fcb18eb23a.tar.gz chromium_src-0850fa6b9e60e7b925ba516d8cf563fcb18eb23a.tar.bz2 |
Add the ability to unload the HistoryBackend.
A small number of places used accessors like in_memory_url_database() or backend_loaded() with the expectation that if they weren't already functional, the history system was in the process of making them so. I elected to make both of these functions that triggered lazy backend initialization.
BUG=23400
TEST=none
Review URL: http://codereview.chromium.org/267019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28461 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_browsertest.cc | 2 | ||||
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc | 2 | ||||
-rw-r--r-- | chrome/browser/autocomplete/history_url_provider.cc | 11 | ||||
-rw-r--r-- | chrome/browser/automation/automation_profile_impl.h | 3 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_index.cc | 2 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_index_unittest.cc | 2 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_storage.cc | 2 | ||||
-rw-r--r-- | chrome/browser/cocoa/history_menu_bridge.mm | 4 | ||||
-rw-r--r-- | chrome/browser/history/history.cc | 101 | ||||
-rw-r--r-- | chrome/browser/history/history.h | 72 | ||||
-rw-r--r-- | chrome/browser/profile.cc | 8 | ||||
-rw-r--r-- | chrome/browser/profile.h | 5 |
12 files changed, 144 insertions, 70 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_browsertest.cc b/chrome/browser/autocomplete/autocomplete_browsertest.cc index 403a259..3700997 100644 --- a/chrome/browser/autocomplete/autocomplete_browsertest.cc +++ b/chrome/browser/autocomplete/autocomplete_browsertest.cc @@ -50,7 +50,7 @@ class AutocompleteBrowserTest : public InProcessBrowserTest, void WaitForHistoryBackendToLoad() { HistoryService* history_service = browser()->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); - if (!history_service->backend_loaded()) { + if (!history_service->BackendLoaded()) { NotificationRegistrar registrar; registrar.Add(this, NotificationType::HISTORY_LOADED, NotificationService::AllSources()); diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc b/chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc index c0988c2..ebe4333 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc @@ -204,7 +204,7 @@ class AutocompleteEditViewTest : public InProcessBrowserTest, profile->GetHistoryService(Profile::EXPLICIT_ACCESS); ASSERT_TRUE(history_service); - if (!history_service->backend_loaded()) { + if (!history_service->BackendLoaded()) { NotificationRegistrar registrar; registrar.Add(this, NotificationType::HISTORY_LOADED, Source<Profile>(profile)); diff --git a/chrome/browser/autocomplete/history_url_provider.cc b/chrome/browser/autocomplete/history_url_provider.cc index 6aa5b7d..d333ec5 100644 --- a/chrome/browser/autocomplete/history_url_provider.cc +++ b/chrome/browser/autocomplete/history_url_provider.cc @@ -636,13 +636,14 @@ void HistoryURLProvider::RunAutocompletePasses( // Pass 1: Get the in-memory URL database, and use it to find and promote // the inline autocomplete match, if any. - history::URLDatabase* url_db = history_service->in_memory_database(); + history::URLDatabase* url_db = history_service->InMemoryDatabase(); // url_db can be NULL if it hasn't finished initializing (or failed to // initialize). In this case all we can do is fall back on the second - // pass. Ultimately, we should probably try to ensure the history system - // starts properly before we get here, as otherwise this can cause - // inconsistent behavior when the user has just started the browser and - // tries to type immediately. + // pass. + // + // TODO(pkasting): We should just block here until this loads. Any time + // someone unloads the history backend, we'll get inconsistent inline + // autocomplete behavior here. if (url_db) { DoAutocomplete(NULL, url_db, params.get()); // params->matches now has the matches we should expose to the provider. diff --git a/chrome/browser/automation/automation_profile_impl.h b/chrome/browser/automation/automation_profile_impl.h index 42ad978..dc57f9b 100644 --- a/chrome/browser/automation/automation_profile_impl.h +++ b/chrome/browser/automation/automation_profile_impl.h @@ -81,6 +81,9 @@ class AutomationProfileImpl : public Profile { virtual HistoryService* GetHistoryService(ServiceAccessType access) { return original_profile_->GetHistoryService(access); } + virtual HistoryService* GetHistoryServiceWithoutCreating() { + return original_profile_->GetHistoryServiceWithoutCreating(); + } virtual WebDataService* GetWebDataService(ServiceAccessType access) { return original_profile_->GetWebDataService(access); } diff --git a/chrome/browser/bookmarks/bookmark_index.cc b/chrome/browser/bookmarks/bookmark_index.cc index 8245ac1..18c3134 100644 --- a/chrome/browser/bookmarks/bookmark_index.cc +++ b/chrome/browser/bookmarks/bookmark_index.cc @@ -80,7 +80,7 @@ void BookmarkIndex::SortMatches(const Matches& matches, profile_->GetHistoryService(Profile::EXPLICIT_ACCESS) : NULL; history::URLDatabase* url_db = history_service ? - history_service->in_memory_database() : NULL; + history_service->InMemoryDatabase() : NULL; for (Matches::const_iterator i = matches.begin(); i != matches.end(); ++i) ExtractBookmarkNodePairs(url_db, *i, node_typed_counts); diff --git a/chrome/browser/bookmarks/bookmark_index_unittest.cc b/chrome/browser/bookmarks/bookmark_index_unittest.cc index edac8b0..102a734 100644 --- a/chrome/browser/bookmarks/bookmark_index_unittest.cc +++ b/chrome/browser/bookmarks/bookmark_index_unittest.cc @@ -224,7 +224,7 @@ TEST_F(BookmarkIndexTest, GetResultsSortedByTypedCount) { HistoryService* const history_service = profile.GetHistoryService(Profile::EXPLICIT_ACCESS); - history::URLDatabase* url_db = history_service->in_memory_database(); + history::URLDatabase* url_db = history_service->InMemoryDatabase(); struct TestData { const GURL url; diff --git a/chrome/browser/bookmarks/bookmark_storage.cc b/chrome/browser/bookmarks/bookmark_storage.cc index d7dbe19..a187921 100644 --- a/chrome/browser/bookmarks/bookmark_storage.cc +++ b/chrome/browser/bookmarks/bookmark_storage.cc @@ -177,7 +177,7 @@ void BookmarkStorage::MigrateFromHistory() { model_->DoneLoading(details_.release()); return; } - if (!history->backend_loaded()) { + if (!history->BackendLoaded()) { // The backend isn't finished loading. Wait for it. notification_registrar_.Add(this, NotificationType::HISTORY_LOADED, Source<Profile>(profile_)); diff --git a/chrome/browser/cocoa/history_menu_bridge.mm b/chrome/browser/cocoa/history_menu_bridge.mm index 1603e8c..0f0693c 100644 --- a/chrome/browser/cocoa/history_menu_bridge.mm +++ b/chrome/browser/cocoa/history_menu_bridge.mm @@ -48,7 +48,7 @@ HistoryMenuBridge::HistoryMenuBridge(Profile* profile) // may not be ready when the Bridge is created. If this happens, register // for a notification that tells us the HistoryService is ready. HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); - if (hs != NULL && hs->backend_loaded()) { + if (hs != NULL && hs->BackendLoaded()) { history_service_ = hs; Init(); } @@ -90,7 +90,7 @@ void HistoryMenuBridge::Observe(NotificationType type, if (type == NotificationType::HISTORY_LOADED) { HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); - if (hs != NULL && hs->backend_loaded()) { + if (hs != NULL && hs->BackendLoaded()) { history_service_ = hs; Init(); diff --git a/chrome/browser/history/history.cc b/chrome/browser/history/history.cc index a8ed50b..a7bf774 100644 --- a/chrome/browser/history/history.cc +++ b/chrome/browser/history/history.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -25,7 +25,6 @@ #include "chrome/browser/history/history.h" #include "app/l10n_util.h" -#include "base/file_util.h" #include "base/message_loop.h" #include "base/path_service.h" #include "base/ref_counted.h" @@ -154,29 +153,41 @@ HistoryService::~HistoryService() { bool HistoryService::Init(const FilePath& history_dir, BookmarkService* bookmark_service) { - if (!thread_->Start()) + if (!thread_->Start()) { + Cleanup(); return false; + } - // Create the history backend. - scoped_refptr<HistoryBackend> backend( - new HistoryBackend(history_dir, - new BackendDelegate(this), - bookmark_service)); - history_backend_.swap(backend); + history_dir_ = history_dir; + bookmark_service_ = bookmark_service; - ScheduleAndForget(PRIORITY_UI, &HistoryBackend::Init); + // Create the history backend. + LoadBackendIfNecessary(); return true; } -void HistoryService::Cleanup() { - if (!thread_) { - // We've already cleaned up. - return; - } +bool HistoryService::BackendLoaded() { + // NOTE: We start the backend loading even though it completes asynchronously + // and thus won't affect the return value of this function. This is because + // callers of this assume that if the backend isn't yet loaded it will be + // soon, so they will either listen for notifications or just retry this call + // later. If we've purged the backend, we haven't necessarily restarted it + // loading by now, so we need to trigger the load in order to maintain that + // expectation. + LoadBackendIfNecessary(); + return backend_loaded_; +} + +void HistoryService::UnloadBackend() { + if (!history_backend_) + return; // Already unloaded. - // Shutdown is a little subtle. The backend's destructor must run on the - // history thread since it is not threadsafe. So this thread must not be the - // last thread holding a reference to the backend, or a crash could happen. + // Get rid of the in-memory backend. + in_memory_backend_.reset(); + + // The backend's destructor must run on the history thread since it is not + // threadsafe. So this thread must not be the last thread holding a reference + // to the backend, or a crash could happen. // // We have a reference to the history backend. There is also an extra // reference held by our delegate installed in the backend, which @@ -195,6 +206,16 @@ void HistoryService::Cleanup() { NewRunnableMethod(history_backend_.get(), &HistoryBackend::Closing); history_backend_ = NULL; ScheduleTask(PRIORITY_NORMAL, closing_task); +} + +void HistoryService::Cleanup() { + if (!thread_) { + // We've already cleaned up. + return; + } + + // Unload the backend. + UnloadBackend(); // Delete the thread, which joins with the background thread. We defensively // NULL the pointer before deleting it in case somebody tries to use it @@ -209,7 +230,11 @@ void HistoryService::NotifyRenderProcessHostDestruction(const void* host) { &HistoryBackend::NotifyRenderProcessHostDestruction, host); } -history::URLDatabase* HistoryService::in_memory_database() const { +history::URLDatabase* HistoryService::InMemoryDatabase() { + // NOTE: See comments in BackendLoaded() as to why we call + // LoadBackendIfNecessary() here even though it won't affect the return value + // for this call. + LoadBackendIfNecessary(); if (in_memory_backend_.get()) return in_memory_backend_->db(); return NULL; @@ -297,7 +322,7 @@ void HistoryService::AddPage(const GURL& url, PageTransition::Type transition, const history::RedirectList& redirects, bool did_replace_entry) { - DCHECK(history_backend_) << "History service being called after cleanup"; + DCHECK(thread_) << "History service being called after cleanup"; // Filter out unwanted URLs. We don't add auto-subframe URLs. They are a // large part of history (think iframes for ads) and we never display them in @@ -387,6 +412,7 @@ void HistoryService::SetPageContents(const GURL& url, const std::wstring& contents) { if (!CanAddURL(url)) return; + ScheduleAndForget(PRIORITY_LOW, &HistoryBackend::SetPageContents, url, contents); } @@ -411,33 +437,23 @@ HistoryService::Handle HistoryService::GetPageThumbnail( void HistoryService::GetFavicon(FaviconService::GetFaviconRequest* request, const GURL& icon_url) { - ScheduleTask(PRIORITY_NORMAL, - NewRunnableMethod(history_backend_.get(), - &HistoryBackend::GetFavIcon, - scoped_refptr<FaviconService::GetFaviconRequest>(request), - icon_url)); + Schedule(PRIORITY_NORMAL, &HistoryBackend::GetFavIcon, NULL, request, + icon_url); } void HistoryService::UpdateFaviconMappingAndFetch( FaviconService::GetFaviconRequest* request, const GURL& page_url, const GURL& icon_url) { - ScheduleTask(PRIORITY_NORMAL, - NewRunnableMethod(history_backend_.get(), - &HistoryBackend::UpdateFavIconMappingAndFetch, - scoped_refptr<FaviconService::GetFaviconRequest>(request), - page_url, - icon_url)); + Schedule(PRIORITY_NORMAL, &HistoryBackend::UpdateFavIconMappingAndFetch, NULL, + request, page_url, icon_url); } void HistoryService::GetFaviconForURL( FaviconService::GetFaviconRequest* request, const GURL& page_url) { - ScheduleTask(PRIORITY_UI, - NewRunnableMethod(history_backend_.get(), - &HistoryBackend::GetFavIconForURL, - scoped_refptr<FaviconService::GetFaviconRequest>(request), - page_url)); + Schedule(PRIORITY_NORMAL, &HistoryBackend::GetFavIconForURL, NULL, request, + page_url); } void HistoryService::SetFavicon(const GURL& page_url, @@ -696,6 +712,19 @@ void HistoryService::BroadcastNotifications( NotificationService::current()->Notify(type, source, det); } +void HistoryService::LoadBackendIfNecessary() { + if (!thread_ || history_backend_) + return; // Failed to init, or already started loading. + + scoped_refptr<HistoryBackend> backend( + new HistoryBackend(history_dir_, + new BackendDelegate(this), + bookmark_service_)); + history_backend_.swap(backend); + + ScheduleAndForget(PRIORITY_UI, &HistoryBackend::Init); +} + void HistoryService::OnDBLoaded() { LOG(INFO) << "History backend finished loading"; backend_loaded_ = true; diff --git a/chrome/browser/history/history.h b/chrome/browser/history/history.h index cf80a57..13bbf4c 100644 --- a/chrome/browser/history/history.h +++ b/chrome/browser/history/history.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,6 +9,7 @@ #include <vector> #include "base/basictypes.h" +#include "base/file_path.h" #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "base/task.h" @@ -102,8 +103,14 @@ class HistoryService : public CancelableRequestProvider, // test if a URL is bookmarked; it may be NULL during testing. bool Init(const FilePath& history_dir, BookmarkService* bookmark_service); - // Did the backend finish loading the databases? - bool backend_loaded() const { return backend_loaded_; } + // Triggers the backend to load if it hasn't already, and then returns whether + // it's finished loading. + bool BackendLoaded(); + + // Unloads the backend without actually shutting down the history service. + // This can be used to temporarily reduce the browser process' memory + // footprint. + void UnloadBackend(); // Called on shutdown, this will tell the history backend to complete and // will release pointers to it. No other functions should be called once @@ -124,12 +131,13 @@ class HistoryService : public CancelableRequestProvider, // identification purposes, hence it is a void*. void NotifyRenderProcessHostDestruction(const void* host); - // Returns the in-memory URL database. The returned pointer MAY BE NULL if - // the in-memory database has not been loaded yet. This pointer is owned - // by the history system. Callers should not store or cache this value. + // Triggers the backend to load if it hasn't already, and then returns the + // in-memory URL database. The returned pointer MAY BE NULL if the in-memory + // database has not been loaded yet. This pointer is owned by the history + // system. Callers should not store or cache this value. // // TODO(brettw) this should return the InMemoryHistoryBackend. - history::URLDatabase* in_memory_database() const; + history::URLDatabase* InMemoryDatabase(); // Navigation ---------------------------------------------------------------- @@ -553,6 +561,9 @@ class HistoryService : public CancelableRequestProvider, void BroadcastNotifications(NotificationType type, history::HistoryDetails* details_deleted); + // Initializes the backend. + void LoadBackendIfNecessary(); + // Notification from the backend that it has finished loading. Sends // notification (NOTIFY_HISTORY_LOADED) and sets backend_loaded_ to true. void OnDBLoaded(); @@ -613,7 +624,7 @@ class HistoryService : public CancelableRequestProvider, // Schedule ------------------------------------------------------------------ // // Functions for scheduling operations on the history thread that have a - // handle and are cancelable. For fire-and-forget operations, see + // handle and may be cancelable. For fire-and-forget operations, see // ScheduleAndForget below. template<typename BackendFunc, class RequestType> @@ -621,8 +632,10 @@ class HistoryService : public CancelableRequestProvider, BackendFunc func, // Function to call on the HistoryBackend. CancelableRequestConsumerBase* consumer, RequestType* request) { - DCHECK(history_backend_) << "History service being called after cleanup"; - AddRequest(request, consumer); + DCHECK(thread_) << "History service being called after cleanup"; + LoadBackendIfNecessary(); + if (consumer) + AddRequest(request, consumer); ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func, scoped_refptr<RequestType>(request))); @@ -635,8 +648,10 @@ class HistoryService : public CancelableRequestProvider, CancelableRequestConsumerBase* consumer, RequestType* request, const ArgA& a) { - DCHECK(history_backend_) << "History service being called after cleanup"; - AddRequest(request, consumer); + DCHECK(thread_) << "History service being called after cleanup"; + LoadBackendIfNecessary(); + if (consumer) + AddRequest(request, consumer); ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func, scoped_refptr<RequestType>(request), @@ -654,8 +669,10 @@ class HistoryService : public CancelableRequestProvider, RequestType* request, const ArgA& a, const ArgB& b) { - DCHECK(history_backend_) << "History service being called after cleanup"; - AddRequest(request, consumer); + DCHECK(thread_) << "History service being called after cleanup"; + LoadBackendIfNecessary(); + if (consumer) + AddRequest(request, consumer); ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func, scoped_refptr<RequestType>(request), @@ -675,8 +692,10 @@ class HistoryService : public CancelableRequestProvider, const ArgA& a, const ArgB& b, const ArgC& c) { - DCHECK(history_backend_) << "History service being called after cleanup"; - AddRequest(request, consumer); + DCHECK(thread_) << "History service being called after cleanup"; + LoadBackendIfNecessary(); + if (consumer) + AddRequest(request, consumer); ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func, scoped_refptr<RequestType>(request), @@ -692,7 +711,8 @@ class HistoryService : public CancelableRequestProvider, template<typename BackendFunc> void ScheduleAndForget(SchedulePriority priority, BackendFunc func) { // Function to call on backend. - DCHECK(history_backend_) << "History service being called after cleanup"; + DCHECK(thread_) << "History service being called after cleanup"; + LoadBackendIfNecessary(); ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func)); } @@ -700,7 +720,8 @@ class HistoryService : public CancelableRequestProvider, void ScheduleAndForget(SchedulePriority priority, BackendFunc func, // Function to call on backend. const ArgA& a) { - DCHECK(history_backend_) << "History service being called after cleanup"; + DCHECK(thread_) << "History service being called after cleanup"; + LoadBackendIfNecessary(); ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func, a)); } @@ -709,7 +730,8 @@ class HistoryService : public CancelableRequestProvider, BackendFunc func, // Function to call on backend. const ArgA& a, const ArgB& b) { - DCHECK(history_backend_) << "History service being called after cleanup"; + DCHECK(thread_) << "History service being called after cleanup"; + LoadBackendIfNecessary(); ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func, a, b)); } @@ -720,7 +742,8 @@ class HistoryService : public CancelableRequestProvider, const ArgA& a, const ArgB& b, const ArgC& c) { - DCHECK(history_backend_) << "History service being called after cleanup"; + DCHECK(thread_) << "History service being called after cleanup"; + LoadBackendIfNecessary(); ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func, a, b, c)); } @@ -736,7 +759,8 @@ class HistoryService : public CancelableRequestProvider, const ArgB& b, const ArgC& c, const ArgD& d) { - DCHECK(history_backend_) << "History service being called after cleanup"; + DCHECK(thread_) << "History service being called after cleanup"; + LoadBackendIfNecessary(); ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func, a, b, c, d)); } @@ -770,7 +794,11 @@ class HistoryService : public CancelableRequestProvider, // completed. bool backend_loaded_; - DISALLOW_EVIL_CONSTRUCTORS(HistoryService); + // Cached values from Init(), used whenever we need to reload the backend. + FilePath history_dir_; + BookmarkService* bookmark_service_; + + DISALLOW_COPY_AND_ASSIGN(HistoryService); }; #endif // CHROME_BROWSER_HISTORY_HISTORY_H__ diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc index 2099e99..4508644 100644 --- a/chrome/browser/profile.cc +++ b/chrome/browser/profile.cc @@ -312,6 +312,10 @@ class OffTheRecordProfileImpl : public Profile, } } + virtual HistoryService* GetHistoryServiceWithoutCreating() { + return profile_->GetHistoryServiceWithoutCreating(); + } + virtual FaviconService* GetFaviconService(ServiceAccessType sat) { if (sat == EXPLICIT_ACCESS) { return profile_->GetFaviconService(sat); @@ -1027,6 +1031,10 @@ HistoryService* ProfileImpl::GetHistoryService(ServiceAccessType sat) { return history_service_.get(); } +HistoryService* ProfileImpl::GetHistoryServiceWithoutCreating() { + return history_service_.get(); +} + TemplateURLModel* ProfileImpl::GetTemplateURLModel() { if (!template_url_model_.get()) template_url_model_.reset(new TemplateURLModel(this)); diff --git a/chrome/browser/profile.h b/chrome/browser/profile.h index 45ed081..07e5e34 100644 --- a/chrome/browser/profile.h +++ b/chrome/browser/profile.h @@ -201,6 +201,10 @@ class Profile { // the ServiceAccessType definition above. virtual HistoryService* GetHistoryService(ServiceAccessType access) = 0; + // Similar to GetHistoryService(), but won't create the history service if it + // doesn't already exist. + virtual HistoryService* GetHistoryServiceWithoutCreating() = 0; + // Returns the WebDataService for this profile. This is owned by // the Profile. Callers that outlive the life of this profile need to be // sure they refcount the returned value. @@ -398,6 +402,7 @@ class ProfileImpl : public Profile, virtual ExtensionMessageService* GetExtensionMessageService(); virtual FaviconService* GetFaviconService(ServiceAccessType sat); virtual HistoryService* GetHistoryService(ServiceAccessType sat); + virtual HistoryService* GetHistoryServiceWithoutCreating(); virtual WebDataService* GetWebDataService(ServiceAccessType sat); virtual PasswordStore* GetPasswordStore(ServiceAccessType sat); virtual PrefService* GetPrefs(); |