• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 #pragma once
8 
9 #include <string>
10 #include <utility>
11 
12 #include "app/sql/init_status.h"
13 #include "base/file_path.h"
14 #include "base/gtest_prod_util.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "chrome/browser/history/archived_database.h"
17 #include "chrome/browser/history/expire_history_backend.h"
18 #include "chrome/browser/history/history_database.h"
19 #include "chrome/browser/history/history_marshaling.h"
20 #include "chrome/browser/history/history_types.h"
21 #include "chrome/browser/history/text_database_manager.h"
22 #include "chrome/browser/history/thumbnail_database.h"
23 #include "chrome/browser/history/visit_tracker.h"
24 #include "chrome/browser/search_engines/template_url_id.h"
25 #include "content/common/mru_cache.h"
26 
27 class BookmarkService;
28 struct DownloadCreateInfo;
29 class TestingProfile;
30 struct ThumbnailScore;
31 
32 namespace history {
33 
34 class CommitLaterTask;
35 class HistoryPublisher;
36 
37 // *See the .cc file for more information on the design.*
38 //
39 // Internal history implementation which does most of the work of the history
40 // system. This runs on a background thread (to not block the browser when we
41 // do expensive operations) and is NOT threadsafe, so it must only be called
42 // from message handlers on the background thread. Invoking on another thread
43 // requires threadsafe refcounting.
44 //
45 // Most functions here are just the implementations of the corresponding
46 // functions in the history service. These functions are not documented
47 // here, see the history service for behavior.
48 class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
49                        public BroadcastNotificationDelegate {
50  public:
51   // Interface implemented by the owner of the HistoryBackend object. Normally,
52   // the history service implements this to send stuff back to the main thread.
53   // The unit tests can provide a different implementation if they don't have
54   // a history service object.
55   class Delegate {
56    public:
~Delegate()57     virtual ~Delegate() {}
58 
59     // Called when the database cannot be read correctly for some reason.
60     virtual void NotifyProfileError(sql::InitStatus init_status) = 0;
61 
62     // Sets the in-memory history backend. The in-memory backend is created by
63     // the main backend. For non-unit tests, this happens on the background
64     // thread. It is to be used on the main thread, so this would transfer
65     // it to the history service. Unit tests can override this behavior.
66     //
67     // This function is NOT guaranteed to be called. If there is an error,
68     // there may be no in-memory database.
69     //
70     // Ownership of the backend pointer is transferred to this function.
71     virtual void SetInMemoryBackend(InMemoryHistoryBackend* backend) = 0;
72 
73     // Broadcasts the specified notification to the notification service.
74     // This is implemented here because notifications must only be sent from
75     // the main thread.
76     //
77     // Ownership of the HistoryDetails is transferred to this function.
78     virtual void BroadcastNotifications(NotificationType type,
79                                         HistoryDetails* details) = 0;
80 
81     // Invoked when the backend has finished loading the db.
82     virtual void DBLoaded() = 0;
83 
84     // Tell TopSites to start reading thumbnails from the ThumbnailsDB.
85     virtual void StartTopSitesMigration() = 0;
86   };
87 
88   // Init must be called to complete object creation. This object can be
89   // constructed on any thread, but all other functions including Init() must
90   // be called on the history thread.
91   //
92   // |history_dir| is the directory where the history files will be placed.
93   // See the definition of BroadcastNotificationsCallback above. This function
94   // takes ownership of the callback pointer.
95   //
96   // |bookmark_service| is used to determine bookmarked URLs when deleting and
97   // may be NULL.
98   //
99   // This constructor is fast and does no I/O, so can be called at any time.
100   HistoryBackend(const FilePath& history_dir,
101                  Delegate* delegate,
102                  BookmarkService* bookmark_service);
103 
104   // Must be called after creation but before any objects are created. If this
105   // fails, all other functions will fail as well. (Since this runs on another
106   // thread, we don't bother returning failure.)
107   //
108   // |languages| gives a list of language encodings with which the history
109   // URLs and omnibox searches are interpreted.
110   // |force_fail| can be set during unittests to unconditionally fail to init.
111   void Init(const std::string& languages, bool force_fail);
112 
113   // Notification that the history system is shutting down. This will break
114   // the refs owned by the delegate and any pending transaction so it will
115   // actually be deleted.
116   void Closing();
117 
118   // See NotifyRenderProcessHostDestruction.
119   void NotifyRenderProcessHostDestruction(const void* host);
120 
121   // Navigation ----------------------------------------------------------------
122 
123   void AddPage(scoped_refptr<HistoryAddPageArgs> request);
124   virtual void SetPageTitle(const GURL& url, const string16& title);
125   void AddPageNoVisitForBookmark(const GURL& url);
126 
127   // Indexing ------------------------------------------------------------------
128 
129   void SetPageContents(const GURL& url, const string16& contents);
130 
131   // Querying ------------------------------------------------------------------
132 
133   // ScheduleAutocomplete() never frees |provider| (which is globally live).
134   // It passes |params| on to the autocomplete system which will eventually
135   // free it.
136   void ScheduleAutocomplete(HistoryURLProvider* provider,
137                             HistoryURLProviderParams* params);
138 
139   void IterateURLs(HistoryService::URLEnumerator* enumerator);
140   void QueryURL(scoped_refptr<QueryURLRequest> request,
141                 const GURL& url,
142                 bool want_visits);
143   void QueryHistory(scoped_refptr<QueryHistoryRequest> request,
144                     const string16& text_query,
145                     const QueryOptions& options);
146   void QueryRedirectsFrom(scoped_refptr<QueryRedirectsRequest> request,
147                           const GURL& url);
148   void QueryRedirectsTo(scoped_refptr<QueryRedirectsRequest> request,
149                         const GURL& url);
150 
151   void GetVisitCountToHost(scoped_refptr<GetVisitCountToHostRequest> request,
152                            const GURL& url);
153 
154   // TODO(Nik): remove. Use QueryMostVisitedURLs instead.
155   void QueryTopURLsAndRedirects(
156       scoped_refptr<QueryTopURLsAndRedirectsRequest> request,
157       int result_count);
158 
159   // Request the |result_count| most visited URLs and the chain of
160   // redirects leading to each of these URLs. |days_back| is the
161   // number of days of history to use. Used by TopSites.
162   void QueryMostVisitedURLs(
163       scoped_refptr<QueryMostVisitedURLsRequest> request,
164       int result_count,
165       int days_back);
166 
167   // QueryMostVisitedURLs without the request.
168   void QueryMostVisitedURLsImpl(int result_count,
169                                 int days_back,
170                                 MostVisitedURLList* result);
171 
172   // Computes the most recent URL(s) that the given canonical URL has
173   // redirected to and returns true on success. There may be more than one
174   // redirect in a row, so this function will fill the given array with the
175   // entire chain. If there are no redirects for the most recent visit of the
176   // URL, or the URL is not in history, returns false.
177   //
178   // Backend for QueryRedirectsFrom.
179   bool GetMostRecentRedirectsFrom(const GURL& url,
180                                   history::RedirectList* redirects);
181 
182   // Similar to above function except computes a chain of redirects to the
183   // given URL. Stores the most recent list of redirects ending at |url| in the
184   // given RedirectList. For example, if we have the redirect list A -> B -> C,
185   // then calling this function with url=C would fill redirects with {B, A}.
186   bool GetMostRecentRedirectsTo(const GURL& url,
187                                       history::RedirectList* redirects);
188 
189   // Thumbnails ----------------------------------------------------------------
190 
191   void SetPageThumbnail(const GURL& url,
192                         const SkBitmap& thumbnail,
193                         const ThumbnailScore& score);
194 
195   // Retrieves a thumbnail, passing it across thread boundaries
196   // via. the included callback.
197   void GetPageThumbnail(scoped_refptr<GetPageThumbnailRequest> request,
198                         const GURL& page_url);
199 
200   // Backend implementation of GetPageThumbnail. Unlike
201   // GetPageThumbnail(), this method has way to transport data across
202   // thread boundaries.
203   //
204   // Exposed for testing reasons.
205   void GetPageThumbnailDirectly(
206       const GURL& page_url,
207       scoped_refptr<RefCountedBytes>* data);
208 
209   void MigrateThumbnailsDatabase();
210 
211   // Favicon -------------------------------------------------------------------
212 
213   void GetFavicon(scoped_refptr<GetFaviconRequest> request,
214                   const GURL& icon_url,
215                   int icon_types);
216 
217   void GetFaviconForURL(scoped_refptr<GetFaviconRequest> request,
218                         const GURL& page_url,
219                         int icon_types);
220 
221   void SetFavicon(const GURL& page_url,
222                   const GURL& icon_url,
223                   scoped_refptr<RefCountedMemory> data,
224                   IconType icon_type);
225 
226   void UpdateFaviconMappingAndFetch(scoped_refptr<GetFaviconRequest> request,
227                                     const GURL& page_url,
228                                     const GURL& icon_url,
229                                     IconType icon_type);
230 
231   void SetFaviconOutOfDateForPage(const GURL& page_url);
232 
233   void SetImportedFavicons(
234       const std::vector<ImportedFaviconUsage>& favicon_usage);
235 
236   // Downloads -----------------------------------------------------------------
237 
238   void QueryDownloads(scoped_refptr<DownloadQueryRequest> request);
239   void CleanUpInProgressEntries();
240   void UpdateDownload(int64 received_bytes, int32 state, int64 db_handle);
241   void UpdateDownloadPath(const FilePath& path, int64 db_handle);
242   void CreateDownload(scoped_refptr<DownloadCreateRequest> request,
243                       const DownloadCreateInfo& info);
244   void RemoveDownload(int64 db_handle);
245   void RemoveDownloadsBetween(const base::Time remove_begin,
246                               const base::Time remove_end);
247   void RemoveDownloads(const base::Time remove_end);
248 
249   // Segment usage -------------------------------------------------------------
250 
251   void QuerySegmentUsage(scoped_refptr<QuerySegmentUsageRequest> request,
252                          const base::Time from_time,
253                          int max_result_count);
254   void DeleteOldSegmentData();
255   void SetSegmentPresentationIndex(SegmentID segment_id, int index);
256 
257   // Keyword search terms ------------------------------------------------------
258 
259   void SetKeywordSearchTermsForURL(const GURL& url,
260                                    TemplateURLID keyword_id,
261                                    const string16& term);
262 
263   void DeleteAllSearchTermsForKeyword(TemplateURLID keyword_id);
264 
265   void GetMostRecentKeywordSearchTerms(
266       scoped_refptr<GetMostRecentKeywordSearchTermsRequest> request,
267       TemplateURLID keyword_id,
268       const string16& prefix,
269       int max_count);
270 
271   // Generic operations --------------------------------------------------------
272 
273   void ProcessDBTask(scoped_refptr<HistoryDBTaskRequest> request);
274 
275   virtual bool GetAllTypedURLs(std::vector<history::URLRow>* urls);
276 
277   virtual bool GetVisitsForURL(URLID id, VisitVector* visits);
278 
279   virtual bool UpdateURL(URLID id, const history::URLRow& url);
280 
281   // While adding visits in batch, the source needs to be provided.
282   virtual bool AddVisits(const GURL& url,
283                          const std::vector<base::Time>& visits,
284                          VisitSource visit_source);
285 
286   virtual bool RemoveVisits(const VisitVector& visits);
287 
288   virtual bool GetURL(const GURL& url, history::URLRow* url_row);
289 
290   // Deleting ------------------------------------------------------------------
291 
292   virtual void DeleteURLs(const std::vector<GURL>& urls);
293 
294   virtual void DeleteURL(const GURL& url);
295 
296   // Calls ExpireHistoryBackend::ExpireHistoryBetween and commits the change.
297   void ExpireHistoryBetween(scoped_refptr<ExpireHistoryRequest> request,
298                             const std::set<GURL>& restrict_urls,
299                             base::Time begin_time,
300                             base::Time end_time);
301 
302   // Bookmarks -----------------------------------------------------------------
303 
304   // Notification that a URL is no longer bookmarked. If there are no visits
305   // for the specified url, it is deleted.
306   void URLsNoLongerBookmarked(const std::set<GURL>& urls);
307 
308   // Testing -------------------------------------------------------------------
309 
310   // Sets the task to run and the message loop to run it on when this object
311   // is destroyed. See HistoryService::SetOnBackendDestroyTask for a more
312   // complete description.
313   void SetOnBackendDestroyTask(MessageLoop* message_loop, Task* task);
314 
315   // Adds the given rows to the database if it doesn't exist. A visit will be
316   // added for each given URL at the last visit time in the URLRow.
317   // Each visit will have the visit_source type set.
318   void AddPagesWithDetails(const std::vector<URLRow>& info,
319                            VisitSource visit_source);
320 
321 #if defined(UNIT_TEST)
db()322   HistoryDatabase* db() const { return db_.get(); }
323 
expire_backend()324   ExpireHistoryBackend* expire_backend() { return &expirer_; }
325 #endif
326 
327  protected:
328   virtual ~HistoryBackend();
329 
330  private:
331   friend class base::RefCountedThreadSafe<HistoryBackend>;
332   friend class CommitLaterTask;  // The commit task needs to call Commit().
333   friend class HistoryBackendTest;
334   friend class HistoryTest;  // So the unit tests can poke our innards.
335   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, DeleteAll);
336   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, ImportedFaviconsTest);
337   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, URLsNoLongerBookmarked);
338   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, StripUsernamePasswordTest);
339   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, DeleteThumbnailsDatabaseTest);
340   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, AddPageVisitSource);
341   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, AddPageArgsSource);
342   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, AddVisitsSource);
343   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, RemoveVisitsSource);
344   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, MigrationVisitSource);
345   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, MigrationIconMapping);
346   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, SetFaviconMapping);
347   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, AddOrUpdateIconMapping);
348 
349   friend class ::TestingProfile;
350 
351   // Computes the name of the specified database on disk.
352   FilePath GetThumbnailFileName() const;
353 
354   // Returns the name of the Favicons database. This is the new name
355   // of the Thumbnails database.
356   // See ThumbnailDatabase::RenameAndDropThumbnails.
357   FilePath GetFaviconsFileName() const;
358   FilePath GetArchivedFileName() const;
359 
360   class URLQuerier;
361   friend class URLQuerier;
362 
363   // Does the work of Init.
364   void InitImpl(const std::string& languages);
365 
366   // Adds a single visit to the database, updating the URL information such
367   // as visit and typed count. The visit ID of the added visit and the URL ID
368   // of the associated URL (whether added or not) is returned. Both values will
369   // be 0 on failure.
370   //
371   // This does not schedule database commits, it is intended to be used as a
372   // subroutine for AddPage only. It also assumes the database is valid.
373   std::pair<URLID, VisitID> AddPageVisit(const GURL& url,
374                                          base::Time time,
375                                          VisitID referring_visit,
376                                          PageTransition::Type transition,
377                                          VisitSource visit_source);
378 
379   // Returns a redirect chain in |redirects| for the VisitID
380   // |cur_visit|. |cur_visit| is assumed to be valid. Assumes that
381   // this HistoryBackend object has been Init()ed successfully.
382   void GetRedirectsFromSpecificVisit(
383       VisitID cur_visit, history::RedirectList* redirects);
384 
385   // Similar to the above function except returns a redirect list ending
386   // at |cur_visit|.
387   void GetRedirectsToSpecificVisit(
388       VisitID cur_visit, history::RedirectList* redirects);
389 
390   // Thumbnail Helpers ---------------------------------------------------------
391 
392   // When a simple GetMostRecentRedirectsFrom() fails, this method is
393   // called which searches the last N visit sessions instead of just
394   // the current one. Returns true and puts thumbnail data in |data|
395   // if a proper thumbnail was found. Returns false otherwise. Assumes
396   // that this HistoryBackend object has been Init()ed successfully.
397   bool GetThumbnailFromOlderRedirect(
398       const GURL& page_url, std::vector<unsigned char>* data);
399 
400   // Querying ------------------------------------------------------------------
401 
402   // Backends for QueryHistory. *Basic() handles queries that are not FTS (full
403   // text search) queries and can just be given directly to the history DB).
404   // The FTS version queries the text_database, then merges with the history DB.
405   // Both functions assume QueryHistory already checked the DB for validity.
406   void QueryHistoryBasic(URLDatabase* url_db, VisitDatabase* visit_db,
407                          const QueryOptions& options, QueryResults* result);
408   void QueryHistoryFTS(const string16& text_query,
409                        const QueryOptions& options,
410                        QueryResults* result);
411 
412   // Committing ----------------------------------------------------------------
413 
414   // We always keep a transaction open on the history database so that multiple
415   // transactions can be batched. Periodically, these are flushed (use
416   // ScheduleCommit). This function does the commit to write any new changes to
417   // disk and opens a new transaction. This will be called automatically by
418   // ScheduleCommit, or it can be called explicitly if a caller really wants
419   // to write something to disk.
420   void Commit();
421 
422   // Schedules a commit to happen in the future. We do this so that many
423   // operations over a period of time will be batched together. If there is
424   // already a commit scheduled for the future, this will do nothing.
425   void ScheduleCommit();
426 
427   // Cancels the scheduled commit, if any. If there is no scheduled commit,
428   // does nothing.
429   void CancelScheduledCommit();
430 
431   // Segments ------------------------------------------------------------------
432 
433   // Walks back a segment chain to find the last visit with a non null segment
434   // id and returns it. If there is none found, returns 0.
435   SegmentID GetLastSegmentID(VisitID from_visit);
436 
437   // Update the segment information. This is called internally when a page is
438   // added. Return the segment id of the segment that has been updated.
439   SegmentID UpdateSegments(const GURL& url,
440                            VisitID from_visit,
441                            VisitID visit_id,
442                            PageTransition::Type transition_type,
443                            const base::Time ts);
444 
445   // Favicons ------------------------------------------------------------------
446 
447   // Used by both UpdateFaviconMappingAndFetch and GetFavicon.
448   // If page_url is non-null and SetFavicon has previously been invoked for
449   // icon_url the favicon url for page_url (and all redirects) is set to
450   // icon_url.
451   // Only a single type can be given in icon_type when page_url is specified.
452   void UpdateFaviconMappingAndFetchImpl(
453       const GURL* page_url,
454       const GURL& icon_url,
455       scoped_refptr<GetFaviconRequest> request,
456       int icon_type);
457 
458   // Sets the favicon url id for page_url to id. This will also broadcast
459   // notifications as necessary.
460   void SetFaviconMapping(const GURL& page_url,
461                          FaviconID id,
462                          IconType icon_type);
463 
464   // Updates the FaviconID associated with the url of a page. If there is an
465   // existing mapping between |page_url| and |id| this does nothing and returns
466   // false. If the mapping needs to be added or updated, true is returned. If
467   // there is an existing mapping but it does not map to |id|, then the |id| of
468   // the replaced FaviconID is set in |replaced_icon_id|.
469   bool AddOrUpdateIconMapping(const GURL& page_url,
470                               FaviconID id,
471                               IconType icon_type,
472                               FaviconID* replaced_icon_id);
473 
474   // Generic stuff -------------------------------------------------------------
475 
476   // Processes the next scheduled HistoryDBTask, scheduling this method
477   // to be invoked again if there are more tasks that need to run.
478   void ProcessDBTaskImpl();
479 
480   // Release all tasks in history_db_tasks_ and clears it.
481   void ReleaseDBTasks();
482 
483   // Schedules a broadcast of the given notification on the main thread. The
484   // details argument will have ownership taken by this function (it will be
485   // sent to the main thread and deleted there).
486   virtual void BroadcastNotifications(NotificationType type,
487                                       HistoryDetails* details_deleted);
488 
489   // Deleting all history ------------------------------------------------------
490 
491   // Deletes all history. This is a special case of deleting that is separated
492   // from our normal dependency-following method for performance reasons. The
493   // logic lives here instead of ExpireHistoryBackend since it will cause
494   // re-initialization of some databases such as Thumbnails or Archived that
495   // could fail. When these databases are not valid, our pointers must be NULL,
496   // so we need to handle this type of operation to keep the pointers in sync.
497   void DeleteAllHistory();
498 
499   // Given a vector of all URLs that we will keep, removes all thumbnails
500   // referenced by any URL, and also all favicons that aren't used by those
501   // URLs. The favicon IDs will change, so this will update the url rows in the
502   // vector to reference the new IDs.
503   bool ClearAllThumbnailHistory(std::vector<URLRow>* kept_urls);
504 
505   // Deletes all information in the history database, except for the supplied
506   // set of URLs in the URL table (these should correspond to the bookmarked
507   // URLs).
508   //
509   // The IDs of the URLs may change.
510   bool ClearAllMainHistory(const std::vector<URLRow>& kept_urls);
511 
512   // Returns the BookmarkService, blocking until it is loaded. This may return
513   // NULL during testing.
514   BookmarkService* GetBookmarkService();
515 
516   // Data ----------------------------------------------------------------------
517 
518   // Delegate. See the class definition above for more information. This will
519   // be NULL before Init is called and after Cleanup, but is guaranteed
520   // non-NULL in between.
521   scoped_ptr<Delegate> delegate_;
522 
523   // Directory where database files will be stored.
524   FilePath history_dir_;
525 
526   // The history/thumbnail databases. Either MAY BE NULL if the database could
527   // not be opened, all users must first check for NULL and return immediately
528   // if it is. The thumbnail DB may be NULL when the history one isn't, but not
529   // vice-versa.
530   scoped_ptr<HistoryDatabase> db_;
531   scoped_ptr<ThumbnailDatabase> thumbnail_db_;
532 
533   // Stores old history in a larger, slower database.
534   scoped_ptr<ArchivedDatabase> archived_db_;
535 
536   // Full text database manager, possibly NULL if the database could not be
537   // created.
538   scoped_ptr<TextDatabaseManager> text_database_;
539 
540   // Manages expiration between the various databases.
541   ExpireHistoryBackend expirer_;
542 
543   // A commit has been scheduled to occur sometime in the future. We can check
544   // non-null-ness to see if there is a commit scheduled in the future, and we
545   // can use the pointer to cancel the scheduled commit. There can be only one
546   // scheduled commit at a time (see ScheduleCommit).
547   scoped_refptr<CommitLaterTask> scheduled_commit_;
548 
549   // Maps recent redirect destination pages to the chain of redirects that
550   // brought us to there. Pages that did not have redirects or were not the
551   // final redirect in a chain will not be in this list, as well as pages that
552   // redirected "too long" ago (as determined by ExpireOldRedirects above).
553   // It is used to set titles & favicons for redirects to that of the
554   // destination.
555   //
556   // As with AddPage, the last item in the redirect chain will be the
557   // destination of the redirect (i.e., the key into recent_redirects_);
558   typedef MRUCache<GURL, history::RedirectList> RedirectCache;
559   RedirectCache recent_redirects_;
560 
561   // Timestamp of the last page addition request. We use this to detect when
562   // multiple additions are requested at the same time (within the resolution
563   // of the timer), so we can try to ensure they're unique when they're added
564   // to the database by using the last_recorded_time_ (q.v.). We still can't
565   // enforce or guarantee uniqueness, since the user might set his clock back.
566   base::Time last_requested_time_;
567 
568   // Timestamp of the last page addition, as it was recorded in the database.
569   // If two or more requests come in at the same time, we increment that time
570   // by 1 us between them so it's more likely to be unique in the database.
571   // This keeps track of that higher-resolution timestamp.
572   base::Time last_recorded_time_;
573 
574   // Timestamp of the first entry in our database.
575   base::Time first_recorded_time_;
576 
577   // When non-NULL, this is the task that should be invoked on
578   MessageLoop* backend_destroy_message_loop_;
579   Task* backend_destroy_task_;
580 
581   // Tracks page transition types.
582   VisitTracker tracker_;
583 
584   // A boolean variable to track whether we have already purged obsolete segment
585   // data.
586   bool segment_queried_;
587 
588   // HistoryDBTasks to run. Be sure to AddRef when adding, and Release when
589   // done.
590   std::list<HistoryDBTaskRequest*> db_task_requests_;
591 
592   // Used to determine if a URL is bookmarked. This is owned by the Profile and
593   // may be NULL (during testing).
594   //
595   // Use GetBookmarkService to access this, which makes sure the service is
596   // loaded.
597   BookmarkService* bookmark_service_;
598 
599   // Publishes the history to all indexers which are registered to receive
600   // history data from us. Can be NULL if there are no listeners.
601   scoped_ptr<HistoryPublisher> history_publisher_;
602 
603   DISALLOW_COPY_AND_ASSIGN(HistoryBackend);
604 };
605 
606 }  // namespace history
607 
608 #endif  // CHROME_BROWSER_HISTORY_HISTORY_BACKEND_H_
609