• 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_H_
6 #define CHROME_BROWSER_HISTORY_HISTORY_H_
7 #pragma once
8 
9 #include <set>
10 #include <vector>
11 
12 #include "app/sql/init_status.h"
13 #include "base/basictypes.h"
14 #include "base/callback.h"
15 #include "base/file_path.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/string16.h"
19 #include "base/task.h"
20 #include "chrome/browser/favicon_service.h"
21 #include "chrome/browser/history/history_types.h"
22 #include "chrome/browser/search_engines/template_url_id.h"
23 #include "chrome/common/ref_counted_util.h"
24 #include "content/browser/cancelable_request.h"
25 #include "content/common/notification_observer.h"
26 #include "content/common/notification_registrar.h"
27 #include "content/common/page_transition_types.h"
28 
29 class BookmarkService;
30 struct DownloadCreateInfo;
31 class FilePath;
32 class GURL;
33 class HistoryURLProvider;
34 struct HistoryURLProviderParams;
35 class InMemoryURLDatabase;
36 class MainPagesRequest;
37 class PageUsageData;
38 class PageUsageRequest;
39 class Profile;
40 class SkBitmap;
41 struct ThumbnailScore;
42 
43 namespace base {
44 class Thread;
45 class Time;
46 }
47 
48 namespace browser_sync {
49 class HistoryModelWorker;
50 class TypedUrlDataTypeController;
51 }
52 
53 namespace history {
54 class InMemoryHistoryBackend;
55 class InMemoryURLIndex;
56 class HistoryAddPageArgs;
57 class HistoryBackend;
58 class HistoryDatabase;
59 struct HistoryDetails;
60 class HistoryQueryTest;
61 class URLDatabase;
62 }  // namespace history
63 
64 
65 // HistoryDBTask can be used to process arbitrary work on the history backend
66 // thread. HistoryDBTask is scheduled using HistoryService::ScheduleDBTask.
67 // When HistoryBackend processes the task it invokes RunOnDBThread. Once the
68 // task completes and has not been canceled, DoneRunOnMainThread is invoked back
69 // on the main thread.
70 class HistoryDBTask : public base::RefCountedThreadSafe<HistoryDBTask> {
71  public:
72   // Invoked on the database thread. The return value indicates whether the
73   // task is done. A return value of true signals the task is done and
74   // RunOnDBThread should NOT be invoked again. A return value of false
75   // indicates the task is not done, and should be run again after other
76   // tasks are given a chance to be processed.
77   virtual bool RunOnDBThread(history::HistoryBackend* backend,
78                              history::HistoryDatabase* db) = 0;
79 
80   // Invoked on the main thread once RunOnDBThread has returned false. This is
81   // only invoked if the request was not canceled and returned true from
82   // RunOnDBThread.
83   virtual void DoneRunOnMainThread() = 0;
84 
85  protected:
86   friend class base::RefCountedThreadSafe<HistoryDBTask>;
87 
~HistoryDBTask()88   virtual ~HistoryDBTask() {}
89 };
90 
91 // The history service records page titles, and visit times, as well as
92 // (eventually) information about autocomplete.
93 //
94 // This service is thread safe. Each request callback is invoked in the
95 // thread that made the request.
96 class HistoryService : public CancelableRequestProvider,
97                        public NotificationObserver,
98                        public base::RefCountedThreadSafe<HistoryService> {
99  public:
100   // Miscellaneous commonly-used types.
101   typedef std::vector<PageUsageData*> PageUsageDataList;
102 
103   // ID (both star_id and folder_id) of the bookmark bar.
104   // This entry always exists.
105   static const history::StarID kBookmarkBarID;
106 
107   // Must call Init after construction.
108   explicit HistoryService(Profile* profile);
109   // The empty constructor is provided only for testing.
110   HistoryService();
111 
112   // Initializes the history service, returning true on success. On false, do
113   // not call any other functions. The given directory will be used for storing
114   // the history files. The BookmarkService is used when deleting URLs to
115   // test if a URL is bookmarked; it may be NULL during testing.
Init(const FilePath & history_dir,BookmarkService * bookmark_service)116   bool Init(const FilePath& history_dir, BookmarkService* bookmark_service) {
117     return Init(history_dir, bookmark_service, false);
118   }
119 
120   // Triggers the backend to load if it hasn't already, and then returns whether
121   // it's finished loading.
122   bool BackendLoaded();
123 
124   // Returns true if the backend has finished loading.
backend_loaded()125   bool backend_loaded() const { return backend_loaded_; }
126 
127   // Unloads the backend without actually shutting down the history service.
128   // This can be used to temporarily reduce the browser process' memory
129   // footprint.
130   void UnloadBackend();
131 
132   // Called on shutdown, this will tell the history backend to complete and
133   // will release pointers to it. No other functions should be called once
134   // cleanup has happened that may dispatch to the history thread (because it
135   // will be NULL).
136   //
137   // In practice, this will be called by the service manager (BrowserProcess)
138   // when it is being destroyed. Because that reference is being destroyed, it
139   // should be impossible for anybody else to call the service, even if it is
140   // still in memory (pending requests may be holding a reference to us).
141   void Cleanup();
142 
143   // RenderProcessHost pointers are used to scope page IDs (see AddPage). These
144   // objects must tell us when they are being destroyed so that we can clear
145   // out any cached data associated with that scope.
146   //
147   // The given pointer will not be dereferenced, it is only used for
148   // identification purposes, hence it is a void*.
149   void NotifyRenderProcessHostDestruction(const void* host);
150 
151   // Triggers the backend to load if it hasn't already, and then returns the
152   // in-memory URL database. The returned pointer MAY BE NULL if the in-memory
153   // database has not been loaded yet. This pointer is owned by the history
154   // system. Callers should not store or cache this value.
155   //
156   // TODO(brettw) this should return the InMemoryHistoryBackend.
157   history::URLDatabase* InMemoryDatabase();
158 
159   // Return the quick history index.
160   history::InMemoryURLIndex* InMemoryIndex();
161 
162   // Navigation ----------------------------------------------------------------
163 
164   // Adds the given canonical URL to history with the current time as the visit
165   // time. Referrer may be the empty string.
166   //
167   // The supplied render process host is used to scope the given page ID. Page
168   // IDs are only unique inside a given render process, so we need that to
169   // differentiate them. This pointer should not be dereferenced by the history
170   // system. Since render view host pointers may be reused (if one gets deleted
171   // and a new one created at the same address), TabContents should notify
172   // us when they are being destroyed through NotifyTabContentsDestruction.
173   //
174   // The scope/ids can be NULL if there is no meaningful tracking information
175   // that can be performed on the given URL. The 'page_id' should be the ID of
176   // the current session history entry in the given process.
177   //
178   // 'redirects' is an array of redirect URLs leading to this page, with the
179   // page itself as the last item (so when there is no redirect, it will have
180   // one entry). If there are no redirects, this array may also be empty for
181   // the convenience of callers.
182   //
183   // 'did_replace_entry' is true when the navigation entry for this page has
184   // replaced the existing entry. A non-user initiated redirect causes such
185   // replacement.
186   //
187   // All "Add Page" functions will update the visited link database.
188   void AddPage(const GURL& url,
189                const void* id_scope,
190                int32 page_id,
191                const GURL& referrer,
192                PageTransition::Type transition,
193                const history::RedirectList& redirects,
194                history::VisitSource visit_source,
195                bool did_replace_entry);
196 
197   // For adding pages to history with a specific time. This is for testing
198   // purposes. Call the previous one to use the current time.
199   void AddPage(const GURL& url,
200                base::Time time,
201                const void* id_scope,
202                int32 page_id,
203                const GURL& referrer,
204                PageTransition::Type transition,
205                const history::RedirectList& redirects,
206                history::VisitSource visit_source,
207                bool did_replace_entry);
208 
209   // For adding pages to history where no tracking information can be done.
AddPage(const GURL & url,history::VisitSource visit_source)210   void AddPage(const GURL& url, history::VisitSource visit_source) {
211     AddPage(url, NULL, 0, GURL(), PageTransition::LINK,
212             history::RedirectList(), visit_source, false);
213   }
214 
215   // All AddPage variants end up here.
216   void AddPage(const history::HistoryAddPageArgs& add_page_args);
217 
218   // Adds an entry for the specified url without creating a visit. This should
219   // only be used when bookmarking a page, otherwise the row leaks in the
220   // history db (it never gets cleaned).
221   void AddPageNoVisitForBookmark(const GURL& url);
222 
223   // Sets the title for the given page. The page should be in history. If it
224   // is not, this operation is ignored. This call will not update the full
225   // text index. The last title set when the page is indexed will be the
226   // title in the full text index.
227   void SetPageTitle(const GURL& url, const string16& title);
228 
229   // Indexing ------------------------------------------------------------------
230 
231   // Notifies history of the body text of the given recently-visited URL.
232   // If the URL was not visited "recently enough," the history system may
233   // discard it.
234   void SetPageContents(const GURL& url, const string16& contents);
235 
236   // Querying ------------------------------------------------------------------
237 
238   // Callback class that a client can implement to iterate over URLs. The
239   // callbacks WILL BE CALLED ON THE BACKGROUND THREAD! Your implementation
240   // should handle this appropriately.
241   class URLEnumerator {
242    public:
~URLEnumerator()243     virtual ~URLEnumerator() {}
244 
245     // Indicates that a URL is available. There will be exactly one call for
246     // every URL in history.
247     virtual void OnURL(const GURL& url) = 0;
248 
249     // Indicates we are done iterating over URLs. Once called, there will be no
250     // more callbacks made. This call is guaranteed to occur, even if there are
251     // no URLs. If all URLs were iterated, success will be true.
252     virtual void OnComplete(bool success) = 0;
253   };
254 
255   // Enumerate all URLs in history. The given iterator will be owned by the
256   // caller, so the caller should ensure it exists until OnComplete is called.
257   // You should not generally use this since it will be slow to slurp all URLs
258   // in from the database. It is designed for rebuilding the visited link
259   // database from history.
260   void IterateURLs(URLEnumerator* iterator);
261 
262   // Returns the information about the requested URL. If the URL is found,
263   // success will be true and the information will be in the URLRow parameter.
264   // On success, the visits, if requested, will be sorted by date. If they have
265   // not been requested, the pointer will be valid, but the vector will be
266   // empty.
267   //
268   // If success is false, neither the row nor the vector will be valid.
269   typedef Callback4<Handle,
270                     bool,  // Success flag, when false, nothing else is valid.
271                     const history::URLRow*,
272                     history::VisitVector*>::Type
273       QueryURLCallback;
274 
275   // Queries the basic information about the URL in the history database. If
276   // the caller is interested in the visits (each time the URL is visited),
277   // set |want_visits| to true. If these are not needed, the function will be
278   // faster by setting this to false.
279   Handle QueryURL(const GURL& url,
280                   bool want_visits,
281                   CancelableRequestConsumerBase* consumer,
282                   QueryURLCallback* callback);
283 
284   // Provides the result of a query. See QueryResults in history_types.h.
285   // The common use will be to use QueryResults.Swap to suck the contents of
286   // the results out of the passed in parameter and take ownership of them.
287   typedef Callback2<Handle, history::QueryResults*>::Type
288       QueryHistoryCallback;
289 
290   // Queries all history with the given options (see QueryOptions in
291   // history_types.h). If non-empty, the full-text database will be queried with
292   // the given |text_query|. If empty, all results matching the given options
293   // will be returned.
294   //
295   // This isn't totally hooked up yet, this will query the "new" full text
296   // database (see SetPageContents) which won't generally be set yet.
297   Handle QueryHistory(const string16& text_query,
298                       const history::QueryOptions& options,
299                       CancelableRequestConsumerBase* consumer,
300                       QueryHistoryCallback* callback);
301 
302   // Called when the results of QueryRedirectsFrom are available.
303   // The given vector will contain a list of all redirects, not counting
304   // the original page. If A redirects to B, the vector will contain only B,
305   // and A will be in 'source_url'.
306   //
307   // If there is no such URL in the database or the most recent visit has no
308   // redirect, the vector will be empty. If the history system failed for
309   // some reason, success will additionally be false. If the given page
310   // has redirected to multiple destinations, this will pick a random one.
311   typedef Callback4<Handle,
312                     GURL,  // from_url
313                     bool,  // success
314                     history::RedirectList*>::Type
315       QueryRedirectsCallback;
316 
317   // Schedules a query for the most recent redirect coming out of the given
318   // URL. See the RedirectQuerySource above, which is guaranteed to be called
319   // if the request is not canceled.
320   Handle QueryRedirectsFrom(const GURL& from_url,
321                             CancelableRequestConsumerBase* consumer,
322                             QueryRedirectsCallback* callback);
323 
324   // Schedules a query to get the most recent redirects ending at the given
325   // URL.
326   Handle QueryRedirectsTo(const GURL& to_url,
327                           CancelableRequestConsumerBase* consumer,
328                           QueryRedirectsCallback* callback);
329 
330   typedef Callback4<Handle,
331                     bool,        // Were we able to determine the # of visits?
332                     int,         // Number of visits.
333                     base::Time>::Type  // Time of first visit. Only first bool
334                                        // is true and int is > 0.
335       GetVisitCountToHostCallback;
336 
337   // Requests the number of visits to all urls on the scheme/host/post
338   // identified by url. This is only valid for http and https urls.
339   Handle GetVisitCountToHost(const GURL& url,
340                              CancelableRequestConsumerBase* consumer,
341                              GetVisitCountToHostCallback* callback);
342 
343   // Called when QueryTopURLsAndRedirects completes. The vector contains a list
344   // of the top |result_count| URLs.  For each of these URLs, there is an entry
345   // in the map containing redirects from the URL.  For example, if we have the
346   // redirect chain A -> B -> C and A is a top visited URL, then A will be in
347   // the vector and "A => {B -> C}" will be in the map.
348   typedef Callback4<Handle,
349                     bool,  // Did we get the top urls and redirects?
350                     std::vector<GURL>*,  // List of top URLs.
351                     history::RedirectMap*>::Type  // Redirects for top URLs.
352       QueryTopURLsAndRedirectsCallback;
353 
354   // Request the top |result_count| most visited URLs and the chain of redirects
355   // leading to each of these URLs.
356   // TODO(Nik): remove this. Use QueryMostVisitedURLs instead.
357   Handle QueryTopURLsAndRedirects(int result_count,
358                                   CancelableRequestConsumerBase* consumer,
359                                   QueryTopURLsAndRedirectsCallback* callback);
360 
361   typedef Callback2<Handle, history::MostVisitedURLList>::Type
362                     QueryMostVisitedURLsCallback;
363 
364   // Request the |result_count| most visited URLs and the chain of
365   // redirects leading to each of these URLs. |days_back| is the
366   // number of days of history to use. Used by TopSites.
367   Handle QueryMostVisitedURLs(int result_count, int days_back,
368                               CancelableRequestConsumerBase* consumer,
369                               QueryMostVisitedURLsCallback* callback);
370 
371   // Thumbnails ----------------------------------------------------------------
372 
373   // Implemented by consumers to get thumbnail data. Called when a request for
374   // the thumbnail data is complete. Once this callback is made, the request
375   // will be completed and no other calls will be made for that handle.
376   //
377   // This function will be called even on error conditions or if there is no
378   // thumbnail for that page. In these cases, the data pointer will be NULL.
379   typedef Callback2<Handle, scoped_refptr<RefCountedBytes> >::Type
380       ThumbnailDataCallback;
381 
382   // Sets the thumbnail for a given URL. The URL must be in the history
383   // database or the request will be ignored.
384   void SetPageThumbnail(const GURL& url,
385                         const SkBitmap& thumbnail,
386                         const ThumbnailScore& score);
387 
388   // Requests a page thumbnail. See ThumbnailDataCallback definition above.
389   Handle GetPageThumbnail(const GURL& page_url,
390                           CancelableRequestConsumerBase* consumer,
391                           ThumbnailDataCallback* callback);
392 
393   // Database management operations --------------------------------------------
394 
395   // Delete all the information related to a single url.
396   void DeleteURL(const GURL& url);
397 
398   // Implemented by the caller of ExpireHistoryBetween, and
399   // is called when the history service has deleted the history.
400   typedef Callback0::Type ExpireHistoryCallback;
401 
402   // Removes all visits in the selected time range (including the start time),
403   // updating the URLs accordingly. This deletes the associated data, including
404   // the full text index. This function also deletes the associated favicons,
405   // if they are no longer referenced. |callback| runs when the expiration is
406   // complete. You may use null Time values to do an unbounded delete in
407   // either direction.
408   // If |restrict_urls| is not empty, only visits to the URLs in this set are
409   // removed.
410   void ExpireHistoryBetween(const std::set<GURL>& restrict_urls,
411                             base::Time begin_time, base::Time end_time,
412                             CancelableRequestConsumerBase* consumer,
413                             ExpireHistoryCallback* callback);
414 
415   // Downloads -----------------------------------------------------------------
416 
417   // Implemented by the caller of 'CreateDownload' below, and is called when the
418   // history service has created a new entry for a download in the history db.
419   typedef Callback2<DownloadCreateInfo, int64>::Type
420       DownloadCreateCallback;
421 
422   // Begins a history request to create a new persistent entry for a download.
423   // 'info' contains all the download's creation state, and 'callback' runs
424   // when the history service request is complete.
425   Handle CreateDownload(const DownloadCreateInfo& info,
426                         CancelableRequestConsumerBase* consumer,
427                         DownloadCreateCallback* callback);
428 
429   // Implemented by the caller of 'QueryDownloads' below, and is called when the
430   // history service has retrieved a list of all download state. The call
431   typedef Callback1<std::vector<DownloadCreateInfo>*>::Type
432       DownloadQueryCallback;
433 
434   // Begins a history request to retrieve the state of all downloads in the
435   // history db. 'callback' runs when the history service request is complete,
436   // at which point 'info' contains an array of DownloadCreateInfo, one per
437   // download.
438   Handle QueryDownloads(CancelableRequestConsumerBase* consumer,
439                         DownloadQueryCallback* callback);
440 
441   // Begins a request to clean up entries that has been corrupted (because of
442   // the crash, for example).
443   void CleanUpInProgressEntries();
444 
445   // Called to update the history service about the current state of a download.
446   // This is a 'fire and forget' query, so just pass the relevant state info to
447   // the database with no need for a callback.
448   void UpdateDownload(int64 received_bytes, int32 state, int64 db_handle);
449 
450   // Called to update the history service about the path of a download.
451   // This is a 'fire and forget' query.
452   void UpdateDownloadPath(const FilePath& path, int64 db_handle);
453 
454   // Permanently remove a download from the history system. This is a 'fire and
455   // forget' operation.
456   void RemoveDownload(int64 db_handle);
457 
458   // Permanently removes all completed download from the history system within
459   // the specified range. This function does not delete downloads that are in
460   // progress or in the process of being cancelled. This is a 'fire and forget'
461   // operation. You can pass is_null times to get unbounded time in either or
462   // both directions.
463   void RemoveDownloadsBetween(base::Time remove_begin, base::Time remove_end);
464 
465   // Visit Segments ------------------------------------------------------------
466 
467   typedef Callback2<Handle, std::vector<PageUsageData*>*>::Type
468       SegmentQueryCallback;
469 
470   // Query usage data for all visit segments since the provided time.
471   //
472   // The request is performed asynchronously and can be cancelled by using the
473   // returned handle.
474   //
475   // The vector provided to the callback and its contents is owned by the
476   // history system. It will be deeply deleted after the callback is invoked.
477   // If you want to preserve any PageUsageData instance, simply remove them
478   // from the vector.
479   //
480   // The vector contains a list of PageUsageData. Each PageUsageData ID is set
481   // to the segment ID. The URL and all the other information is set to the page
482   // representing the segment.
483   Handle QuerySegmentUsageSince(CancelableRequestConsumerBase* consumer,
484                                 const base::Time from_time,
485                                 int max_result_count,
486                                 SegmentQueryCallback* callback);
487 
488   // Set the presentation index for the segment identified by |segment_id|.
489   void SetSegmentPresentationIndex(int64 segment_id, int index);
490 
491   // Keyword search terms -----------------------------------------------------
492 
493   // Sets the search terms for the specified url and keyword. url_id gives the
494   // id of the url, keyword_id the id of the keyword and term the search term.
495   void SetKeywordSearchTermsForURL(const GURL& url,
496                                    TemplateURLID keyword_id,
497                                    const string16& term);
498 
499   // Deletes all search terms for the specified keyword.
500   void DeleteAllSearchTermsForKeyword(TemplateURLID keyword_id);
501 
502   typedef Callback2<Handle, std::vector<history::KeywordSearchTermVisit>*>::Type
503       GetMostRecentKeywordSearchTermsCallback;
504 
505   // Returns up to max_count of the most recent search terms starting with the
506   // specified text. The matching is case insensitive. The results are ordered
507   // in descending order up to |max_count| with the most recent search term
508   // first.
509   Handle GetMostRecentKeywordSearchTerms(
510       TemplateURLID keyword_id,
511       const string16& prefix,
512       int max_count,
513       CancelableRequestConsumerBase* consumer,
514       GetMostRecentKeywordSearchTermsCallback* callback);
515 
516   // Bookmarks -----------------------------------------------------------------
517 
518   // Notification that a URL is no longer bookmarked.
519   void URLsNoLongerBookmarked(const std::set<GURL>& urls);
520 
521   // Generic Stuff -------------------------------------------------------------
522 
523   typedef Callback0::Type HistoryDBTaskCallback;
524 
525   // Schedules a HistoryDBTask for running on the history backend thread. See
526   // HistoryDBTask for details on what this does.
527   virtual Handle ScheduleDBTask(HistoryDBTask* task,
528                                 CancelableRequestConsumerBase* consumer);
529 
530   // Returns true if top sites needs to be migrated out of history into its own
531   // db.
needs_top_sites_migration()532   bool needs_top_sites_migration() const { return needs_top_sites_migration_; }
533 
534   // Testing -------------------------------------------------------------------
535 
536   // Designed for unit tests, this passes the given task on to the history
537   // backend to be called once the history backend has terminated. This allows
538   // callers to know when the history thread is complete and the database files
539   // can be deleted and the next test run. Otherwise, the history thread may
540   // still be running, causing problems in subsequent tests.
541   //
542   // There can be only one closing task, so this will override any previously
543   // set task. We will take ownership of the pointer and delete it when done.
544   // The task will be run on the calling thread (this function is threadsafe).
545   void SetOnBackendDestroyTask(Task* task);
546 
547   // Used for unit testing and potentially importing to get known information
548   // into the database. This assumes the URL doesn't exist in the database
549   //
550   // Calling this function many times may be slow because each call will
551   // dispatch to the history thread and will be a separate database
552   // transaction. If this functionality is needed for importing many URLs, a
553   // version that takes an array should probably be added.
554   void AddPageWithDetails(const GURL& url,
555                           const string16& title,
556                           int visit_count,
557                           int typed_count,
558                           base::Time last_visit,
559                           bool hidden,
560                           history::VisitSource visit_source);
561 
562   // The same as AddPageWithDetails() but takes a vector.
563   void AddPagesWithDetails(const std::vector<history::URLRow>& info,
564                            history::VisitSource visit_source);
565 
566   // Starts the TopSites migration in the HistoryThread. Called by the
567   // BackendDelegate.
568   void StartTopSitesMigration();
569 
570   // Called by TopSites after the thumbnails were read and it is safe
571   // to delete the thumbnails DB.
572   void OnTopSitesReady();
573 
574   // Returns true if this looks like the type of URL we want to add to the
575   // history. We filter out some URLs such as JavaScript.
576   static bool CanAddURL(const GURL& url);
577 
578  protected:
579   ~HistoryService();
580 
581   // These are not currently used, hopefully we can do something in the future
582   // to ensure that the most important things happen first.
583   enum SchedulePriority {
584     PRIORITY_UI,      // The highest priority (must respond to UI events).
585     PRIORITY_NORMAL,  // Normal stuff like adding a page.
586     PRIORITY_LOW,     // Low priority things like indexing or expiration.
587   };
588 
589  private:
590   class BackendDelegate;
591   friend class base::RefCountedThreadSafe<HistoryService>;
592   friend class BackendDelegate;
593   friend class FaviconService;
594   friend class history::HistoryBackend;
595   friend class history::HistoryQueryTest;
596   friend class HistoryOperation;
597   friend class HistoryURLProvider;
598   friend class HistoryURLProviderTest;
599   template<typename Info, typename Callback> friend class DownloadRequest;
600   friend class PageUsageRequest;
601   friend class RedirectRequest;
602   friend class TestingProfile;
603 
604   // Implementation of NotificationObserver.
605   virtual void Observe(NotificationType type,
606                        const NotificationSource& source,
607                        const NotificationDetails& details);
608 
609   // Low-level Init().  Same as the public version, but adds a |no_db| parameter
610   // that is only set by unittests which causes the backend to not init its DB.
611   bool Init(const FilePath& history_dir,
612             BookmarkService* bookmark_service,
613             bool no_db);
614 
615   // Called by the HistoryURLProvider class to schedule an autocomplete, it
616   // will be called back on the internal history thread with the history
617   // database so it can query. See history_autocomplete.cc for a diagram.
618   void ScheduleAutocomplete(HistoryURLProvider* provider,
619                             HistoryURLProviderParams* params);
620 
621   // Broadcasts the given notification. This is called by the backend so that
622   // the notification will be broadcast on the main thread.
623   //
624   // The |details_deleted| pointer will be sent as the "details" for the
625   // notification. The function takes ownership of the pointer and deletes it
626   // when the notification is sent (it is coming from another thread, so must
627   // be allocated on the heap).
628   void BroadcastNotifications(NotificationType type,
629                               history::HistoryDetails* details_deleted);
630 
631   // Initializes the backend.
632   void LoadBackendIfNecessary();
633 
634   // Notification from the backend that it has finished loading. Sends
635   // notification (NOTIFY_HISTORY_LOADED) and sets backend_loaded_ to true.
636   void OnDBLoaded();
637 
638   // Favicon -------------------------------------------------------------------
639 
640   // These favicon methods are exposed to the FaviconService. Instead of calling
641   // these methods directly you should call the respective method on the
642   // FaviconService.
643 
644   // Used by the FaviconService to get a favicon from the history backend.
645   void GetFavicon(FaviconService::GetFaviconRequest* request,
646                   const GURL& icon_url,
647                   history::IconType icon_type);
648 
649   // Used by the FaviconService to update the favicon mappings on the history
650   // backend.
651   void UpdateFaviconMappingAndFetch(FaviconService::GetFaviconRequest* request,
652                                     const GURL& page_url,
653                                     const GURL& icon_url,
654                                     history::IconType icon_type);
655 
656   // Used by the FaviconService to get a favicon from the history backend.
657   void GetFaviconForURL(FaviconService::GetFaviconRequest* request,
658                         const GURL& page_url,
659                         int icon_types);
660 
661   // Used by the FaviconService to mark the favicon for the page as being out
662   // of date.
663   void SetFaviconOutOfDateForPage(const GURL& page_url);
664 
665   // Used by the FaviconService for importing many favicons for many pages at
666   // once. The pages must exist, any favicon sets for unknown pages will be
667   // discarded. Existing favicons will not be overwritten.
668   void SetImportedFavicons(
669       const std::vector<history::ImportedFaviconUsage>& favicon_usage);
670 
671   // Used by the FaviconService to set the favicon for a page on the history
672   // backend.
673   void SetFavicon(const GURL& page_url,
674                   const GURL& icon_url,
675                   const std::vector<unsigned char>& image_data,
676                   history::IconType icon_type);
677 
678 
679   // Sets the in-memory URL database. This is called by the backend once the
680   // database is loaded to make it available.
681   void SetInMemoryBackend(history::InMemoryHistoryBackend* mem_backend);
682 
683   // Called by our BackendDelegate when there is a problem reading the database.
684   void NotifyProfileError(sql::InitStatus init_status);
685 
686   // Call to schedule a given task for running on the history thread with the
687   // specified priority. The task will have ownership taken.
688   void ScheduleTask(SchedulePriority priority, Task* task);
689 
690   // Schedule ------------------------------------------------------------------
691   //
692   // Functions for scheduling operations on the history thread that have a
693   // handle and may be cancelable. For fire-and-forget operations, see
694   // ScheduleAndForget below.
695 
696   template<typename BackendFunc, class RequestType>
Schedule(SchedulePriority priority,BackendFunc func,CancelableRequestConsumerBase * consumer,RequestType * request)697   Handle Schedule(SchedulePriority priority,
698                   BackendFunc func,  // Function to call on the HistoryBackend.
699                   CancelableRequestConsumerBase* consumer,
700                   RequestType* request) {
701     DCHECK(thread_) << "History service being called after cleanup";
702     LoadBackendIfNecessary();
703     if (consumer)
704       AddRequest(request, consumer);
705     ScheduleTask(priority,
706                  NewRunnableMethod(history_backend_.get(), func,
707                                    scoped_refptr<RequestType>(request)));
708     return request->handle();
709   }
710 
711   template<typename BackendFunc, class RequestType, typename ArgA>
Schedule(SchedulePriority priority,BackendFunc func,CancelableRequestConsumerBase * consumer,RequestType * request,const ArgA & a)712   Handle Schedule(SchedulePriority priority,
713                   BackendFunc func,  // Function to call on the HistoryBackend.
714                   CancelableRequestConsumerBase* consumer,
715                   RequestType* request,
716                   const ArgA& a) {
717     DCHECK(thread_) << "History service being called after cleanup";
718     LoadBackendIfNecessary();
719     if (consumer)
720       AddRequest(request, consumer);
721     ScheduleTask(priority,
722                  NewRunnableMethod(history_backend_.get(), func,
723                                    scoped_refptr<RequestType>(request),
724                                    a));
725     return request->handle();
726   }
727 
728   template<typename BackendFunc,
729            class RequestType,  // Descendant of CancelableRequstBase.
730            typename ArgA,
731            typename ArgB>
Schedule(SchedulePriority priority,BackendFunc func,CancelableRequestConsumerBase * consumer,RequestType * request,const ArgA & a,const ArgB & b)732   Handle Schedule(SchedulePriority priority,
733                   BackendFunc func,  // Function to call on the HistoryBackend.
734                   CancelableRequestConsumerBase* consumer,
735                   RequestType* request,
736                   const ArgA& a,
737                   const ArgB& b) {
738     DCHECK(thread_) << "History service being called after cleanup";
739     LoadBackendIfNecessary();
740     if (consumer)
741       AddRequest(request, consumer);
742     ScheduleTask(priority,
743                  NewRunnableMethod(history_backend_.get(), func,
744                                    scoped_refptr<RequestType>(request),
745                                    a, b));
746     return request->handle();
747   }
748 
749   template<typename BackendFunc,
750            class RequestType,  // Descendant of CancelableRequstBase.
751            typename ArgA,
752            typename ArgB,
753            typename ArgC>
Schedule(SchedulePriority priority,BackendFunc func,CancelableRequestConsumerBase * consumer,RequestType * request,const ArgA & a,const ArgB & b,const ArgC & c)754   Handle Schedule(SchedulePriority priority,
755                   BackendFunc func,  // Function to call on the HistoryBackend.
756                   CancelableRequestConsumerBase* consumer,
757                   RequestType* request,
758                   const ArgA& a,
759                   const ArgB& b,
760                   const ArgC& c) {
761     DCHECK(thread_) << "History service being called after cleanup";
762     LoadBackendIfNecessary();
763     if (consumer)
764       AddRequest(request, consumer);
765     ScheduleTask(priority,
766                  NewRunnableMethod(history_backend_.get(), func,
767                                    scoped_refptr<RequestType>(request),
768                                    a, b, c));
769     return request->handle();
770   }
771 
772   // ScheduleAndForget ---------------------------------------------------------
773   //
774   // Functions for scheduling operations on the history thread that do not need
775   // any callbacks and are not cancelable.
776 
777   template<typename BackendFunc>
ScheduleAndForget(SchedulePriority priority,BackendFunc func)778   void ScheduleAndForget(SchedulePriority priority,
779                          BackendFunc func) {  // Function to call on backend.
780     DCHECK(thread_) << "History service being called after cleanup";
781     LoadBackendIfNecessary();
782     ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func));
783   }
784 
785   template<typename BackendFunc, typename ArgA>
ScheduleAndForget(SchedulePriority priority,BackendFunc func,const ArgA & a)786   void ScheduleAndForget(SchedulePriority priority,
787                          BackendFunc func,  // Function to call on backend.
788                          const ArgA& a) {
789     DCHECK(thread_) << "History service being called after cleanup";
790     LoadBackendIfNecessary();
791     ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func, a));
792   }
793 
794   template<typename BackendFunc, typename ArgA, typename ArgB>
ScheduleAndForget(SchedulePriority priority,BackendFunc func,const ArgA & a,const ArgB & b)795   void ScheduleAndForget(SchedulePriority priority,
796                          BackendFunc func,  // Function to call on backend.
797                          const ArgA& a,
798                          const ArgB& b) {
799     DCHECK(thread_) << "History service being called after cleanup";
800     LoadBackendIfNecessary();
801     ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func,
802                                              a, b));
803   }
804 
805   template<typename BackendFunc, typename ArgA, typename ArgB, typename ArgC>
ScheduleAndForget(SchedulePriority priority,BackendFunc func,const ArgA & a,const ArgB & b,const ArgC & c)806   void ScheduleAndForget(SchedulePriority priority,
807                          BackendFunc func,  // Function to call on backend.
808                          const ArgA& a,
809                          const ArgB& b,
810                          const ArgC& c) {
811     DCHECK(thread_) << "History service being called after cleanup";
812     LoadBackendIfNecessary();
813     ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func,
814                                              a, b, c));
815   }
816 
817   template<typename BackendFunc,
818            typename ArgA,
819            typename ArgB,
820            typename ArgC,
821            typename ArgD>
ScheduleAndForget(SchedulePriority priority,BackendFunc func,const ArgA & a,const ArgB & b,const ArgC & c,const ArgD & d)822   void ScheduleAndForget(SchedulePriority priority,
823                          BackendFunc func,  // Function to call on backend.
824                          const ArgA& a,
825                          const ArgB& b,
826                          const ArgC& c,
827                          const ArgD& d) {
828     DCHECK(thread_) << "History service being called after cleanup";
829     LoadBackendIfNecessary();
830     ScheduleTask(priority, NewRunnableMethod(history_backend_.get(), func,
831                                              a, b, c, d));
832   }
833 
834   NotificationRegistrar registrar_;
835 
836   // Some void primitives require some internal processing in the main thread
837   // when done. We use this internal consumer for this purpose.
838   CancelableRequestConsumer internal_consumer_;
839 
840   // The thread used by the history service to run complicated operations.
841   // |thread_| is NULL once |Cleanup| is NULL.
842   base::Thread* thread_;
843 
844   // This class has most of the implementation and runs on the 'thread_'.
845   // You MUST communicate with this class ONLY through the thread_'s
846   // message_loop().
847   //
848   // This pointer will be NULL once Cleanup() has been called, meaning no
849   // more calls should be made to the history thread.
850   scoped_refptr<history::HistoryBackend> history_backend_;
851 
852   // A cache of the user-typed URLs kept in memory that is used by the
853   // autocomplete system. This will be NULL until the database has been created
854   // on the background thread.
855   scoped_ptr<history::InMemoryHistoryBackend> in_memory_backend_;
856 
857   // The profile, may be null when testing.
858   Profile* profile_;
859 
860   // Has the backend finished loading? The backend is loaded once Init has
861   // completed.
862   bool backend_loaded_;
863 
864   // Cached values from Init(), used whenever we need to reload the backend.
865   FilePath history_dir_;
866   BookmarkService* bookmark_service_;
867   bool no_db_;
868 
869   // True if needs top site migration.
870   bool needs_top_sites_migration_;
871 
872   DISALLOW_COPY_AND_ASSIGN(HistoryService);
873 };
874 
875 #endif  // CHROME_BROWSER_HISTORY_HISTORY_H_
876