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