15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_url_index.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/debug/trace_event.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h" 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_notifications.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_service_factory.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/url_index_private_data.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/browser/bookmark_model.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/history/core/browser/url_database.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using in_memory_url_index::InMemoryURLIndexCacheItem; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace history { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called by DoSaveToCacheFile to delete any old cache file at |path| when 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// there is no private data to save. Runs on the FILE thread. 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeleteCacheFile(const base::FilePath& path) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::DeleteFile(path, false); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initializes a whitelist of URL schemes. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitializeSchemeWhitelist(std::set<std::string>* whitelist) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(whitelist); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!whitelist->empty()) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Nothing to do, already initialized. 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) whitelist->insert(std::string(url::kAboutScheme)); 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) whitelist->insert(std::string(content::kChromeUIScheme)); 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) whitelist->insert(std::string(url::kFileScheme)); 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) whitelist->insert(std::string(url::kFtpScheme)); 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) whitelist->insert(std::string(url::kHttpScheme)); 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) whitelist->insert(std::string(url::kHttpsScheme)); 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) whitelist->insert(std::string(url::kMailToScheme)); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Restore/SaveCacheObserver --------------------------------------------------- 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InMemoryURLIndex::RestoreCacheObserver::~RestoreCacheObserver() {} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InMemoryURLIndex::SaveCacheObserver::~SaveCacheObserver() {} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RebuildPrivateDataFromHistoryDBTask ----------------------------------------- 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask:: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RebuildPrivateDataFromHistoryDBTask( 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InMemoryURLIndex* index, 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& languages, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::set<std::string>& scheme_whitelist) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : index_(index), 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) languages_(languages), 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheme_whitelist_(scheme_whitelist), 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) succeeded_(false) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::RunOnDBThread( 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryBackend* backend, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryDatabase* db) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_ = URLIndexPrivateData::RebuildFromHistory(db, languages_, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheme_whitelist_); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) succeeded_ = data_.get() && !data_->Empty(); 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!succeeded_ && data_.get()) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_->Clear(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask:: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneRunOnMainThread() { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index_->DoneRebuidingPrivateDataFromHistoryDB(succeeded_, data_); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask:: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~RebuildPrivateDataFromHistoryDBTask() { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// InMemoryURLIndex ------------------------------------------------------------ 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InMemoryURLIndex::InMemoryURLIndex(Profile* profile, 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& history_dir, 9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& languages, 9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) HistoryClient* history_client) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(profile), 9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) history_client_(history_client), 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_dir_(history_dir), 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) languages_(languages), 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private_data_(new URLIndexPrivateData), 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restore_cache_observer_(NULL), 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save_cache_observer_(NULL), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutdown_(false), 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restored_(false), 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) needs_to_be_cached_(false) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeSchemeWhitelist(&scheme_whitelist_); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (profile) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mrossetti): Register for language change notifications. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile> source(profile); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED, source); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_MODIFIED, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, source); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called only by unit tests. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InMemoryURLIndex::InMemoryURLIndex() 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(NULL), 11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) history_client_(NULL), 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private_data_(new URLIndexPrivateData), 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restore_cache_observer_(NULL), 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save_cache_observer_(NULL), 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutdown_(false), 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restored_(false), 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) needs_to_be_cached_(false) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeSchemeWhitelist(&scheme_whitelist_); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InMemoryURLIndex::~InMemoryURLIndex() { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there was a history directory (which there won't be for some unit tests) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // then insure that the cache has already been saved. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(history_dir_.empty() || !needs_to_be_cached_); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::Init() { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostRestoreFromCacheFileTask(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::ShutDown() { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.RemoveAll(); 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cache_reader_tracker_.TryCancelAll(); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutdown_ = true; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetCacheFilePath(&path)) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private_data_tracker_.TryCancelAll(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLIndexPrivateData::WritePrivateDataToCacheFileTask(private_data_, path); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) needs_to_be_cached_ = false; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::ClearPrivateData() { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private_data_->Clear(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool InMemoryURLIndex::GetCacheFilePath(base::FilePath* file_path) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history_dir_.empty()) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *file_path = history_dir_.Append(FILE_PATH_LITERAL("History Provider Cache")); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Querying -------------------------------------------------------------------- 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScoredHistoryMatches InMemoryURLIndex::HistoryItemsForTerms( 165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& term_string, 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t cursor_position, 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t max_matches) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return private_data_->HistoryItemsForTerms( 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) term_string, 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cursor_position, 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) max_matches, 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) languages_, 17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) history_client_); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Updating -------------------------------------------------------------------- 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::DeleteURL(const GURL& url) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private_data_->DeleteURL(url); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::Observe(int notification_type, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (notification_type) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_HISTORY_URL_VISITED: 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnURLVisited(content::Details<URLVisitedDetails>(details).ptr()); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_HISTORY_URLS_MODIFIED: 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnURLsModified( 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<history::URLsModifiedDetails>(details).ptr()); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_HISTORY_URLS_DELETED: 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnURLsDeleted( 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<history::URLsDeletedDetails>(details).ptr()); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_HISTORY_LOADED: 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Remove(this, chrome::NOTIFICATION_HISTORY_LOADED, 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_)); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleRebuildFromHistory(); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For simplicity, the unit tests send us all notifications, even when 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we haven't registered for them, so don't assert here. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::OnURLVisited(const URLVisitedDetails* details) { 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HistoryService* service = 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HistoryServiceFactory::GetForProfile(profile_, 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile::EXPLICIT_ACCESS); 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch needs_to_be_cached_ |= private_data_->UpdateURL(service, 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch details->row, 215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch languages_, 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scheme_whitelist_, 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &private_data_tracker_); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::OnURLsModified(const URLsModifiedDetails* details) { 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HistoryService* service = 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HistoryServiceFactory::GetForProfile(profile_, 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile::EXPLICIT_ACCESS); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (URLRows::const_iterator row = details->changed_urls.begin(); 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch row != details->changed_urls.end(); 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++row) { 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch needs_to_be_cached_ |= private_data_->UpdateURL( 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch service, *row, languages_, scheme_whitelist_, &private_data_tracker_); 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::OnURLsDeleted(const URLsDeletedDetails* details) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (details->all_history) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearPrivateData(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) needs_to_be_cached_ = true; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (URLRows::const_iterator row = details->rows.begin(); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row != details->rows.end(); ++row) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) needs_to_be_cached_ |= private_data_->DeleteURL(row->url()); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // If we made changes, destroy the previous cache. Otherwise, if we go 2426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // through an unclean shutdown (and therefore fail to write a new cache file), 2436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // when Chrome restarts and we restore from the previous cache, we'll end up 2446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // searching over URLs that may be deleted. This would be wrong, and 2456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // surprising to the user who bothered to delete some URLs from his/her 2466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // history. In this situation, deleting the cache is a better solution than 2476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // writing a new cache (after deleting the URLs from the in-memory structure) 2486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // because deleting the cache forces it to be rebuilt from history upon 2496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // startup. If we instead write a new, updated cache then at the time of next 2506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // startup (after an unclean shutdown) we will not rebuild the in-memory data 2516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // structures from history but rather use the cache. This solution is 2526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // mediocre because this cache may not have the most-recently-visited URLs 2536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // in it (URLs visited after user deleted some URLs from history), which 2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // would be odd and confusing. It's better to force a rebuild. 2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::FilePath path; 2566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (needs_to_be_cached_ && GetCacheFilePath(&path)) { 2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) content::BrowserThread::PostBlockingPoolTask( 2586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) FROM_HERE, base::Bind(DeleteCacheFile, path)); 2596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Restoring from Cache -------------------------------------------------------- 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::PostRestoreFromCacheFileTask() { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT0("browser", "InMemoryURLIndex::PostRestoreFromCacheFileTask"); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetCacheFilePath(&path) || shutdown_) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restored_ = true; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (restore_cache_observer_) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restore_cache_observer_->OnCacheRestoreFinished(false); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserThread::PostTaskAndReplyWithResult 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) <scoped_refptr<URLIndexPrivateData> >( 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::FILE, FROM_HERE, 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLIndexPrivateData::RestoreFromFile, path, languages_), 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&InMemoryURLIndex::OnCacheLoadDone, AsWeakPtr())); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::OnCacheLoadDone( 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<URLIndexPrivateData> private_data) { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (private_data.get() && !private_data->Empty()) { 286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private_data_tracker_.TryCancelAll(); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private_data_ = private_data; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restored_ = true; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (restore_cache_observer_) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restore_cache_observer_->OnCacheRestoreFinished(true); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (profile_) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When unable to restore from the cache file delete the cache file, if 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it exists, and then rebuild from the history database if it's available, 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // otherwise wait until the history database loaded and then rebuild. 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetCacheFilePath(&path) || shutdown_) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::PostBlockingPoolTask( 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(DeleteCacheFile, path)); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryService* service = 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryServiceFactory::GetForProfileWithoutCreating(profile_); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (service && service->backend_loaded()) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleRebuildFromHistory(); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED, 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_)); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Restoring from the History DB ----------------------------------------------- 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::ScheduleRebuildFromHistory() { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryService* service = 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryServiceFactory::GetForProfile(profile_, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::EXPLICIT_ACCESS); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service->ScheduleDBTask( 3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<history::HistoryDBTask>( 3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask( 3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, languages_, scheme_whitelist_)), 321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &cache_reader_tracker_); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::DoneRebuidingPrivateDataFromHistoryDB( 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool succeeded, 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<URLIndexPrivateData> private_data) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (succeeded) { 329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private_data_tracker_.TryCancelAll(); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private_data_ = private_data; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostSaveToCacheFileTask(); // Cache the newly rebuilt index. 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private_data_->Clear(); // Dump the old private data. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no need to do anything with the cache file as it was deleted 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when the rebuild from the history operation was kicked off. 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restored_ = true; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (restore_cache_observer_) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restore_cache_observer_->OnCacheRestoreFinished(succeeded); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::RebuildFromHistory(HistoryDatabase* history_db) { 343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private_data_tracker_.TryCancelAll(); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private_data_ = URLIndexPrivateData::RebuildFromHistory(history_db, 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) languages_, 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheme_whitelist_); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Saving to Cache ------------------------------------------------------------- 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::PostSaveToCacheFileTask() { 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetCacheFilePath(&path)) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is anything in our private data then make a copy of it and tell 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it to save itself to a file. 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (private_data_.get() && !private_data_->Empty()) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that ownership of the copy of our private data is passed to the 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // completion closure below. 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<URLIndexPrivateData> private_data_copy = 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private_data_->Duplicate(); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::PostTaskAndReplyWithResult<bool>( 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::FILE, FROM_HERE, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLIndexPrivateData::WritePrivateDataToCacheFileTask, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private_data_copy, path), 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&InMemoryURLIndex::OnCacheSaveDone, AsWeakPtr())); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is no data in our index then delete any existing cache file. 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::PostBlockingPoolTask( 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(DeleteCacheFile, path)); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InMemoryURLIndex::OnCacheSaveDone(bool succeeded) { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (save_cache_observer_) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save_cache_observer_->OnCacheSaveFinished(succeeded); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace history 381