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