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