Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 1 | // Copyright (c) 2012 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/in_memory_url_index.h" |
| 6 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 7 | #include "base/debug/trace_event.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 8 | #include "base/file_util.h" |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 9 | #include "base/strings/utf_string_conversions.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 10 | #include "chrome/browser/bookmarks/bookmark_model_factory.h" |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 11 | #include "chrome/browser/chrome_notification_types.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 12 | #include "chrome/browser/history/history_notifications.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 13 | #include "chrome/browser/history/history_service.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 14 | #include "chrome/browser/history/history_service_factory.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 15 | #include "chrome/browser/history/url_index_private_data.h" |
| 16 | #include "chrome/browser/profiles/profile.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 17 | #include "chrome/common/url_constants.h" |
Torne (Richard Coles) | cedac22 | 2014-06-03 10:58:34 +0100 | [diff] [blame] | 18 | #include "components/bookmarks/browser/bookmark_model.h" |
Ben Murdoch | 116680a | 2014-07-20 18:25:52 -0700 | [diff] [blame] | 19 | #include "components/history/core/browser/url_database.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 20 | #include "content/public/browser/browser_thread.h" |
| 21 | #include "content/public/browser/notification_details.h" |
| 22 | #include "content/public/browser/notification_service.h" |
| 23 | #include "content/public/browser/notification_source.h" |
| 24 | |
| 25 | using in_memory_url_index::InMemoryURLIndexCacheItem; |
| 26 | |
| 27 | namespace history { |
| 28 | |
| 29 | // Called by DoSaveToCacheFile to delete any old cache file at |path| when |
| 30 | // there is no private data to save. Runs on the FILE thread. |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 31 | void DeleteCacheFile(const base::FilePath& path) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 32 | DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 33 | base::DeleteFile(path, false); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 34 | } |
| 35 | |
| 36 | // Initializes a whitelist of URL schemes. |
| 37 | void InitializeSchemeWhitelist(std::set<std::string>* whitelist) { |
| 38 | DCHECK(whitelist); |
| 39 | if (!whitelist->empty()) |
| 40 | return; // Nothing to do, already initialized. |
Torne (Richard Coles) | f8ee788 | 2014-06-20 14:52:04 +0100 | [diff] [blame] | 41 | whitelist->insert(std::string(url::kAboutScheme)); |
Torne (Richard Coles) | 5d1f7b1 | 2014-02-21 12:16:55 +0000 | [diff] [blame] | 42 | whitelist->insert(std::string(content::kChromeUIScheme)); |
Torne (Richard Coles) | cedac22 | 2014-06-03 10:58:34 +0100 | [diff] [blame] | 43 | whitelist->insert(std::string(url::kFileScheme)); |
| 44 | whitelist->insert(std::string(url::kFtpScheme)); |
Torne (Richard Coles) | 010d83a | 2014-05-14 12:12:37 +0100 | [diff] [blame] | 45 | whitelist->insert(std::string(url::kHttpScheme)); |
| 46 | whitelist->insert(std::string(url::kHttpsScheme)); |
Torne (Richard Coles) | cedac22 | 2014-06-03 10:58:34 +0100 | [diff] [blame] | 47 | whitelist->insert(std::string(url::kMailToScheme)); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 48 | } |
| 49 | |
| 50 | // Restore/SaveCacheObserver --------------------------------------------------- |
| 51 | |
| 52 | InMemoryURLIndex::RestoreCacheObserver::~RestoreCacheObserver() {} |
| 53 | |
| 54 | InMemoryURLIndex::SaveCacheObserver::~SaveCacheObserver() {} |
| 55 | |
| 56 | // RebuildPrivateDataFromHistoryDBTask ----------------------------------------- |
| 57 | |
| 58 | InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask:: |
| 59 | RebuildPrivateDataFromHistoryDBTask( |
| 60 | InMemoryURLIndex* index, |
| 61 | const std::string& languages, |
| 62 | const std::set<std::string>& scheme_whitelist) |
| 63 | : index_(index), |
| 64 | languages_(languages), |
| 65 | scheme_whitelist_(scheme_whitelist), |
| 66 | succeeded_(false) { |
| 67 | } |
| 68 | |
| 69 | bool InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::RunOnDBThread( |
| 70 | HistoryBackend* backend, |
| 71 | HistoryDatabase* db) { |
| 72 | data_ = URLIndexPrivateData::RebuildFromHistory(db, languages_, |
| 73 | scheme_whitelist_); |
| 74 | succeeded_ = data_.get() && !data_->Empty(); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 75 | if (!succeeded_ && data_.get()) |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 76 | data_->Clear(); |
| 77 | return true; |
| 78 | } |
| 79 | |
| 80 | void InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask:: |
| 81 | DoneRunOnMainThread() { |
| 82 | index_->DoneRebuidingPrivateDataFromHistoryDB(succeeded_, data_); |
| 83 | } |
| 84 | |
| 85 | InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask:: |
| 86 | ~RebuildPrivateDataFromHistoryDBTask() { |
| 87 | } |
| 88 | |
| 89 | // InMemoryURLIndex ------------------------------------------------------------ |
| 90 | |
| 91 | InMemoryURLIndex::InMemoryURLIndex(Profile* profile, |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 92 | const base::FilePath& history_dir, |
Torne (Richard Coles) | 46d4c2b | 2014-06-09 12:00:27 +0100 | [diff] [blame] | 93 | const std::string& languages, |
| 94 | HistoryClient* history_client) |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 95 | : profile_(profile), |
Torne (Richard Coles) | 46d4c2b | 2014-06-09 12:00:27 +0100 | [diff] [blame] | 96 | history_client_(history_client), |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 97 | history_dir_(history_dir), |
| 98 | languages_(languages), |
| 99 | private_data_(new URLIndexPrivateData), |
| 100 | restore_cache_observer_(NULL), |
| 101 | save_cache_observer_(NULL), |
| 102 | shutdown_(false), |
| 103 | restored_(false), |
| 104 | needs_to_be_cached_(false) { |
| 105 | InitializeSchemeWhitelist(&scheme_whitelist_); |
| 106 | if (profile) { |
| 107 | // TODO(mrossetti): Register for language change notifications. |
| 108 | content::Source<Profile> source(profile); |
| 109 | registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED, source); |
| 110 | registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_MODIFIED, |
| 111 | source); |
| 112 | registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, source); |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | // Called only by unit tests. |
| 117 | InMemoryURLIndex::InMemoryURLIndex() |
| 118 | : profile_(NULL), |
Torne (Richard Coles) | 46d4c2b | 2014-06-09 12:00:27 +0100 | [diff] [blame] | 119 | history_client_(NULL), |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 120 | private_data_(new URLIndexPrivateData), |
| 121 | restore_cache_observer_(NULL), |
| 122 | save_cache_observer_(NULL), |
| 123 | shutdown_(false), |
| 124 | restored_(false), |
| 125 | needs_to_be_cached_(false) { |
| 126 | InitializeSchemeWhitelist(&scheme_whitelist_); |
| 127 | } |
| 128 | |
| 129 | InMemoryURLIndex::~InMemoryURLIndex() { |
| 130 | // If there was a history directory (which there won't be for some unit tests) |
| 131 | // then insure that the cache has already been saved. |
| 132 | DCHECK(history_dir_.empty() || !needs_to_be_cached_); |
| 133 | } |
| 134 | |
| 135 | void InMemoryURLIndex::Init() { |
| 136 | PostRestoreFromCacheFileTask(); |
| 137 | } |
| 138 | |
| 139 | void InMemoryURLIndex::ShutDown() { |
| 140 | registrar_.RemoveAll(); |
Ben Murdoch | 116680a | 2014-07-20 18:25:52 -0700 | [diff] [blame] | 141 | cache_reader_tracker_.TryCancelAll(); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 142 | shutdown_ = true; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 143 | base::FilePath path; |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 144 | if (!GetCacheFilePath(&path)) |
| 145 | return; |
Ben Murdoch | 116680a | 2014-07-20 18:25:52 -0700 | [diff] [blame] | 146 | private_data_tracker_.TryCancelAll(); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 147 | URLIndexPrivateData::WritePrivateDataToCacheFileTask(private_data_, path); |
| 148 | needs_to_be_cached_ = false; |
| 149 | } |
| 150 | |
| 151 | void InMemoryURLIndex::ClearPrivateData() { |
| 152 | private_data_->Clear(); |
| 153 | } |
| 154 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 155 | bool InMemoryURLIndex::GetCacheFilePath(base::FilePath* file_path) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 156 | if (history_dir_.empty()) |
| 157 | return false; |
| 158 | *file_path = history_dir_.Append(FILE_PATH_LITERAL("History Provider Cache")); |
| 159 | return true; |
| 160 | } |
| 161 | |
| 162 | // Querying -------------------------------------------------------------------- |
| 163 | |
| 164 | ScoredHistoryMatches InMemoryURLIndex::HistoryItemsForTerms( |
Torne (Richard Coles) | a3f6a49 | 2013-12-18 16:25:09 +0000 | [diff] [blame] | 165 | const base::string16& term_string, |
Torne (Richard Coles) | cedac22 | 2014-06-03 10:58:34 +0100 | [diff] [blame] | 166 | size_t cursor_position, |
| 167 | size_t max_matches) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 168 | return private_data_->HistoryItemsForTerms( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 169 | term_string, |
| 170 | cursor_position, |
Torne (Richard Coles) | cedac22 | 2014-06-03 10:58:34 +0100 | [diff] [blame] | 171 | max_matches, |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 172 | languages_, |
Torne (Richard Coles) | 46d4c2b | 2014-06-09 12:00:27 +0100 | [diff] [blame] | 173 | history_client_); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 174 | } |
| 175 | |
| 176 | // Updating -------------------------------------------------------------------- |
| 177 | |
| 178 | void InMemoryURLIndex::DeleteURL(const GURL& url) { |
| 179 | private_data_->DeleteURL(url); |
| 180 | } |
| 181 | |
| 182 | void InMemoryURLIndex::Observe(int notification_type, |
| 183 | const content::NotificationSource& source, |
| 184 | const content::NotificationDetails& details) { |
| 185 | switch (notification_type) { |
| 186 | case chrome::NOTIFICATION_HISTORY_URL_VISITED: |
| 187 | OnURLVisited(content::Details<URLVisitedDetails>(details).ptr()); |
| 188 | break; |
| 189 | case chrome::NOTIFICATION_HISTORY_URLS_MODIFIED: |
| 190 | OnURLsModified( |
| 191 | content::Details<history::URLsModifiedDetails>(details).ptr()); |
| 192 | break; |
| 193 | case chrome::NOTIFICATION_HISTORY_URLS_DELETED: |
| 194 | OnURLsDeleted( |
| 195 | content::Details<history::URLsDeletedDetails>(details).ptr()); |
| 196 | break; |
| 197 | case chrome::NOTIFICATION_HISTORY_LOADED: |
| 198 | registrar_.Remove(this, chrome::NOTIFICATION_HISTORY_LOADED, |
| 199 | content::Source<Profile>(profile_)); |
| 200 | ScheduleRebuildFromHistory(); |
| 201 | break; |
| 202 | default: |
| 203 | // For simplicity, the unit tests send us all notifications, even when |
| 204 | // we haven't registered for them, so don't assert here. |
| 205 | break; |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | void InMemoryURLIndex::OnURLVisited(const URLVisitedDetails* details) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 210 | HistoryService* service = |
| 211 | HistoryServiceFactory::GetForProfile(profile_, |
| 212 | Profile::EXPLICIT_ACCESS); |
Ben Murdoch | 116680a | 2014-07-20 18:25:52 -0700 | [diff] [blame] | 213 | needs_to_be_cached_ |= private_data_->UpdateURL(service, |
| 214 | details->row, |
| 215 | languages_, |
| 216 | scheme_whitelist_, |
| 217 | &private_data_tracker_); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 218 | } |
| 219 | |
| 220 | void InMemoryURLIndex::OnURLsModified(const URLsModifiedDetails* details) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 221 | HistoryService* service = |
| 222 | HistoryServiceFactory::GetForProfile(profile_, |
| 223 | Profile::EXPLICIT_ACCESS); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 224 | for (URLRows::const_iterator row = details->changed_urls.begin(); |
Ben Murdoch | 116680a | 2014-07-20 18:25:52 -0700 | [diff] [blame] | 225 | row != details->changed_urls.end(); |
| 226 | ++row) { |
| 227 | needs_to_be_cached_ |= private_data_->UpdateURL( |
| 228 | service, *row, languages_, scheme_whitelist_, &private_data_tracker_); |
| 229 | } |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 230 | } |
| 231 | |
| 232 | void InMemoryURLIndex::OnURLsDeleted(const URLsDeletedDetails* details) { |
| 233 | if (details->all_history) { |
| 234 | ClearPrivateData(); |
| 235 | needs_to_be_cached_ = true; |
| 236 | } else { |
| 237 | for (URLRows::const_iterator row = details->rows.begin(); |
| 238 | row != details->rows.end(); ++row) |
| 239 | needs_to_be_cached_ |= private_data_->DeleteURL(row->url()); |
| 240 | } |
Torne (Richard Coles) | 6e8cce6 | 2014-08-19 13:00:08 +0100 | [diff] [blame^] | 241 | // If we made changes, destroy the previous cache. Otherwise, if we go |
| 242 | // through an unclean shutdown (and therefore fail to write a new cache file), |
| 243 | // when Chrome restarts and we restore from the previous cache, we'll end up |
| 244 | // searching over URLs that may be deleted. This would be wrong, and |
| 245 | // surprising to the user who bothered to delete some URLs from his/her |
| 246 | // history. In this situation, deleting the cache is a better solution than |
| 247 | // writing a new cache (after deleting the URLs from the in-memory structure) |
| 248 | // because deleting the cache forces it to be rebuilt from history upon |
| 249 | // startup. If we instead write a new, updated cache then at the time of next |
| 250 | // startup (after an unclean shutdown) we will not rebuild the in-memory data |
| 251 | // structures from history but rather use the cache. This solution is |
| 252 | // mediocre because this cache may not have the most-recently-visited URLs |
| 253 | // in it (URLs visited after user deleted some URLs from history), which |
| 254 | // would be odd and confusing. It's better to force a rebuild. |
| 255 | base::FilePath path; |
| 256 | if (needs_to_be_cached_ && GetCacheFilePath(&path)) { |
| 257 | content::BrowserThread::PostBlockingPoolTask( |
| 258 | FROM_HERE, base::Bind(DeleteCacheFile, path)); |
| 259 | } |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 260 | } |
| 261 | |
| 262 | // Restoring from Cache -------------------------------------------------------- |
| 263 | |
| 264 | void InMemoryURLIndex::PostRestoreFromCacheFileTask() { |
| 265 | DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 266 | TRACE_EVENT0("browser", "InMemoryURLIndex::PostRestoreFromCacheFileTask"); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 267 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 268 | base::FilePath path; |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 269 | if (!GetCacheFilePath(&path) || shutdown_) { |
| 270 | restored_ = true; |
| 271 | if (restore_cache_observer_) |
| 272 | restore_cache_observer_->OnCacheRestoreFinished(false); |
| 273 | return; |
| 274 | } |
| 275 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 276 | content::BrowserThread::PostTaskAndReplyWithResult |
| 277 | <scoped_refptr<URLIndexPrivateData> >( |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 278 | content::BrowserThread::FILE, FROM_HERE, |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 279 | base::Bind(&URLIndexPrivateData::RestoreFromFile, path, languages_), |
| 280 | base::Bind(&InMemoryURLIndex::OnCacheLoadDone, AsWeakPtr())); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 281 | } |
| 282 | |
| 283 | void InMemoryURLIndex::OnCacheLoadDone( |
| 284 | scoped_refptr<URLIndexPrivateData> private_data) { |
| 285 | if (private_data.get() && !private_data->Empty()) { |
Ben Murdoch | 116680a | 2014-07-20 18:25:52 -0700 | [diff] [blame] | 286 | private_data_tracker_.TryCancelAll(); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 287 | private_data_ = private_data; |
| 288 | restored_ = true; |
| 289 | if (restore_cache_observer_) |
| 290 | restore_cache_observer_->OnCacheRestoreFinished(true); |
| 291 | } else if (profile_) { |
| 292 | // When unable to restore from the cache file delete the cache file, if |
| 293 | // it exists, and then rebuild from the history database if it's available, |
| 294 | // otherwise wait until the history database loaded and then rebuild. |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 295 | base::FilePath path; |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 296 | if (!GetCacheFilePath(&path) || shutdown_) |
| 297 | return; |
| 298 | content::BrowserThread::PostBlockingPoolTask( |
| 299 | FROM_HERE, base::Bind(DeleteCacheFile, path)); |
| 300 | HistoryService* service = |
| 301 | HistoryServiceFactory::GetForProfileWithoutCreating(profile_); |
| 302 | if (service && service->backend_loaded()) { |
| 303 | ScheduleRebuildFromHistory(); |
| 304 | } else { |
| 305 | registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED, |
| 306 | content::Source<Profile>(profile_)); |
| 307 | } |
| 308 | } |
| 309 | } |
| 310 | |
| 311 | // Restoring from the History DB ----------------------------------------------- |
| 312 | |
| 313 | void InMemoryURLIndex::ScheduleRebuildFromHistory() { |
| 314 | HistoryService* service = |
| 315 | HistoryServiceFactory::GetForProfile(profile_, |
| 316 | Profile::EXPLICIT_ACCESS); |
| 317 | service->ScheduleDBTask( |
Torne (Richard Coles) | 5f1c943 | 2014-08-12 13:47:38 +0100 | [diff] [blame] | 318 | scoped_ptr<history::HistoryDBTask>( |
| 319 | new InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask( |
| 320 | this, languages_, scheme_whitelist_)), |
Ben Murdoch | 116680a | 2014-07-20 18:25:52 -0700 | [diff] [blame] | 321 | &cache_reader_tracker_); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 322 | } |
| 323 | |
| 324 | void InMemoryURLIndex::DoneRebuidingPrivateDataFromHistoryDB( |
| 325 | bool succeeded, |
| 326 | scoped_refptr<URLIndexPrivateData> private_data) { |
| 327 | DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 328 | if (succeeded) { |
Ben Murdoch | 116680a | 2014-07-20 18:25:52 -0700 | [diff] [blame] | 329 | private_data_tracker_.TryCancelAll(); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 330 | private_data_ = private_data; |
| 331 | PostSaveToCacheFileTask(); // Cache the newly rebuilt index. |
| 332 | } else { |
| 333 | private_data_->Clear(); // Dump the old private data. |
| 334 | // There is no need to do anything with the cache file as it was deleted |
| 335 | // when the rebuild from the history operation was kicked off. |
| 336 | } |
| 337 | restored_ = true; |
| 338 | if (restore_cache_observer_) |
| 339 | restore_cache_observer_->OnCacheRestoreFinished(succeeded); |
| 340 | } |
| 341 | |
| 342 | void InMemoryURLIndex::RebuildFromHistory(HistoryDatabase* history_db) { |
Ben Murdoch | 116680a | 2014-07-20 18:25:52 -0700 | [diff] [blame] | 343 | private_data_tracker_.TryCancelAll(); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 344 | private_data_ = URLIndexPrivateData::RebuildFromHistory(history_db, |
| 345 | languages_, |
| 346 | scheme_whitelist_); |
| 347 | } |
| 348 | |
| 349 | // Saving to Cache ------------------------------------------------------------- |
| 350 | |
| 351 | void InMemoryURLIndex::PostSaveToCacheFileTask() { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 352 | base::FilePath path; |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 353 | if (!GetCacheFilePath(&path)) |
| 354 | return; |
| 355 | // If there is anything in our private data then make a copy of it and tell |
| 356 | // it to save itself to a file. |
| 357 | if (private_data_.get() && !private_data_->Empty()) { |
| 358 | // Note that ownership of the copy of our private data is passed to the |
| 359 | // completion closure below. |
| 360 | scoped_refptr<URLIndexPrivateData> private_data_copy = |
| 361 | private_data_->Duplicate(); |
| 362 | content::BrowserThread::PostTaskAndReplyWithResult<bool>( |
| 363 | content::BrowserThread::FILE, FROM_HERE, |
| 364 | base::Bind(&URLIndexPrivateData::WritePrivateDataToCacheFileTask, |
| 365 | private_data_copy, path), |
| 366 | base::Bind(&InMemoryURLIndex::OnCacheSaveDone, AsWeakPtr())); |
| 367 | } else { |
| 368 | // If there is no data in our index then delete any existing cache file. |
| 369 | content::BrowserThread::PostBlockingPoolTask( |
| 370 | FROM_HERE, |
| 371 | base::Bind(DeleteCacheFile, path)); |
| 372 | } |
| 373 | } |
| 374 | |
| 375 | void InMemoryURLIndex::OnCacheSaveDone(bool succeeded) { |
| 376 | if (save_cache_observer_) |
| 377 | save_cache_observer_->OnCacheSaveFinished(succeeded); |
| 378 | } |
| 379 | |
| 380 | } // namespace history |