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.
5 #ifndef CHROME_BROWSER_HISTORY_HISTORY_BACKEND_H_
6 #define CHROME_BROWSER_HISTORY_HISTORY_BACKEND_H_
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"
28 class TypedUrlSyncableService;
29 struct ThumbnailScore;
32 #if defined(OS_ANDROID)
33 class AndroidProviderBackend;
36 class CommitLaterTask;
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;
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;
49 // *See the .cc file for more information on the design.*
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.
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 {
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.
69 virtual ~Delegate() {}
71 // Called when the database cannot be read correctly for some reason.
72 virtual void NotifyProfileError(sql::InitStatus init_status) = 0;
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.
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;
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;
91 // Invoked when the backend has finished loading the db.
92 virtual void DBLoaded() = 0;
94 virtual void NotifyVisitDBObserversOnAddVisit(
95 const history::BriefVisitInfo& info) = 0;
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 {
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.
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.
116 // |history_client| is used to determine bookmarked URLs when deleting and
119 // This constructor is fast and does no I/O, so can be called at any time.
120 HistoryBackend(const base::FilePath& history_dir,
122 HistoryClient* history_client);
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.)
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);
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.
138 void ClearCachedDataForContextID(ContextID context_id);
140 // Navigation ----------------------------------------------------------------
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,
151 // Querying ------------------------------------------------------------------
153 // ScheduleAutocomplete() never frees |provider| (which is globally live).
154 // It passes |params| on to the autocomplete system which will eventually
156 void ScheduleAutocomplete(HistoryURLProvider* provider,
157 HistoryURLProviderParams* params);
160 const scoped_refptr<visitedlink::VisitedLinkDelegate::URLEnumerator>&
162 void QueryURL(const GURL& url,
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,
170 void QueryRedirectsTo(scoped_refptr<QueryRedirectsRequest> request,
173 void GetVisibleVisitCountToHost(
174 scoped_refptr<GetVisibleVisitCountToHostRequest> request,
177 // TODO(Nik): remove. Use QueryMostVisitedURLs instead.
178 void QueryTopURLsAndRedirects(
179 scoped_refptr<QueryTopURLsAndRedirectsRequest> request,
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,
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,
196 const history::VisitFilter& filter,
199 // QueryMostVisitedURLs without the request.
200 void QueryMostVisitedURLsImpl(int result_count,
202 MostVisitedURLList* result);
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.
210 // Backend for QueryRedirectsFrom.
211 bool GetMostRecentRedirectsFrom(const GURL& url,
212 history::RedirectList* redirects);
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);
221 // Favicon -------------------------------------------------------------------
224 const std::vector<GURL>& icon_urls,
226 const std::vector<int>& desired_sizes,
227 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results);
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);
235 void GetFaviconsForURL(
236 const GURL& page_url,
238 const std::vector<int>& desired_sizes,
239 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results);
241 void GetFaviconForID(
242 favicon_base::FaviconID favicon_id,
244 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results);
246 void UpdateFaviconMappingsAndFetch(
247 const GURL& page_url,
248 const std::vector<GURL>& icon_urls,
250 const std::vector<int>& desired_sizes,
251 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results);
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);
259 void SetFavicons(const GURL& page_url,
260 favicon_base::IconType icon_type,
261 const std::vector<favicon_base::FaviconRawBitmapData>&
262 favicon_bitmap_data);
264 void SetFaviconsOutOfDateForPage(const GURL& page_url);
266 void CloneFavicons(const GURL& old_page_url, const GURL& new_page_url);
268 void SetImportedFavicons(
269 const std::vector<ImportedFaviconUsage>& favicon_usage);
271 // Downloads -----------------------------------------------------------------
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);
279 // Segment usage -------------------------------------------------------------
281 void QuerySegmentUsage(scoped_refptr<QuerySegmentUsageRequest> request,
282 const base::Time from_time,
283 int max_result_count);
284 void DeleteOldSegmentData();
286 // Keyword search terms ------------------------------------------------------
288 void SetKeywordSearchTermsForURL(const GURL& url,
289 TemplateURLID keyword_id,
290 const base::string16& term);
292 void DeleteAllSearchTermsForKeyword(TemplateURLID keyword_id);
294 void GetMostRecentKeywordSearchTerms(
295 scoped_refptr<GetMostRecentKeywordSearchTermsRequest> request,
296 TemplateURLID keyword_id,
297 const base::string16& prefix,
300 void DeleteKeywordSearchTermForURL(const GURL& url);
302 void DeleteMatchingURLsForKeyword(TemplateURLID keyword_id,
303 const base::string16& term);
305 #if defined(OS_ANDROID)
306 // Android Provider ---------------------------------------------------------
308 // History and bookmarks ----------------------------------------------------
309 void InsertHistoryAndBookmark(scoped_refptr<InsertRequest> request,
310 const HistoryAndBookmarkRow& row);
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);
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);
325 void DeleteHistoryAndBookmarks(
326 scoped_refptr<DeleteRequest> request,
327 const std::string& selection,
328 const std::vector<base::string16>& selection_args);
330 void DeleteHistory(scoped_refptr<DeleteRequest> request,
331 const std::string& selection,
332 const std::vector<base::string16>& selection_args);
334 // Statement ----------------------------------------------------------------
335 // Move the statement's current position.
336 void MoveStatement(scoped_refptr<MoveStatementRequest> request,
337 history::AndroidStatement* statement,
341 // Close the given statement. The ownership is transfered.
342 void CloseStatement(AndroidStatement* statement);
344 // Search terms -------------------------------------------------------------
345 void InsertSearchTerm(scoped_refptr<InsertRequest> request,
346 const SearchRow& row);
348 void UpdateSearchTerms(scoped_refptr<UpdateRequest> request,
349 const SearchRow& row,
350 const std::string& selection,
351 const std::vector<base::string16> selection_args);
353 void DeleteSearchTerms(scoped_refptr<DeleteRequest> request,
354 const std::string& selection,
355 const std::vector<base::string16> selection_args);
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);
363 #endif // defined(OS_ANDROID)
365 // Generic operations --------------------------------------------------------
367 void ProcessDBTask(scoped_refptr<HistoryDBTaskRequest> request);
369 virtual bool GetAllTypedURLs(URLRows* urls);
371 virtual bool GetVisitsForURL(URLID id, VisitVector* visits);
373 // Fetches up to |max_visits| most recent visits for the passed URL.
374 virtual bool GetMostRecentVisitsForURL(URLID id,
376 VisitVector* visits);
378 virtual bool UpdateURL(URLID id, const history::URLRow& url);
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);
385 virtual bool RemoveVisits(const VisitVector& visits);
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);
392 virtual bool GetURL(const GURL& url, history::URLRow* url_row);
394 // Returns the syncable service for syncing typed urls. The returned service
395 // is owned by |this| object.
396 virtual TypedUrlSyncableService* GetTypedUrlSyncableService() const;
398 // Deleting ------------------------------------------------------------------
400 virtual void DeleteURLs(const std::vector<GURL>& urls);
402 virtual void DeleteURL(const GURL& url);
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);
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);
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);
423 // Bookmarks -----------------------------------------------------------------
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);
429 // Callbacks To Kill Database When It Gets Corrupted -------------------------
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);
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();
442 // Testing -------------------------------------------------------------------
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);
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);
456 #if defined(UNIT_TEST)
457 HistoryDatabase* db() const { return db_.get(); }
459 ExpireHistoryBackend* expire_backend() { return &expirer_; }
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);
466 base::Time GetFirstRecordedTimeForTest() {
467 return first_recorded_time_;
471 virtual ~HistoryBackend();
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);
531 friend class ::TestingProfile;
533 // Computes the name of the specified database on disk.
534 base::FilePath GetArchivedFileName() const;
535 base::FilePath GetThumbnailFileName() const;
537 // Returns the name of the Favicons database. This is the new name
538 // of the Thumbnails database.
539 base::FilePath GetFaviconsFileName() const;
541 #if defined(OS_ANDROID)
542 // Returns the name of android cache database.
543 base::FilePath GetAndroidCacheFileName() const;
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
548 // This can be removed for M31. (See issue 248761.)
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);
559 friend class URLQuerier;
561 // Does the work of Init.
562 void InitImpl(const std::string& languages);
564 // Called when the system is under memory pressure.
565 void OnMemoryPressure(
566 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
568 // Closes all databases managed by HistoryBackend. Commits any pending
570 void CloseAllDatabases();
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
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,
581 VisitID referring_visit,
582 content::PageTransition transition,
583 VisitSource visit_source);
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);
591 // Similar to the above function except returns a redirect list ending
593 void GetRedirectsToSpecificVisit(
594 VisitID cur_visit, history::RedirectList* redirects);
596 // Update the visit_duration information in visits table.
597 void UpdateVisitDuration(VisitID visit_id, const base::Time end_ts);
599 // Querying ------------------------------------------------------------------
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);
611 // Committing ----------------------------------------------------------------
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.
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();
626 // Cancels the scheduled commit, if any. If there is no scheduled commit,
628 void CancelScheduledCommit();
630 // Segments ------------------------------------------------------------------
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);
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,
641 content::PageTransition transition_type,
642 const base::Time ts);
644 // Favicons ------------------------------------------------------------------
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,
658 const std::vector<int>& desired_sizes,
659 std::vector<favicon_base::FaviconRawBitmapResult>* results);
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>&
674 bool* favicon_bitmaps_changed);
676 // Returns true if |favicon_bitmap_data| passed to SetFavicons() is valid.
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;
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);
690 // Returns true if there are favicons for |page_url| and one of the types in
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,
704 const std::vector<int>& desired_sizes,
705 std::vector<favicon_base::FaviconRawBitmapResult>*
706 favicon_bitmap_results);
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);
723 // Maps the favicon ids in |icon_ids| to |page_url| (and all redirects)
725 // Returns true if the mappings for the page or any of its redirects were
727 bool SetFaviconMappingsForPageAndRedirects(
728 const GURL& page_url,
729 favicon_base::IconType icon_type,
730 const std::vector<favicon_base::FaviconID>& icon_ids);
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);
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);
744 // Send notification that the favicon has changed for |page_url| and all its
746 void SendFaviconChangedNotificationForPageAndRedirects(
747 const GURL& page_url);
749 // Generic stuff -------------------------------------------------------------
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();
755 // Release all tasks in history_db_tasks_ and clears it.
756 void ReleaseDBTasks();
758 virtual void BroadcastNotifications(
760 scoped_ptr<HistoryDetails> details) OVERRIDE;
761 virtual void NotifySyncURLsModified(URLRows* rows) OVERRIDE;
762 virtual void NotifySyncURLsDeleted(bool all_history,
764 URLRows* rows) OVERRIDE;
766 // Deleting all history ------------------------------------------------------
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();
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
779 bool ClearAllThumbnailHistory(const URLRows& kept_urls);
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
785 // The IDs of the URLs may change.
786 bool ClearAllMainHistory(const URLRows& kept_urls);
788 // Deletes the FTS index database files, which are no longer used.
789 void DeleteFTSIndexDatabases();
791 // Returns the HistoryClient, blocking until the bookmarks are loaded. This
792 // may return NULL during testing.
793 HistoryClient* GetHistoryClient();
795 // Notify any observers of an addition to the visit database.
796 void NotifyVisitObservers(const VisitRow& visit);
798 // Data ----------------------------------------------------------------------
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_;
805 // Directory where database files will be stored.
806 base::FilePath history_dir_;
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
812 scoped_ptr<HistoryDatabase> db_;
813 bool scheduled_kill_db_; // Database is being killed due to error.
814 scoped_ptr<ThumbnailDatabase> thumbnail_db_;
816 // Manages expiration between the various databases.
817 ExpireHistoryBackend expirer_;
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_;
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
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_;
837 // Timestamp of the first entry in our database.
838 base::Time first_recorded_time_;
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_;
844 // Tracks page transition types.
845 VisitTracker tracker_;
847 // A boolean variable to track whether we have already purged obsolete segment
849 bool segment_queried_;
851 // HistoryDBTasks to run. Be sure to AddRef when adding, and Release when
853 std::list<HistoryDBTaskRequest*> db_task_requests_;
855 // Used to determine if a URL is bookmarked; may be NULL.
857 // Use GetHistoryClient to access this, which makes sure the bookmarks are
858 // loaded before returning.
859 HistoryClient* history_client_;
861 #if defined(OS_ANDROID)
862 // Used to provide the Android ContentProvider APIs.
863 scoped_ptr<AndroidProviderBackend> android_provider_backend_;
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_;
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_;
876 // Listens for the system being under memory pressure.
877 scoped_ptr<base::MemoryPressureListener> memory_pressure_listener_;
879 DISALLOW_COPY_AND_ASSIGN(HistoryBackend);
882 } // namespace history
884 #endif // CHROME_BROWSER_HISTORY_HISTORY_BACKEND_H_