1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_HISTORY_HISTORY_BACKEND_H_ 6 #define CHROME_BROWSER_HISTORY_HISTORY_BACKEND_H_ 7 8 #include <set> 9 #include <string> 10 #include <utility> 11 #include <vector> 12 13 #include "base/containers/mru_cache.h" 14 #include "base/files/file_path.h" 15 #include "base/gtest_prod_util.h" 16 #include "base/memory/memory_pressure_listener.h" 17 #include "base/memory/scoped_ptr.h" 18 #include "base/single_thread_task_runner.h" 19 #include "base/task/cancelable_task_tracker.h" 20 #include "chrome/browser/history/expire_history_backend.h" 21 #include "chrome/browser/history/history_database.h" 22 #include "chrome/browser/history/thumbnail_database.h" 23 #include "chrome/browser/history/visit_tracker.h" 24 #include "components/history/core/browser/history_types.h" 25 #include "components/history/core/browser/keyword_id.h" 26 #include "components/visitedlink/browser/visitedlink_delegate.h" 27 #include "sql/init_status.h" 28 29 #if defined(OS_ANDROID) 30 #include "components/history/core/android/android_history_types.h" 31 #endif 32 33 class HistoryURLProvider; 34 struct HistoryURLProviderParams; 35 struct ImportedFaviconUsage; 36 class SkBitmap; 37 class TestingProfile; 38 struct ThumbnailScore; 39 40 namespace base { 41 class MessageLoop; 42 class SingleThreadTaskRunner; 43 } 44 45 namespace history { 46 #if defined(OS_ANDROID) 47 class AndroidProviderBackend; 48 #endif 49 50 class CommitLaterTask; 51 struct DownloadRow; 52 class HistoryClient; 53 class HistoryDBTask; 54 class InMemoryHistoryBackend; 55 class TypedUrlSyncableService; 56 class VisitFilter; 57 58 // The maximum number of icons URLs per page which can be stored in the 59 // thumbnail database. 60 static const size_t kMaxFaviconsPerPage = 8; 61 62 // The maximum number of bitmaps for a single icon URL which can be stored in 63 // the thumbnail database. 64 static const size_t kMaxFaviconBitmapsPerIconURL = 8; 65 66 // Keeps track of a queued HistoryDBTask. This class lives solely on the 67 // DB thread. 68 class QueuedHistoryDBTask { 69 public: 70 QueuedHistoryDBTask( 71 scoped_ptr<HistoryDBTask> task, 72 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, 73 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled); 74 ~QueuedHistoryDBTask(); 75 76 bool is_canceled(); 77 bool Run(HistoryBackend* backend, HistoryDatabase* db); 78 void DoneRun(); 79 80 private: 81 scoped_ptr<HistoryDBTask> task_; 82 scoped_refptr<base::SingleThreadTaskRunner> origin_loop_; 83 base::CancelableTaskTracker::IsCanceledCallback is_canceled_; 84 85 DISALLOW_COPY_AND_ASSIGN(QueuedHistoryDBTask); 86 }; 87 88 // *See the .cc file for more information on the design.* 89 // 90 // Internal history implementation which does most of the work of the history 91 // system. This runs on a background thread (to not block the browser when we 92 // do expensive operations) and is NOT threadsafe, so it must only be called 93 // from message handlers on the background thread. Invoking on another thread 94 // requires threadsafe refcounting. 95 // 96 // Most functions here are just the implementations of the corresponding 97 // functions in the history service. These functions are not documented 98 // here, see the history service for behavior. 99 class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>, 100 public BroadcastNotificationDelegate { 101 public: 102 // Interface implemented by the owner of the HistoryBackend object. Normally, 103 // the history service implements this to send stuff back to the main thread. 104 // The unit tests can provide a different implementation if they don't have 105 // a history service object. 106 class Delegate { 107 public: 108 virtual ~Delegate() {} 109 110 // Called when the database cannot be read correctly for some reason. 111 virtual void NotifyProfileError(sql::InitStatus init_status) = 0; 112 113 // Sets the in-memory history backend. The in-memory backend is created by 114 // the main backend. For non-unit tests, this happens on the background 115 // thread. It is to be used on the main thread, so this would transfer 116 // it to the history service. Unit tests can override this behavior. 117 // 118 // This function is NOT guaranteed to be called. If there is an error, 119 // there may be no in-memory database. 120 virtual void SetInMemoryBackend( 121 scoped_ptr<InMemoryHistoryBackend> backend) = 0; 122 123 // Notify HistoryService that some URLs favicon changed that will forward 124 // the events to the FaviconChangedObservers in the correct thread. 125 virtual void NotifyFaviconChanged(const std::set<GURL>& urls) = 0; 126 127 // Broadcasts the specified notification to the notification service. 128 // This is implemented here because notifications must only be sent from 129 // the main thread. This is the only method that doesn't identify the 130 // caller because notifications must always be sent. 131 virtual void BroadcastNotifications(int type, 132 scoped_ptr<HistoryDetails> details) = 0; 133 134 // Invoked when the backend has finished loading the db. 135 virtual void DBLoaded() = 0; 136 137 virtual void NotifyVisitDBObserversOnAddVisit( 138 const history::BriefVisitInfo& info) = 0; 139 }; 140 141 // Init must be called to complete object creation. This object can be 142 // constructed on any thread, but all other functions including Init() must 143 // be called on the history thread. 144 // 145 // |history_dir| is the directory where the history files will be placed. 146 // See the definition of BroadcastNotificationsCallback above. This function 147 // takes ownership of the callback pointer. 148 // 149 // |history_client| is used to determine bookmarked URLs when deleting and 150 // may be NULL. 151 // 152 // This constructor is fast and does no I/O, so can be called at any time. 153 HistoryBackend(const base::FilePath& history_dir, 154 Delegate* delegate, 155 HistoryClient* history_client); 156 157 // Must be called after creation but before any objects are created. If this 158 // fails, all other functions will fail as well. (Since this runs on another 159 // thread, we don't bother returning failure.) 160 // 161 // |languages| gives a list of language encodings with which the history 162 // URLs and omnibox searches are interpreted. 163 // |force_fail| can be set during unittests to unconditionally fail to init. 164 void Init(const std::string& languages, bool force_fail); 165 166 // Notification that the history system is shutting down. This will break 167 // the refs owned by the delegate and any pending transaction so it will 168 // actually be deleted. 169 void Closing(); 170 171 void ClearCachedDataForContextID(ContextID context_id); 172 173 // Navigation ---------------------------------------------------------------- 174 175 // |request.time| must be unique with high probability. 176 void AddPage(const HistoryAddPageArgs& request); 177 virtual void SetPageTitle(const GURL& url, const base::string16& title); 178 void AddPageNoVisitForBookmark(const GURL& url, const base::string16& title); 179 void UpdateWithPageEndTime(ContextID context_id, 180 int32 page_id, 181 const GURL& url, 182 base::Time end_ts); 183 184 // Querying ------------------------------------------------------------------ 185 186 // Run the |callback| on the History thread. 187 // history_url_provider.h has the temporal ordering for 188 // the call sequence. 189 // |callback| should handle the NULL database case. 190 void ScheduleAutocomplete(const base::Callback< 191 void(history::HistoryBackend*, history::URLDatabase*)>& callback); 192 193 void IterateURLs( 194 const scoped_refptr<visitedlink::VisitedLinkDelegate::URLEnumerator>& 195 enumerator); 196 void QueryURL(const GURL& url, 197 bool want_visits, 198 QueryURLResult* query_url_result); 199 void QueryHistory(const base::string16& text_query, 200 const QueryOptions& options, 201 QueryResults* query_results); 202 203 // Computes the most recent URL(s) that the given canonical URL has 204 // redirected to. There may be more than one redirect in a row, so this 205 // function will fill the given array with the entire chain. If there are 206 // no redirects for the most recent visit of the URL, or the URL is not 207 // in history, the array will be empty. 208 void QueryRedirectsFrom(const GURL& url, RedirectList* redirects); 209 210 // Similar to above function except computes a chain of redirects to the 211 // given URL. Stores the most recent list of redirects ending at |url| in the 212 // given RedirectList. For example, if we have the redirect list A -> B -> C, 213 // then calling this function with url=C would fill redirects with {B, A}. 214 void QueryRedirectsTo(const GURL& url, RedirectList* redirects); 215 216 void GetVisibleVisitCountToHost(const GURL& url, 217 VisibleVisitCountToHostResult* result); 218 219 // Request the |result_count| most visited URLs and the chain of 220 // redirects leading to each of these URLs. |days_back| is the 221 // number of days of history to use. Used by TopSites. 222 void QueryMostVisitedURLs(int result_count, 223 int days_back, 224 MostVisitedURLList* result); 225 226 // Request the |result_count| URLs and the chain of redirects 227 // leading to each of these URLs, filterd and sorted based on the |filter|. 228 // If |debug| is enabled, additional data will be computed and provided. 229 void QueryFilteredURLs(int result_count, 230 const history::VisitFilter& filter, 231 bool debug, 232 history::FilteredURLList* result); 233 234 // Favicon ------------------------------------------------------------------- 235 236 void GetFavicons( 237 const std::vector<GURL>& icon_urls, 238 int icon_types, 239 const std::vector<int>& desired_sizes, 240 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results); 241 242 void GetLargestFaviconForURL( 243 const GURL& page_url, 244 const std::vector<int>& icon_types, 245 int minimum_size_in_pixels, 246 favicon_base::FaviconRawBitmapResult* bitmap_result); 247 248 void GetFaviconsForURL( 249 const GURL& page_url, 250 int icon_types, 251 const std::vector<int>& desired_sizes, 252 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results); 253 254 void GetFaviconForID( 255 favicon_base::FaviconID favicon_id, 256 int desired_size, 257 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results); 258 259 void UpdateFaviconMappingsAndFetch( 260 const GURL& page_url, 261 const std::vector<GURL>& icon_urls, 262 int icon_types, 263 const std::vector<int>& desired_sizes, 264 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results); 265 266 void MergeFavicon(const GURL& page_url, 267 const GURL& icon_url, 268 favicon_base::IconType icon_type, 269 scoped_refptr<base::RefCountedMemory> bitmap_data, 270 const gfx::Size& pixel_size); 271 272 void SetFavicons(const GURL& page_url, 273 favicon_base::IconType icon_type, 274 const GURL& icon_url, 275 const std::vector<SkBitmap>& bitmaps); 276 277 void SetFaviconsOutOfDateForPage(const GURL& page_url); 278 279 void CloneFavicons(const GURL& old_page_url, const GURL& new_page_url); 280 281 void SetImportedFavicons( 282 const std::vector<ImportedFaviconUsage>& favicon_usage); 283 284 // Downloads ----------------------------------------------------------------- 285 286 uint32 GetNextDownloadId(); 287 void QueryDownloads(std::vector<DownloadRow>* rows); 288 void UpdateDownload(const DownloadRow& data); 289 bool CreateDownload(const history::DownloadRow& history_info); 290 void RemoveDownloads(const std::set<uint32>& ids); 291 292 // Keyword search terms ------------------------------------------------------ 293 294 void SetKeywordSearchTermsForURL(const GURL& url, 295 KeywordID keyword_id, 296 const base::string16& term); 297 298 void DeleteAllSearchTermsForKeyword(KeywordID keyword_id); 299 300 void DeleteKeywordSearchTermForURL(const GURL& url); 301 302 void DeleteMatchingURLsForKeyword(KeywordID keyword_id, 303 const base::string16& term); 304 305 #if defined(OS_ANDROID) 306 // Android Provider --------------------------------------------------------- 307 308 // History and bookmarks ---------------------------------------------------- 309 // Inserts the given values into history backend. 310 AndroidURLID InsertHistoryAndBookmark(const HistoryAndBookmarkRow& row); 311 312 // Runs the given query on history backend and returns the result. 313 // 314 // |projections| is the vector of the result columns. 315 // |selection| is the SQL WHERE clause without 'WHERE'. 316 // |selection_args| is the arguments for WHERE clause. 317 // |sort_order| is the SQL ORDER clause. 318 history::AndroidStatement* QueryHistoryAndBookmarks( 319 const std::vector<HistoryAndBookmarkRow::ColumnID>& projections, 320 const std::string& selection, 321 const std::vector<base::string16>& selection_args, 322 const std::string& sort_order); 323 324 // Returns the number of row updated by the update query. 325 // 326 // |row| is the value to update. 327 // |selection| is the SQL WHERE clause without 'WHERE'. 328 // |selection_args| is the arguments for the WHERE clause. 329 int UpdateHistoryAndBookmarks( 330 const HistoryAndBookmarkRow& row, 331 const std::string& selection, 332 const std::vector<base::string16>& selection_args); 333 334 // Deletes the specified rows and returns the number of rows deleted. 335 // 336 // |selection| is the SQL WHERE clause without 'WHERE'. 337 // |selection_args| is the arguments for the WHERE clause. 338 // 339 // If |selection| is empty all history and bookmarks are deleted. 340 int DeleteHistoryAndBookmarks( 341 const std::string& selection, 342 const std::vector<base::string16>& selection_args); 343 344 // Deletes the matched history and returns the number of rows deleted. 345 int DeleteHistory(const std::string& selection, 346 const std::vector<base::string16>& selection_args); 347 348 // Statement ---------------------------------------------------------------- 349 // Move the statement's current position. 350 int MoveStatement(history::AndroidStatement* statement, 351 int current_pos, 352 int destination); 353 354 // Close the given statement. The ownership is transfered. 355 void CloseStatement(AndroidStatement* statement); 356 357 // Search terms ------------------------------------------------------------- 358 // Inserts the given values and returns the SearchTermID of the inserted row. 359 SearchTermID InsertSearchTerm(const SearchRow& row); 360 361 // Returns the number of row updated by the update query. 362 // 363 // |row| is the value to update. 364 // |selection| is the SQL WHERE clause without 'WHERE'. 365 // |selection_args| is the arguments for the WHERE clause. 366 int UpdateSearchTerms(const SearchRow& row, 367 const std::string& selection, 368 const std::vector<base::string16> selection_args); 369 370 // Deletes the matched rows and returns the number of deleted rows. 371 // 372 // |selection| is the SQL WHERE clause without 'WHERE'. 373 // |selection_args| is the arguments for WHERE clause. 374 // 375 // If |selection| is empty all search terms will be deleted. 376 int DeleteSearchTerms(const std::string& selection, 377 const std::vector<base::string16> selection_args); 378 379 // Returns the result of the given query. 380 // 381 // |projections| specifies the result columns. 382 // |selection| is the SQL WHERE clause without 'WHERE'. 383 // |selection_args| is the arguments for WHERE clause. 384 // |sort_order| is the SQL ORDER clause. 385 history::AndroidStatement* QuerySearchTerms( 386 const std::vector<SearchRow::ColumnID>& projections, 387 const std::string& selection, 388 const std::vector<base::string16>& selection_args, 389 const std::string& sort_order); 390 391 #endif // defined(OS_ANDROID) 392 393 // Generic operations -------------------------------------------------------- 394 395 void ProcessDBTask( 396 scoped_ptr<HistoryDBTask> task, 397 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, 398 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled); 399 400 virtual bool GetAllTypedURLs(URLRows* urls); 401 402 virtual bool GetVisitsForURL(URLID id, VisitVector* visits); 403 404 // Fetches up to |max_visits| most recent visits for the passed URL. 405 virtual bool GetMostRecentVisitsForURL(URLID id, 406 int max_visits, 407 VisitVector* visits); 408 409 // For each element in |urls|, updates the pre-existing URLRow in the database 410 // with the same ID; or ignores the element if no such row exists. Returns the 411 // number of records successfully updated. 412 virtual size_t UpdateURLs(const history::URLRows& urls); 413 414 // While adding visits in batch, the source needs to be provided. 415 virtual bool AddVisits(const GURL& url, 416 const std::vector<history::VisitInfo>& visits, 417 VisitSource visit_source); 418 419 virtual bool RemoveVisits(const VisitVector& visits); 420 421 // Returns the VisitSource associated with each one of the passed visits. 422 // If there is no entry in the map for a given visit, that means the visit 423 // was SOURCE_BROWSED. Returns false if there is no HistoryDatabase.. 424 bool GetVisitsSource(const VisitVector& visits, VisitSourceMap* sources); 425 426 virtual bool GetURL(const GURL& url, history::URLRow* url_row); 427 428 // Returns the syncable service for syncing typed urls. The returned service 429 // is owned by |this| object. 430 virtual TypedUrlSyncableService* GetTypedUrlSyncableService() const; 431 432 // Deleting ------------------------------------------------------------------ 433 434 virtual void DeleteURLs(const std::vector<GURL>& urls); 435 436 virtual void DeleteURL(const GURL& url); 437 438 // Calls ExpireHistoryBackend::ExpireHistoryBetween and commits the change. 439 void ExpireHistoryBetween( 440 const std::set<GURL>& restrict_urls, 441 base::Time begin_time, 442 base::Time end_time); 443 444 // Finds the URLs visited at |times| and expires all their visits within 445 // [|begin_time|, |end_time|). All times in |times| should be in 446 // [|begin_time|, |end_time|). This is used when expiration request is from 447 // server side, i.e. web history deletes, where only visit times (possibly 448 // incomplete) are transmitted to protect user's privacy. 449 void ExpireHistoryForTimes(const std::set<base::Time>& times, 450 base::Time begin_time, base::Time end_time); 451 452 // Calls ExpireHistoryBetween() once for each element in the vector. 453 // The fields of |ExpireHistoryArgs| map directly to the arguments of 454 // of ExpireHistoryBetween(). 455 void ExpireHistory(const std::vector<ExpireHistoryArgs>& expire_list); 456 457 // Bookmarks ----------------------------------------------------------------- 458 459 // Notification that a URL is no longer bookmarked. If there are no visits 460 // for the specified url, it is deleted. 461 void URLsNoLongerBookmarked(const std::set<GURL>& urls); 462 463 // Callbacks To Kill Database When It Gets Corrupted ------------------------- 464 465 // Called by the database to report errors. Schedules one call to 466 // KillHistoryDatabase() in case of corruption. 467 void DatabaseErrorCallback(int error, sql::Statement* stmt); 468 469 // Raze the history database. It will be recreated in a future run. Hopefully 470 // things go better then. Continue running but without reading or storing any 471 // state into the HistoryBackend databases. Close all of the databases managed 472 // HistoryBackend as there are no provisions for accessing the other databases 473 // managed by HistoryBackend when the history database cannot be accessed. 474 void KillHistoryDatabase(); 475 476 // Testing ------------------------------------------------------------------- 477 478 // Sets the task to run and the message loop to run it on when this object 479 // is destroyed. See HistoryService::SetOnBackendDestroyTask for a more 480 // complete description. 481 void SetOnBackendDestroyTask(base::MessageLoop* message_loop, 482 const base::Closure& task); 483 484 // Adds the given rows to the database if it doesn't exist. A visit will be 485 // added for each given URL at the last visit time in the URLRow if the 486 // passed visit type != SOURCE_SYNCED (the sync code manages visits itself). 487 // Each visit will have the visit_source type set. 488 void AddPagesWithDetails(const URLRows& info, VisitSource visit_source); 489 490 #if defined(UNIT_TEST) 491 HistoryDatabase* db() const { return db_.get(); } 492 493 ExpireHistoryBackend* expire_backend() { return &expirer_; } 494 #endif 495 496 // Returns true if the passed visit time is already expired (used by the sync 497 // code to avoid syncing visits that would immediately be expired). 498 virtual bool IsExpiredVisitTime(const base::Time& time); 499 500 base::Time GetFirstRecordedTimeForTest() { 501 return first_recorded_time_; 502 } 503 504 protected: 505 virtual ~HistoryBackend(); 506 507 private: 508 friend class base::RefCountedThreadSafe<HistoryBackend>; 509 friend class CommitLaterTask; // The commit task needs to call Commit(). 510 friend class HistoryBackendTest; 511 friend class HistoryBackendDBTest; // So the unit tests can poke our innards. 512 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, DeleteAll); 513 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, DeleteAllThenAddData); 514 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, AddPagesWithDetails); 515 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, UpdateURLs); 516 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, ImportedFaviconsTest); 517 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, URLsNoLongerBookmarked); 518 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, StripUsernamePasswordTest); 519 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, DeleteThumbnailsDatabaseTest); 520 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, AddPageVisitSource); 521 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, AddPageVisitNotLastVisit); 522 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, 523 AddPageVisitFiresNotificationWithCorrectDetails); 524 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, AddPageArgsSource); 525 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, AddVisitsSource); 526 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, GetMostRecentVisits); 527 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, RemoveVisitsSource); 528 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, RemoveVisitsTransitions); 529 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, MigrationVisitSource); 530 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, 531 SetFaviconMappingsForPageAndRedirects); 532 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, 533 SetFaviconMappingsForPageDuplicates); 534 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, SetFaviconsDeleteBitmaps); 535 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, SetFaviconsReplaceBitmapData); 536 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, 537 SetFaviconsSameFaviconURLForTwoPages); 538 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, 539 UpdateFaviconMappingsAndFetchNoChange); 540 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, MergeFaviconPageURLNotInDB); 541 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, MergeFaviconPageURLInDB); 542 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, MergeFaviconMaxFaviconsPerPage); 543 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, 544 MergeFaviconIconURLMappedToDifferentPageURL); 545 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, 546 MergeFaviconMaxFaviconBitmapsPerIconURL); 547 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, 548 UpdateFaviconMappingsAndFetchMultipleIconTypes); 549 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, GetFaviconsFromDBEmpty); 550 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, 551 GetFaviconsFromDBNoFaviconBitmaps); 552 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, 553 GetFaviconsFromDBSelectClosestMatch); 554 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, GetFaviconsFromDBIconType); 555 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, GetFaviconsFromDBExpired); 556 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, 557 UpdateFaviconMappingsAndFetchNoDB); 558 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, 559 CloneFaviconIsRestrictedToSameDomain); 560 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, QueryFilteredURLs); 561 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, UpdateVisitDuration); 562 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, ExpireHistoryForTimes); 563 FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, DeleteFTSIndexDatabases); 564 565 friend class ::TestingProfile; 566 567 // Computes the name of the specified database on disk. 568 base::FilePath GetArchivedFileName() const; 569 base::FilePath GetThumbnailFileName() const; 570 571 // Returns the name of the Favicons database. This is the new name 572 // of the Thumbnails database. 573 base::FilePath GetFaviconsFileName() const; 574 575 #if defined(OS_ANDROID) 576 // Returns the name of android cache database. 577 base::FilePath GetAndroidCacheFileName() const; 578 579 // Populate a map from a |MostVisitedURLList|. The map assigns a rank to each 580 // top URL and its redirects. This should only be done once at backend 581 // initialization. 582 // This can be removed for M31. (See issue 248761.) 583 584 void PopulateMostVisitedURLMap(); 585 // Record counts of page visits by rank. If a url is not ranked, record the 586 // page visit in a slot corresponding to |max_top_url_count|, which should 587 // be one greater than the largest rank of any url in |top_urls|. 588 // This can be removed for M31. (See issue 248761.) 589 void RecordTopPageVisitStats(const GURL& url); 590 #endif 591 592 class URLQuerier; 593 friend class URLQuerier; 594 595 // Does the work of Init. 596 void InitImpl(const std::string& languages); 597 598 // Called when the system is under memory pressure. 599 void OnMemoryPressure( 600 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level); 601 602 // Closes all databases managed by HistoryBackend. Commits any pending 603 // transactions. 604 void CloseAllDatabases(); 605 606 // Adds a single visit to the database, updating the URL information such 607 // as visit and typed count. The visit ID of the added visit and the URL ID 608 // of the associated URL (whether added or not) is returned. Both values will 609 // be 0 on failure. 610 // 611 // This does not schedule database commits, it is intended to be used as a 612 // subroutine for AddPage only. It also assumes the database is valid. 613 std::pair<URLID, VisitID> AddPageVisit(const GURL& url, 614 base::Time time, 615 VisitID referring_visit, 616 ui::PageTransition transition, 617 VisitSource visit_source); 618 619 // Returns a redirect chain in |redirects| for the VisitID 620 // |cur_visit|. |cur_visit| is assumed to be valid. Assumes that 621 // this HistoryBackend object has been Init()ed successfully. 622 void GetRedirectsFromSpecificVisit( 623 VisitID cur_visit, history::RedirectList* redirects); 624 625 // Similar to the above function except returns a redirect list ending 626 // at |cur_visit|. 627 void GetRedirectsToSpecificVisit( 628 VisitID cur_visit, history::RedirectList* redirects); 629 630 // Update the visit_duration information in visits table. 631 void UpdateVisitDuration(VisitID visit_id, const base::Time end_ts); 632 633 // Querying ------------------------------------------------------------------ 634 635 // Backends for QueryHistory. *Basic() handles queries that are not 636 // text search queries and can just be given directly to the history DB. 637 // The *Text() version performs a brute force query of the history DB to 638 // search for results which match the given text query. 639 // Both functions assume QueryHistory already checked the DB for validity. 640 void QueryHistoryBasic(const QueryOptions& options, QueryResults* result); 641 void QueryHistoryText(const base::string16& text_query, 642 const QueryOptions& options, 643 QueryResults* result); 644 645 // Committing ---------------------------------------------------------------- 646 647 // We always keep a transaction open on the history database so that multiple 648 // transactions can be batched. Periodically, these are flushed (use 649 // ScheduleCommit). This function does the commit to write any new changes to 650 // disk and opens a new transaction. This will be called automatically by 651 // ScheduleCommit, or it can be called explicitly if a caller really wants 652 // to write something to disk. 653 void Commit(); 654 655 // Schedules a commit to happen in the future. We do this so that many 656 // operations over a period of time will be batched together. If there is 657 // already a commit scheduled for the future, this will do nothing. 658 void ScheduleCommit(); 659 660 // Cancels the scheduled commit, if any. If there is no scheduled commit, 661 // does nothing. 662 void CancelScheduledCommit(); 663 664 // Segments ------------------------------------------------------------------ 665 666 // Walks back a segment chain to find the last visit with a non null segment 667 // id and returns it. If there is none found, returns 0. 668 SegmentID GetLastSegmentID(VisitID from_visit); 669 670 // Update the segment information. This is called internally when a page is 671 // added. Return the segment id of the segment that has been updated. 672 SegmentID UpdateSegments(const GURL& url, 673 VisitID from_visit, 674 VisitID visit_id, 675 ui::PageTransition transition_type, 676 const base::Time ts); 677 678 // Favicons ------------------------------------------------------------------ 679 680 // Used by both UpdateFaviconMappingsAndFetch and GetFavicons. 681 // If |page_url| is non-null, the icon urls for |page_url| (and all 682 // redirects) are set to the subset of |icon_urls| for which icons are 683 // already stored in the database. 684 // If |page_url| is non-null, |icon_types| can be multiple icon types 685 // only if |icon_types| == TOUCH_ICON | TOUCH_PRECOMPOSED_ICON. 686 // If multiple icon types are specified, |page_url| will be mapped to the 687 // icon URLs of the largest type available in the database. 688 void UpdateFaviconMappingsAndFetchImpl( 689 const GURL* page_url, 690 const std::vector<GURL>& icon_urls, 691 int icon_types, 692 const std::vector<int>& desired_sizes, 693 std::vector<favicon_base::FaviconRawBitmapResult>* results); 694 695 // Set the favicon bitmaps for |icon_id|. 696 // For each entry in |bitmaps|, if a favicon bitmap already exists at the 697 // entry's pixel size, replace the favicon bitmap's data with the entry's 698 // bitmap data. Otherwise add a new favicon bitmap. 699 // Any favicon bitmaps already mapped to |icon_id| whose pixel size does not 700 // match the pixel size of one of |bitmaps| is deleted. 701 // Returns true if any of the bitmap data at |icon_id| is changed as a result 702 // of calling this method. 703 bool SetFaviconBitmaps(favicon_base::FaviconID icon_id, 704 const std::vector<SkBitmap>& bitmaps); 705 706 // Returns true if the bitmap data at |bitmap_id| equals |new_bitmap_data|. 707 bool IsFaviconBitmapDataEqual( 708 FaviconBitmapID bitmap_id, 709 const scoped_refptr<base::RefCountedMemory>& new_bitmap_data); 710 711 // Returns true if there are favicons for |page_url| and one of the types in 712 // |icon_types|. 713 // |favicon_bitmap_results| is set to the favicon bitmaps whose edge sizes 714 // most closely match |desired_sizes|. If |desired_sizes| has a '0' entry, the 715 // largest favicon bitmap with one of the icon types in |icon_types| is 716 // returned. If |icon_types| contains multiple icon types and there are 717 // several matched icon types in the database, results will only be returned 718 // for a single icon type in the priority of TOUCH_PRECOMPOSED_ICON, 719 // TOUCH_ICON, and FAVICON. See the comment for 720 // GetFaviconResultsForBestMatch() for more details on how 721 // |favicon_bitmap_results| is constructed. 722 bool GetFaviconsFromDB( 723 const GURL& page_url, 724 int icon_types, 725 const std::vector<int>& desired_sizes, 726 std::vector<favicon_base::FaviconRawBitmapResult>* 727 favicon_bitmap_results); 728 729 // Returns the favicon bitmaps whose edge sizes most closely match 730 // |desired_sizes| in |favicon_bitmap_results|. If |desired_sizes| has a '0' 731 // entry, only the largest favicon bitmap is returned. Goodness is computed 732 // via SelectFaviconFrameIndices(). It is computed on a per FaviconID basis, 733 // thus all |favicon_bitmap_results| are guaranteed to be for the same 734 // FaviconID. |favicon_bitmap_results| will have at most one entry for each 735 // desired edge size. There will be fewer entries if the same favicon bitmap 736 // is the best result for multiple edge sizes. 737 // Returns true if there were no errors. 738 bool GetFaviconBitmapResultsForBestMatch( 739 const std::vector<favicon_base::FaviconID>& candidate_favicon_ids, 740 const std::vector<int>& desired_sizes, 741 std::vector<favicon_base::FaviconRawBitmapResult>* 742 favicon_bitmap_results); 743 744 // Maps the favicon ids in |icon_ids| to |page_url| (and all redirects) 745 // for |icon_type|. 746 // Returns true if the mappings for the page or any of its redirects were 747 // changed. 748 bool SetFaviconMappingsForPageAndRedirects( 749 const GURL& page_url, 750 favicon_base::IconType icon_type, 751 const std::vector<favicon_base::FaviconID>& icon_ids); 752 753 // Maps the favicon ids in |icon_ids| to |page_url| for |icon_type|. 754 // Returns true if the function changed some of |page_url|'s mappings. 755 bool SetFaviconMappingsForPage( 756 const GURL& page_url, 757 favicon_base::IconType icon_type, 758 const std::vector<favicon_base::FaviconID>& icon_ids); 759 760 // Returns all the page URLs in the redirect chain for |page_url|. If there 761 // are no known redirects for |page_url|, returns a vector with |page_url|. 762 void GetCachedRecentRedirects(const GURL& page_url, 763 history::RedirectList* redirect_list); 764 765 // Send notification that the favicon has changed for |page_url| and all its 766 // redirects. 767 void SendFaviconChangedNotificationForPageAndRedirects( 768 const GURL& page_url); 769 770 // Generic stuff ------------------------------------------------------------- 771 772 // Processes the next scheduled HistoryDBTask, scheduling this method 773 // to be invoked again if there are more tasks that need to run. 774 void ProcessDBTaskImpl(); 775 776 virtual void BroadcastNotifications( 777 int type, 778 scoped_ptr<HistoryDetails> details) OVERRIDE; 779 virtual void NotifySyncURLsModified(URLRows* rows) OVERRIDE; 780 virtual void NotifySyncURLsDeleted(bool all_history, 781 bool expired, 782 URLRows* rows) OVERRIDE; 783 784 // Deleting all history ------------------------------------------------------ 785 786 // Deletes all history. This is a special case of deleting that is separated 787 // from our normal dependency-following method for performance reasons. The 788 // logic lives here instead of ExpireHistoryBackend since it will cause 789 // re-initialization of some databases (e.g. Thumbnails) that could fail. 790 // When these databases are not valid, our pointers must be NULL, so we need 791 // to handle this type of operation to keep the pointers in sync. 792 void DeleteAllHistory(); 793 794 // Given a vector of all URLs that we will keep, removes all thumbnails 795 // referenced by any URL, and also all favicons that aren't used by those 796 // URLs. 797 bool ClearAllThumbnailHistory(const URLRows& kept_urls); 798 799 // Deletes all information in the history database, except for the supplied 800 // set of URLs in the URL table (these should correspond to the bookmarked 801 // URLs). 802 // 803 // The IDs of the URLs may change. 804 bool ClearAllMainHistory(const URLRows& kept_urls); 805 806 // Deletes the FTS index database files, which are no longer used. 807 void DeleteFTSIndexDatabases(); 808 809 // Returns the HistoryClient, blocking until the bookmarks are loaded. This 810 // may return NULL during testing. 811 HistoryClient* GetHistoryClient(); 812 813 // Notify any observers of an addition to the visit database. 814 void NotifyVisitObservers(const VisitRow& visit); 815 816 // Data ---------------------------------------------------------------------- 817 818 // Delegate. See the class definition above for more information. This will 819 // be NULL before Init is called and after Cleanup, but is guaranteed 820 // non-NULL in between. 821 scoped_ptr<Delegate> delegate_; 822 823 // Directory where database files will be stored. 824 base::FilePath history_dir_; 825 826 // The history/thumbnail databases. Either MAY BE NULL if the database could 827 // not be opened, all users must first check for NULL and return immediately 828 // if it is. The thumbnail DB may be NULL when the history one isn't, but not 829 // vice-versa. 830 scoped_ptr<HistoryDatabase> db_; 831 bool scheduled_kill_db_; // Database is being killed due to error. 832 scoped_ptr<ThumbnailDatabase> thumbnail_db_; 833 834 // Manages expiration between the various databases. 835 ExpireHistoryBackend expirer_; 836 837 // A commit has been scheduled to occur sometime in the future. We can check 838 // non-null-ness to see if there is a commit scheduled in the future, and we 839 // can use the pointer to cancel the scheduled commit. There can be only one 840 // scheduled commit at a time (see ScheduleCommit). 841 scoped_refptr<CommitLaterTask> scheduled_commit_; 842 843 // Maps recent redirect destination pages to the chain of redirects that 844 // brought us to there. Pages that did not have redirects or were not the 845 // final redirect in a chain will not be in this list, as well as pages that 846 // redirected "too long" ago (as determined by ExpireOldRedirects above). 847 // It is used to set titles & favicons for redirects to that of the 848 // destination. 849 // 850 // As with AddPage, the last item in the redirect chain will be the 851 // destination of the redirect (i.e., the key into recent_redirects_); 852 typedef base::MRUCache<GURL, history::RedirectList> RedirectCache; 853 RedirectCache recent_redirects_; 854 855 // Timestamp of the first entry in our database. 856 base::Time first_recorded_time_; 857 858 // When set, this is the task that should be invoked on destruction. 859 base::MessageLoop* backend_destroy_message_loop_; 860 base::Closure backend_destroy_task_; 861 862 // Tracks page transition types. 863 VisitTracker tracker_; 864 865 // A boolean variable to track whether we have already purged obsolete segment 866 // data. 867 bool segment_queried_; 868 869 // List of QueuedHistoryDBTasks to run; 870 std::list<QueuedHistoryDBTask*> queued_history_db_tasks_; 871 872 // Used to determine if a URL is bookmarked; may be NULL. 873 // 874 // Use GetHistoryClient to access this, which makes sure the bookmarks are 875 // loaded before returning. 876 HistoryClient* history_client_; 877 878 #if defined(OS_ANDROID) 879 // Used to provide the Android ContentProvider APIs. 880 scoped_ptr<AndroidProviderBackend> android_provider_backend_; 881 882 // Used to provide UMA on the number of page visits that are to the most 883 // visited URLs. This is here because the backend both has access to this 884 // information and is notified of page visits. The top sites service should 885 // be used instead whenever possible. 886 std::map<GURL, int> most_visited_urls_map_; 887 #endif 888 889 // Used to manage syncing of the typed urls datatype. This will be NULL 890 // before Init is called. 891 scoped_ptr<TypedUrlSyncableService> typed_url_syncable_service_; 892 893 // Listens for the system being under memory pressure. 894 scoped_ptr<base::MemoryPressureListener> memory_pressure_listener_; 895 896 DISALLOW_COPY_AND_ASSIGN(HistoryBackend); 897 }; 898 899 } // namespace history 900 901 #endif // CHROME_BROWSER_HISTORY_HISTORY_BACKEND_H_ 902