1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/history/top_sites_backend.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/files/file_path.h"
10 #include "base/memory/ref_counted.h"
11 #include "chrome/browser/history/top_sites_database.h"
12 #include "chrome/common/cancelable_task_tracker.h"
13 #include "content/public/browser/browser_thread.h"
14
15 using content::BrowserThread;
16
17 namespace history {
18
TopSitesBackend()19 TopSitesBackend::TopSitesBackend()
20 : db_(new TopSitesDatabase()) {
21 }
22
Init(const base::FilePath & path)23 void TopSitesBackend::Init(const base::FilePath& path) {
24 db_path_ = path;
25 BrowserThread::PostTask(
26 BrowserThread::DB, FROM_HERE,
27 base::Bind(&TopSitesBackend::InitDBOnDBThread, this, path));
28 }
29
Shutdown()30 void TopSitesBackend::Shutdown() {
31 BrowserThread::PostTask(
32 BrowserThread::DB, FROM_HERE,
33 base::Bind(&TopSitesBackend::ShutdownDBOnDBThread, this));
34 }
35
GetMostVisitedThumbnails(const GetMostVisitedThumbnailsCallback & callback,CancelableTaskTracker * tracker)36 void TopSitesBackend::GetMostVisitedThumbnails(
37 const GetMostVisitedThumbnailsCallback& callback,
38 CancelableTaskTracker* tracker) {
39 scoped_refptr<MostVisitedThumbnails> thumbnails = new MostVisitedThumbnails();
40
41 tracker->PostTaskAndReply(
42 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB).get(),
43 FROM_HERE,
44 base::Bind(&TopSitesBackend::GetMostVisitedThumbnailsOnDBThread,
45 this,
46 thumbnails),
47 base::Bind(callback, thumbnails));
48 }
49
UpdateTopSites(const TopSitesDelta & delta)50 void TopSitesBackend::UpdateTopSites(const TopSitesDelta& delta) {
51 BrowserThread::PostTask(
52 BrowserThread::DB, FROM_HERE,
53 base::Bind(&TopSitesBackend::UpdateTopSitesOnDBThread, this, delta));
54 }
55
SetPageThumbnail(const MostVisitedURL & url,int url_rank,const Images & thumbnail)56 void TopSitesBackend::SetPageThumbnail(const MostVisitedURL& url,
57 int url_rank,
58 const Images& thumbnail) {
59 BrowserThread::PostTask(
60 BrowserThread::DB, FROM_HERE,
61 base::Bind(&TopSitesBackend::SetPageThumbnailOnDBThread, this, url,
62 url_rank, thumbnail));
63 }
64
ResetDatabase()65 void TopSitesBackend::ResetDatabase() {
66 BrowserThread::PostTask(
67 BrowserThread::DB, FROM_HERE,
68 base::Bind(&TopSitesBackend::ResetDatabaseOnDBThread, this, db_path_));
69 }
70
DoEmptyRequest(const base::Closure & reply,CancelableTaskTracker * tracker)71 void TopSitesBackend::DoEmptyRequest(const base::Closure& reply,
72 CancelableTaskTracker* tracker) {
73 tracker->PostTaskAndReply(
74 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB).get(),
75 FROM_HERE,
76 base::Bind(&base::DoNothing),
77 reply);
78 }
79
~TopSitesBackend()80 TopSitesBackend::~TopSitesBackend() {
81 DCHECK(!db_); // Shutdown should have happened first (which results in
82 // nulling out db).
83 }
84
InitDBOnDBThread(const base::FilePath & path)85 void TopSitesBackend::InitDBOnDBThread(const base::FilePath& path) {
86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
87 if (!db_->Init(path)) {
88 LOG(ERROR) << "Failed to initialize database.";
89 db_.reset();
90 }
91 }
92
ShutdownDBOnDBThread()93 void TopSitesBackend::ShutdownDBOnDBThread() {
94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
95 db_.reset();
96 }
97
GetMostVisitedThumbnailsOnDBThread(scoped_refptr<MostVisitedThumbnails> thumbnails)98 void TopSitesBackend::GetMostVisitedThumbnailsOnDBThread(
99 scoped_refptr<MostVisitedThumbnails> thumbnails) {
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
101
102 if (db_) {
103 db_->GetPageThumbnails(&(thumbnails->most_visited),
104 &(thumbnails->url_to_images_map));
105 }
106 }
107
UpdateTopSitesOnDBThread(const TopSitesDelta & delta)108 void TopSitesBackend::UpdateTopSitesOnDBThread(const TopSitesDelta& delta) {
109 if (!db_)
110 return;
111
112 for (size_t i = 0; i < delta.deleted.size(); ++i)
113 db_->RemoveURL(delta.deleted[i]);
114
115 for (size_t i = 0; i < delta.added.size(); ++i)
116 db_->SetPageThumbnail(delta.added[i].url, delta.added[i].rank, Images());
117
118 for (size_t i = 0; i < delta.moved.size(); ++i)
119 db_->UpdatePageRank(delta.moved[i].url, delta.moved[i].rank);
120 }
121
SetPageThumbnailOnDBThread(const MostVisitedURL & url,int url_rank,const Images & thumbnail)122 void TopSitesBackend::SetPageThumbnailOnDBThread(const MostVisitedURL& url,
123 int url_rank,
124 const Images& thumbnail) {
125 if (!db_)
126 return;
127
128 db_->SetPageThumbnail(url, url_rank, thumbnail);
129 }
130
ResetDatabaseOnDBThread(const base::FilePath & file_path)131 void TopSitesBackend::ResetDatabaseOnDBThread(const base::FilePath& file_path) {
132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
133 db_.reset(NULL);
134 sql::Connection::Delete(db_path_);
135 db_.reset(new TopSitesDatabase());
136 InitDBOnDBThread(db_path_);
137 }
138
139 } // namespace history
140