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