history_backend.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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/history_backend.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <functional> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 17bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/files/file_enumerator.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h" 209ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/rand_util.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/history_url_provider.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_service.h" 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/favicon/favicon_changed_details.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/download_row.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_db_task.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_notifications.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_publisher.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_history_backend.h" 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/history/page_collector.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/page_usage_data.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/select_favicon_frames.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/top_sites.h" 39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/browser/history/typed_url_syncable_service.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/visit_filter.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h" 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/importer/imported_favicon_usage.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/registry_controlled_domains/registry_controlled_domain.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/error_delegate_util.h" 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/android/android_provider_backend.h" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The HistoryBackend consists of a number of components: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryDatabase (stores past 3 months of history) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLDatabase (stores a list of URLs) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadDatabase (stores a list of downloads) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitDatabase (stores a list of visits for the URLs) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitSegmentDatabase (stores groups of URLs for the most visited view). 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArchivedDatabase (stores history older than 3 months) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLDatabase (stores a list of URLs) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadDatabase (stores a list of downloads) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitDatabase (stores a list of visits for the URLs) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (this does not store visit segments as they expire after 3 mos.) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExpireHistoryBackend (manages moving things from HistoryDatabase to 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) the ArchivedDatabase and deleting) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace history { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// How long we keep segment data for in days. Currently 3 months. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This value needs to be greater or equal to 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MostVisitedModel::kMostVisitedScope but we don't want to introduce a direct 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dependency between MostVisitedModel and the history backend. 8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kSegmentDataRetention = 90; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// How long we'll wait to do a commit, so that things are batched together. 8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kCommitIntervalSeconds = 10; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The amount of time before we re-fetch the favicon. 8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kFaviconRefetchDays = 7; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The maximum number of items we'll allow in the redirect list before 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// deleting some. 9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kMaxRedirectCount = 32; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The number of days old a history entry can be before it is considered "old" 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and is archived. 9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kArchiveDaysThreshold = 90; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID) 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The maximum number of top sites to track when recording top page visit stats. 10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const size_t kPageVisitStatsMaxTopSites = 50; 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts from PageUsageData to MostVisitedURL. |redirects| is a 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// list of redirects for this URL. Empty list means no redirects. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MostVisitedURL MakeMostVisitedURL(const PageUsageData& page_data, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RedirectList& redirects) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MostVisitedURL mv; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mv.url = page_data.GetURL(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mv.title = page_data.GetTitle(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (redirects.empty()) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Redirects must contain at least the target url. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mv.redirects.push_back(mv.url); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mv.redirects = redirects; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mv.redirects[mv.redirects.size() - 1] != mv.url) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The last url must be the target url. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mv.redirects.push_back(mv.url); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mv; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This task is run on a timer so that commits happen at regular intervals 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// so they are batched together. The important thing about this class is that 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it supports canceling of the task so the reference to the backend will be 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// freed. The problem is that when history is shutting down, there is likely 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to be one of these commits still pending and holding a reference. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The backend can call Cancel to have this task release the reference. The 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// task will still run (if we ever get to processing the event before 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// shutdown), but it will not do anything. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that this is a refcounted object and is not a task in itself. It should 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be assigned to a RunnableMethod. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(brettw): bug 1165182: This should be replaced with a 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base::WeakPtrFactory which will handle everything automatically (like we do 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in ExpireHistoryBackend). 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CommitLaterTask : public base::RefCounted<CommitLaterTask> { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit CommitLaterTask(HistoryBackend* history_backend) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : history_backend_(history_backend) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The backend will call this function if it is being destroyed so that we 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // release our reference. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Cancel() { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_backend_ = NULL; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RunCommit() { 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (history_backend_.get()) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_backend_->Commit(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCounted<CommitLaterTask>; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~CommitLaterTask() {} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<HistoryBackend> history_backend_; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HistoryBackend -------------------------------------------------------------- 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HistoryBackend::HistoryBackend(const base::FilePath& history_dir, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int id, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkService* bookmark_service) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : delegate_(delegate), 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_(id), 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_dir_(history_dir), 1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scheduled_kill_db_(false), 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expirer_(this, bookmark_service), 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recent_redirects_(kMaxRedirectCount), 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_destroy_message_loop_(NULL), 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) segment_queried_(false), 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_service_(bookmark_service) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryBackend::~HistoryBackend() { 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!scheduled_commit_.get()) << "Deleting without cleanup"; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseDBTasks(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Release AndroidProviderBackend before other objects. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) android_provider_backend_.reset(); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First close the databases before optionally running the "destroy" task. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseAllDatabases(); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!backend_destroy_task_.is_null()) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notify an interested party (typically a unit test) that we're done. 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(backend_destroy_message_loop_); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_destroy_message_loop_->PostTask(FROM_HERE, backend_destroy_task_); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sql::Connection::Delete(GetAndroidCacheFileName()); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::Init(const std::string& languages, bool force_fail) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!force_fail) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitImpl(languages); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->DBLoaded(id_); 209b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) typed_url_syncable_service_.reset(new TypedUrlSyncableService(this)); 210ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch memory_pressure_listener_.reset(new base::MemoryPressureListener( 211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&HistoryBackend::OnMemoryPressure, base::Unretained(this)))); 212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID) 213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PopulateMostVisitedURLMap(); 214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void HistoryBackend::SetOnBackendDestroyTask(base::MessageLoop* message_loop, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!backend_destroy_task_.is_null()) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(WARNING) << "Setting more than one destroy task, overriding"; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_destroy_message_loop_ = message_loop; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_destroy_task_ = task; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::Closing() { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Any scheduled commit will have a reference to us, we must make it 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // release that reference before we can be destroyed. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelScheduledCommit(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Release our reference to the delegate, this reference will be keeping the 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // history service alive. 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_.reset(); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::NotifyRenderProcessHostDestruction(const void* host) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracker_.NotifyRenderProcessHostDestruction(host); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath HistoryBackend::GetThumbnailFileName() const { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return history_dir_.Append(chrome::kThumbnailsFilename); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath HistoryBackend::GetFaviconsFileName() const { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return history_dir_.Append(chrome::kFaviconsFilename); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath HistoryBackend::GetArchivedFileName() const { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return history_dir_.Append(chrome::kArchivedHistoryFilename); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath HistoryBackend::GetAndroidCacheFileName() const { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return history_dir_.Append(chrome::kAndroidCacheFilename); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SegmentID HistoryBackend::GetLastSegmentID(VisitID from_visit) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set is used to detect referrer loops. Should not happen, but can 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if the database is corrupt. 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<VisitID> visit_set; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitID visit_id = from_visit; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (visit_id) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitRow row; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->GetRowForVisit(visit_id, &row)) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row.segment_id) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return row.segment_id; // Found a visit in this change with a segment. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the referrer of this visit, if any. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_id = row.referring_visit; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visit_set.find(visit_id) != visit_set.end()) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Loop in referer chain, giving up"; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_set.insert(visit_id); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SegmentID HistoryBackend::UpdateSegments( 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitID from_visit, 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitID visit_id, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransition transition_type, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Time ts) { 287b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only consider main frames. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!content::PageTransitionIsMainFrame(transition_type)) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SegmentID segment_id = 0; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransition t = 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransitionStripQualifier(transition_type); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Are we at the beginning of a new segment? 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that navigating to an existing entry (with back/forward) reuses the 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // same transition type. We are not adding it as a new segment in that case 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because if this was the target of a redirect, we might end up with 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2 entries for the same final URL. Ex: User types google.net, gets 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // redirected to google.com. A segment is created for google.net. On 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // google.com users navigates through a link, then press back. That last 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // navigation is for the entry google.com transition typed. We end up adding 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a segment for that one as well. So we end up with google.net and google.com 30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // in the segment table, showing as 2 entries in the NTP. 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note also that we should still be updating the visit count for that segment 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which we are not doing now. It should be addressed when 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/96860 is fixed. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((t == content::PAGE_TRANSITION_TYPED || 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t == content::PAGE_TRANSITION_AUTO_BOOKMARK) && 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (transition_type & content::PAGE_TRANSITION_FORWARD_BACK) == 0) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If so, create or get the segment. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string segment_name = db_->ComputeSegmentName(url); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLID url_id = db_->GetRowForURL(url, NULL); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url_id) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(segment_id = db_->GetSegmentNamed(segment_name))) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(segment_id = db_->CreateSegment(url_id, segment_name))) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: if we update an existing segment, we update the url used to 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // represent that segment in order to minimize stale most visited 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // images. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->UpdateSegmentRepresentationURL(segment_id, url_id); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: it is possible there is no segment ID set for this visit chain. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can happen if the initial navigation wasn't AUTO_BOOKMARK or 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TYPED. (For example GENERATED). In this case this visit doesn't count 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // toward any segment. 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(segment_id = GetLastSegmentID(from_visit))) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the segment in the visit. 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->SetSegmentID(visit_id, segment_id)) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finally, increase the counter for that segment / day. 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->IncreaseSegmentVisitCount(segment_id, ts, 1)) { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return segment_id; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::UpdateWithPageEndTime(const void* host, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 page_id, 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time end_ts) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Will be filled with the URL ID and the visit ID of the last addition. 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitID visit_id = tracker_.GetLastVisit(host, page_id, url); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateVisitDuration(visit_id, end_ts); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::UpdateVisitDuration(VisitID visit_id, const Time end_ts) { 364b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the starting visit_time for visit_id. 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitRow visit_row; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (db_->GetRowForVisit(visit_id, &visit_row)) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should never have a negative duration time even when time is skewed. 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_row.visit_duration = end_ts > visit_row.visit_time ? 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_ts - visit_row.visit_time : TimeDelta::FromMicroseconds(0); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->UpdateVisitRow(visit_row); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::AddPage(const HistoryAddPageArgs& request) { 378b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Will be filled with the URL ID and the visit ID of the last addition. 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::pair<URLID, VisitID> last_ids(0, tracker_.GetLastVisit( 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.id_scope, request.page_id, request.referrer)); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitID from_visit_id = last_ids.second; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a redirect chain is given, we expect the last item in that chain to be 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the final URL. 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request.redirects.empty() || 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.redirects.back() == request.url); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the user is adding older history, we need to make sure our times 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are correct. 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request.time < first_recorded_time_) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_recorded_time_ = request.time; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransition request_transition = request.transition; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransition stripped_transition = 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransitionStripQualifier(request_transition); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_keyword_generated = 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (stripped_transition == content::PAGE_TRANSITION_KEYWORD_GENERATED); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the user is navigating to a not-previously-typed intranet hostname, 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // change the transition to TYPED so that the omnibox will learn that this is 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a known host. 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_redirects = request.redirects.size() > 1; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (content::PageTransitionIsMainFrame(request_transition) && 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (stripped_transition != content::PAGE_TRANSITION_TYPED) && 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !is_keyword_generated) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin_url(has_redirects ? 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.redirects[0] : request.url); 412d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (origin_url.SchemeIs(content::kHttpScheme) || 413424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) origin_url.SchemeIs(content::kHttpsScheme) || 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_url.SchemeIs(chrome::kFtpScheme)) { 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string host(origin_url.host()); 416a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) size_t registry_length = 417a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) net::registry_controlled_domains::GetRegistryLength( 418a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) host, 419a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, 420a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); 421a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (registry_length == 0 && !db_->IsTypedHost(host)) { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stripped_transition = content::PAGE_TRANSITION_TYPED; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_transition = 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransitionFromInt( 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stripped_transition | 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransitionGetQualifier(request_transition)); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_redirects) { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The single entry is both a chain start and end. 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransition t = content::PageTransitionFromInt( 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_transition | 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PAGE_TRANSITION_CHAIN_START | 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PAGE_TRANSITION_CHAIN_END); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No redirect case (one element means just the page itself). 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_ids = AddPageVisit(request.url, request.time, 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_ids.second, t, request.visit_source); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the segment for this visit. KEYWORD_GENERATED visits should not 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // result in changing most visited, so we don't update segments (most 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // visited db). 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_keyword_generated) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateSegments(request.url, from_visit_id, last_ids.second, t, 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.time); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the referrer's duration. 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateVisitDuration(from_visit_id, request.time); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Redirect case. Add the redirect chain. 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransition redirect_info = 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PAGE_TRANSITION_CHAIN_START; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RedirectList redirects = request.redirects; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (redirects[0].SchemeIs(chrome::kAboutScheme)) { 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When the redirect source + referrer is "about" we skip it. This 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // happens when a page opens a new frame/window to about:blank and then 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // script sets the URL to somewhere else (used to hide the referrer). It 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // would be nice to keep all these redirects properly but we don't ever 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // see the initial about:blank load, so we don't know where the 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subsequent client redirect came from. 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In this case, we just don't bother hooking up the source of the 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // redirects, so we remove it. 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) redirects.erase(redirects.begin()); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (request_transition & content::PAGE_TRANSITION_CLIENT_REDIRECT) { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) redirect_info = content::PAGE_TRANSITION_CLIENT_REDIRECT; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first entry in the redirect chain initiated a client redirect. 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't add this to the database since the referrer is already 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there, so we skip over it but change the transition type of the first 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // transition to client redirect. 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The referrer is invalid when restoring a session that features an 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // https tab that redirects to a different host or to http. In this 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // case we don't need to reconnect the new redirect with the existing 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // chain. 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request.referrer.is_valid()) { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request.referrer == redirects[0]); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) redirects.erase(redirects.begin()); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the navigation entry for this visit has replaced that for the 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // first visit, remove the CHAIN_END marker from the first visit. This 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can be called a lot, for example, the page cycler, and most of the 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // time we won't have changed anything. 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitRow visit_row; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request.did_replace_entry && 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetRowForVisit(last_ids.second, &visit_row) && 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_row.transition & content::PAGE_TRANSITION_CHAIN_END) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_row.transition = content::PageTransitionFromInt( 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_row.transition & ~content::PAGE_TRANSITION_CHAIN_END); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->UpdateVisitRow(visit_row); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t redirect_index = 0; redirect_index < redirects.size(); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) redirect_index++) { 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransition t = 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransitionFromInt(stripped_transition | redirect_info); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is the last transition, add a CHAIN_END marker 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (redirect_index == (redirects.size() - 1)) { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = content::PageTransitionFromInt( 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t | content::PAGE_TRANSITION_CHAIN_END); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record all redirect visits with the same timestamp. We don't display 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // them anyway, and if we ever decide to, we can reconstruct their order 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the redirect chain. 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_ids = AddPageVisit(redirects[redirect_index], 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request.time, last_ids.second, 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t, request.visit_source); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t & content::PAGE_TRANSITION_CHAIN_START) { 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the segment for this visit. 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateSegments(redirects[redirect_index], 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) from_visit_id, last_ids.second, t, request.time); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the visit_details for this visit. 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateVisitDuration(from_visit_id, request.time); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subsequent transitions in the redirect list must all be server 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // redirects. 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) redirect_info = content::PAGE_TRANSITION_SERVER_REDIRECT; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Last, save this redirect chain for later so we can set titles & favicons 532bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // on the redirected pages properly. 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recent_redirects_.Put(request.url, redirects); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(brettw) bug 1140015: Add an "add page" notification so the history 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // views can keep in sync. 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the last visit to the tracker so we can get outgoing transitions. 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(evanm): Due to http://b/1194536 we lose the referrers of a subframe 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // navigation anyway, so last_visit_id is always zero for them. But adding 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // them here confuses main frame history, so we skip them for now. 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stripped_transition != content::PAGE_TRANSITION_AUTO_SUBFRAME && 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stripped_transition != content::PAGE_TRANSITION_MANUAL_SUBFRAME && 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !is_keyword_generated) { 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracker_.AddVisit(request.id_scope, request.page_id, request.url, 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_ids.second); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (page_collector_) 55168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) page_collector_->AddPageURL(request.url, request.time); 55268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleCommit(); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::InitImpl(const std::string& languages) { 557b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(!db_) << "Initializing HistoryBackend twice"; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In the rare case where the db fails to initialize a dialog may get shown 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the blocks the caller, yet allows other messages through. For this reason 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we only set db_ to the created database if creation is successful. That 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // way other methods won't do anything as db_ is still NULL. 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks beginning_time = TimeTicks::Now(); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Compute the file names. 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath history_name = history_dir_.Append(chrome::kHistoryFilename); 5673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::FilePath thumbnail_name = GetFaviconsFileName(); 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath archived_name = GetArchivedFileName(); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 570bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Delete the old index database files which are no longer used. 571bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DeleteFTSIndexDatabases(); 572bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // History database. 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.reset(new HistoryDatabase()); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Unretained to avoid a ref loop with db_. 5777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_->set_error_callback( 5787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&HistoryBackend::DatabaseErrorCallback, 5797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Unretained(this))); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) sql::InitStatus status = db_->Init(history_name); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (status) { 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case sql::INIT_OK: 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case sql::INIT_FAILURE: { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A NULL db_ will cause all calls on this object to notice this error 5877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // and to not continue. If the error callback scheduled killing the 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // database, the task it posted has not executed yet. Try killing the 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // database now before we close it. 5907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool kill_db = scheduled_kill_db_; 5917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (kill_db) 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KillHistoryDatabase(); 5937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("History.AttemptedToFixProfileError", kill_db); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->NotifyProfileError(id_, status); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.reset(); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill the in-memory database and send it back to the history service on the 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // main thread. 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InMemoryHistoryBackend* mem_backend = new InMemoryHistoryBackend; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mem_backend->Init(history_name, db_.get())) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->SetInMemoryBackend(id_, mem_backend); // Takes ownership of 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pointer. 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete mem_backend; // Error case, run without the in-memory DB. 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->BeginExclusiveMode(); // Must be after the mem backend read the data. 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 612bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Create the history publisher which needs to be passed on to the thumbnail 613bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // database for publishing history. 61468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // TODO(shess): HistoryPublisher is being deprecated. I am still 61568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // trying to track down who depends on it, meanwhile talk to me 61668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // before removing interactions with it. http://crbug.com/294306 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_publisher_.reset(new HistoryPublisher()); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!history_publisher_->Init()) { 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The init may fail when there are no indexers wanting our history. 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hence no need to log the failure. 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_publisher_.reset(); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Collects page data for history_publisher_. 62568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (history_publisher_.get()) { 62668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) page_collector_.reset(new PageCollector()); 62768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) page_collector_->Init(history_publisher_.get()); 62868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 62968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Thumbnail database. 6313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(shess): "thumbnail database" these days only stores 6323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // favicons. Thumbnails are stored in "top sites". Consider 6333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // renaming "thumbnail" references to "favicons" or something of the 6343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // sort. 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_.reset(new ThumbnailDatabase()); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (thumbnail_db_->Init(thumbnail_name, 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.get()) != sql::INIT_OK) { 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unlike the main database, we don't error out when the database is too 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // new because this error is much less severe. Generally, this shouldn't 64058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // happen since the thumbnail and main database versions should be in sync. 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We'll just continue without thumbnails & favicons in this case or any 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // other error. 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Could not initialize the thumbnail database."; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_.reset(); 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Archived database. 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (db_->needs_version_17_migration()) { 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See needs_version_17_migration() decl for more. In this case, we want 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to delete the archived database and need to do so before we try to 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // open the file. We can ignore any error (maybe the file doesn't exist). 652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sql::Connection::Delete(archived_name); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archived_db_.reset(new ArchivedDatabase()); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!archived_db_->Init(archived_name)) { 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Could not initialize the archived database."; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archived_db_.reset(); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Generate the history and thumbnail database metrics only after performing 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // any migration work. 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base::RandInt(1, 100) == 50) { 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only do this computation sometimes since it can be expensive. 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) db_->ComputeDatabaseMetrics(history_name); 6652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (thumbnail_db_) 6662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch thumbnail_db_->ComputeDatabaseMetrics(); 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the expiration module about all the nice databases we made. This must 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // happen before db_->Init() is called since the callback ForceArchiveHistory 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // may need to expire stuff. 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // *sigh*, this can all be cleaned up when that migration code is removed. 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The main DB initialization should intuitively be first (not that it 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // actually matters) and the expirer should be set last. 67668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) expirer_.SetDatabases(db_.get(), archived_db_.get(), thumbnail_db_.get()); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open the long-running transaction. 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->BeginTransaction(); 680b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (thumbnail_db_) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->BeginTransaction(); 682b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (archived_db_) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archived_db_->BeginTransaction(); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the first item in our database. 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetStartDate(&first_recorded_time_); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start expiring old stuff. 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expirer_.StartArchivingOldStuff(TimeDelta::FromDays(kArchiveDaysThreshold)); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 692b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (thumbnail_db_) { 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) android_provider_backend_.reset(new AndroidProviderBackend( 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetAndroidCacheFileName(), db_.get(), thumbnail_db_.get(), 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_service_, delegate_.get())); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HISTOGRAM_TIMES("History.InitTime", 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks::Now() - beginning_time); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 703ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid HistoryBackend::OnMemoryPressure( 704ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { 705ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool trim_aggressively = memory_pressure_level == 706ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::MemoryPressureListener::MEMORY_PRESSURE_CRITICAL; 707ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (db_) 708ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch db_->TrimMemory(trim_aggressively); 709ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (thumbnail_db_) 710ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch thumbnail_db_->TrimMemory(trim_aggressively); 711ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (archived_db_) 712ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch archived_db_->TrimMemory(trim_aggressively); 713ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 714ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::CloseAllDatabases() { 716b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) { 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Commit the long-running transaction. 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->CommitTransaction(); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.reset(); 72058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Forget the first recorded time since the database is closed. 72158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) first_recorded_time_ = base::Time(); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 723b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (thumbnail_db_) { 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->CommitTransaction(); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_.reset(); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 727b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (archived_db_) { 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archived_db_->CommitTransaction(); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archived_db_.reset(); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::pair<URLID, VisitID> HistoryBackend::AddPageVisit( 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time time, 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitID referring_visit, 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransition transition, 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitSource visit_source) { 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Top-level frame navigations are visible, everything else is hidden 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool new_hidden = !content::PageTransitionIsMainFrame(transition); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: This code must stay in sync with 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ExpireHistoryBackend::ExpireURLsForVisits(). 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(pkasting): http://b/1148304 We shouldn't be marking so many URLs as 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // typed, which would eliminate the need for this code. 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int typed_increment = 0; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransition transition_type = 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransitionStripQualifier(transition); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((transition_type == content::PAGE_TRANSITION_TYPED && 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !content::PageTransitionIsRedirect(transition)) || 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transition_type == content::PAGE_TRANSITION_KEYWORD_GENERATED) 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typed_increment = 1; 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 754eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID) 755eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Only count the page visit if it came from user browsing and only count it 756eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // once when cycling through a redirect chain. 757eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (visit_source == SOURCE_BROWSED && 758eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (transition & content::PAGE_TRANSITION_CHAIN_END) != 0) { 759eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RecordTopPageVisitStats(url); 760eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 761eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 762eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See if this URL is already in the DB. 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRow url_info(url); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLID url_id = db_->GetRowForURL(url, &url_info); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url_id) { 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update of an existing row. 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (content::PageTransitionStripQualifier(transition) != 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PAGE_TRANSITION_RELOAD) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_visit_count(url_info.visit_count() + 1); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (typed_increment) 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_typed_count(url_info.typed_count() + typed_increment); 773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (url_info.last_visit() < time) 774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) url_info.set_last_visit(time); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only allow un-hiding of pages, never hiding. 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!new_hidden) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_hidden(false); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->UpdateURLRow(url_id, url_info); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Addition of a new row. 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_visit_count(1); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_typed_count(typed_increment); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_last_visit(time); 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_hidden(new_hidden); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_id = db_->AddURL(url_info); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url_id) { 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Adding URL failed."; 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::make_pair(0, 0); 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.id_ = url_id; 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the visit with the time to the database. 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitRow visit_info(url_id, time, referring_visit, transition, 0); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitID visit_id = db_->AddVisit(&visit_info, visit_source); 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyVisitObservers(visit_info); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visit_info.visit_time < first_recorded_time_) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_recorded_time_ = visit_info.visit_time; 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Broadcast a notification of the visit. 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visit_id) { 806b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (typed_url_syncable_service_.get()) 807b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) typed_url_syncable_service_->OnUrlVisited(transition, &url_info); 808b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLVisitedDetails* details = new URLVisitedDetails; 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details->transition = transition; 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details->row = url_info; 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(meelapshah) Disabled due to potential PageCycler regression. 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Re-enable this. 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetMostRecentRedirectsTo(url, &details->redirects); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BroadcastNotifications(chrome::NOTIFICATION_HISTORY_URL_VISITED, details); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(0) << "Failed to build visit insert statement: " 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "url_id = " << url_id; 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::make_pair(url_id, visit_id); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::AddPagesWithDetails(const URLRows& urls, 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitSource visit_source) { 826b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<URLsModifiedDetails> modified(new URLsModifiedDetails); 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (URLRows::const_iterator i = urls.begin(); i != urls.end(); ++i) { 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!i->last_visit().is_null()); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We will add to either the archived database or the main one depending on 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the date of the added visit. 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLDatabase* url_database; 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitDatabase* visit_database; 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsExpiredVisitTime(i->last_visit())) { 838b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!archived_db_) 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // No archived database to save it to, just forget this. 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_database = archived_db_.get(); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_database = archived_db_.get(); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_database = db_.get(); 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_database = db_.get(); 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRow existing_url; 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLID url_id = url_database->GetRowForURL(i->url(), &existing_url); 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url_id) { 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the page if it doesn't exist. 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_id = url_database->AddURL(*i); 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url_id) { 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Could not add row to DB"; 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->typed_count() > 0) { 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified->changed_urls.push_back(*i); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified->changed_urls.back().set_id(url_id); // *i likely has |id_| 0. 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 86368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // TODO(shess): I'm not sure this case needs to exist anymore. 86468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (page_collector_) { 86568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) page_collector_->AddPageData(i->url(), i->last_visit(), 86668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) i->title(), string16()); 86768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 86868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sync code manages the visits itself. 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visit_source != SOURCE_SYNCED) { 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make up a visit to correspond to the last visit to the page. 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitRow visit_info(url_id, i->last_visit(), 0, 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageTransitionFromInt( 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PAGE_TRANSITION_LINK | 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PAGE_TRANSITION_CHAIN_START | 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PAGE_TRANSITION_CHAIN_END), 0); 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!visit_database->AddVisit(&visit_info, visit_source)) { 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Adding visit failed."; 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyVisitObservers(visit_info); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visit_info.visit_time < first_recorded_time_) 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_recorded_time_ = visit_info.visit_time; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 888b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (typed_url_syncable_service_.get()) 889b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) typed_url_syncable_service_->OnUrlsModified(&modified->changed_urls); 890b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Broadcast a notification for typed URLs that have been modified. This 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be picked up by the in-memory URL database on the main thread. 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(brettw) bug 1140015: Add an "add page" notification so the history 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // views can keep in sync. 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BroadcastNotifications(chrome::NOTIFICATION_HISTORY_URLS_MODIFIED, 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified.release()); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleCommit(); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::IsExpiredVisitTime(const base::Time& time) { 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return time < expirer_.GetCurrentArchiveTime(); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 90668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void HistoryBackend::SetPageTitle(const GURL& url, const string16& title) { 907b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 91068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (page_collector_) 91168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) page_collector_->AddPageTitle(url, title); 91268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search for recent redirects which should get the same title. We make a 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dummy list containing the exact URL visited if there are no redirects so 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the processing below can be the same. 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::RedirectList dummy_list; 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::RedirectList* redirects; 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RedirectCache::iterator iter = recent_redirects_.Get(url); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter != recent_redirects_.end()) { 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) redirects = &iter->second; 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This redirect chain should have the destination URL as the last item. 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!redirects->empty()); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(redirects->back() == url); 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No redirect chain stored, make up one containing the URL we want so we 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can use the same logic below. 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dummy_list.push_back(url); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) redirects = &dummy_list; 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<URLsModifiedDetails> details(new URLsModifiedDetails); 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < redirects->size(); i++) { 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRow row; 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLID row_id = db_->GetRowForURL(redirects->at(i), &row); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_id && row.title() != title) { 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row.set_title(title); 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->UpdateURLRow(row_id, row); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details->changed_urls.push_back(row); 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Broadcast notifications for any URLs that have changed. This will 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // update the in-memory database and the InMemoryURLIndex. 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!details->changed_urls.empty()) { 946b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (typed_url_syncable_service_.get()) 947b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) typed_url_syncable_service_->OnUrlsModified(&details->changed_urls); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BroadcastNotifications(chrome::NOTIFICATION_HISTORY_URLS_MODIFIED, 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details.release()); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleCommit(); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::AddPageNoVisitForBookmark(const GURL& url, 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& title) { 956b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRow url_info(url); 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLID url_id = db_->GetRowForURL(url, &url_info); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url_id) { 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URL is already known, nothing to do. 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!title.empty()) { 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_title(title); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_title(UTF8ToUTF16(url.spec())); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_last_visit(Time::Now()); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mark the page hidden. If the user types it in, it'll unhide. 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_hidden(true); 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->AddURL(url_info); 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryBackend::IterateURLs( 98090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const scoped_refptr<visitedlink::VisitedLinkDelegate::URLEnumerator>& 9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iterator) { 982b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) { 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryDatabase::URLEnumerator e; 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (db_->InitURLEnumeratorForEverything(&e)) { 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRow info; 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (e.GetNextURL(&info)) { 9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iterator->OnURL(info.url()); 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iterator->OnComplete(true); // Success. 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iterator->OnComplete(false); // Failure. 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::GetAllTypedURLs(URLRows* urls) { 997b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return db_->GetAllTypedUrls(urls); 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::GetVisitsForURL(URLID id, VisitVector* visits) { 1003b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return db_->GetVisitsForURL(id, visits); 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::GetMostRecentVisitsForURL(URLID id, 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_visits, 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitVector* visits) { 1011b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return db_->GetMostRecentVisitsForURL(id, max_visits, visits); 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::UpdateURL(URLID id, const history::URLRow& url) { 1017b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return db_->UpdateURLRow(id, url); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::AddVisits(const GURL& url, 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<VisitInfo>& visits, 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitSource visit_source) { 1025b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) { 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<VisitInfo>::const_iterator visit = visits.begin(); 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit != visits.end(); ++visit) { 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!AddPageVisit( 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url, visit->first, 0, visit->second, visit_source).first) { 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleCommit(); 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::RemoveVisits(const VisitVector& visits) { 1040b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expirer_.ExpireVisits(visits); 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleCommit(); 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::GetVisitsSource(const VisitVector& visits, 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitSourceMap* sources) { 1050b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetVisitsSource(visits, sources); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::GetURL(const GURL& url, history::URLRow* url_row) { 1058b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return db_->GetRowForURL(url, url_row) != 0; 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::QueryURL(scoped_refptr<QueryURLRequest> request, 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool want_visits) { 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->canceled()) 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = false; 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRow* row = &request->value.a; 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitVector* visits = &request->value.b; 1072b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) { 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (db_->GetRowForURL(url, row)) { 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Have a row. 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = true; 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Optionally query the visits. 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (want_visits) 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetVisitsForURL(row->id(), visits); 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(request->handle(), success, row, visits); 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)TypedUrlSyncableService* HistoryBackend::GetTypedUrlSyncableService() const { 1086b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return typed_url_syncable_service_.get(); 1087b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 1088b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Segment usage --------------------------------------------------------------- 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::DeleteOldSegmentData() { 1092b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->DeleteSegmentData(Time::Now() - 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta::FromDays(kSegmentDataRetention)); 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::QuerySegmentUsage( 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<QuerySegmentUsageRequest> request, 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Time from_time, 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_result_count) { 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->canceled()) 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) { 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->QuerySegmentUsage(from_time, max_result_count, &request->value.get()); 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is the first time we query segments, invoke 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DeleteOldSegmentData asynchronously. We do this to cleanup old 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // entries. 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!segment_queried_) { 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) segment_queried_ = true; 111290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&HistoryBackend::DeleteOldSegmentData, this)); 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(request->handle(), &request->value.get()); 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryBackend::IncreaseSegmentDuration(const GURL& url, 11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time time, 11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta delta) { 1123b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string segment_name(VisitSegmentDatabase::ComputeSegmentName(url)); 11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SegmentID segment_id = db_->GetSegmentNamed(segment_name); 11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!segment_id) { 11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLID url_id = db_->GetRowForURL(url, NULL); 11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!url_id) 11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) segment_id = db_->CreateSegment(url_id, segment_name); 11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!segment_id) 11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SegmentDurationID duration_id; 11372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta total_delta; 11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!db_->GetSegmentDuration(segment_id, time, &duration_id, 11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &total_delta)) { 11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) db_->CreateSegmentDuration(segment_id, time, delta); 11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) total_delta += delta; 11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) db_->SetSegmentDuration(duration_id, total_delta); 11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryBackend::QuerySegmentDuration( 11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<QuerySegmentUsageRequest> request, 11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time from_time, 11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int max_result_count) { 11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (request->canceled()) 11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1154b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) { 11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) db_->QuerySegmentDuration(from_time, max_result_count, 11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &request->value.get()); 11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request->ForwardResult(request->handle(), &request->value.get()); 11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Keyword visits -------------------------------------------------------------- 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::SetKeywordSearchTermsForURL(const GURL& url, 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TemplateURLID keyword_id, 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& term) { 1166b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the ID for this URL. 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRow url_row; 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->GetRowForURL(url, &url_row)) { 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is a small possibility the url was deleted before the keyword 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // was added. Ignore the request. 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->SetKeywordSearchTermsForURL(url_row.id(), keyword_id, term); 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // details is deleted by BroadcastNotifications. 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KeywordSearchTermDetails* details = new KeywordSearchTermDetails; 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details->url = url; 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details->keyword_id = keyword_id; 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details->term = term; 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BroadcastNotifications( 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_HISTORY_KEYWORD_SEARCH_TERM_UPDATED, details); 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleCommit(); 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::DeleteAllSearchTermsForKeyword( 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TemplateURLID keyword_id) { 1191b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->DeleteAllSearchTermsForKeyword(keyword_id); 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sky): bug 1168470. Need to move from archive dbs too. 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleCommit(); 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::GetMostRecentKeywordSearchTerms( 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<GetMostRecentKeywordSearchTermsRequest> request, 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TemplateURLID keyword_id, 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& prefix, 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_count) { 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->canceled()) 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1207b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) { 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetMostRecentKeywordSearchTerms(keyword_id, prefix, max_count, 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &(request->value)); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(request->handle(), &request->value); 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Downloads ------------------------------------------------------------------- 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HistoryBackend::GetNextDownloadId(uint32* next_id) { 1217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) 12187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch db_->GetNextDownloadId(next_id); 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get all the download entries from the database. 12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryBackend::QueryDownloads(std::vector<DownloadRow>* rows) { 1223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) 12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) db_->QueryDownloads(rows); 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Update a particular download entry. 12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryBackend::UpdateDownload(const history::DownloadRow& data) { 1229b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) db_->UpdateDownload(data); 12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScheduleCommit(); 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryBackend::CreateDownload(const history::DownloadRow& history_info, 12367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool* success) { 1237b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 12397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch *success = db_->CreateDownload(history_info); 12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScheduleCommit(); 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HistoryBackend::RemoveDownloads(const std::set<uint32>& ids) { 1244b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 12467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t downloads_count_before = db_->CountDownloads(); 12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks started_removing = base::TimeTicks::Now(); 12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // HistoryBackend uses a long-running Transaction that is committed 12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // periodically, so this loop doesn't actually hit the disk too hard. 12507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (std::set<uint32>::const_iterator it = ids.begin(); 12517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch it != ids.end(); ++it) { 12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) db_->RemoveDownload(*it); 12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScheduleCommit(); 12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks finished_removing = base::TimeTicks::Now(); 12567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t downloads_count_after = db_->CountDownloads(); 12577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 12587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_LE(downloads_count_after, downloads_count_before); 12597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (downloads_count_after > downloads_count_before) 12607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 12617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t num_downloads_deleted = downloads_count_before - downloads_count_after; 12627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch UMA_HISTOGRAM_COUNTS("Download.DatabaseRemoveDownloadsCount", 12637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch num_downloads_deleted); 12647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::TimeDelta micros = (1000 * (finished_removing - started_removing)); 12657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch UMA_HISTOGRAM_TIMES("Download.DatabaseRemoveDownloadsTime", micros); 12667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (num_downloads_deleted > 0) { 12677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch UMA_HISTOGRAM_TIMES("Download.DatabaseRemoveDownloadsTimePerRecord", 12687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch (1000 * micros) / num_downloads_deleted); 12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_GE(ids.size(), num_downloads_deleted); 12717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (ids.size() < num_downloads_deleted) 12727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 12737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch UMA_HISTOGRAM_COUNTS("Download.DatabaseRemoveDownloadsCountNotRemoved", 12747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ids.size() - num_downloads_deleted); 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::QueryHistory(scoped_refptr<QueryHistoryRequest> request, 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& text_query, 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const QueryOptions& options) { 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->canceled()) 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks beginning_time = TimeTicks::Now(); 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) { 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (text_query.empty()) { 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Basic history query for the main database. 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueryHistoryBasic(db_.get(), db_.get(), options, &request->value); 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now query the archived database. This is a bit tricky because we don't 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // want to query it if the queried time range isn't going to find anything 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in it. 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(brettw) bug 1171036: do blimpie querying for the archived database 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as well. 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if (archived_db_.get() && 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // expirer_.GetCurrentArchiveTime() - TimeDelta::FromDays(7)) { 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Text history query. 1299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch QueryHistoryText(db_.get(), db_.get(), text_query, options, 1300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &request->value); 1301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (archived_db_.get() && 1302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expirer_.GetCurrentArchiveTime() >= options.begin_time) { 1303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch QueryHistoryText(archived_db_.get(), archived_db_.get(), text_query, 1304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch options, &request->value); 1305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(request->handle(), &request->value); 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("History.QueryHistory", 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks::Now() - beginning_time); 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Basic time-based querying of history. 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::QueryHistoryBasic(URLDatabase* url_db, 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitDatabase* visit_db, 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const QueryOptions& options, 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueryResults* result) { 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First get all visits. 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitVector visits; 13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_more_results = visit_db->GetVisibleVisitsInRange(options, &visits); 13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(static_cast<int>(visits.size()) <= options.EffectiveMaxCount()); 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now add them and the URL rows to the results. 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLResult url_result; 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < visits.size(); i++) { 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const VisitRow visit = visits[i]; 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a result row for this visit, get the URL info from the DB. 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url_db->GetURLRow(visit.url_id, &url_result)) { 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(0) << "Failed to get id " << visit.url_id 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " from history.urls."; 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // DB out of sync and URL doesn't exist, try to recover. 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url_result.url().is_valid()) { 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(0) << "Got invalid URL from history.urls with id " 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << visit.url_id << ": " 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << url_result.url().possibly_invalid_spec(); 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // Don't report invalid URLs in case of corruption. 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The archived database may be out of sync with respect to starring, 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // titles, last visit date, etc. Therefore, we query the main DB if the 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // current URL database is not the main one. 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url_db == db_.get()) { 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Currently querying the archived DB, update with the main database to 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // catch any interesting stuff. This will update it if it exists in the 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // main DB, and do nothing otherwise. 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetRowForURL(url_result.url(), &url_result); 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_result.set_visit_time(visit.visit_time); 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Set whether the visit was blocked for a managed user by looking at the 1357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // transition type. 1358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) url_result.set_blocked_visit( 1359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (visit.transition & content::PAGE_TRANSITION_BLOCKED) != 0); 1360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't set any of the query-specific parts of the URLResult, since 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // snippets and stuff don't apply to basic querying. 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->AppendURLBySwapping(&url_result); 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_more_results && options.begin_time <= first_recorded_time_) 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->set_reached_beginning(true); 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Text-based querying of history. 1371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid HistoryBackend::QueryHistoryText(URLDatabase* url_db, 1372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VisitDatabase* visit_db, 1373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const string16& text_query, 1374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const QueryOptions& options, 1375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch QueryResults* result) { 1376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch URLRows text_matches; 1377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch url_db->GetTextMatches(text_query, &text_matches); 1378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<URLResult> matching_visits; 1380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VisitVector visits; // Declare outside loop to prevent re-construction. 1381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < text_matches.size(); i++) { 1382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const URLRow& text_match = text_matches[i]; 1383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Get all visits for given URL match. 1384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch visit_db->GetVisitsForURLWithOptions(text_match.id(), options, &visits); 1385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t j = 0; j < visits.size(); j++) { 1386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch URLResult url_result(text_match); 1387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch url_result.set_visit_time(visits[j].visit_time); 1388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch matching_visits.push_back(url_result); 1389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::sort(matching_visits.begin(), matching_visits.end(), 1393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch URLResult::CompareVisitTime); 1394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t max_results = options.max_count == 0 ? 1396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::numeric_limits<size_t>::max() : static_cast<int>(options.max_count); 1397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (std::vector<URLResult>::iterator it = matching_visits.begin(); 1398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch it != matching_visits.end() && result->size() < max_results; ++it) { 1399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch result->AppendURLBySwapping(&(*it)); 1400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (matching_visits.size() == result->size() && 1403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch options.begin_time <= first_recorded_time_) 1404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch result->set_reached_beginning(true); 1405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 1406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Frontend to GetMostRecentRedirectsFrom from the history thread. 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::QueryRedirectsFrom( 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<QueryRedirectsRequest> request, 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url) { 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->canceled()) 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = GetMostRecentRedirectsFrom(url, &request->value); 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(request->handle(), url, success, &request->value); 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::QueryRedirectsTo( 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<QueryRedirectsRequest> request, 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url) { 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->canceled()) 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = GetMostRecentRedirectsTo(url, &request->value); 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(request->handle(), url, success, &request->value); 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::GetVisibleVisitCountToHost( 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<GetVisibleVisitCountToHostRequest> request, 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url) { 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->canceled()) 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count = 0; 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time first_visit; 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = db_.get() && 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetVisibleVisitCountToHost(url, &count, &first_visit); 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(request->handle(), success, count, first_visit); 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::QueryTopURLsAndRedirects( 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<QueryTopURLsAndRedirectsRequest> request, 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result_count) { 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->canceled()) 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1444b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) { 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(request->handle(), false, NULL, NULL); 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL>* top_urls = &request->value.a; 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::RedirectMap* redirects = &request->value.b; 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedVector<PageUsageData> data; 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->QuerySegmentUsage(base::Time::Now() - base::TimeDelta::FromDays(90), 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_count, &data.get()); 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < data.size(); ++i) { 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top_urls->push_back(data[i]->GetURL()); 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RefCountedVector<GURL>* list = new RefCountedVector<GURL>; 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMostRecentRedirectsFrom(top_urls->back(), &list->data); 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*redirects)[top_urls->back()] = list; 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(request->handle(), true, top_urls, redirects); 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Will replace QueryTopURLsAndRedirectsRequest. 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::QueryMostVisitedURLs( 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<QueryMostVisitedURLsRequest> request, 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result_count, 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int days_back) { 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->canceled()) 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1474b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) { 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No History Database - return an empty list. 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(request->handle(), MostVisitedURLList()); 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MostVisitedURLList* result = &request->value; 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueryMostVisitedURLsImpl(result_count, days_back, result); 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(request->handle(), *result); 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::QueryFilteredURLs( 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<QueryFilteredURLsRequest> request, 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result_count, 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const history::VisitFilter& filter, 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool extended_info) { 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->canceled()) 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time request_start = base::Time::Now(); 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) { 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No History Database - return an empty list. 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(request->handle(), FilteredURLList()); 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitVector visits; 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetDirectVisitsDuringTimes(filter, 0, &visits); 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<URLID, double> score_map; 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < visits.size(); ++i) { 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) score_map[visits[i].url_id] += filter.GetVisitScore(visits[i]); 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(georgey): experiment with visit_segment database granularity (it is 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // currently 24 hours) to use it directly instead of using visits database, 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which is considerably slower. 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedVector<PageUsageData> data; 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.reserve(score_map.size()); 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<URLID, double>::iterator it = score_map.begin(); 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != score_map.end(); ++it) { 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PageUsageData* pud = new PageUsageData(it->first); 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pud->SetScore(it->second); 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.push_back(pud); 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Limit to the top |result_count| results. 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(data.begin(), data.end(), PageUsageData::Predicate); 15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result_count && implicit_cast<int>(data.size()) > result_count) 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.resize(result_count); 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < data.size(); ++i) { 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRow info; 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (db_->GetURLRow(data[i]->GetID(), &info)) { 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data[i]->SetURL(info.url()); 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data[i]->SetTitle(info.title()); 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilteredURLList& result = request->value; 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < data.size(); ++i) { 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PageUsageData* current_data = data[i]; 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilteredURL url(*current_data); 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extended_info) { 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitVector visits; 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetVisitsForURL(current_data->GetID(), &visits); 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visits.size() > 0) { 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url.extended_info.total_visits = visits.size(); 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < visits.size(); ++i) { 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url.extended_info.duration_opened += 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visits[i].visit_duration.InSeconds(); 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visits[i].visit_time > url.extended_info.last_visit_time) { 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url.extended_info.last_visit_time = visits[i].visit_time; 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(macourteau): implement the url.extended_info.visits stat. 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.push_back(url); 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int delta_time = std::max(1, std::min(999, 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>((base::Time::Now() - request_start).InMilliseconds()))); 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATIC_HISTOGRAM_POINTER_BLOCK( 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "NewTabPage.SuggestedSitesLoadTime", 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Add(delta_time), 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::LinearHistogram::FactoryGet("NewTabPage.SuggestedSitesLoadTime", 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, 1000, 100, base::Histogram::kUmaTargetedHistogramFlag)); 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(request->handle(), result); 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::QueryMostVisitedURLsImpl(int result_count, 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int days_back, 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MostVisitedURLList* result) { 1571b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedVector<PageUsageData> data; 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->QuerySegmentUsage(base::Time::Now() - 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromDays(days_back), 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_count, &data.get()); 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < data.size(); ++i) { 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PageUsageData* current_data = data[i]; 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RedirectList redirects; 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMostRecentRedirectsFrom(current_data->GetURL(), &redirects); 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MostVisitedURL url = MakeMostVisitedURL(*current_data, redirects); 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->push_back(url); 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::GetRedirectsFromSpecificVisit( 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitID cur_visit, history::RedirectList* redirects) { 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Follow any redirects from the given visit and add them to the list. 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It *should* be impossible to get a circular chain here, but we check 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // just in case to avoid infinite loops. 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL cur_url; 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<VisitID> visit_set; 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_set.insert(cur_visit); 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (db_->GetRedirectFromVisit(cur_visit, &cur_visit, &cur_url)) { 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visit_set.find(cur_visit) != visit_set.end()) { 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Loop in visit chain, giving up"; 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_set.insert(cur_visit); 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) redirects->push_back(cur_url); 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::GetRedirectsToSpecificVisit( 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitID cur_visit, 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::RedirectList* redirects) { 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Follow redirects going to cur_visit. These are added to |redirects| in 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the order they are found. If a redirect chain looks like A -> B -> C and 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |cur_visit| = C, redirects will be {B, A} in that order. 1612b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL cur_url; 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<VisitID> visit_set; 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_set.insert(cur_visit); 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (db_->GetRedirectToVisit(cur_visit, &cur_visit, &cur_url)) { 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visit_set.find(cur_visit) != visit_set.end()) { 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Loop in visit chain, giving up"; 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_set.insert(cur_visit); 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) redirects->push_back(cur_url); 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::GetMostRecentRedirectsFrom( 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& from_url, 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::RedirectList* redirects) { 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) redirects->clear(); 1632b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLID from_url_id = db_->GetRowForURL(from_url, NULL); 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitID cur_visit = db_->GetMostRecentVisitForURL(from_url_id, NULL); 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!cur_visit) 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // No visits for URL. 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRedirectsFromSpecificVisit(cur_visit, redirects); 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::GetMostRecentRedirectsTo( 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& to_url, 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::RedirectList* redirects) { 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) redirects->clear(); 1648b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLID to_url_id = db_->GetRowForURL(to_url, NULL); 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitID cur_visit = db_->GetMostRecentVisitForURL(to_url_id, NULL); 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!cur_visit) 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // No visits for URL. 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRedirectsToSpecificVisit(cur_visit, redirects); 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::ScheduleAutocomplete(HistoryURLProvider* provider, 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryURLProviderParams* params) { 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ExecuteWithDB should handle the NULL database case. 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provider->ExecuteWithDB(this, db_.get(), params); 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1666bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid HistoryBackend::DeleteFTSIndexDatabases() { 1667bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Find files on disk matching the text databases file pattern so we can 1668bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // quickly test for and delete them. 1669bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::FilePath::StringType filepattern = 1670bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch FILE_PATH_LITERAL("History Index *"); 1671bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::FileEnumerator enumerator( 1672bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch history_dir_, false, base::FileEnumerator::FILES, filepattern); 1673bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch int num_databases_deleted = 0; 1674bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::FilePath current_file; 1675bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch while (!(current_file = enumerator.Next()).empty()) { 1676bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (sql::Connection::Delete(current_file)) 1677bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch num_databases_deleted++; 1678bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 1679bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch UMA_HISTOGRAM_COUNTS("History.DeleteFTSIndexDatabases", 1680bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch num_databases_deleted); 1681bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 1682bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 168368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void HistoryBackend::SetPageContents(const GURL& url, 168468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const string16& contents) { 168568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (page_collector_) 168668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) page_collector_->AddPageContents(url, contents); 168768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 168868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::GetFavicons( 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<GURL>& icon_urls, 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int icon_types, 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size_in_dip, 16932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<ui::ScaleFactor>& desired_scale_factors, 169490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconBitmapResult>* bitmap_results) { 16952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateFaviconMappingsAndFetchImpl(NULL, icon_urls, icon_types, 16962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) desired_size_in_dip, desired_scale_factors, 16972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bitmap_results); 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::GetFaviconsForURL( 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& page_url, 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int icon_types, 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size_in_dip, 17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<ui::ScaleFactor>& desired_scale_factors, 170590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconBitmapResult>* bitmap_results) { 17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(bitmap_results); 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetFaviconsFromDB(page_url, icon_types, desired_size_in_dip, 17082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) desired_scale_factors, bitmap_results); 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryBackend::GetFaviconForID( 171290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::FaviconID favicon_id, 17132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int desired_size_in_dip, 17142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ScaleFactor desired_scale_factor, 171590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconBitmapResult>* bitmap_results) { 171690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconID> favicon_ids; 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_ids.push_back(favicon_id); 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ui::ScaleFactor> desired_scale_factors; 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_scale_factors.push_back(desired_scale_factor); 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get results from DB. 17222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetFaviconBitmapResultsForBestMatch(favicon_ids, 17232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) desired_size_in_dip, 17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) desired_scale_factors, 17252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bitmap_results); 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::UpdateFaviconMappingsAndFetch( 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& page_url, 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<GURL>& icon_urls, 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int icon_types, 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size_in_dip, 17332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<ui::ScaleFactor>& desired_scale_factors, 173490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconBitmapResult>* bitmap_results) { 17352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateFaviconMappingsAndFetchImpl(&page_url, icon_urls, icon_types, 17362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) desired_size_in_dip, desired_scale_factors, 17372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bitmap_results); 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::MergeFavicon( 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& page_url, 17422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& icon_url, 174390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::IconType icon_type, 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::RefCountedMemory> bitmap_data, 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& pixel_size) { 1746b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!thumbnail_db_ || !db_) 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 174990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::FaviconID favicon_id = 175090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, NULL); 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!favicon_id) { 17532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // There is no favicon at |icon_url|, create it. 1754eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch favicon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); 17552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<FaviconBitmapIDSize> bitmap_id_sizes; 17582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->GetFaviconBitmapIDSizes(favicon_id, &bitmap_id_sizes); 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there is already a favicon bitmap of |pixel_size| at |icon_url|, 17612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // replace it. 17622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool bitmap_identical = false; 17632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool replaced_bitmap = false; 17642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) { 17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (bitmap_id_sizes[i].pixel_size == pixel_size) { 17662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsFaviconBitmapDataEqual(bitmap_id_sizes[i].bitmap_id, bitmap_data)) { 17672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->SetFaviconBitmapLastUpdateTime( 17682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bitmap_id_sizes[i].bitmap_id, base::Time::Now()); 17692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bitmap_identical = true; 17702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 17712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->SetFaviconBitmap(bitmap_id_sizes[i].bitmap_id, 17722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bitmap_data, base::Time::Now()); 17732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replaced_bitmap = true; 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create a vector of the pixel sizes of the favicon bitmaps currently at 17802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |icon_url|. 17812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<gfx::Size> favicon_sizes; 17822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) 17832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) favicon_sizes.push_back(bitmap_id_sizes[i].pixel_size); 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!replaced_bitmap && !bitmap_identical) { 17862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set the preexisting favicon bitmaps as expired as the preexisting favicon 17872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // bitmaps are not consistent with the merged in data. 17882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->SetFaviconOutOfDate(favicon_id); 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Delete an arbitrary favicon bitmap to avoid going over the limit of 17912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |kMaxFaviconBitmapsPerIconURL|. 17922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (bitmap_id_sizes.size() >= kMaxFaviconBitmapsPerIconURL) { 17932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->DeleteFaviconBitmap(bitmap_id_sizes[0].bitmap_id); 17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) favicon_sizes.erase(favicon_sizes.begin()); 17952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 17962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->AddFaviconBitmap(favicon_id, bitmap_data, base::Time::Now(), 17972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pixel_size); 17982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) favicon_sizes.push_back(pixel_size); 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A site may have changed the favicons that it uses for |page_url|. 18022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Example Scenario: 18032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // page_url = news.google.com 180458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Initial State: www.google.com/favicon.ico 16x16, 32x32 18052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // MergeFavicon(news.google.com, news.google.com/news_specific.ico, ..., 18062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ..., 16x16) 18072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 18082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Difficulties: 18092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 1. Sync requires that a call to GetFaviconsForURL() returns the 18102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |bitmap_data| passed into MergeFavicon(). 18112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - It is invalid for the 16x16 bitmap for www.google.com/favicon.ico to 18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // stay mapped to news.google.com because it would be unclear which 16x16 18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // bitmap should be returned via GetFaviconsForURL(). 18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2. www.google.com/favicon.ico may be mapped to more than just 18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // news.google.com (eg www.google.com). 18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - The 16x16 bitmap cannot be deleted from www.google.com/favicon.ico 18182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 18192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // To resolve these problems, we copy all of the favicon bitmaps previously 18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // mapped to news.google.com (|page_url|) and add them to the favicon at 18212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // news.google.com/news_specific.ico (|icon_url|). The favicon sizes for 18222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |icon_url| are set to default to indicate that |icon_url| has incomplete 18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // / incorrect data. 182458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Difficulty 1: All but news.google.com/news_specific.ico are unmapped from 18252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // news.google.com 18262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Difficulty 2: The favicon bitmaps for www.google.com/favicon.ico are not 18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // modified. 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<IconMapping> icon_mappings; 18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, &icon_mappings); 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Copy the favicon bitmaps mapped to |page_url| to the favicon at |icon_url| 18332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // till the limit of |kMaxFaviconBitmapsPerIconURL| is reached. 18342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < icon_mappings.size(); ++i) { 18352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) 18362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (icon_mappings[i].icon_url == icon_url) 18392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<FaviconBitmap> bitmaps_to_copy; 18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->GetFaviconBitmaps(icon_mappings[i].icon_id, 18432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &bitmaps_to_copy); 18442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t j = 0; j < bitmaps_to_copy.size(); ++j) { 18452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Do not add a favicon bitmap at a pixel size for which there is already 18462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // a favicon bitmap mapped to |icon_url|. The one there is more correct 18472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and having multiple equally sized favicon bitmaps for |page_url| is 18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ambiguous in terms of GetFaviconsForURL(). 18492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<gfx::Size>::iterator it = std::find(favicon_sizes.begin(), 18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) favicon_sizes.end(), bitmaps_to_copy[j].pixel_size); 18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it != favicon_sizes.end()) 18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 18532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add the favicon bitmap as expired as it is not consistent with the 18552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // merged in data. 18562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->AddFaviconBitmap(favicon_id, 18572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bitmaps_to_copy[j].bitmap_data, base::Time(), 18582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bitmaps_to_copy[j].pixel_size); 18592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) favicon_sizes.push_back(bitmaps_to_copy[j].pixel_size); 18602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) 18622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 18632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 18642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 18652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update the favicon mappings such that only |icon_url| is mapped to 18672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |page_url|. 18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool mapping_changed = false; 18692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (icon_mappings.size() != 1 || icon_mappings[0].icon_url != icon_url) { 187090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconID> favicon_ids; 18712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) favicon_ids.push_back(favicon_id); 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetFaviconMappingsForPageAndRedirects(page_url, icon_type, favicon_ids); 18732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mapping_changed = true; 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mapping_changed || !bitmap_identical) 18772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendFaviconChangedNotificationForPageAndRedirects(page_url); 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleCommit(); 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::SetFavicons( 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& page_url, 188390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::IconType icon_type, 188490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<chrome::FaviconBitmapData>& favicon_bitmap_data) { 1885b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!thumbnail_db_ || !db_) 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(ValidateSetFaviconsParams(favicon_bitmap_data)); 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Build map of FaviconBitmapData for each icon url. 189190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) typedef std::map<GURL, std::vector<chrome::FaviconBitmapData> > 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BitmapDataByIconURL; 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BitmapDataByIconURL grouped_by_icon_url; 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < favicon_bitmap_data.size(); ++i) { 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& icon_url = favicon_bitmap_data[i].icon_url; 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) grouped_by_icon_url[icon_url].push_back(favicon_bitmap_data[i]); 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Track whether the method modifies or creates any favicon bitmaps, favicons 19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // or icon mappings. 19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool data_modified = false; 19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 190390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconID> icon_ids; 19042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (BitmapDataByIconURL::const_iterator it = grouped_by_icon_url.begin(); 19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != grouped_by_icon_url.end(); ++it) { 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& icon_url = it->first; 190790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::FaviconID icon_id = 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, NULL); 19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!icon_id) { 19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(pkotwicz): Remove the favicon sizes attribute from 19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ThumbnailDatabase::AddFavicon(). 1913eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); 19142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data_modified = true; 19152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_ids.push_back(icon_id); 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!data_modified) 19192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetFaviconBitmaps(icon_id, it->second, &data_modified); 19202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 19212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetFaviconBitmaps(icon_id, it->second, NULL); 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data_modified |= 19252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_ids); 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (data_modified) { 19282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send notification to the UI as an icon mapping, favicon, or favicon 19292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // bitmap was changed by this function. 19302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendFaviconChangedNotificationForPageAndRedirects(page_url); 19312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleCommit(); 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) { 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<IconMapping> icon_mappings; 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1938b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!thumbnail_db_ || 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !thumbnail_db_->GetIconMappingsForPageURL(page_url, 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &icon_mappings)) 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m != icon_mappings.end(); ++m) { 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->SetFaviconOutOfDate(m->icon_id); 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleCommit(); 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::CloneFavicons(const GURL& old_page_url, 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& new_page_url) { 1952b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!thumbnail_db_) 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prevent cross-domain cloning. 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_page_url.GetOrigin() != new_page_url.GetOrigin()) 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->CloneIconMappings(old_page_url, new_page_url); 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleCommit(); 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::SetImportedFavicons( 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<ImportedFaviconUsage>& favicon_usage) { 1965b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_ || !thumbnail_db_) 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time now = Time::Now(); 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Track all URLs that had their favicons set or updated. 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<GURL> favicons_changed; 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < favicon_usage.size(); i++) { 197490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::FaviconID favicon_id = thumbnail_db_->GetFaviconIDForFaviconURL( 197590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) favicon_usage[i].favicon_url, chrome::FAVICON, NULL); 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!favicon_id) { 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This favicon doesn't exist yet, so we create it using the given data. 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(pkotwicz): Pass in real pixel size. 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_id = thumbnail_db_->AddFavicon( 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_usage[i].favicon_url, 198190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::FAVICON, 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new base::RefCountedBytes(favicon_usage[i].png_data), 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now, 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size()); 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save the mapping from all the URLs to the favicon. 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkService* bookmark_service = GetBookmarkService(); 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<GURL>::const_iterator url = favicon_usage[i].urls.begin(); 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url != favicon_usage[i].urls.end(); ++url) { 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRow url_row; 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->GetRowForURL(*url, &url_row)) { 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the URL is present as a bookmark, add the url in history to 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // save the favicon mapping. This will match with what history db does 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for regular bookmarked URLs with favicons - when history db is 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cleaned, we keep an entry in the db with 0 visits as long as that 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // url is bookmarked. 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_service && bookmark_service_->IsBookmarked(*url)) { 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRow url_info(*url); 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_visit_count(0); 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_typed_count(0); 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_last_visit(base::Time()); 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_info.set_hidden(false); 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->AddURL(url_info); 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->AddIconMapping(*url, favicon_id); 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicons_changed.insert(*url); 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 200990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!thumbnail_db_->GetIconMappingsForPageURL( 201090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *url, chrome::FAVICON, NULL)) { 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URL is present in history, update the favicon *only* if it is not 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // set already. 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->AddIconMapping(*url, favicon_id); 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicons_changed.insert(*url); 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!favicons_changed.empty()) { 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send the notification about the changed favicon URLs. 202290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FaviconChangedDetails* changed_details = new FaviconChangedDetails; 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) changed_details->urls.swap(favicons_changed); 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) changed_details); 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL* page_url, 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<GURL>& icon_urls, 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int icon_types, 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size_in_dip, 20342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<ui::ScaleFactor>& desired_scale_factors, 203590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconBitmapResult>* bitmap_results) { 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |page_url| is specified, |icon_types| must be either a single icon 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // type or icon types which are equivalent. 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!page_url || 203990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) icon_types == chrome::FAVICON || 204090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) icon_types == chrome::TOUCH_ICON || 204190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) icon_types == chrome::TOUCH_PRECOMPOSED_ICON || 204290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) icon_types == (chrome::TOUCH_ICON | chrome::TOUCH_PRECOMPOSED_ICON)); 20432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bitmap_results->clear(); 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!thumbnail_db_) { 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 204990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconID> favicon_ids; 20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The icon type for which the mappings will the updated and data will be 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returned. 205390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::IconType selected_icon_type = chrome::INVALID_ICON; 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < icon_urls.size(); ++i) { 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& icon_url = icon_urls[i]; 205790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::IconType icon_type_out; 205890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const chrome::FaviconID favicon_id = 205990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thumbnail_db_->GetFaviconIDForFaviconURL( 206090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) icon_url, icon_types, &icon_type_out); 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (favicon_id) { 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return and update icon mappings only for the largest icon type. As 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |icon_urls| is not sorted in terms of icon type, clear |favicon_ids| 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if an |icon_url| with a larger icon type is found. 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon_type_out > selected_icon_type) { 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_icon_type = icon_type_out; 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_ids.clear(); 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon_type_out == selected_icon_type) 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_ids.push_back(favicon_id); 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (page_url && !favicon_ids.empty()) { 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool mappings_updated = 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetFaviconMappingsForPageAndRedirects(*page_url, selected_icon_type, 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_ids); 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mappings_updated) { 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendFaviconChangedNotificationForPageAndRedirects(*page_url); 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleCommit(); 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetFaviconBitmapResultsForBestMatch(favicon_ids, desired_size_in_dip, 20862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) desired_scale_factors, bitmap_results); 20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::SetFaviconBitmaps( 209090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::FaviconID icon_id, 209190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<chrome::FaviconBitmapData>& favicon_bitmap_data, 20922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* favicon_bitmaps_changed) { 20932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (favicon_bitmaps_changed) 20942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *favicon_bitmaps_changed = false; 20952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<FaviconBitmapIDSize> bitmap_id_sizes; 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->GetFaviconBitmapIDSizes(icon_id, &bitmap_id_sizes); 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 209990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconBitmapData> to_add = favicon_bitmap_data; 21002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) { 21022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Size& pixel_size = bitmap_id_sizes[i].pixel_size; 210390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconBitmapData>::iterator match_it = to_add.end(); 210490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (std::vector<chrome::FaviconBitmapData>::iterator it = to_add.begin(); 21052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != to_add.end(); ++it) { 21062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->pixel_size == pixel_size) { 21072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) match_it = it; 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconBitmapID bitmap_id = bitmap_id_sizes[i].bitmap_id; 21132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (match_it == to_add.end()) { 21142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->DeleteFaviconBitmap(bitmap_id); 21152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (favicon_bitmaps_changed) 21172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *favicon_bitmaps_changed = true; 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 21192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (favicon_bitmaps_changed && 21202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !*favicon_bitmaps_changed && 21212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IsFaviconBitmapDataEqual(bitmap_id, match_it->bitmap_data)) { 21222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->SetFaviconBitmapLastUpdateTime( 21232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bitmap_id, base::Time::Now()); 21242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 21252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->SetFaviconBitmap(bitmap_id, match_it->bitmap_data, 21262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time::Now()); 21272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (favicon_bitmaps_changed) 21292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *favicon_bitmaps_changed = true; 21302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 21312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) to_add.erase(match_it); 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < to_add.size(); ++i) { 21362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->AddFaviconBitmap(icon_id, to_add[i].bitmap_data, 21372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time::Now(), to_add[i].pixel_size); 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (favicon_bitmaps_changed) 21402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *favicon_bitmaps_changed = true; 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HistoryBackend::ValidateSetFaviconsParams( 214590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<chrome::FaviconBitmapData>& favicon_bitmap_data) const { 21462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::map<GURL, size_t> BitmapsPerIconURL; 21472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BitmapsPerIconURL num_bitmaps_per_icon_url; 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < favicon_bitmap_data.size(); ++i) { 2149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!favicon_bitmap_data[i].bitmap_data.get()) 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& icon_url = favicon_bitmap_data[i].icon_url; 21532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!num_bitmaps_per_icon_url.count(icon_url)) 21542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_bitmaps_per_icon_url[icon_url] = 1u; 21552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 21562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++num_bitmaps_per_icon_url[icon_url]; 21572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 21582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (num_bitmaps_per_icon_url.size() > kMaxFaviconsPerPage) 21602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (BitmapsPerIconURL::const_iterator it = num_bitmaps_per_icon_url.begin(); 21632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != num_bitmaps_per_icon_url.end(); ++it) { 21642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->second > kMaxFaviconBitmapsPerIconURL) 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HistoryBackend::IsFaviconBitmapDataEqual( 21712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconBitmapID bitmap_id, 21722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const scoped_refptr<base::RefCountedMemory>& new_bitmap_data) { 2173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!new_bitmap_data.get()) 21742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::RefCountedMemory> original_bitmap_data; 21772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thumbnail_db_->GetFaviconBitmap(bitmap_id, 21782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, 21792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &original_bitmap_data, 21802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL); 21812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new_bitmap_data->Equals(original_bitmap_data); 21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::GetFaviconsFromDB( 21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& page_url, 21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int icon_types, 21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size_in_dip, 21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<ui::ScaleFactor>& desired_scale_factors, 218990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconBitmapResult>* favicon_bitmap_results) { 21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(favicon_bitmap_results); 21912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) favicon_bitmap_results->clear(); 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2193b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_ || !thumbnail_db_) 21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Time the query. 21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks beginning_time = TimeTicks::Now(); 21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get FaviconIDs for |page_url| and one of |icon_types|. 22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<IconMapping> icon_mappings; 22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_types, 22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &icon_mappings); 220390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconID> favicon_ids; 22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < icon_mappings.size(); ++i) 22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_ids.push_back(icon_mappings[i].icon_id); 22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Populate |favicon_bitmap_results| and |icon_url_sizes|. 22082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool success = GetFaviconBitmapResultsForBestMatch(favicon_ids, 22092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) desired_size_in_dip, desired_scale_factors, favicon_bitmap_results); 22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name 22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks::Now() - beginning_time); 22122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return success && !favicon_bitmap_results->empty(); 22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::GetFaviconBitmapResultsForBestMatch( 221690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<chrome::FaviconID>& candidate_favicon_ids, 22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int desired_size_in_dip, 22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<ui::ScaleFactor>& desired_scale_factors, 221990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconBitmapResult>* favicon_bitmap_results) { 22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_bitmap_results->clear(); 22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (candidate_favicon_ids.empty()) 22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the FaviconID and the FaviconBitmapIDs which best match 22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |desired_size_in_dip| and |desired_scale_factors|. 22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(pkotwicz): Select bitmap results from multiple favicons once 22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // content::FaviconStatus supports multiple icon URLs. 222990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::FaviconID best_favicon_id = 0; 22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<FaviconBitmapID> best_bitmap_ids; 22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float highest_score = kSelectFaviconFramesInvalidScore; 22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < candidate_favicon_ids.size(); ++i) { 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<FaviconBitmapIDSize> bitmap_id_sizes; 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->GetFaviconBitmapIDSizes(candidate_favicon_ids[i], 22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &bitmap_id_sizes); 22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Build vector of gfx::Size from |bitmap_id_sizes|. 22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<gfx::Size> sizes; 22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < bitmap_id_sizes.size(); ++j) 22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizes.push_back(bitmap_id_sizes[j].pixel_size); 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<size_t> candidate_bitmap_indices; 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float score = 0; 22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectFaviconFrameIndices(sizes, 22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_scale_factors, 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_size_in_dip, 22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &candidate_bitmap_indices, 22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &score); 22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (score > highest_score) { 22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) highest_score = score; 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) best_favicon_id = candidate_favicon_ids[i], 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) best_bitmap_ids.clear(); 22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < candidate_bitmap_indices.size(); ++j) { 22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t candidate_index = candidate_bitmap_indices[j]; 22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) best_bitmap_ids.push_back( 22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap_id_sizes[candidate_index].bitmap_id); 22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct FaviconBitmapResults from |best_favicon_id| and 22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |best_bitmap_ids|. 22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL icon_url; 226490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::IconType icon_type; 22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!thumbnail_db_->GetFaviconHeader(best_favicon_id, &icon_url, 2266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &icon_type)) { 22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < best_bitmap_ids.size(); ++i) { 22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time last_updated; 227290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::FaviconBitmapResult bitmap_result; 22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap_result.icon_url = icon_url; 22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap_result.icon_type = icon_type; 22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!thumbnail_db_->GetFaviconBitmap(best_bitmap_ids[i], 22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &last_updated, 22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &bitmap_result.bitmap_data, 22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &bitmap_result.pixel_size)) { 22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap_result.expired = (Time::Now() - last_updated) > 22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta::FromDays(kFaviconRefetchDays); 22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bitmap_result.is_valid()) 22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_bitmap_results->push_back(bitmap_result); 22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::SetFaviconMappingsForPageAndRedirects( 22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& page_url, 229290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::IconType icon_type, 229390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<chrome::FaviconID>& icon_ids) { 2294b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!thumbnail_db_) 22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find all the pages whose favicons we should set, we want to set it for 22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // all the pages in the redirect chain if it redirected. 22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::RedirectList redirects; 23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetCachedRecentRedirects(page_url, &redirects); 23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool mappings_changed = false; 23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save page <-> favicon associations. 23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (history::RedirectList::const_iterator i(redirects.begin()); 23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != redirects.end(); ++i) { 23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mappings_changed |= SetFaviconMappingsForPage(*i, icon_type, icon_ids); 23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mappings_changed; 23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::SetFaviconMappingsForPage( 23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& page_url, 231490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::IconType icon_type, 231590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<chrome::FaviconID>& icon_ids) { 23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(icon_ids.size(), kMaxFaviconsPerPage); 23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool mappings_changed = false; 23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Two icon types are considered 'equivalent' if one of the icon types is 23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TOUCH_ICON and the other is TOUCH_PRECOMPOSED_ICON. 23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets the icon mappings from |page_url| for |icon_type| to the favicons 23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with |icon_ids|. Mappings for |page_url| to favicons of type |icon_type| 23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // whose FaviconID is not in |icon_ids| are removed. All icon mappings for 23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |page_url| to favicons of a type equivalent to |icon_type| are removed. 23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove any favicons which are orphaned as a result of the removal of the 23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // icon mappings. 23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 232990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconID> unmapped_icon_ids = icon_ids; 23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<IconMapping> icon_mappings; 23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings); 23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); 23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m != icon_mappings.end(); ++m) { 233690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<chrome::FaviconID>::iterator icon_id_it = std::find( 23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unmapped_icon_ids.begin(), unmapped_icon_ids.end(), m->icon_id); 23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the icon mapping already exists, avoid removing it and adding it back. 23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon_id_it != unmapped_icon_ids.end()) { 23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unmapped_icon_ids.erase(icon_id_it); 23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 234590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if ((icon_type == chrome::TOUCH_ICON && 234690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) m->icon_type == chrome::TOUCH_PRECOMPOSED_ICON) || 234790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (icon_type == chrome::TOUCH_PRECOMPOSED_ICON && 234890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) m->icon_type == chrome::TOUCH_ICON) || (icon_type == m->icon_type)) { 23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->DeleteIconMapping(m->mapping_id); 23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Removing the icon mapping may have orphaned the associated favicon so 23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we must recheck it. This is not super fast, but this case will get 23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // triggered rarely, since normally a page will always map to the same 23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // favicon IDs. It will mostly happen for favicons we import. 23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!thumbnail_db_->HasMappingFor(m->icon_id)) 23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->DeleteFavicon(m->icon_id); 23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mappings_changed = true; 23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < unmapped_icon_ids.size(); ++i) { 23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->AddIconMapping(page_url, unmapped_icon_ids[i]); 23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mappings_changed = true; 23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mappings_changed; 23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::GetCachedRecentRedirects( 23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& page_url, 23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::RedirectList* redirect_list) { 23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RedirectCache::iterator iter = recent_redirects_.Get(page_url); 23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter != recent_redirects_.end()) { 23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *redirect_list = iter->second; 23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The redirect chain should have the destination URL as the last item. 23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!redirect_list->empty()); 23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(redirect_list->back() == page_url); 23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No known redirects, construct mock redirect chain containing |page_url|. 23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) redirect_list->push_back(page_url); 23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::SendFaviconChangedNotificationForPageAndRedirects( 23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& page_url) { 23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::RedirectList redirect_list; 23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetCachedRecentRedirects(page_url, &redirect_list); 23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 238990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FaviconChangedDetails* changed_details = new FaviconChangedDetails; 23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < redirect_list.size(); ++i) 23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) changed_details->urls.insert(redirect_list[i]); 23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, 23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) changed_details); 23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::Commit() { 2398b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that a commit may not actually have been scheduled if a caller 24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // explicitly calls this instead of using ScheduleCommit. Likewise, we 24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // may reset the flag written by a pending commit. But this is OK! It 24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will merely cause extra commits (which is kind of the idea). We 24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // could optimize more for this case (we may get two extra commits in 24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // some cases) but it hasn't been important yet. 24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelScheduledCommit(); 24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->CommitTransaction(); 24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(db_->transaction_nesting() == 0) << "Somebody left a transaction open"; 24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->BeginTransaction(); 24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2413b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (thumbnail_db_) { 24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->CommitTransaction(); 24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thumbnail_db_->transaction_nesting() == 0) << 24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Somebody left a transaction open"; 24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->BeginTransaction(); 24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2420b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (archived_db_) { 24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archived_db_->CommitTransaction(); 24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archived_db_->BeginTransaction(); 24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::ScheduleCommit() { 2427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (scheduled_commit_.get()) 24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduled_commit_ = new CommitLaterTask(this); 243090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CommitLaterTask::RunCommit, scheduled_commit_.get()), 24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(kCommitIntervalSeconds)); 24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::CancelScheduledCommit() { 2437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (scheduled_commit_.get()) { 24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduled_commit_->Cancel(); 24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduled_commit_ = NULL; 24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::ProcessDBTaskImpl() { 2444b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) { 24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // db went away, release all the refs. 24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseDBTasks(); 24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove any canceled tasks. 24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!db_task_requests_.empty() && db_task_requests_.front()->canceled()) { 24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_task_requests_.front()->Release(); 24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_task_requests_.pop_front(); 24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (db_task_requests_.empty()) 24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run the first task. 24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryDBTaskRequest* request = db_task_requests_.front(); 24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_task_requests_.pop_front(); 24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->value->RunOnDBThread(this, db_.get())) { 24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The task is done. Notify the callback. 24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->ForwardResult(); 24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We AddRef'd the request before adding, need to release it now. 24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->Release(); 24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tasks wants to run some more. Schedule it at the end of current tasks. 24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_task_requests_.push_back(request); 24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And process it after an invoke later. 247090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&HistoryBackend::ProcessDBTaskImpl, this)); 24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::ReleaseDBTasks() { 24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::list<HistoryDBTaskRequest*>::iterator i = 24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_task_requests_.begin(); i != db_task_requests_.end(); ++i) { 24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i)->Release(); 24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_task_requests_.clear(); 24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generic operations 24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::DeleteURLs(const std::vector<GURL>& urls) { 24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expirer_.DeleteURLs(urls); 24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetStartDate(&first_recorded_time_); 24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Force a commit, if the user is deleting something for privacy reasons, we 24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // want to get it on disk ASAP. 24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Commit(); 24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::DeleteURL(const GURL& url) { 24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expirer_.DeleteURL(url); 25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetStartDate(&first_recorded_time_); 25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Force a commit, if the user is deleting something for privacy reasons, we 25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // want to get it on disk ASAP. 25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Commit(); 25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::ExpireHistoryBetween( 25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::set<GURL>& restrict_urls, 25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time begin_time, 25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time end_time) { 251158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!db_) 251258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 251458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (begin_time.is_null() && (end_time.is_null() || end_time.is_max()) && 251558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) restrict_urls.empty()) { 251658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Special case deleting all history so it can be faster and to reduce the 251758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // possibility of an information leak. 251858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DeleteAllHistory(); 251958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 252058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Clearing parts of history, have the expirer do the depend 252158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) expirer_.ExpireHistoryBetween(restrict_urls, begin_time, end_time); 252258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 252358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Force a commit, if the user is deleting something for privacy reasons, 252458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // we want to get it on disk ASAP. 252558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Commit(); 25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (begin_time <= first_recorded_time_) 25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetStartDate(&first_recorded_time_); 25302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 25312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryBackend::ExpireHistoryForTimes( 25332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::set<base::Time>& times, 25342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time begin_time, base::Time end_time) { 2535b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (times.empty() || !db_) 25362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 25372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(*times.begin() >= begin_time) 25392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "Min time is before begin time: " 25402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << times.begin()->ToJsTime() << " v.s. " << begin_time.ToJsTime(); 25412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(*times.rbegin() < end_time) 25422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "Max time is after end time: " 25432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << times.rbegin()->ToJsTime() << " v.s. " << end_time.ToJsTime(); 25442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) history::QueryOptions options; 25462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) options.begin_time = begin_time; 25472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) options.end_time = end_time; 25482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) options.duplicate_policy = QueryOptions::KEEP_ALL_DUPLICATES; 25492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QueryResults results; 25502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QueryHistoryBasic(db_.get(), db_.get(), options, &results); 25512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 1st pass: find URLs that are visited at one of |times|. 25532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<GURL> urls; 25542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < results.size(); ++i) { 25552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (times.count(results[i].visit_time()) > 0) 25562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) urls.insert(results[i].url()); 25572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 25582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (urls.empty()) 25592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 25602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2nd pass: collect all visit times of those URLs. 25622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::Time> times_to_expire; 25632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < results.size(); ++i) { 25642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (urls.count(results[i].url())) 25652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) times_to_expire.push_back(results[i].visit_time()); 25662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 25672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Put the times in reverse chronological order and remove 25692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // duplicates (for expirer_.ExpireHistoryForTimes()). 25702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::sort(times_to_expire.begin(), times_to_expire.end(), 25712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::greater<base::Time>()); 25722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) times_to_expire.erase( 25732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::unique(times_to_expire.begin(), times_to_expire.end()), 25742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) times_to_expire.end()); 25752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Expires by times and commit. 25772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!times_to_expire.empty()); 25782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expirer_.ExpireHistoryForTimes(times_to_expire); 25792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Commit(); 25802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(times_to_expire.back() >= first_recorded_time_); 25822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update |first_recorded_time_| if we expired it. 25832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (times_to_expire.back() == first_recorded_time_) 25842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) db_->GetStartDate(&first_recorded_time_); 25852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryBackend::ExpireHistory( 25882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<history::ExpireHistoryArgs>& expire_list) { 2589b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (db_) { 25902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool update_first_recorded_time = false; 25912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::vector<history::ExpireHistoryArgs>::const_iterator it = 25932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expire_list.begin(); it != expire_list.end(); ++it) { 25942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expirer_.ExpireHistoryBetween(it->urls, it->begin_time, it->end_time); 25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->begin_time < first_recorded_time_) 25972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) update_first_recorded_time = true; 25982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 25992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Commit(); 26002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 26012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update |first_recorded_time_| if any deletion might have affected it. 26022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (update_first_recorded_time) 26032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) db_->GetStartDate(&first_recorded_time_); 26042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::URLsNoLongerBookmarked(const std::set<GURL>& urls) { 2608b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<GURL>::const_iterator i = urls.begin(); i != urls.end(); ++i) { 26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRow url_row; 26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->GetRowForURL(*i, &url_row)) 26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // The URL isn't in the db; nothing to do. 26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisitVector visits; 26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetVisitsForURL(url_row.id(), &visits); 26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visits.empty()) 26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expirer_.DeleteURL(*i); // There are no more visits; nuke the URL. 26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HistoryBackend::DatabaseErrorCallback(int error, sql::Statement* stmt) { 26257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!scheduled_kill_db_ && sql::IsErrorCatastrophic(error)) { 26267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scheduled_kill_db_ = true; 26277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Don't just do the close/delete here, as we are being called by |db| and 26287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // that seems dangerous. 26297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // TODO(shess): Consider changing KillHistoryDatabase() to use 26307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // RazeAndClose(). Then it can be cleared immediately. 26317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::MessageLoop::current()->PostTask( 26327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) FROM_HERE, 26337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&HistoryBackend::KillHistoryDatabase, this)); 26347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 26357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 26367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::KillHistoryDatabase() { 26387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scheduled_kill_db_ = false; 2639b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!db_) 26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Rollback transaction because Raze() cannot be called from within a 26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // transaction. 26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->RollbackTransaction(); 26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = db_->Raze(); 26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("History.KillHistoryDatabaseResult", success); 26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Release AndroidProviderBackend before other objects. 26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) android_provider_backend_.reset(); 26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The expirer keeps tabs on the active databases. Tell it about the 26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // databases which will be closed. 2655bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch expirer_.SetDatabases(NULL, NULL, NULL); 26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reopen a new transaction for |db_| for the sake of CloseAllDatabases(). 26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->BeginTransaction(); 26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseAllDatabases(); 26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::ProcessDBTask( 26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<HistoryDBTaskRequest> request) { 2664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(request.get()); 26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->canceled()) 26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool task_scheduled = !db_task_requests_.empty(); 26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure we up the refcount of the request. ProcessDBTaskImpl will 26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // release when done with the task. 26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->AddRef(); 26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_task_requests_.push_back(request.get()); 26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!task_scheduled) { 26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No other tasks are scheduled. Process request now. 26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessDBTaskImpl(); 26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::BroadcastNotifications( 26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type, 26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryDetails* details_deleted) { 26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |delegate_| may be NULL if |this| is in the process of closing (closed by 2683b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // HistoryService -> HistoryBackend::Closing(). 2684b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (delegate_) 26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->BroadcastNotifications(type, details_deleted); 26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete details_deleted; 26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2690b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void HistoryBackend::NotifySyncURLsDeleted(bool all_history, 2691b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bool archived, 2692b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) URLRows* rows) { 2693b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (typed_url_syncable_service_.get()) 2694b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) typed_url_syncable_service_->OnUrlsDeleted(all_history, archived, rows); 2695b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 2696b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Deleting -------------------------------------------------------------------- 26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::DeleteAllHistory() { 27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Our approach to deleting all history is: 27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1. Copy the bookmarks and their dependencies to new tables with temporary 27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // names. 27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2. Delete the original tables. Since tables can not share pages, we know 27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that any data we don't want to keep is now in an unused page. 27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3. Renaming the temporary tables to match the original. 27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 4. Vacuuming the database to delete the unused pages. 27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we are likely to have very few bookmarks and their dependencies 27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // compared to all history, this is also much faster than just deleting from 27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the original tables directly. 27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the bookmarked URLs. 27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<BookmarkService::URLAndTitle> starred_urls; 27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkService* bookmark_service = GetBookmarkService(); 27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_service) 27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_service_->GetBookmarks(&starred_urls); 27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRows kept_urls; 27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < starred_urls.size(); i++) { 27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRow row; 27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->GetRowForURL(starred_urls[i].url, &row)) 27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the last visit time so when we write these rows they are "clean." 27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row.set_last_visit(Time()); 27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row.set_visit_count(0); 27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row.set_typed_count(0); 27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kept_urls.push_back(row); 27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear thumbnail and favicon history. The favicons for the given URLs will 27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be kept. 27333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!ClearAllThumbnailHistory(kept_urls)) { 27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Thumbnail history could not be cleared"; 27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We continue in this error case. If the user wants to delete their 27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // history, we should delete as much as we can. 27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 273958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // ClearAllMainHistory will change the IDs of the URLs in kept_urls. 274058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Therefore, we clear the list afterwards to make sure nobody uses this 274158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // invalid data. 27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ClearAllMainHistory(kept_urls)) 27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Main history could not be cleared"; 27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kept_urls.clear(); 27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2746bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Delete archived history. 2747b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (archived_db_) { 27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close the database and delete the file. 27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archived_db_.reset(); 27502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath archived_file_name = GetArchivedFileName(); 2751eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sql::Connection::Delete(archived_file_name); 27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now re-initialize the database (which may fail). 27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archived_db_.reset(new ArchivedDatabase()); 27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!archived_db_->Init(archived_file_name)) { 27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Could not initialize the archived database."; 27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archived_db_.reset(); 27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open our long-running transaction on this database. 27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archived_db_->BeginTransaction(); 27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetStartDate(&first_recorded_time_); 27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 276658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Send out the notification that history is cleared. The in-memory database 27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will pick this up and clear itself. 27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLsDeletedDetails* details = new URLsDeletedDetails; 27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details->all_history = true; 2770b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) NotifySyncURLsDeleted(true, false, NULL); 27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BroadcastNotifications(chrome::NOTIFICATION_HISTORY_URLS_DELETED, details); 27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool HistoryBackend::ClearAllThumbnailHistory(const URLRows& kept_urls) { 2775b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!thumbnail_db_) { 27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When we have no reference to the thumbnail database, maybe there was an 27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // error opening it. In this case, we just try to blow it away to try to 27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fix the error if it exists. This may fail, in which case either the 27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // file doesn't exist or there's no more we can do. 27803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sql::Connection::Delete(GetFaviconsFileName()); 27813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 27823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Older version of the database. 2783eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sql::Connection::Delete(GetThumbnailFileName()); 27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Urls to retain mappings for. 27883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::vector<GURL> urls_to_keep; 27893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (URLRows::const_iterator i = kept_urls.begin(); 27903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) i != kept_urls.end(); ++i) { 27913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) urls_to_keep.push_back(i->url()); 27923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Isolate from any long-running transaction. 27953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) thumbnail_db_->CommitTransaction(); 27963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) thumbnail_db_->BeginTransaction(); 27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(shess): If this fails, perhaps the database should be razed 27993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // or deleted. 28003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!thumbnail_db_->RetainDataForPageUrls(urls_to_keep)) { 28013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) thumbnail_db_->RollbackTransaction(); 28023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) thumbnail_db_->BeginTransaction(); 28033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO (michaelbai): Add the unit test once AndroidProviderBackend is 28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // avaliable in HistoryBackend. 28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->ClearAndroidURLRows(); 28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Vacuum to remove all the pages associated with the dropped tables. There 28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // must be no transaction open on the table when we do this. We assume that 28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // our long-running transaction is open, so we complete it and start it again. 28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(thumbnail_db_->transaction_nesting() == 1); 28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->CommitTransaction(); 28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->Vacuum(); 28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thumbnail_db_->BeginTransaction(); 28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryBackend::ClearAllMainHistory(const URLRows& kept_urls) { 28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the duplicate URL table. We will copy the kept URLs into this. 28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->CreateTemporaryURLTable()) 28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 282758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Insert the URLs into the temporary table. 28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (URLRows::const_iterator i = kept_urls.begin(); i != kept_urls.end(); 28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i) { 283058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) db_->AddTemporaryURL(*i); 28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Replace the original URL table with the temporary one. 28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->CommitTemporaryURLTable()) 28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the old tables and recreate them empty. 28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->RecreateAllTablesButURL(); 28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Vacuum to reclaim the space from the dropped tables. This must be done 28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when there is no transaction open, and we assume that our long-running 28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // transaction is currently open. 28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->CommitTransaction(); 28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->Vacuum(); 28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->BeginTransaction(); 28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->GetStartDate(&first_recorded_time_); 28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 28495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BookmarkService* HistoryBackend::GetBookmarkService() { 28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_service_) 28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_service_->BlockTillLoaded(); 28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bookmark_service_; 28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryBackend::NotifyVisitObservers(const VisitRow& visit) { 28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BriefVisitInfo info; 28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.url_id = visit.url_id; 28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.time = visit.visit_time; 28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.transition = visit.transition; 28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we don't have a delegate yet during setup or shutdown, we will drop 28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // these notifications. 2864b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (delegate_) 28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->NotifyVisitDBObserversOnAddVisit(info); 28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2868eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID) 2869eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid HistoryBackend::PopulateMostVisitedURLMap() { 2870eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MostVisitedURLList most_visited_urls; 2871eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch QueryMostVisitedURLsImpl(kPageVisitStatsMaxTopSites, kSegmentDataRetention, 2872eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &most_visited_urls); 2873eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2874eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK_LE(most_visited_urls.size(), kPageVisitStatsMaxTopSites); 2875eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < most_visited_urls.size(); ++i) { 2876eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch most_visited_urls_map_[most_visited_urls[i].url] = i; 2877eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t j = 0; j < most_visited_urls[i].redirects.size(); ++j) 2878eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch most_visited_urls_map_[most_visited_urls[i].redirects[j]] = i; 2879eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 2880eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2881eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2882eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid HistoryBackend::RecordTopPageVisitStats(const GURL& url) { 2883eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int rank = kPageVisitStatsMaxTopSites; 2884eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::map<GURL, int>::const_iterator it = most_visited_urls_map_.find(url); 2885eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (it != most_visited_urls_map_.end()) 2886eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rank = (*it).second; 2887eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UMA_HISTOGRAM_ENUMERATION("History.TopSitesVisitsByRank", 2888eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rank, kPageVisitStatsMaxTopSites + 1); 2889eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2890eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 2891eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace history 2893