summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-01 14:40:56 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-01 14:40:56 +0000
commita5894febf1f091bb122ae6273fd49f26dba5f0aa (patch)
treeceeb84bc784a00a68e465663d151d04df5f8c1c5 /chrome/browser
parent32f72e6f11a2a9a65ef50a674b838c66ee2c677d (diff)
downloadchromium_src-a5894febf1f091bb122ae6273fd49f26dba5f0aa.zip
chromium_src-a5894febf1f091bb122ae6273fd49f26dba5f0aa.tar.gz
chromium_src-a5894febf1f091bb122ae6273fd49f26dba5f0aa.tar.bz2
Make history service not ref-counted and not thread-safe
This is in preparation for making it handle delete directives. Make HistoryService use a ThreadChecker. Make VisitDataObserver list a non-thread-safe observer list. Make HistoryService vend WeakPtrs for sync. Make PrerenderLocalPredictor not keep a pointer to the HistoryService. Make sync trampoline to the UI thread when posting tasks on the history thread. BUG=141245 Review URL: https://chromiumcodereview.appspot.com/11229049 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@165370 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/android/dev_tools_server.cc1
-rw-r--r--chrome/browser/history/DEPS2
-rw-r--r--chrome/browser/history/history.cc157
-rw-r--r--chrome/browser/history/history.h42
-rw-r--r--chrome/browser/history/history_backend.h2
-rw-r--r--chrome/browser/history/history_browsertest.cc7
-rw-r--r--chrome/browser/history/history_querying_unittest.cc8
-rw-r--r--chrome/browser/history/history_service_factory.cc19
-rw-r--r--chrome/browser/history/history_service_factory.h13
-rw-r--r--chrome/browser/history/history_types.cc4
-rw-r--r--chrome/browser/history/history_types.h2
-rw-r--r--chrome/browser/history/history_unittest.cc629
-rw-r--r--chrome/browser/prerender/prerender_local_predictor.cc18
-rw-r--r--chrome/browser/prerender/prerender_local_predictor.h10
-rw-r--r--chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc5
-rw-r--r--chrome/browser/sync/glue/history_model_worker.cc41
-rw-r--r--chrome/browser/sync/glue/history_model_worker.h6
-rw-r--r--chrome/browser/sync/glue/sync_backend_registrar.cc3
-rw-r--r--chrome/browser/sync/profile_sync_service_typed_url_unittest.cc5
-rw-r--r--chrome/browser/ui/cocoa/tabpose_window.mm1
-rw-r--r--chrome/browser/visitedlink/visitedlink_unittest.cc8
21 files changed, 578 insertions, 405 deletions
diff --git a/chrome/browser/android/dev_tools_server.cc b/chrome/browser/android/dev_tools_server.cc
index 92489a1..aa45426 100644
--- a/chrome/browser/android/dev_tools_server.cc
+++ b/chrome/browser/android/dev_tools_server.cc
@@ -18,6 +18,7 @@
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_version_info.h"
#include "content/public/browser/android/devtools_auth.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_http_handler.h"
#include "content/public/browser/devtools_http_handler_delegate.h"
#include "jni/DevToolsServer_jni.h"
diff --git a/chrome/browser/history/DEPS b/chrome/browser/history/DEPS
index 03a0bde..e0a0542 100644
--- a/chrome/browser/history/DEPS
+++ b/chrome/browser/history/DEPS
@@ -37,6 +37,8 @@ include_rules = [
"!chrome/browser/profiles/profile.h",
"!chrome/browser/profiles/profile_dependency_manager.h",
"!chrome/browser/profiles/profile_manager.h",
+ "!chrome/browser/profiles/profile_keyed_service.h",
+ "!chrome/browser/profiles/profile_keyed_service_factory.h",
"!chrome/browser/profiles/refcounted_profile_keyed_service.h",
"!chrome/browser/profiles/refcounted_profile_keyed_service_factory.h",
"!chrome/browser/ui/browser.h",
diff --git a/chrome/browser/history/history.cc b/chrome/browser/history/history.cc
index 0b3375d..307fbc5 100644
--- a/chrome/browser/history/history.cc
+++ b/chrome/browser/history/history.cc
@@ -26,10 +26,13 @@
#include "base/callback.h"
#include "base/command_line.h"
+#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
#include "base/path_service.h"
+#include "base/sequenced_task_runner.h"
#include "base/string_util.h"
+#include "base/thread_task_runner_handle.h"
#include "base/threading/thread.h"
#include "chrome/browser/autocomplete/history_url_provider.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
@@ -76,27 +79,30 @@ static const char* kHistoryThreadName = "Chrome_HistoryThread";
// Release when the Backend has a reference to us).
class HistoryService::BackendDelegate : public HistoryBackend::Delegate {
public:
- BackendDelegate(HistoryService* history_service, Profile* profile)
+ BackendDelegate(
+ const base::WeakPtr<HistoryService>& history_service,
+ const scoped_refptr<base::SequencedTaskRunner>& service_task_runner,
+ Profile* profile)
: history_service_(history_service),
- message_loop_(MessageLoop::current()),
+ service_task_runner_(service_task_runner),
profile_(profile) {
}
virtual void NotifyProfileError(int backend_id,
sql::InitStatus init_status) OVERRIDE {
// Send to the history service on the main thread.
- message_loop_->PostTask(
+ service_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&HistoryService::NotifyProfileError, history_service_.get(),
+ base::Bind(&HistoryService::NotifyProfileError, history_service_,
backend_id, init_status));
}
virtual void SetInMemoryBackend(int backend_id,
history::InMemoryHistoryBackend* backend) OVERRIDE {
// Send the backend to the history service on the main thread.
- message_loop_->PostTask(
+ service_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&HistoryService::SetInMemoryBackend, history_service_.get(),
+ base::Bind(&HistoryService::SetInMemoryBackend, history_service_,
backend_id, backend));
}
@@ -110,64 +116,63 @@ class HistoryService::BackendDelegate : public HistoryBackend::Delegate {
type, content::Source<Profile>(profile_), det);
}
// Send the notification to the history service on the main thread.
- message_loop_->PostTask(
+ service_task_runner_->PostTask(
FROM_HERE,
base::Bind(&HistoryService::BroadcastNotificationsHelper,
- history_service_.get(), type, base::Owned(details)));
+ history_service_, type, base::Owned(details)));
}
virtual void DBLoaded(int backend_id) OVERRIDE {
- message_loop_->PostTask(
+ service_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&HistoryService::OnDBLoaded, history_service_.get(),
+ base::Bind(&HistoryService::OnDBLoaded, history_service_,
backend_id));
}
virtual void StartTopSitesMigration(int backend_id) OVERRIDE {
- message_loop_->PostTask(
+ service_task_runner_->PostTask(
FROM_HERE,
base::Bind(&HistoryService::StartTopSitesMigration,
- history_service_.get(), backend_id));
+ history_service_, backend_id));
}
virtual void NotifyVisitDBObserversOnAddVisit(
const history::BriefVisitInfo& info) OVERRIDE {
- // Since the notification method can be run on any thread, we can
- // call it right away.
- history_service_->NotifyVisitDBObserversOnAddVisit(info);
+ service_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&HistoryService::NotifyVisitDBObserversOnAddVisit,
+ history_service_, info));
}
private:
- scoped_refptr<HistoryService> history_service_;
- MessageLoop* message_loop_;
- Profile* profile_;
+ const base::WeakPtr<HistoryService> history_service_;
+ const scoped_refptr<base::SequencedTaskRunner> service_task_runner_;
+ Profile* const profile_;
};
// The history thread is intentionally not a BrowserThread because the
// sync integration unit tests depend on being able to create more than one
// history thread.
HistoryService::HistoryService()
- : thread_(new base::Thread(kHistoryThreadName)),
+ : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ thread_(new base::Thread(kHistoryThreadName)),
profile_(NULL),
backend_loaded_(false),
current_backend_id_(-1),
bookmark_service_(NULL),
no_db_(false),
- needs_top_sites_migration_(false),
- visit_database_observers_(
- new ObserverListThreadSafe<history::VisitDatabaseObserver>()) {
+ needs_top_sites_migration_(false) {
}
HistoryService::HistoryService(Profile* profile)
- : thread_(new base::Thread(kHistoryThreadName)),
+ : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ thread_(new base::Thread(kHistoryThreadName)),
profile_(profile),
backend_loaded_(false),
current_backend_id_(-1),
bookmark_service_(NULL),
no_db_(false),
- needs_top_sites_migration_(false),
- visit_database_observers_(
- new ObserverListThreadSafe<history::VisitDatabaseObserver>()) {
+ needs_top_sites_migration_(false) {
DCHECK(profile_);
registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED,
content::Source<Profile>(profile_));
@@ -176,11 +181,13 @@ HistoryService::HistoryService(Profile* profile)
}
HistoryService::~HistoryService() {
+ DCHECK(thread_checker_.CalledOnValidThread());
// Shutdown the backend. This does nothing if Cleanup was already invoked.
Cleanup();
}
bool HistoryService::BackendLoaded() {
+ DCHECK(thread_checker_.CalledOnValidThread());
// 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
@@ -193,6 +200,7 @@ bool HistoryService::BackendLoaded() {
}
void HistoryService::UnloadBackend() {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!history_backend_)
return; // Already unloaded.
@@ -234,11 +242,14 @@ void HistoryService::UnloadBackend() {
}
void HistoryService::Cleanup() {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!thread_) {
// We've already cleaned up.
return;
}
+ weak_ptr_factory_.InvalidateWeakPtrs();
+
// Unload the backend.
UnloadBackend();
@@ -251,11 +262,13 @@ void HistoryService::Cleanup() {
}
void HistoryService::NotifyRenderProcessHostDestruction(const void* host) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL,
&HistoryBackend::NotifyRenderProcessHostDestruction, host);
}
history::URLDatabase* HistoryService::InMemoryDatabase() {
+ DCHECK(thread_checker_.CalledOnValidThread());
// NOTE: See comments in BackendLoaded() as to why we call
// LoadBackendIfNecessary() here even though it won't affect the return value
// for this call.
@@ -266,6 +279,7 @@ history::URLDatabase* HistoryService::InMemoryDatabase() {
}
bool HistoryService::GetTypedCountForURL(const GURL& url, int* typed_count) {
+ DCHECK(thread_checker_.CalledOnValidThread());
history::URLRow url_row;
if (!GetRowForURL(url, &url_row))
return false;
@@ -275,6 +289,7 @@ bool HistoryService::GetTypedCountForURL(const GURL& url, int* typed_count) {
bool HistoryService::GetLastVisitTimeForURL(const GURL& url,
base::Time* last_visit) {
+ DCHECK(thread_checker_.CalledOnValidThread());
history::URLRow url_row;
if (!GetRowForURL(url, &url_row))
return false;
@@ -283,6 +298,7 @@ bool HistoryService::GetLastVisitTimeForURL(const GURL& url,
}
bool HistoryService::GetVisitCountForURL(const GURL& url, int* visit_count) {
+ DCHECK(thread_checker_.CalledOnValidThread());
history::URLRow url_row;
if (!GetRowForURL(url, &url_row))
return false;
@@ -290,7 +306,8 @@ bool HistoryService::GetVisitCountForURL(const GURL& url, int* visit_count) {
return true;
}
-void HistoryService::ShutdownOnUIThread() {
+void HistoryService::Shutdown() {
+ DCHECK(thread_checker_.CalledOnValidThread());
// It's possible that bookmarks haven't loaded and history is waiting for
// bookmarks to complete loading. In such a situation history can't shutdown
// (meaning if we invoked history_service_->Cleanup now, we would
@@ -308,6 +325,7 @@ void HistoryService::ShutdownOnUIThread() {
}
void HistoryService::SetSegmentPresentationIndex(int64 segment_id, int index) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_UI,
&HistoryBackend::SetSegmentPresentationIndex,
segment_id, index);
@@ -316,6 +334,7 @@ void HistoryService::SetSegmentPresentationIndex(int64 segment_id, int index) {
void HistoryService::SetKeywordSearchTermsForURL(const GURL& url,
TemplateURLID keyword_id,
const string16& term) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_UI,
&HistoryBackend::SetKeywordSearchTermsForURL,
url, keyword_id, term);
@@ -323,6 +342,7 @@ void HistoryService::SetKeywordSearchTermsForURL(const GURL& url,
void HistoryService::DeleteAllSearchTermsForKeyword(
TemplateURLID keyword_id) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_UI,
&HistoryBackend::DeleteAllSearchTermsForKeyword,
keyword_id);
@@ -334,6 +354,7 @@ HistoryService::Handle HistoryService::GetMostRecentKeywordSearchTerms(
int max_count,
CancelableRequestConsumerBase* consumer,
const GetMostRecentKeywordSearchTermsCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_UI, &HistoryBackend::GetMostRecentKeywordSearchTerms,
consumer,
new history::GetMostRecentKeywordSearchTermsRequest(callback),
@@ -341,12 +362,14 @@ HistoryService::Handle HistoryService::GetMostRecentKeywordSearchTerms(
}
void HistoryService::URLsNoLongerBookmarked(const std::set<GURL>& urls) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::URLsNoLongerBookmarked,
urls);
}
void HistoryService::ScheduleDBTask(HistoryDBTask* task,
CancelableRequestConsumerBase* consumer) {
+ DCHECK(thread_checker_.CalledOnValidThread());
history::HistoryDBTaskRequest* request = new history::HistoryDBTaskRequest(
base::Bind(&HistoryDBTask::DoneRunOnMainThread, task));
request->value = task; // The value is the task to execute.
@@ -358,12 +381,14 @@ HistoryService::Handle HistoryService::QuerySegmentUsageSince(
const Time from_time,
int max_result_count,
const SegmentQueryCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_UI, &HistoryBackend::QuerySegmentUsage,
consumer, new history::QuerySegmentUsageRequest(callback),
from_time, max_result_count);
}
void HistoryService::SetOnBackendDestroyTask(const base::Closure& task) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetOnBackendDestroyTask,
MessageLoop::current(), task);
}
@@ -377,6 +402,7 @@ void HistoryService::AddPage(const GURL& url,
content::PageTransition transition,
history::VisitSource visit_source,
bool did_replace_entry) {
+ DCHECK(thread_checker_.CalledOnValidThread());
AddPage(
history::HistoryAddPageArgs(url, time, id_scope, page_id, referrer,
redirects, transition, visit_source,
@@ -386,6 +412,7 @@ void HistoryService::AddPage(const GURL& url,
void HistoryService::AddPage(const GURL& url,
base::Time time,
history::VisitSource visit_source) {
+ DCHECK(thread_checker_.CalledOnValidThread());
AddPage(
history::HistoryAddPageArgs(url, time, NULL, 0, GURL(),
history::RedirectList(),
@@ -394,6 +421,7 @@ void HistoryService::AddPage(const GURL& url,
}
void HistoryService::AddPage(const history::HistoryAddPageArgs& add_page_args) {
+ DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(thread_) << "History service being called after cleanup";
// Filter out unwanted URLs. We don't add auto-subframe URLs. They are a
@@ -426,6 +454,7 @@ void HistoryService::AddPage(const history::HistoryAddPageArgs& add_page_args) {
void HistoryService::AddPageNoVisitForBookmark(const GURL& url,
const string16& title) {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!CanAddURL(url))
return;
@@ -435,6 +464,7 @@ void HistoryService::AddPageNoVisitForBookmark(const GURL& url,
void HistoryService::SetPageTitle(const GURL& url,
const string16& title) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetPageTitle, url, title);
}
@@ -442,6 +472,7 @@ void HistoryService::UpdateWithPageEndTime(const void* host,
int32 page_id,
const GURL& url,
Time end_ts) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::UpdateWithPageEndTime,
host, page_id, url, end_ts);
}
@@ -453,6 +484,7 @@ void HistoryService::AddPageWithDetails(const GURL& url,
Time last_visit,
bool hidden,
history::VisitSource visit_source) {
+ DCHECK(thread_checker_.CalledOnValidThread());
// Filter out unwanted URLs.
if (!CanAddURL(url))
return;
@@ -480,7 +512,7 @@ void HistoryService::AddPageWithDetails(const GURL& url,
void HistoryService::AddPagesWithDetails(const history::URLRows& info,
history::VisitSource visit_source) {
-
+ DCHECK(thread_checker_.CalledOnValidThread());
// Add to the visited links system.
VisitedLinkMaster* visited_links;
if (profile_ &&
@@ -500,6 +532,7 @@ void HistoryService::AddPagesWithDetails(const history::URLRows& info,
void HistoryService::SetPageContents(const GURL& url,
const string16& contents) {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!CanAddURL(url))
return;
@@ -511,6 +544,7 @@ HistoryService::Handle HistoryService::GetPageThumbnail(
const GURL& page_url,
CancelableRequestConsumerBase* consumer,
const ThumbnailDataCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_NORMAL, &HistoryBackend::GetPageThumbnail, consumer,
new history::GetPageThumbnailRequest(callback), page_url);
}
@@ -521,6 +555,7 @@ void HistoryService::GetFavicons(
int icon_types,
int desired_size_in_dip,
const std::vector<ui::ScaleFactor>& desired_scale_factors) {
+ DCHECK(thread_checker_.CalledOnValidThread());
Schedule(PRIORITY_NORMAL, &HistoryBackend::GetFavicons, NULL, request,
icon_urls, icon_types, desired_size_in_dip, desired_scale_factors);
}
@@ -531,6 +566,7 @@ void HistoryService::GetFaviconsForURL(
int icon_types,
int desired_size_in_dip,
const std::vector<ui::ScaleFactor>& desired_scale_factors) {
+ DCHECK(thread_checker_.CalledOnValidThread());
Schedule(PRIORITY_NORMAL, &HistoryBackend::GetFaviconsForURL, NULL, request,
page_url, icon_types, desired_size_in_dip, desired_scale_factors);
}
@@ -539,6 +575,7 @@ void HistoryService::GetFaviconForID(FaviconService::GetFaviconRequest* request,
history::FaviconID favicon_id,
int desired_size_in_dip,
ui::ScaleFactor desired_scale_factor) {
+ DCHECK(thread_checker_.CalledOnValidThread());
Schedule(PRIORITY_NORMAL, &HistoryBackend::GetFaviconForID, NULL, request,
favicon_id, desired_size_in_dip, desired_scale_factor);
}
@@ -550,6 +587,7 @@ void HistoryService::UpdateFaviconMappingsAndFetch(
int icon_types,
int desired_size_in_dip,
const std::vector<ui::ScaleFactor>& desired_scale_factors) {
+ DCHECK(thread_checker_.CalledOnValidThread());
Schedule(PRIORITY_NORMAL, &HistoryBackend::UpdateFaviconMappingsAndFetch,
NULL, request, page_url, icon_urls, icon_types, desired_size_in_dip,
desired_scale_factors);
@@ -560,6 +598,7 @@ void HistoryService::MergeFavicon(
history::IconType icon_type,
scoped_refptr<base::RefCountedMemory> bitmap_data,
const gfx::Size& pixel_size) {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!CanAddURL(page_url))
return;
@@ -572,6 +611,7 @@ void HistoryService::SetFavicons(
history::IconType icon_type,
const std::vector<history::FaviconBitmapData>& favicon_bitmap_data,
const history::IconURLSizesMap& icon_url_sizes) {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!CanAddURL(page_url))
return;
@@ -580,23 +620,27 @@ void HistoryService::SetFavicons(
}
void HistoryService::SetFaviconsOutOfDateForPage(const GURL& page_url) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL,
&HistoryBackend::SetFaviconsOutOfDateForPage, page_url);
}
void HistoryService::CloneFavicons(const GURL& old_page_url,
- const GURL& new_page_url) {
+ const GURL& new_page_url) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::CloneFavicons,
old_page_url, new_page_url);
}
void HistoryService::SetImportedFavicons(
const std::vector<history::ImportedFaviconUsage>& favicon_usage) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL,
&HistoryBackend::SetImportedFavicons, favicon_usage);
}
void HistoryService::IterateURLs(URLEnumerator* enumerator) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::IterateURLs, enumerator);
}
@@ -605,6 +649,7 @@ HistoryService::Handle HistoryService::QueryURL(
bool want_visits,
CancelableRequestConsumerBase* consumer,
const QueryURLCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_UI, &HistoryBackend::QueryURL, consumer,
new history::QueryURLRequest(callback), url, want_visits);
}
@@ -618,6 +663,7 @@ HistoryService::Handle HistoryService::CreateDownload(
const content::DownloadPersistentStoreInfo& create_info,
CancelableRequestConsumerBase* consumer,
const HistoryService::DownloadCreateCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_NORMAL, &HistoryBackend::CreateDownload, consumer,
new history::DownloadCreateRequest(callback), id,
create_info);
@@ -626,6 +672,7 @@ HistoryService::Handle HistoryService::CreateDownload(
HistoryService::Handle HistoryService::GetNextDownloadId(
CancelableRequestConsumerBase* consumer,
const DownloadNextIdCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_NORMAL, &HistoryBackend::GetNextDownloadId, consumer,
new history::DownloadNextIdRequest(callback));
}
@@ -635,6 +682,7 @@ HistoryService::Handle HistoryService::GetNextDownloadId(
HistoryService::Handle HistoryService::QueryDownloads(
CancelableRequestConsumerBase* consumer,
const DownloadQueryCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryDownloads, consumer,
new history::DownloadQueryRequest(callback));
}
@@ -643,6 +691,7 @@ HistoryService::Handle HistoryService::QueryDownloads(
// IN_PROGRESS entries are the corrupted entries, not updated by next function
// because of the crash or some other extremal exit.
void HistoryService::CleanUpInProgressEntries() {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::CleanUpInProgressEntries);
}
@@ -650,22 +699,26 @@ void HistoryService::CleanUpInProgressEntries() {
// operation, so we don't need to be called back.
void HistoryService::UpdateDownload(
const content::DownloadPersistentStoreInfo& data) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::UpdateDownload, data);
}
void HistoryService::UpdateDownloadPath(const FilePath& path,
int64 db_handle) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::UpdateDownloadPath,
path, db_handle);
}
void HistoryService::RemoveDownload(int64 db_handle) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL,
&HistoryBackend::RemoveDownload, db_handle);
}
void HistoryService::RemoveDownloadsBetween(Time remove_begin,
Time remove_end) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL,
&HistoryBackend::RemoveDownloadsBetween,
remove_begin,
@@ -677,6 +730,7 @@ HistoryService::Handle HistoryService::QueryHistory(
const history::QueryOptions& options,
CancelableRequestConsumerBase* consumer,
const QueryHistoryCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_UI, &HistoryBackend::QueryHistory, consumer,
new history::QueryHistoryRequest(callback),
text_query, options);
@@ -686,6 +740,7 @@ HistoryService::Handle HistoryService::QueryRedirectsFrom(
const GURL& from_url,
CancelableRequestConsumerBase* consumer,
const QueryRedirectsCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_UI, &HistoryBackend::QueryRedirectsFrom, consumer,
new history::QueryRedirectsRequest(callback), from_url);
}
@@ -694,6 +749,7 @@ HistoryService::Handle HistoryService::QueryRedirectsTo(
const GURL& to_url,
CancelableRequestConsumerBase* consumer,
const QueryRedirectsCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryRedirectsTo, consumer,
new history::QueryRedirectsRequest(callback), to_url);
}
@@ -702,6 +758,7 @@ HistoryService::Handle HistoryService::GetVisibleVisitCountToHost(
const GURL& url,
CancelableRequestConsumerBase* consumer,
const GetVisibleVisitCountToHostCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_UI, &HistoryBackend::GetVisibleVisitCountToHost,
consumer, new history::GetVisibleVisitCountToHostRequest(callback), url);
}
@@ -710,6 +767,7 @@ HistoryService::Handle HistoryService::QueryTopURLsAndRedirects(
int result_count,
CancelableRequestConsumerBase* consumer,
const QueryTopURLsAndRedirectsCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryTopURLsAndRedirects,
consumer, new history::QueryTopURLsAndRedirectsRequest(callback),
result_count);
@@ -720,6 +778,7 @@ HistoryService::Handle HistoryService::QueryMostVisitedURLs(
int days_back,
CancelableRequestConsumerBase* consumer,
const QueryMostVisitedURLsCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryMostVisitedURLs,
consumer,
new history::QueryMostVisitedURLsRequest(callback),
@@ -732,6 +791,7 @@ HistoryService::Handle HistoryService::QueryFilteredURLs(
bool extended_info,
CancelableRequestConsumerBase* consumer,
const QueryFilteredURLsCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
return Schedule(PRIORITY_NORMAL,
&HistoryBackend::QueryFilteredURLs,
consumer,
@@ -742,6 +802,7 @@ HistoryService::Handle HistoryService::QueryFilteredURLs(
void HistoryService::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!thread_)
return;
@@ -783,6 +844,7 @@ void HistoryService::Observe(int type,
bool HistoryService::Init(const FilePath& history_dir,
BookmarkService* bookmark_service,
bool no_db) {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!thread_->Start()) {
Cleanup();
return false;
@@ -807,12 +869,16 @@ bool HistoryService::Init(const FilePath& history_dir,
void HistoryService::ScheduleAutocomplete(HistoryURLProvider* provider,
HistoryURLProviderParams* params) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_UI, &HistoryBackend::ScheduleAutocomplete,
scoped_refptr<HistoryURLProvider>(provider), params);
}
void HistoryService::ScheduleTask(SchedulePriority priority,
const base::Closure& task) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ CHECK(thread_);
+ CHECK(thread_->message_loop());
// TODO(brettw): Do prioritization.
thread_->message_loop()->PostTask(FROM_HERE, task);
}
@@ -840,8 +906,14 @@ bool HistoryService::CanAddURL(const GURL& url) {
return true;
}
+base::WeakPtr<HistoryService> HistoryService::AsWeakPtr() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return weak_ptr_factory_.GetWeakPtr();
+}
+
void HistoryService::SetInMemoryBackend(int backend_id,
history::InMemoryHistoryBackend* mem_backend) {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!history_backend_ || current_backend_id_ != backend_id) {
VLOG(1) << "Message from obsolete backend";
// Cleaning up the memory backend.
@@ -857,6 +929,7 @@ void HistoryService::SetInMemoryBackend(int backend_id,
void HistoryService::NotifyProfileError(int backend_id,
sql::InitStatus init_status) {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!history_backend_ || current_backend_id_ != backend_id) {
VLOG(1) << "Message from obsolete backend";
return;
@@ -867,11 +940,13 @@ void HistoryService::NotifyProfileError(int backend_id,
}
void HistoryService::DeleteURL(const GURL& url) {
+ DCHECK(thread_checker_.CalledOnValidThread());
// We will update the visited links when we observe the delete notifications.
ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::DeleteURL, url);
}
void HistoryService::DeleteURLsForTest(const std::vector<GURL>& urls) {
+ DCHECK(thread_checker_.CalledOnValidThread());
// We will update the visited links when we observe the delete
// notifications.
ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::DeleteURLs, urls);
@@ -882,7 +957,7 @@ void HistoryService::ExpireHistoryBetween(
Time begin_time, Time end_time,
CancelableRequestConsumerBase* consumer,
const base::Closure& callback) {
-
+ DCHECK(thread_checker_.CalledOnValidThread());
// We will update the visited links when we observe the delete notifications.
Schedule(PRIORITY_UI, &HistoryBackend::ExpireHistoryBetween, consumer,
new CancelableRequest<base::Closure>(callback),
@@ -892,6 +967,7 @@ void HistoryService::ExpireHistoryBetween(
void HistoryService::BroadcastNotificationsHelper(
int type,
history::HistoryDetails* details) {
+ DCHECK(thread_checker_.CalledOnValidThread());
// TODO(evanm): this is currently necessitated by generate_profile, which
// runs without a browser process. generate_profile should really create
// a browser process, at which point this check can then be nuked.
@@ -914,6 +990,7 @@ void HistoryService::BroadcastNotificationsHelper(
}
void HistoryService::LoadBackendIfNecessary() {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!thread_ || history_backend_)
return; // Failed to init, or already started loading.
@@ -921,7 +998,10 @@ void HistoryService::LoadBackendIfNecessary() {
scoped_refptr<HistoryBackend> backend(
new HistoryBackend(history_dir_,
current_backend_id_,
- new BackendDelegate(this, profile_),
+ new BackendDelegate(
+ weak_ptr_factory_.GetWeakPtr(),
+ base::ThreadTaskRunnerHandle::Get(),
+ profile_),
bookmark_service_));
history_backend_.swap(backend);
@@ -935,6 +1015,7 @@ void HistoryService::LoadBackendIfNecessary() {
}
void HistoryService::OnDBLoaded(int backend_id) {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!history_backend_ || current_backend_id_ != backend_id) {
VLOG(1) << "Message from obsolete backend";
return;
@@ -953,11 +1034,13 @@ void HistoryService::OnDBLoaded(int backend_id) {
}
bool HistoryService::GetRowForURL(const GURL& url, history::URLRow* url_row) {
+ DCHECK(thread_checker_.CalledOnValidThread());
history::URLDatabase* db = InMemoryDatabase();
return db && (db->GetRowForURL(url, url_row) != 0);
}
void HistoryService::StartTopSitesMigration(int backend_id) {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!history_backend_ || current_backend_id_ != backend_id) {
VLOG(1) << "Message from obsolete backend";
return;
@@ -972,22 +1055,26 @@ void HistoryService::StartTopSitesMigration(int backend_id) {
}
void HistoryService::OnTopSitesReady() {
+ DCHECK(thread_checker_.CalledOnValidThread());
ScheduleAndForget(PRIORITY_NORMAL,
&HistoryBackend::MigrateThumbnailsDatabase);
}
void HistoryService::AddVisitDatabaseObserver(
history::VisitDatabaseObserver* observer) {
- visit_database_observers_->AddObserver(observer);
+ DCHECK(thread_checker_.CalledOnValidThread());
+ visit_database_observers_.AddObserver(observer);
}
void HistoryService::RemoveVisitDatabaseObserver(
history::VisitDatabaseObserver* observer) {
- visit_database_observers_->RemoveObserver(observer);
+ DCHECK(thread_checker_.CalledOnValidThread());
+ visit_database_observers_.RemoveObserver(observer);
}
void HistoryService::NotifyVisitDBObserversOnAddVisit(
const history::BriefVisitInfo& info) {
- visit_database_observers_->Notify(
- &history::VisitDatabaseObserver::OnAddVisit, info);
+ DCHECK(thread_checker_.CalledOnValidThread());
+ FOR_EACH_OBSERVER(history::VisitDatabaseObserver, visit_database_observers_,
+ OnAddVisit(info));
}
diff --git a/chrome/browser/history/history.h b/chrome/browser/history/history.h
index 3a6362b..c8273e6 100644
--- a/chrome/browser/history/history.h
+++ b/chrome/browser/history/history.h
@@ -13,13 +13,15 @@
#include "base/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/observer_list_threadsafe.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
#include "base/string16.h"
#include "base/time.h"
+#include "base/threading/thread_checker.h"
#include "chrome/browser/common/cancelable_request.h"
#include "chrome/browser/favicon/favicon_service.h"
#include "chrome/browser/history/history_types.h"
-#include "chrome/browser/profiles/refcounted_profile_keyed_service.h"
+#include "chrome/browser/profiles/profile_keyed_service.h"
#include "chrome/browser/search_engines/template_url_id.h"
#include "chrome/common/ref_counted_util.h"
#include "content/public/browser/notification_observer.h"
@@ -97,7 +99,7 @@ class HistoryDBTask : public base::RefCountedThreadSafe<HistoryDBTask> {
// thread that made the request.
class HistoryService : public CancelableRequestProvider,
public content::NotificationObserver,
- public RefcountedProfileKeyedService {
+ public ProfileKeyedService {
public:
// Miscellaneous commonly-used types.
typedef std::vector<PageUsageData*> PageUsageDataList;
@@ -107,6 +109,8 @@ class HistoryService : public CancelableRequestProvider,
// The empty constructor is provided only for testing.
HistoryService();
+ virtual ~HistoryService();
+
// Initializes the history service, returning true on success. On false, do
// not call any other functions. The given directory will be used for storing
// the history files. The BookmarkService is used when deleting URLs to
@@ -173,8 +177,8 @@ class HistoryService : public CancelableRequestProvider,
return in_memory_url_index_.get();
}
- // RefcountedProfileKeyedService:
- virtual void ShutdownOnUIThread() OVERRIDE;
+ // ProfileKeyedService:
+ virtual void Shutdown() OVERRIDE;
// Navigation ----------------------------------------------------------------
@@ -567,12 +571,10 @@ class HistoryService : public CancelableRequestProvider,
// db.
bool needs_top_sites_migration() const { return needs_top_sites_migration_; }
- // Adds or removes observers for the VisitDatabase. Should be run in the
- // thread in which the observer would like to be notified.
+ // Adds or removes observers for the VisitDatabase.
void AddVisitDatabaseObserver(history::VisitDatabaseObserver* observer);
void RemoveVisitDatabaseObserver(history::VisitDatabaseObserver* observer);
- // This notification method may be called on any thread.
void NotifyVisitDBObserversOnAddVisit(const history::BriefVisitInfo& info);
// Testing -------------------------------------------------------------------
@@ -623,9 +625,9 @@ class HistoryService : public CancelableRequestProvider,
// history. We filter out some URLs such as JavaScript.
static bool CanAddURL(const GURL& url);
- protected:
- virtual ~HistoryService();
+ base::WeakPtr<HistoryService> AsWeakPtr();
+ protected:
// These are not currently used, hopefully we can do something in the future
// to ensure that the most important things happen first.
enum SchedulePriority {
@@ -837,6 +839,7 @@ class HistoryService : public CancelableRequestProvider,
CancelableRequestConsumerBase* consumer,
RequestType* request) {
DCHECK(thread_) << "History service being called after cleanup";
+ DCHECK(thread_checker_.CalledOnValidThread());
LoadBackendIfNecessary();
if (consumer)
AddRequest(request, consumer);
@@ -853,6 +856,7 @@ class HistoryService : public CancelableRequestProvider,
RequestType* request,
const ArgA& a) {
DCHECK(thread_) << "History service being called after cleanup";
+ DCHECK(thread_checker_.CalledOnValidThread());
LoadBackendIfNecessary();
if (consumer)
AddRequest(request, consumer);
@@ -873,6 +877,7 @@ class HistoryService : public CancelableRequestProvider,
const ArgA& a,
const ArgB& b) {
DCHECK(thread_) << "History service being called after cleanup";
+ DCHECK(thread_checker_.CalledOnValidThread());
LoadBackendIfNecessary();
if (consumer)
AddRequest(request, consumer);
@@ -895,6 +900,7 @@ class HistoryService : public CancelableRequestProvider,
const ArgB& b,
const ArgC& c) {
DCHECK(thread_) << "History service being called after cleanup";
+ DCHECK(thread_checker_.CalledOnValidThread());
LoadBackendIfNecessary();
if (consumer)
AddRequest(request, consumer);
@@ -919,6 +925,7 @@ class HistoryService : public CancelableRequestProvider,
const ArgC& c,
const ArgD& d) {
DCHECK(thread_) << "History service being called after cleanup";
+ DCHECK(thread_checker_.CalledOnValidThread());
LoadBackendIfNecessary();
if (consumer)
AddRequest(request, consumer);
@@ -945,6 +952,7 @@ class HistoryService : public CancelableRequestProvider,
const ArgD& d,
const ArgE& e) {
DCHECK(thread_) << "History service being called after cleanup";
+ DCHECK(thread_checker_.CalledOnValidThread());
LoadBackendIfNecessary();
if (consumer)
AddRequest(request, consumer);
@@ -964,6 +972,7 @@ class HistoryService : public CancelableRequestProvider,
void ScheduleAndForget(SchedulePriority priority,
BackendFunc func) { // Function to call on backend.
DCHECK(thread_) << "History service being called after cleanup";
+ DCHECK(thread_checker_.CalledOnValidThread());
LoadBackendIfNecessary();
ScheduleTask(priority, base::Bind(func, history_backend_.get()));
}
@@ -973,6 +982,7 @@ class HistoryService : public CancelableRequestProvider,
BackendFunc func, // Function to call on backend.
const ArgA& a) {
DCHECK(thread_) << "History service being called after cleanup";
+ DCHECK(thread_checker_.CalledOnValidThread());
LoadBackendIfNecessary();
ScheduleTask(priority, base::Bind(func, history_backend_.get(), a));
}
@@ -983,6 +993,7 @@ class HistoryService : public CancelableRequestProvider,
const ArgA& a,
const ArgB& b) {
DCHECK(thread_) << "History service being called after cleanup";
+ DCHECK(thread_checker_.CalledOnValidThread());
LoadBackendIfNecessary();
ScheduleTask(priority, base::Bind(func, history_backend_.get(), a, b));
}
@@ -994,6 +1005,7 @@ class HistoryService : public CancelableRequestProvider,
const ArgB& b,
const ArgC& c) {
DCHECK(thread_) << "History service being called after cleanup";
+ DCHECK(thread_checker_.CalledOnValidThread());
LoadBackendIfNecessary();
ScheduleTask(priority, base::Bind(func, history_backend_.get(), a, b, c));
}
@@ -1010,6 +1022,7 @@ class HistoryService : public CancelableRequestProvider,
const ArgC& c,
const ArgD& d) {
DCHECK(thread_) << "History service being called after cleanup";
+ DCHECK(thread_checker_.CalledOnValidThread());
LoadBackendIfNecessary();
ScheduleTask(priority, base::Bind(func, history_backend_.get(),
a, b, c, d));
@@ -1029,11 +1042,17 @@ class HistoryService : public CancelableRequestProvider,
const ArgD& d,
const ArgE& e) {
DCHECK(thread_) << "History service being called after cleanup";
+ DCHECK(thread_checker_.CalledOnValidThread());
LoadBackendIfNecessary();
ScheduleTask(priority, base::Bind(func, history_backend_.get(),
a, b, c, d, e));
}
+ // All vended weak pointers are invalidated in Cleanup().
+ base::WeakPtrFactory<HistoryService> weak_ptr_factory_;
+
+ base::ThreadChecker thread_checker_;
+
content::NotificationRegistrar registrar_;
// Some void primitives require some internal processing in the main thread
@@ -1082,8 +1101,7 @@ class HistoryService : public CancelableRequestProvider,
// See http://crbug.com/138321
scoped_ptr<history::InMemoryURLIndex> in_memory_url_index_;
- scoped_refptr<ObserverListThreadSafe<history::VisitDatabaseObserver> >
- visit_database_observers_;
+ ObserverList<history::VisitDatabaseObserver> visit_database_observers_;
DISALLOW_COPY_AND_ASSIGN(HistoryService);
};
diff --git a/chrome/browser/history/history_backend.h b/chrome/browser/history/history_backend.h
index ef82922..a3f831d 100644
--- a/chrome/browser/history/history_backend.h
+++ b/chrome/browser/history/history_backend.h
@@ -486,7 +486,7 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
friend class base::RefCountedThreadSafe<HistoryBackend>;
friend class CommitLaterTask; // The commit task needs to call Commit().
friend class HistoryBackendTest;
- friend class HistoryTest; // So the unit tests can poke our innards.
+ friend class HistoryBackendDBTest; // So the unit tests can poke our innards.
FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, DeleteAll);
FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, DeleteAllThenAddData);
FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, ImportedFaviconsTest);
diff --git a/chrome/browser/history/history_browsertest.cc b/chrome/browser/history/history_browsertest.cc
index b7c8be2..4b5614d 100644
--- a/chrome/browser/history/history_browsertest.cc
+++ b/chrome/browser/history/history_browsertest.cc
@@ -91,11 +91,8 @@ class HistoryBrowserTest : public InProcessBrowserTest {
scoped_refptr<HistoryDBTask> task(new WaitForHistoryTask());
HistoryService* history =
HistoryServiceFactory::GetForProfile(GetProfile(),
- Profile::EXPLICIT_ACCESS);
- BrowserThread::PostTask(BrowserThread::UI,
- FROM_HERE,
- base::Bind(&HistoryService::ScheduleDBTask,
- history, task, &request_consumer));
+ Profile::EXPLICIT_ACCESS);
+ history->HistoryService::ScheduleDBTask(task, &request_consumer);
content::RunMessageLoop();
}
diff --git a/chrome/browser/history/history_querying_unittest.cc b/chrome/browser/history/history_querying_unittest.cc
index 1dc3f72..e7b4b41 100644
--- a/chrome/browser/history/history_querying_unittest.cc
+++ b/chrome/browser/history/history_querying_unittest.cc
@@ -86,7 +86,7 @@ class HistoryQueryTest : public testing::Test {
}
protected:
- scoped_refptr<HistoryService> history_;
+ scoped_ptr<HistoryService> history_;
private:
virtual void SetUp() {
@@ -94,9 +94,9 @@ class HistoryQueryTest : public testing::Test {
history_dir_ = temp_dir_.path().AppendASCII("HistoryTest");
ASSERT_TRUE(file_util::CreateDirectory(history_dir_));
- history_ = new HistoryService;
+ history_.reset(new HistoryService);
if (!history_->Init(history_dir_, NULL)) {
- history_ = NULL; // Tests should notice this NULL ptr & fail.
+ history_.reset(); // Tests should notice this NULL ptr & fail.
return;
}
@@ -123,7 +123,7 @@ class HistoryQueryTest : public testing::Test {
if (history_.get()) {
history_->SetOnBackendDestroyTask(MessageLoop::QuitClosure());
history_->Cleanup();
- history_ = NULL;
+ history_.reset();
MessageLoop::current()->Run(); // Wait for the other thread.
}
}
diff --git a/chrome/browser/history/history_service_factory.cc b/chrome/browser/history/history_service_factory.cc
index 2947e25..7cc0d3e 100644
--- a/chrome/browser/history/history_service_factory.cc
+++ b/chrome/browser/history/history_service_factory.cc
@@ -12,7 +12,7 @@
#include "chrome/common/pref_names.h"
// static
-scoped_refptr<HistoryService> HistoryServiceFactory::GetForProfile(
+HistoryService* HistoryServiceFactory::GetForProfile(
Profile* profile, Profile::ServiceAccessType sat) {
// If saving history is disabled, only allow explicit access.
if (profile->GetPrefs()->GetBoolean(prefs::kSavingBrowserHistoryDisabled) &&
@@ -20,11 +20,11 @@ scoped_refptr<HistoryService> HistoryServiceFactory::GetForProfile(
return NULL;
return static_cast<HistoryService*>(
- GetInstance()->GetServiceForProfile(profile, true).get());
+ GetInstance()->GetServiceForProfile(profile, true));
}
// static
-scoped_refptr<HistoryService>
+HistoryService*
HistoryServiceFactory::GetForProfileIfExists(
Profile* profile, Profile::ServiceAccessType sat) {
// If saving history is disabled, only allow explicit access.
@@ -33,14 +33,14 @@ HistoryServiceFactory::GetForProfileIfExists(
return NULL;
return static_cast<HistoryService*>(
- GetInstance()->GetServiceForProfile(profile, false).get());
+ GetInstance()->GetServiceForProfile(profile, false));
}
// static
-scoped_refptr<HistoryService>
+HistoryService*
HistoryServiceFactory::GetForProfileWithoutCreating(Profile* profile) {
return static_cast<HistoryService*>(
- GetInstance()->GetServiceForProfile(profile, false).get());
+ GetInstance()->GetServiceForProfile(profile, false));
}
// static
@@ -55,7 +55,7 @@ void HistoryServiceFactory::ShutdownForProfile(Profile* profile) {
}
HistoryServiceFactory::HistoryServiceFactory()
- : RefcountedProfileKeyedServiceFactory(
+ : ProfileKeyedServiceFactory(
"HistoryService", ProfileDependencyManager::GetInstance()) {
DependsOn(BookmarkModelFactory::GetInstance());
}
@@ -63,10 +63,9 @@ HistoryServiceFactory::HistoryServiceFactory()
HistoryServiceFactory::~HistoryServiceFactory() {
}
-scoped_refptr<RefcountedProfileKeyedService>
+ProfileKeyedService*
HistoryServiceFactory::BuildServiceInstanceFor(Profile* profile) const {
- scoped_refptr<HistoryService> history_service(
- new HistoryService(profile));
+ HistoryService* history_service = new HistoryService(profile);
if (!history_service->Init(profile->GetPath(),
BookmarkModelFactory::GetForProfile(profile))) {
return NULL;
diff --git a/chrome/browser/history/history_service_factory.h b/chrome/browser/history/history_service_factory.h
index 540b938..9927902 100644
--- a/chrome/browser/history/history_service_factory.h
+++ b/chrome/browser/history/history_service_factory.h
@@ -7,22 +7,21 @@
#include "base/memory/singleton.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/refcounted_profile_keyed_service_factory.h"
+#include "chrome/browser/profiles/profile_keyed_service_factory.h"
class HistoryService;
// Singleton that owns all HistoryService and associates them with
// Profiles.
-class HistoryServiceFactory
- : public RefcountedProfileKeyedServiceFactory {
+class HistoryServiceFactory : public ProfileKeyedServiceFactory {
public:
- static scoped_refptr<HistoryService> GetForProfile(
+ static HistoryService* GetForProfile(
Profile* profile, Profile::ServiceAccessType sat);
- static scoped_refptr<HistoryService> GetForProfileIfExists(
+ static HistoryService* GetForProfileIfExists(
Profile* profile, Profile::ServiceAccessType sat);
- static scoped_refptr<HistoryService> GetForProfileWithoutCreating(
+ static HistoryService* GetForProfileWithoutCreating(
Profile* profile);
static HistoryServiceFactory* GetInstance();
@@ -40,7 +39,7 @@ class HistoryServiceFactory
virtual ~HistoryServiceFactory();
// ProfileKeyedServiceFactory:
- virtual scoped_refptr<RefcountedProfileKeyedService> BuildServiceInstanceFor(
+ virtual ProfileKeyedService* BuildServiceInstanceFor(
Profile* profile) const OVERRIDE;
virtual bool ServiceRedirectedInIncognito() const OVERRIDE;
virtual bool ServiceIsNULLWhileTesting() const OVERRIDE;
diff --git a/chrome/browser/history/history_types.cc b/chrome/browser/history/history_types.cc
index f99f7db..d401873 100644
--- a/chrome/browser/history/history_types.cc
+++ b/chrome/browser/history/history_types.cc
@@ -447,4 +447,8 @@ ImportedFaviconUsage::ImportedFaviconUsage() {
ImportedFaviconUsage::~ImportedFaviconUsage() {
}
+// VisitDatabaseObserver -------------------------------------------------------
+
+VisitDatabaseObserver::~VisitDatabaseObserver() {}
+
} // namespace history
diff --git a/chrome/browser/history/history_types.h b/chrome/browser/history/history_types.h
index 36f2ebd..c97c5b7 100644
--- a/chrome/browser/history/history_types.h
+++ b/chrome/browser/history/history_types.h
@@ -802,7 +802,7 @@ struct BriefVisitInfo {
// An observer of VisitDatabase.
class VisitDatabaseObserver {
public:
- virtual ~VisitDatabaseObserver() {}
+ virtual ~VisitDatabaseObserver();
virtual void OnAddVisit(const BriefVisitInfo& info) = 0;
};
diff --git a/chrome/browser/history/history_unittest.cc b/chrome/browser/history/history_unittest.cc
index f4fa4d4..ff2a202 100644
--- a/chrome/browser/history/history_unittest.cc
+++ b/chrome/browser/history/history_unittest.cc
@@ -63,28 +63,15 @@ using content::DownloadItem;
using content::DownloadPersistentStoreInfo;
namespace history {
-class HistoryTest;
-}
-
-namespace history {
-
-namespace {
-
-// The tracker uses RenderProcessHost pointers for scoping but never
-// dereferences them. We use ints because it's easier. This function converts
-// between the two.
-static void* MakeFakeHost(int id) {
- void* host = 0;
- memcpy(&host, &id, sizeof(id));
- return host;
-}
-
-} // namespace
+class HistoryBackendDBTest;
// Delegate class for when we create a backend without a HistoryService.
+//
+// This must be outside the anonymous namespace for the friend statement in
+// HistoryBackendDBTest to work.
class BackendDelegate : public HistoryBackend::Delegate {
public:
- explicit BackendDelegate(HistoryTest* history_test)
+ explicit BackendDelegate(HistoryBackendDBTest* history_test)
: history_test_(history_test) {
}
@@ -99,23 +86,22 @@ class BackendDelegate : public HistoryBackend::Delegate {
virtual void NotifyVisitDBObserversOnAddVisit(
const BriefVisitInfo& info) OVERRIDE {}
private:
- HistoryTest* history_test_;
+ HistoryBackendDBTest* history_test_;
};
// This must be outside the anonymous namespace for the friend statement in
// HistoryBackend to work.
-class HistoryTest : public testing::Test {
+class HistoryBackendDBTest : public testing::Test {
public:
- HistoryTest()
- : history_service_(NULL),
- got_thumbnail_callback_(false),
- redirect_query_success_(false),
- query_url_success_(false),
- db_(NULL) {
+ HistoryBackendDBTest() : db_(NULL) {
}
- ~HistoryTest() {
+
+ ~HistoryBackendDBTest() {
}
+ protected:
+ friend class BackendDelegate;
+
// Creates the HistoryBackend and HistoryDatabase on the current thread,
// assigning the values to backend_ and db_.
void CreateBackendAndDatabase() {
@@ -127,29 +113,10 @@ class HistoryTest : public testing::Test {
"HistoryBackend::Init";
}
- void OnSegmentUsageAvailable(CancelableRequestProvider::Handle handle,
- std::vector<PageUsageData*>* data) {
- page_usage_data_.swap(*data);
- MessageLoop::current()->Quit();
- }
-
- void OnDeleteURLsDone(CancelableRequestProvider::Handle handle) {
- MessageLoop::current()->Quit();
- }
-
- void OnMostVisitedURLsAvailable(CancelableRequestProvider::Handle handle,
- MostVisitedURLList url_list) {
- most_visited_urls_.swap(url_list);
- MessageLoop::current()->Quit();
- }
-
- protected:
- friend class BackendDelegate;
-
// testing::Test
virtual void SetUp() {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- history_dir_ = temp_dir_.path().AppendASCII("HistoryTest");
+ history_dir_ = temp_dir_.path().AppendASCII("HistoryBackendDBTest");
ASSERT_TRUE(file_util::CreateDirectory(history_dir_));
}
@@ -163,30 +130,12 @@ class HistoryTest : public testing::Test {
virtual void TearDown() {
DeleteBackend();
- if (history_service_)
- CleanupHistoryService();
-
// Make sure we don't have any event pending that could disrupt the next
// test.
MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
MessageLoop::current()->Run();
}
- void CleanupHistoryService() {
- DCHECK(history_service_.get());
-
- history_service_->NotifyRenderProcessHostDestruction(0);
- history_service_->SetOnBackendDestroyTask(MessageLoop::QuitClosure());
- history_service_->Cleanup();
- history_service_ = NULL;
-
- // Wait for the backend class to terminate before deleting the files and
- // moving to the next test. Note: if this never terminates, somebody is
- // probably leaking a reference to the history backend, so it never calls
- // our destroy task.
- MessageLoop::current()->Run();
- }
-
int64 AddDownload(DownloadItem::DownloadState state, const Time& time) {
DownloadPersistentStoreInfo download(
FilePath(FILE_PATH_LITERAL("foo-path")),
@@ -202,91 +151,13 @@ class HistoryTest : public testing::Test {
return db_->CreateDownload(download);
}
- // Fills the query_url_row_ and query_url_visits_ structures with the
- // information about the given URL and returns true. If the URL was not
- // found, this will return false and those structures will not be changed.
- bool QueryURL(HistoryService* history, const GURL& url) {
- history->QueryURL(url, true, &consumer_,
- base::Bind(&HistoryTest::SaveURLAndQuit,
- base::Unretained(this)));
- MessageLoop::current()->Run(); // Will be exited in SaveURLAndQuit.
- return query_url_success_;
- }
-
- // Callback for HistoryService::QueryURL.
- void SaveURLAndQuit(HistoryService::Handle handle,
- bool success,
- const URLRow* url_row,
- VisitVector* visit_vector) {
- query_url_success_ = success;
- if (query_url_success_) {
- query_url_row_ = *url_row;
- query_url_visits_.swap(*visit_vector);
- } else {
- query_url_row_ = URLRow();
- query_url_visits_.clear();
- }
- MessageLoop::current()->Quit();
- }
-
- // Fills in saved_redirects_ with the redirect information for the given URL,
- // returning true on success. False means the URL was not found.
- bool QueryRedirectsFrom(HistoryService* history, const GURL& url) {
- history->QueryRedirectsFrom(url, &consumer_,
- base::Bind(&HistoryTest::OnRedirectQueryComplete,
- base::Unretained(this)));
- MessageLoop::current()->Run(); // Will be exited in *QueryComplete.
- return redirect_query_success_;
- }
-
- // Callback for QueryRedirects.
- void OnRedirectQueryComplete(HistoryService::Handle handle,
- GURL url,
- bool success,
- history::RedirectList* redirects) {
- redirect_query_success_ = success;
- if (redirect_query_success_)
- saved_redirects_.swap(*redirects);
- else
- saved_redirects_.clear();
- MessageLoop::current()->Quit();
- }
-
ScopedTempDir temp_dir_;
MessageLoopForUI message_loop_;
- // PageUsageData vector to test segments.
- ScopedVector<PageUsageData> page_usage_data_;
-
- MostVisitedURLList most_visited_urls_;
-
- // When non-NULL, this will be deleted on tear down and we will block until
- // the backend thread has completed. This allows tests for the history
- // service to use this feature, but other tests to ignore this.
- scoped_refptr<HistoryService> history_service_;
-
// names of the database files
FilePath history_dir_;
- // Set by the thumbnail callback when we get data, you should be sure to
- // clear this before issuing a thumbnail request.
- bool got_thumbnail_callback_;
- std::vector<unsigned char> thumbnail_data_;
-
- // Set by the redirect callback when we get data. You should be sure to
- // clear this before issuing a redirect request.
- history::RedirectList saved_redirects_;
- bool redirect_query_success_;
-
- // For history requests.
- CancelableRequestConsumer consumer_;
-
- // For saving URL info after a call to QueryURL
- bool query_url_success_;
- URLRow query_url_row_;
- VisitVector query_url_visits_;
-
// Created via CreateBackendAndDatabase.
scoped_refptr<HistoryBackend> backend_;
scoped_ptr<InMemoryHistoryBackend> in_mem_backend_;
@@ -306,13 +177,15 @@ void BackendDelegate::BroadcastNotifications(int type,
// We may want do do something more fancy in the future.
content::Details<HistoryDetails> det(details);
history_test_->in_mem_backend_->Observe(type,
- content::Source<HistoryTest>(NULL), det);
+ content::Source<HistoryBackendDBTest>(NULL), det);
// The backend passes ownership of the details pointer to us.
delete details;
}
-TEST_F(HistoryTest, ClearBrowsingData_Downloads) {
+namespace {
+
+TEST_F(HistoryBackendDBTest, ClearBrowsingData_Downloads) {
CreateBackendAndDatabase();
Time now = Time::Now();
@@ -399,7 +272,7 @@ TEST_F(HistoryTest, ClearBrowsingData_Downloads) {
EXPECT_EQ(0U, downloads.size());
}
-TEST_F(HistoryTest, MigrateDownloadsState) {
+TEST_F(HistoryBackendDBTest, MigrateDownloadsState) {
// Create the db and close it so that we can reopen it directly.
CreateBackendAndDatabase();
DeleteBackend();
@@ -470,37 +343,194 @@ TEST_F(HistoryTest, MigrateDownloadsState) {
}
}
-TEST_F(HistoryTest, AddPage) {
- scoped_refptr<HistoryService> history(new HistoryService);
- history_service_ = history;
- ASSERT_TRUE(history->Init(history_dir_, NULL));
+// The tracker uses RenderProcessHost pointers for scoping but never
+// dereferences them. We use ints because it's easier. This function converts
+// between the two.
+static void* MakeFakeHost(int id) {
+ void* host = 0;
+ memcpy(&host, &id, sizeof(id));
+ return host;
+}
+
+class HistoryTest : public testing::Test {
+ public:
+ HistoryTest()
+ : got_thumbnail_callback_(false),
+ redirect_query_success_(false),
+ query_url_success_(false) {
+ }
+
+ ~HistoryTest() {
+ }
+
+ void OnSegmentUsageAvailable(CancelableRequestProvider::Handle handle,
+ std::vector<PageUsageData*>* data) {
+ page_usage_data_.swap(*data);
+ MessageLoop::current()->Quit();
+ }
+
+ void OnDeleteURLsDone(CancelableRequestProvider::Handle handle) {
+ MessageLoop::current()->Quit();
+ }
+
+ void OnMostVisitedURLsAvailable(CancelableRequestProvider::Handle handle,
+ MostVisitedURLList url_list) {
+ most_visited_urls_.swap(url_list);
+ MessageLoop::current()->Quit();
+ }
+
+ protected:
+ friend class BackendDelegate;
+
+ // testing::Test
+ virtual void SetUp() {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ history_dir_ = temp_dir_.path().AppendASCII("HistoryTest");
+ ASSERT_TRUE(file_util::CreateDirectory(history_dir_));
+ history_service_.reset(new HistoryService);
+ if (!history_service_->Init(history_dir_, NULL)) {
+ history_service_.reset();
+ ADD_FAILURE();
+ }
+ }
+
+ virtual void TearDown() {
+ if (history_service_.get())
+ CleanupHistoryService();
+
+ // Make sure we don't have any event pending that could disrupt the next
+ // test.
+ MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ MessageLoop::current()->Run();
+ }
+
+ void CleanupHistoryService() {
+ DCHECK(history_service_.get());
+
+ history_service_->NotifyRenderProcessHostDestruction(0);
+ history_service_->SetOnBackendDestroyTask(MessageLoop::QuitClosure());
+ history_service_->Cleanup();
+ history_service_.reset();
+
+ // Wait for the backend class to terminate before deleting the files and
+ // moving to the next test. Note: if this never terminates, somebody is
+ // probably leaking a reference to the history backend, so it never calls
+ // our destroy task.
+ MessageLoop::current()->Run();
+ }
+
+ // Fills the query_url_row_ and query_url_visits_ structures with the
+ // information about the given URL and returns true. If the URL was not
+ // found, this will return false and those structures will not be changed.
+ bool QueryURL(HistoryService* history, const GURL& url) {
+ history_service_->QueryURL(url, true, &consumer_,
+ base::Bind(&HistoryTest::SaveURLAndQuit,
+ base::Unretained(this)));
+ MessageLoop::current()->Run(); // Will be exited in SaveURLAndQuit.
+ return query_url_success_;
+ }
+
+ // Callback for HistoryService::QueryURL.
+ void SaveURLAndQuit(HistoryService::Handle handle,
+ bool success,
+ const URLRow* url_row,
+ VisitVector* visit_vector) {
+ query_url_success_ = success;
+ if (query_url_success_) {
+ query_url_row_ = *url_row;
+ query_url_visits_.swap(*visit_vector);
+ } else {
+ query_url_row_ = URLRow();
+ query_url_visits_.clear();
+ }
+ MessageLoop::current()->Quit();
+ }
+ // Fills in saved_redirects_ with the redirect information for the given URL,
+ // returning true on success. False means the URL was not found.
+ bool QueryRedirectsFrom(HistoryService* history, const GURL& url) {
+ history_service_->QueryRedirectsFrom(
+ url, &consumer_,
+ base::Bind(&HistoryTest::OnRedirectQueryComplete,
+ base::Unretained(this)));
+ MessageLoop::current()->Run(); // Will be exited in *QueryComplete.
+ return redirect_query_success_;
+ }
+
+ // Callback for QueryRedirects.
+ void OnRedirectQueryComplete(HistoryService::Handle handle,
+ GURL url,
+ bool success,
+ history::RedirectList* redirects) {
+ redirect_query_success_ = success;
+ if (redirect_query_success_)
+ saved_redirects_.swap(*redirects);
+ else
+ saved_redirects_.clear();
+ MessageLoop::current()->Quit();
+ }
+
+ ScopedTempDir temp_dir_;
+
+ MessageLoopForUI message_loop_;
+
+ // PageUsageData vector to test segments.
+ ScopedVector<PageUsageData> page_usage_data_;
+
+ MostVisitedURLList most_visited_urls_;
+
+ // When non-NULL, this will be deleted on tear down and we will block until
+ // the backend thread has completed. This allows tests for the history
+ // service to use this feature, but other tests to ignore this.
+ scoped_ptr<HistoryService> history_service_;
+
+ // names of the database files
+ FilePath history_dir_;
+
+ // Set by the thumbnail callback when we get data, you should be sure to
+ // clear this before issuing a thumbnail request.
+ bool got_thumbnail_callback_;
+ std::vector<unsigned char> thumbnail_data_;
+
+ // Set by the redirect callback when we get data. You should be sure to
+ // clear this before issuing a redirect request.
+ history::RedirectList saved_redirects_;
+ bool redirect_query_success_;
+
+ // For history requests.
+ CancelableRequestConsumer consumer_;
+
+ // For saving URL info after a call to QueryURL
+ bool query_url_success_;
+ URLRow query_url_row_;
+ VisitVector query_url_visits_;
+};
+
+TEST_F(HistoryTest, AddPage) {
+ ASSERT_TRUE(history_service_.get());
// Add the page once from a child frame.
const GURL test_url("http://www.google.com/");
- history->AddPage(test_url, base::Time::Now(), NULL, 0, GURL(),
- history::RedirectList(),
- content::PAGE_TRANSITION_MANUAL_SUBFRAME,
- history::SOURCE_BROWSED, false);
- EXPECT_TRUE(QueryURL(history, test_url));
+ history_service_->AddPage(test_url, base::Time::Now(), NULL, 0, GURL(),
+ history::RedirectList(),
+ content::PAGE_TRANSITION_MANUAL_SUBFRAME,
+ history::SOURCE_BROWSED, false);
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
EXPECT_EQ(1, query_url_row_.visit_count());
EXPECT_EQ(0, query_url_row_.typed_count());
EXPECT_TRUE(query_url_row_.hidden()); // Hidden because of child frame.
// Add the page once from the main frame (should unhide it).
- history->AddPage(test_url, base::Time::Now(), NULL, 0, GURL(),
+ history_service_->AddPage(test_url, base::Time::Now(), NULL, 0, GURL(),
history::RedirectList(), content::PAGE_TRANSITION_LINK,
history::SOURCE_BROWSED, false);
- EXPECT_TRUE(QueryURL(history, test_url));
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
EXPECT_EQ(2, query_url_row_.visit_count()); // Added twice.
EXPECT_EQ(0, query_url_row_.typed_count()); // Never typed.
EXPECT_FALSE(query_url_row_.hidden()); // Because loaded in main frame.
}
TEST_F(HistoryTest, AddRedirect) {
- scoped_refptr<HistoryService> history(new HistoryService);
- history_service_ = history;
- ASSERT_TRUE(history->Init(history_dir_, NULL));
-
+ ASSERT_TRUE(history_service_.get());
const char* first_sequence[] = {
"http://first.page.com/",
"http://second.page.com/"};
@@ -511,13 +541,14 @@ TEST_F(HistoryTest, AddRedirect) {
// Add the sequence of pages as a server with no referrer. Note that we need
// to have a non-NULL page ID scope.
- history->AddPage(first_redirects.back(), base::Time::Now(), MakeFakeHost(1),
- 0, GURL(), first_redirects, content::PAGE_TRANSITION_LINK,
- history::SOURCE_BROWSED, true);
+ history_service_->AddPage(
+ first_redirects.back(), base::Time::Now(), MakeFakeHost(1),
+ 0, GURL(), first_redirects, content::PAGE_TRANSITION_LINK,
+ history::SOURCE_BROWSED, true);
// The first page should be added once with a link visit type (because we set
// LINK when we added the original URL, and a referrer of nowhere (0).
- EXPECT_TRUE(QueryURL(history, first_redirects[0]));
+ EXPECT_TRUE(QueryURL(history_service_.get(), first_redirects[0]));
EXPECT_EQ(1, query_url_row_.visit_count());
ASSERT_EQ(1U, query_url_visits_.size());
int64 first_visit = query_url_visits_[0].visit_id;
@@ -528,7 +559,7 @@ TEST_F(HistoryTest, AddRedirect) {
// The second page should be a server redirect type with a referrer of the
// first page.
- EXPECT_TRUE(QueryURL(history, first_redirects[1]));
+ EXPECT_TRUE(QueryURL(history_service_.get(), first_redirects[1]));
EXPECT_EQ(1, query_url_row_.visit_count());
ASSERT_EQ(1U, query_url_visits_.size());
int64 second_visit = query_url_visits_[0].visit_id;
@@ -539,7 +570,7 @@ TEST_F(HistoryTest, AddRedirect) {
// Check that the redirect finding function successfully reports it.
saved_redirects_.clear();
- QueryRedirectsFrom(history, first_redirects[0]);
+ QueryRedirectsFrom(history_service_.get(), first_redirects[0]);
ASSERT_EQ(1U, saved_redirects_.size());
EXPECT_EQ(first_redirects[1], saved_redirects_[0]);
@@ -549,7 +580,7 @@ TEST_F(HistoryTest, AddRedirect) {
history::RedirectList second_redirects;
second_redirects.push_back(first_redirects[1]);
second_redirects.push_back(GURL("http://last.page.com/"));
- history->AddPage(second_redirects[1], base::Time::Now(),
+ history_service_->AddPage(second_redirects[1], base::Time::Now(),
MakeFakeHost(1), 1, second_redirects[0], second_redirects,
static_cast<content::PageTransition>(
content::PAGE_TRANSITION_LINK |
@@ -559,11 +590,11 @@ TEST_F(HistoryTest, AddRedirect) {
// The last page (source of the client redirect) should NOT have an
// additional visit added, because it was a client redirect (normally it
// would). We should only have 1 left over from the first sequence.
- EXPECT_TRUE(QueryURL(history, second_redirects[0]));
+ EXPECT_TRUE(QueryURL(history_service_.get(), second_redirects[0]));
EXPECT_EQ(1, query_url_row_.visit_count());
// The final page should be set as a client redirect from the previous visit.
- EXPECT_TRUE(QueryURL(history, second_redirects[1]));
+ EXPECT_TRUE(QueryURL(history_service_.get(), second_redirects[1]));
EXPECT_EQ(1, query_url_row_.visit_count());
ASSERT_EQ(1U, query_url_visits_.size());
EXPECT_EQ(content::PAGE_TRANSITION_CLIENT_REDIRECT |
@@ -573,17 +604,16 @@ TEST_F(HistoryTest, AddRedirect) {
}
TEST_F(HistoryTest, MakeIntranetURLsTyped) {
- scoped_refptr<HistoryService> history(new HistoryService);
- history_service_ = history;
- ASSERT_TRUE(history->Init(history_dir_, NULL));
+ ASSERT_TRUE(history_service_.get());
// Add a non-typed visit to an intranet URL on an unvisited host. This should
// get promoted to a typed visit.
const GURL test_url("http://intranet_host/path");
- history->AddPage(test_url, base::Time::Now(), NULL, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_LINK,
- history::SOURCE_BROWSED, false);
- EXPECT_TRUE(QueryURL(history, test_url));
+ history_service_->AddPage(
+ test_url, base::Time::Now(), NULL, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_LINK,
+ history::SOURCE_BROWSED, false);
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
EXPECT_EQ(1, query_url_row_.visit_count());
EXPECT_EQ(1, query_url_row_.typed_count());
ASSERT_EQ(1U, query_url_visits_.size());
@@ -595,10 +625,11 @@ TEST_F(HistoryTest, MakeIntranetURLsTyped) {
// Different path.
const GURL test_url2("http://intranet_host/different_path");
- history->AddPage(test_url2, base::Time::Now(), NULL, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_LINK,
- history::SOURCE_BROWSED, false);
- EXPECT_TRUE(QueryURL(history, test_url2));
+ history_service_->AddPage(
+ test_url2, base::Time::Now(), NULL, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_LINK,
+ history::SOURCE_BROWSED, false);
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url2));
EXPECT_EQ(1, query_url_row_.visit_count());
EXPECT_EQ(0, query_url_row_.typed_count());
ASSERT_EQ(1U, query_url_visits_.size());
@@ -607,10 +638,11 @@ TEST_F(HistoryTest, MakeIntranetURLsTyped) {
// No path.
const GURL test_url3("http://intranet_host/");
- history->AddPage(test_url3, base::Time::Now(), NULL, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_LINK,
- history::SOURCE_BROWSED, false);
- EXPECT_TRUE(QueryURL(history, test_url3));
+ history_service_->AddPage(
+ test_url3, base::Time::Now(), NULL, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_LINK,
+ history::SOURCE_BROWSED, false);
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url3));
EXPECT_EQ(1, query_url_row_.visit_count());
EXPECT_EQ(0, query_url_row_.typed_count());
ASSERT_EQ(1U, query_url_visits_.size());
@@ -619,10 +651,11 @@ TEST_F(HistoryTest, MakeIntranetURLsTyped) {
// Different scheme.
const GURL test_url4("https://intranet_host/");
- history->AddPage(test_url4, base::Time::Now(), NULL, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_LINK,
- history::SOURCE_BROWSED, false);
- EXPECT_TRUE(QueryURL(history, test_url4));
+ history_service_->AddPage(
+ test_url4, base::Time::Now(), NULL, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_LINK,
+ history::SOURCE_BROWSED, false);
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url4));
EXPECT_EQ(1, query_url_row_.visit_count());
EXPECT_EQ(0, query_url_row_.typed_count());
ASSERT_EQ(1U, query_url_visits_.size());
@@ -631,11 +664,12 @@ TEST_F(HistoryTest, MakeIntranetURLsTyped) {
// Different transition.
const GURL test_url5("http://intranet_host/another_path");
- history->AddPage(test_url5, base::Time::Now(), NULL, 0, GURL(),
- history::RedirectList(),
- content::PAGE_TRANSITION_AUTO_BOOKMARK,
- history::SOURCE_BROWSED, false);
- EXPECT_TRUE(QueryURL(history, test_url5));
+ history_service_->AddPage(
+ test_url5, base::Time::Now(), NULL, 0, GURL(),
+ history::RedirectList(),
+ content::PAGE_TRANSITION_AUTO_BOOKMARK,
+ history::SOURCE_BROWSED, false);
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url5));
EXPECT_EQ(1, query_url_row_.visit_count());
EXPECT_EQ(0, query_url_row_.typed_count());
ASSERT_EQ(1U, query_url_visits_.size());
@@ -643,10 +677,11 @@ TEST_F(HistoryTest, MakeIntranetURLsTyped) {
content::PageTransitionStripQualifier(query_url_visits_[0].transition));
// Original URL.
- history->AddPage(test_url, base::Time::Now(), NULL, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_LINK,
- history::SOURCE_BROWSED, false);
- EXPECT_TRUE(QueryURL(history, test_url));
+ history_service_->AddPage(
+ test_url, base::Time::Now(), NULL, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_LINK,
+ history::SOURCE_BROWSED, false);
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
EXPECT_EQ(2, query_url_row_.visit_count());
EXPECT_EQ(1, query_url_row_.typed_count());
ASSERT_EQ(2U, query_url_visits_.size());
@@ -655,46 +690,48 @@ TEST_F(HistoryTest, MakeIntranetURLsTyped) {
}
TEST_F(HistoryTest, Typed) {
- scoped_refptr<HistoryService> history(new HistoryService);
- history_service_ = history;
- ASSERT_TRUE(history->Init(history_dir_, NULL));
+ ASSERT_TRUE(history_service_.get());
// Add the page once as typed.
const GURL test_url("http://www.google.com/");
- history->AddPage(test_url, base::Time::Now(), NULL, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_TYPED,
- history::SOURCE_BROWSED, false);
- EXPECT_TRUE(QueryURL(history, test_url));
+ history_service_->AddPage(
+ test_url, base::Time::Now(), NULL, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_TYPED,
+ history::SOURCE_BROWSED, false);
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
// We should have the same typed & visit count.
EXPECT_EQ(1, query_url_row_.visit_count());
EXPECT_EQ(1, query_url_row_.typed_count());
// Add the page again not typed.
- history->AddPage(test_url, base::Time::Now(), NULL, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_LINK,
- history::SOURCE_BROWSED, false);
- EXPECT_TRUE(QueryURL(history, test_url));
+ history_service_->AddPage(
+ test_url, base::Time::Now(), NULL, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_LINK,
+ history::SOURCE_BROWSED, false);
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
// The second time should not have updated the typed count.
EXPECT_EQ(2, query_url_row_.visit_count());
EXPECT_EQ(1, query_url_row_.typed_count());
// Add the page again as a generated URL.
- history->AddPage(test_url, base::Time::Now(), NULL, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_GENERATED,
- history::SOURCE_BROWSED, false);
- EXPECT_TRUE(QueryURL(history, test_url));
+ history_service_->AddPage(
+ test_url, base::Time::Now(), NULL, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_GENERATED,
+ history::SOURCE_BROWSED, false);
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
// This should have worked like a link click.
EXPECT_EQ(3, query_url_row_.visit_count());
EXPECT_EQ(1, query_url_row_.typed_count());
// Add the page again as a reload.
- history->AddPage(test_url, base::Time::Now(), NULL, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_RELOAD,
- history::SOURCE_BROWSED, false);
- EXPECT_TRUE(QueryURL(history, test_url));
+ history_service_->AddPage(
+ test_url, base::Time::Now(), NULL, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_RELOAD,
+ history::SOURCE_BROWSED, false);
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
// This should not have incremented any visit counts.
EXPECT_EQ(3, query_url_row_.visit_count());
@@ -702,29 +739,28 @@ TEST_F(HistoryTest, Typed) {
}
TEST_F(HistoryTest, SetTitle) {
- scoped_refptr<HistoryService> history(new HistoryService);
- history_service_ = history;
- ASSERT_TRUE(history->Init(history_dir_, NULL));
+ ASSERT_TRUE(history_service_.get());
// Add a URL.
const GURL existing_url("http://www.google.com/");
- history->AddPage(existing_url, base::Time::Now(), history::SOURCE_BROWSED);
+ history_service_->AddPage(
+ existing_url, base::Time::Now(), history::SOURCE_BROWSED);
// Set some title.
const string16 existing_title = UTF8ToUTF16("Google");
- history->SetPageTitle(existing_url, existing_title);
+ history_service_->SetPageTitle(existing_url, existing_title);
// Make sure the title got set.
- EXPECT_TRUE(QueryURL(history, existing_url));
+ EXPECT_TRUE(QueryURL(history_service_.get(), existing_url));
EXPECT_EQ(existing_title, query_url_row_.title());
// set a title on a nonexistent page
const GURL nonexistent_url("http://news.google.com/");
const string16 nonexistent_title = UTF8ToUTF16("Google News");
- history->SetPageTitle(nonexistent_url, nonexistent_title);
+ history_service_->SetPageTitle(nonexistent_url, nonexistent_title);
// Make sure nothing got written.
- EXPECT_FALSE(QueryURL(history, nonexistent_url));
+ EXPECT_FALSE(QueryURL(history_service_.get(), nonexistent_url));
EXPECT_EQ(string16(), query_url_row_.title());
// TODO(brettw) this should also test redirects, which get the title of the
@@ -732,21 +768,19 @@ TEST_F(HistoryTest, SetTitle) {
}
TEST_F(HistoryTest, Segments) {
- scoped_refptr<HistoryService> history(new HistoryService);
- history_service_ = history;
-
- ASSERT_TRUE(history->Init(history_dir_, NULL));
+ ASSERT_TRUE(history_service_.get());
static const void* scope = static_cast<void*>(this);
// Add a URL.
const GURL existing_url("http://www.google.com/");
- history->AddPage(existing_url, base::Time::Now(), scope, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_TYPED,
- history::SOURCE_BROWSED, false);
+ history_service_->AddPage(
+ existing_url, base::Time::Now(), scope, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_TYPED,
+ history::SOURCE_BROWSED, false);
// Make sure a segment was created.
- history->QuerySegmentUsageSince(
+ history_service_->QuerySegmentUsageSince(
&consumer_, Time::Now() - TimeDelta::FromDays(1), 10,
base::Bind(&HistoryTest::OnSegmentUsageAvailable,
base::Unretained(this)));
@@ -760,12 +794,13 @@ TEST_F(HistoryTest, Segments) {
// Add a URL which doesn't create a segment.
const GURL link_url("http://yahoo.com/");
- history->AddPage(link_url, base::Time::Now(), scope, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_LINK,
- history::SOURCE_BROWSED, false);
+ history_service_->AddPage(
+ link_url, base::Time::Now(), scope, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_LINK,
+ history::SOURCE_BROWSED, false);
// Query again
- history->QuerySegmentUsageSince(
+ history_service_->QuerySegmentUsageSince(
&consumer_, Time::Now() - TimeDelta::FromDays(1), 10,
base::Bind(&HistoryTest::OnSegmentUsageAvailable,
base::Unretained(this)));
@@ -778,13 +813,14 @@ TEST_F(HistoryTest, Segments) {
EXPECT_TRUE(page_usage_data_[0]->GetURL() == existing_url);
// Add a page linked from existing_url.
- history->AddPage(GURL("http://www.google.com/foo"), base::Time::Now(),
- scope, 3, existing_url, history::RedirectList(),
- content::PAGE_TRANSITION_LINK, history::SOURCE_BROWSED,
- false);
+ history_service_->AddPage(
+ GURL("http://www.google.com/foo"), base::Time::Now(),
+ scope, 3, existing_url, history::RedirectList(),
+ content::PAGE_TRANSITION_LINK, history::SOURCE_BROWSED,
+ false);
// Query again
- history->QuerySegmentUsageSince(
+ history_service_->QuerySegmentUsageSince(
&consumer_, Time::Now() - TimeDelta::FromDays(1), 10,
base::Bind(&HistoryTest::OnSegmentUsageAvailable,
base::Unretained(this)));
@@ -801,9 +837,7 @@ TEST_F(HistoryTest, Segments) {
}
TEST_F(HistoryTest, MostVisitedURLs) {
- scoped_refptr<HistoryService> history(new HistoryService);
- history_service_ = history;
- ASSERT_TRUE(history->Init(history_dir_, NULL));
+ ASSERT_TRUE(history_service_.get());
const GURL url0("http://www.google.com/url0/");
const GURL url1("http://www.google.com/url1/");
@@ -814,16 +848,19 @@ TEST_F(HistoryTest, MostVisitedURLs) {
static const void* scope = static_cast<void*>(this);
// Add two pages.
- history->AddPage(url0, base::Time::Now(), scope, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_TYPED,
- history::SOURCE_BROWSED, false);
- history->AddPage(url1, base::Time::Now(), scope, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_TYPED,
- history::SOURCE_BROWSED, false);
- history->QueryMostVisitedURLs(20, 90, &consumer_,
- base::Bind(
- &HistoryTest::OnMostVisitedURLsAvailable,
- base::Unretained(this)));
+ history_service_->AddPage(
+ url0, base::Time::Now(), scope, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_TYPED,
+ history::SOURCE_BROWSED, false);
+ history_service_->AddPage(
+ url1, base::Time::Now(), scope, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_TYPED,
+ history::SOURCE_BROWSED, false);
+ history_service_->QueryMostVisitedURLs(
+ 20, 90, &consumer_,
+ base::Bind(
+ &HistoryTest::OnMostVisitedURLsAvailable,
+ base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_EQ(2U, most_visited_urls_.size());
@@ -831,13 +868,15 @@ TEST_F(HistoryTest, MostVisitedURLs) {
EXPECT_EQ(url1, most_visited_urls_[1].url);
// Add another page.
- history->AddPage(url2, base::Time::Now(), scope, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_TYPED,
- history::SOURCE_BROWSED, false);
- history->QueryMostVisitedURLs(20, 90, &consumer_,
- base::Bind(
- &HistoryTest::OnMostVisitedURLsAvailable,
- base::Unretained(this)));
+ history_service_->AddPage(
+ url2, base::Time::Now(), scope, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_TYPED,
+ history::SOURCE_BROWSED, false);
+ history_service_->QueryMostVisitedURLs(
+ 20, 90, &consumer_,
+ base::Bind(
+ &HistoryTest::OnMostVisitedURLsAvailable,
+ base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_EQ(3U, most_visited_urls_.size());
@@ -846,13 +885,15 @@ TEST_F(HistoryTest, MostVisitedURLs) {
EXPECT_EQ(url2, most_visited_urls_[2].url);
// Revisit url2, making it the top URL.
- history->AddPage(url2, base::Time::Now(), scope, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_TYPED,
- history::SOURCE_BROWSED, false);
- history->QueryMostVisitedURLs(20, 90, &consumer_,
- base::Bind(
- &HistoryTest::OnMostVisitedURLsAvailable,
- base::Unretained(this)));
+ history_service_->AddPage(
+ url2, base::Time::Now(), scope, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_TYPED,
+ history::SOURCE_BROWSED, false);
+ history_service_->QueryMostVisitedURLs(
+ 20, 90, &consumer_,
+ base::Bind(
+ &HistoryTest::OnMostVisitedURLsAvailable,
+ base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_EQ(3U, most_visited_urls_.size());
@@ -861,13 +902,15 @@ TEST_F(HistoryTest, MostVisitedURLs) {
EXPECT_EQ(url1, most_visited_urls_[2].url);
// Revisit url1, making it the top URL.
- history->AddPage(url1, base::Time::Now(), scope, 0, GURL(),
- history::RedirectList(), content::PAGE_TRANSITION_TYPED,
- history::SOURCE_BROWSED, false);
- history->QueryMostVisitedURLs(20, 90, &consumer_,
- base::Bind(
- &HistoryTest::OnMostVisitedURLsAvailable,
- base::Unretained(this)));
+ history_service_->AddPage(
+ url1, base::Time::Now(), scope, 0, GURL(),
+ history::RedirectList(), content::PAGE_TRANSITION_TYPED,
+ history::SOURCE_BROWSED, false);
+ history_service_->QueryMostVisitedURLs(
+ 20, 90, &consumer_,
+ base::Bind(
+ &HistoryTest::OnMostVisitedURLsAvailable,
+ base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_EQ(3U, most_visited_urls_.size());
@@ -881,13 +924,15 @@ TEST_F(HistoryTest, MostVisitedURLs) {
redirects.push_back(url4);
// Visit url4 using redirects.
- history->AddPage(url4, base::Time::Now(), scope, 0, GURL(),
- redirects, content::PAGE_TRANSITION_TYPED,
- history::SOURCE_BROWSED, false);
- history->QueryMostVisitedURLs(20, 90, &consumer_,
- base::Bind(
- &HistoryTest::OnMostVisitedURLsAvailable,
- base::Unretained(this)));
+ history_service_->AddPage(
+ url4, base::Time::Now(), scope, 0, GURL(),
+ redirects, content::PAGE_TRANSITION_TYPED,
+ history::SOURCE_BROWSED, false);
+ history_service_->QueryMostVisitedURLs(
+ 20, 90, &consumer_,
+ base::Bind(
+ &HistoryTest::OnMostVisitedURLsAvailable,
+ base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_EQ(4U, most_visited_urls_.size());
@@ -963,35 +1008,33 @@ const int HistoryDBTaskImpl::kWantInvokeCount = 2;
} // namespace
TEST_F(HistoryTest, HistoryDBTask) {
+ ASSERT_TRUE(history_service_.get());
CancelableRequestConsumerT<int, 0> request_consumer;
- HistoryService* history = new HistoryService();
- ASSERT_TRUE(history->Init(history_dir_, NULL));
scoped_refptr<HistoryDBTaskImpl> task(new HistoryDBTaskImpl());
- history_service_ = history;
- history->ScheduleDBTask(task.get(), &request_consumer);
+ history_service_->ScheduleDBTask(task.get(), &request_consumer);
// Run the message loop. When HistoryDBTaskImpl::DoneRunOnMainThread runs,
// it will stop the message loop. If the test hangs here, it means
// DoneRunOnMainThread isn't being invoked correctly.
MessageLoop::current()->Run();
CleanupHistoryService();
// WARNING: history has now been deleted.
- history = NULL;
+ history_service_.reset();
ASSERT_EQ(HistoryDBTaskImpl::kWantInvokeCount, task->invoke_count);
ASSERT_TRUE(task->done_invoked);
}
TEST_F(HistoryTest, HistoryDBTaskCanceled) {
+ ASSERT_TRUE(history_service_.get());
CancelableRequestConsumerT<int, 0> request_consumer;
- HistoryService* history = new HistoryService();
- ASSERT_TRUE(history->Init(history_dir_, NULL));
scoped_refptr<HistoryDBTaskImpl> task(new HistoryDBTaskImpl());
- history_service_ = history;
- history->ScheduleDBTask(task.get(), &request_consumer);
+ history_service_->ScheduleDBTask(task.get(), &request_consumer);
request_consumer.CancelAllRequests();
CleanupHistoryService();
// WARNING: history has now been deleted.
- history = NULL;
+ history_service_.reset();
ASSERT_FALSE(task->done_invoked);
}
+} // namespace
+
} // namespace history
diff --git a/chrome/browser/prerender/prerender_local_predictor.cc b/chrome/browser/prerender/prerender_local_predictor.cc
index eae981e..d7fdfc9 100644
--- a/chrome/browser/prerender/prerender_local_predictor.cc
+++ b/chrome/browser/prerender/prerender_local_predictor.cc
@@ -186,8 +186,9 @@ PrerenderLocalPredictor::PrerenderLocalPredictor(
}
PrerenderLocalPredictor::~PrerenderLocalPredictor() {
- if (observing_history_service_.get())
- observing_history_service_->RemoveVisitDatabaseObserver(this);
+ HistoryService* history = GetHistoryIfExists();
+ if (history)
+ history->RemoveVisitDatabaseObserver(this);
}
void PrerenderLocalPredictor::OnAddVisit(const history::BriefVisitInfo& info) {
@@ -352,15 +353,14 @@ void PrerenderLocalPredictor::Init() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
RecordEvent(EVENT_INIT_STARTED);
HistoryService* history = GetHistoryIfExists();
- if (!history) {
+ if (history) {
+ history->ScheduleDBTask(
+ new GetVisitHistoryTask(this, kMaxVisitHistory),
+ &history_db_consumer_);
+ history->AddVisitDatabaseObserver(this);
+ } else {
RecordEvent(EVENT_INIT_FAILED_NO_HISTORY);
- return;
}
- history->ScheduleDBTask(
- new GetVisitHistoryTask(this, kMaxVisitHistory),
- &history_db_consumer_);
- observing_history_service_ = history;
- observing_history_service_->AddVisitDatabaseObserver(this);
}
void PrerenderLocalPredictor::OnPLTEventForURL(const GURL& url,
diff --git a/chrome/browser/prerender/prerender_local_predictor.h b/chrome/browser/prerender/prerender_local_predictor.h
index fd68bce..4543aed 100644
--- a/chrome/browser/prerender/prerender_local_predictor.h
+++ b/chrome/browser/prerender/prerender_local_predictor.h
@@ -22,7 +22,7 @@ class PrerenderManager;
// predictions.
// At this point, the class is not actually creating prerenders, but just
// recording timing stats about the effect prerendering would have.
-class PrerenderLocalPredictor : history::VisitDatabaseObserver {
+class PrerenderLocalPredictor : public history::VisitDatabaseObserver {
public:
enum Event {
EVENT_CONSTRUCTED = 0,
@@ -92,14 +92,6 @@ class PrerenderLocalPredictor : history::VisitDatabaseObserver {
scoped_ptr<std::vector<history::BriefVisitInfo> > visit_history_;
- // We keep a reference to the HistoryService which we registered to
- // observe. On destruction, we have to remove ourselves from that history
- // service. We can't just grab the HistoryService from the profile, because
- // the profile may have already given up its reference to it. Doing nothing
- // in this case may cause crashes, because the HistoryService may outlive the
- // the PrerenderLocalPredictor.
- scoped_refptr<HistoryService> observing_history_service_;
-
scoped_ptr<PrerenderData> current_prerender_;
scoped_ptr<PrerenderData> last_swapped_in_prerender_;
diff --git a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
index bcef5c6..2cc0a1c 100644
--- a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
@@ -63,8 +63,7 @@ ProfileKeyedService* BuildBookmarkModel(
return new BookmarkModelMock;
}
-scoped_refptr<RefcountedProfileKeyedService> BuildHistoryService(
- Profile* profile) {
+ProfileKeyedService* BuildHistoryService(Profile* profile) {
return new HistoryMock(profile);
}
@@ -80,7 +79,7 @@ class SyncBookmarkDataTypeControllerTest : public testing::Test {
change_processor_ = new ChangeProcessorMock();
history_service_ = static_cast<HistoryMock*>(
HistoryServiceFactory::GetInstance()->SetTestingFactoryAndUse(
- &profile_, BuildHistoryService).get());
+ &profile_, BuildHistoryService));
bookmark_model_ = static_cast<BookmarkModelMock*>(
BookmarkModelFactory::GetInstance()->SetTestingFactoryAndUse(
&profile_, BuildBookmarkModel));
diff --git a/chrome/browser/sync/glue/history_model_worker.cc b/chrome/browser/sync/glue/history_model_worker.cc
index 4fa47ee..5978f3d 100644
--- a/chrome/browser/sync/glue/history_model_worker.cc
+++ b/chrome/browser/sync/glue/history_model_worker.cc
@@ -8,8 +8,10 @@
#include "base/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/history/history.h"
+#include "content/public/browser/browser_thread.h"
using base::WaitableEvent;
+using content::BrowserThread;
namespace browser_sync {
@@ -40,19 +42,46 @@ class WorkerTask : public HistoryDBTask {
syncer::SyncerError* error_;
};
+namespace {
-HistoryModelWorker::HistoryModelWorker(HistoryService* history_service)
+// Post the work task on |history_service|'s DB thread from the UI
+// thread.
+void PostWorkerTask(const base::WeakPtr<HistoryService>& history_service,
+ const syncer::WorkCallback& work,
+ CancelableRequestConsumerT<int, 0>* cancelable_consumer,
+ WaitableEvent* done,
+ syncer::SyncerError* error) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (history_service.get()) {
+ scoped_refptr<WorkerTask> task(new WorkerTask(work, done, error));
+ history_service->ScheduleDBTask(task.get(), cancelable_consumer);
+ } else {
+ *error = syncer::CANNOT_DO_WORK;
+ done->Signal();
+ }
+}
+
+} // namespace
+
+HistoryModelWorker::HistoryModelWorker(
+ const base::WeakPtr<HistoryService>& history_service)
: history_service_(history_service) {
- CHECK(history_service);
+ CHECK(history_service.get());
}
syncer::SyncerError HistoryModelWorker::DoWorkAndWaitUntilDone(
const syncer::WorkCallback& work) {
- WaitableEvent done(false, false);
syncer::SyncerError error = syncer::UNSET;
- scoped_refptr<WorkerTask> task(new WorkerTask(work, &done, &error));
- history_service_->ScheduleDBTask(task.get(), &cancelable_consumer_);
- done.Wait();
+ WaitableEvent done(false, false);
+ if (BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&PostWorkerTask,
+ history_service_, work,
+ &cancelable_consumer_,
+ &done, &error))) {
+ done.Wait();
+ } else {
+ error = syncer::CANNOT_DO_WORK;
+ }
return error;
}
diff --git a/chrome/browser/sync/glue/history_model_worker.h b/chrome/browser/sync/glue/history_model_worker.h
index 73849a1..026c467 100644
--- a/chrome/browser/sync/glue/history_model_worker.h
+++ b/chrome/browser/sync/glue/history_model_worker.h
@@ -11,6 +11,7 @@
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
#include "chrome/browser/common/cancelable_request.h"
#include "chrome/browser/history/history.h"
@@ -22,7 +23,8 @@ namespace browser_sync {
// from the syncapi that need to be fulfilled on the history thread.
class HistoryModelWorker : public syncer::ModelSafeWorker {
public:
- explicit HistoryModelWorker(HistoryService* history_service);
+ explicit HistoryModelWorker(
+ const base::WeakPtr<HistoryService>& history_service);
// syncer::ModelSafeWorker implementation. Called on syncapi SyncerThread.
virtual syncer::SyncerError DoWorkAndWaitUntilDone(
@@ -32,7 +34,7 @@ class HistoryModelWorker : public syncer::ModelSafeWorker {
private:
virtual ~HistoryModelWorker();
- scoped_refptr<HistoryService> history_service_;
+ const base::WeakPtr<HistoryService> history_service_;
// Helper object to make sure we don't leave tasks running on the history
// thread.
CancelableRequestConsumerT<int, 0> cancelable_consumer_;
diff --git a/chrome/browser/sync/glue/sync_backend_registrar.cc b/chrome/browser/sync/glue/sync_backend_registrar.cc
index e3fa3bd..4662e73 100644
--- a/chrome/browser/sync/glue/sync_backend_registrar.cc
+++ b/chrome/browser/sync/glue/sync_backend_registrar.cc
@@ -72,7 +72,8 @@ SyncBackendRegistrar::SyncBackendRegistrar(
HistoryService* history_service =
HistoryServiceFactory::GetForProfile(profile, Profile::IMPLICIT_ACCESS);
if (history_service) {
- workers_[syncer::GROUP_HISTORY] = new HistoryModelWorker(history_service);
+ workers_[syncer::GROUP_HISTORY] =
+ new HistoryModelWorker(history_service->AsWeakPtr());
}
scoped_refptr<PasswordStore> password_store =
diff --git a/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc b/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc
index 2eede91..95a8586 100644
--- a/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc
@@ -99,8 +99,7 @@ class HistoryServiceMock : public HistoryService {
virtual ~HistoryServiceMock() {}
};
-scoped_refptr<RefcountedProfileKeyedService> BuildHistoryService(
- Profile* profile) {
+ProfileKeyedService* BuildHistoryService(Profile* profile) {
return new HistoryServiceMock(profile);
}
@@ -175,7 +174,7 @@ class ProfileSyncServiceTypedUrlTest : public AbstractProfileSyncServiceTest {
history_backend_ = new HistoryBackendMock();
history_service_ = static_cast<HistoryServiceMock*>(
HistoryServiceFactory::GetInstance()->SetTestingFactoryAndUse(
- &profile_, BuildHistoryService).get());
+ &profile_, BuildHistoryService));
EXPECT_CALL((*history_service_), ScheduleDBTask(_, _))
.WillRepeatedly(RunTaskOnDBThread(&history_thread_,
history_backend_.get()));
diff --git a/chrome/browser/ui/cocoa/tabpose_window.mm b/chrome/browser/ui/cocoa/tabpose_window.mm
index 2b9b642..4cf47c1 100644
--- a/chrome/browser/ui/cocoa/tabpose_window.mm
+++ b/chrome/browser/ui/cocoa/tabpose_window.mm
@@ -29,6 +29,7 @@
#import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h"
#include "chrome/browser/ui/tab_contents/tab_contents.h"
#include "chrome/common/pref_names.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/visitedlink/visitedlink_unittest.cc b/chrome/browser/visitedlink/visitedlink_unittest.cc
index 4056110..bfff076 100644
--- a/chrome/browser/visitedlink/visitedlink_unittest.cc
+++ b/chrome/browser/visitedlink/visitedlink_unittest.cc
@@ -93,7 +93,7 @@ class VisitedLinkTest : public testing::Test {
file_thread_(BrowserThread::FILE, &message_loop_) {}
// Initialize the history system. This should be called before InitVisited().
bool InitHistory() {
- history_service_ = new HistoryService;
+ history_service_.reset(new HistoryService);
return history_service_->Init(history_dir_, NULL);
}
@@ -104,7 +104,7 @@ class VisitedLinkTest : public testing::Test {
// the VisitedLinkMaster constructor.
bool InitVisited(int initial_size, bool suppress_rebuild) {
// Initialize the visited link system.
- master_.reset(new VisitedLinkMaster(&listener_, history_service_,
+ master_.reset(new VisitedLinkMaster(&listener_, history_service_.get(),
suppress_rebuild, visited_file_,
initial_size));
return master_->Init();
@@ -119,7 +119,7 @@ class VisitedLinkTest : public testing::Test {
if (history_service_.get()) {
history_service_->SetOnBackendDestroyTask(MessageLoop::QuitClosure());
history_service_->Cleanup();
- history_service_ = NULL;
+ history_service_.reset();
// Wait for the backend class to terminate before deleting the files and
// moving to the next test. Note: if this never terminates, somebody is
@@ -202,7 +202,7 @@ class VisitedLinkTest : public testing::Test {
FilePath visited_file_;
scoped_ptr<VisitedLinkMaster> master_;
- scoped_refptr<HistoryService> history_service_;
+ scoped_ptr<HistoryService> history_service_;
TrackingVisitedLinkEventListener listener_;
};