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