history_service.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The history system runs on a background thread so that potentially slow
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// database operations don't delay the browser. This backend processing is
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// represented by HistoryBackend. The HistoryService's job is to dispatch to
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that thread.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Main thread                       History thread
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------                       --------------
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HistoryService <----------------> HistoryBackend
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                   -> HistoryDatabase
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                      -> SQLite connection to History
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                   -> ThumbnailDatabase
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                      -> SQLite connection to Thumbnails
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                         (and favicons)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind_helpers.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/location.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
279ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/thread_task_runner_handle.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/history_url_provider.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/download_row.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_backend.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_notifications.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_types.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_database.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_history_backend.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_url_index.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/top_sites.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/visit_database.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/visit_filter.h"
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/web_history_service.h"
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/web_history_service_factory.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/profile_error_dialog.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/importer/imported_favicon_usage.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/thumbnail_score.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/history/core/browser/history_client.h"
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/visitedlink/browser/visitedlink_master.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/browser/download_item.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/sync_error_factory.h"
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using history::HistoryBackend;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kHistoryThreadName = "Chrome_HistoryThread";
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RunWithFaviconResults(
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const favicon_base::FaviconResultsCallback& callback,
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    std::vector<favicon_base::FaviconBitmapResult>* bitmap_results) {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(*bitmap_results);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RunWithFaviconResult(const favicon_base::FaviconRawCallback& callback,
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                          favicon_base::FaviconBitmapResult* bitmap_result) {
818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  callback.Run(*bitmap_result);
828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Extract history::URLRows into GURLs for VisitedLinkMaster.
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class URLIteratorFromURLRows
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : public visitedlink::VisitedLinkMaster::URLIterator {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit URLIteratorFromURLRows(const history::URLRows& url_rows)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : itr_(url_rows.begin()),
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        end_(url_rows.end()) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const GURL& NextURL() OVERRIDE {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (itr_++)->url();
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool HasNextURL() const OVERRIDE {
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return itr_ != end_;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  history::URLRows::const_iterator itr_;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  history::URLRows::const_iterator end_;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(URLIteratorFromURLRows);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Callback from WebHistoryService::ExpireWebHistory().
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ExpireWebHistoryComplete(bool success) {
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Ignore the result.
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  //
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(davidben): ExpireLocalAndRemoteHistoryBetween callback should not fire
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // until this completes.
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sends messages from the backend to us on the main thread. This must be a
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// separate class from the history service so that it can hold a reference to
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the history service (otherwise we would have to manually AddRef and
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Release when the Backend has a reference to us).
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistoryService::BackendDelegate : public HistoryBackend::Delegate {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackendDelegate(
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::WeakPtr<HistoryService>& history_service,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const scoped_refptr<base::SequencedTaskRunner>& service_task_runner,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Profile* profile)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : history_service_(history_service),
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        service_task_runner_(service_task_runner),
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        profile_(profile) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void NotifyProfileError(sql::InitStatus init_status) OVERRIDE {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send to the history service on the main thread.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::NotifyProfileError, history_service_,
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   init_status));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void SetInMemoryBackend(
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      scoped_ptr<history::InMemoryHistoryBackend> backend) OVERRIDE {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send the backend to the history service on the main thread.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::SetInMemoryBackend, history_service_,
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   base::Passed(&backend)));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void BroadcastNotifications(
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int type,
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      scoped_ptr<history::HistoryDetails> details) OVERRIDE {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send the notification on the history thread.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (content::NotificationService::current()) {
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      content::Details<history::HistoryDetails> det(details.get());
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::current()->Notify(
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          type, content::Source<Profile>(profile_), det);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send the notification to the history service on the main thread.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::BroadcastNotificationsHelper,
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   history_service_, type, base::Passed(&details)));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void DBLoaded() OVERRIDE {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&HistoryService::OnDBLoaded, history_service_));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void NotifyVisitDBObserversOnAddVisit(
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const history::BriefVisitInfo& info) OVERRIDE {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::NotifyVisitDBObserversOnAddVisit,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   history_service_, info));
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::WeakPtr<HistoryService> history_service_;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_refptr<base::SequencedTaskRunner> service_task_runner_;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* const profile_;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The history thread is intentionally not a BrowserThread because the
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sync integration unit tests depend on being able to create more than one
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// history thread.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::HistoryService()
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : weak_ptr_factory_(this),
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      thread_(new base::Thread(kHistoryThreadName)),
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      history_client_(NULL),
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_(NULL),
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_loaded_(false),
1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      no_db_(false) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)HistoryService::HistoryService(history::HistoryClient* client, Profile* profile)
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : weak_ptr_factory_(this),
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      thread_(new base::Thread(kHistoryThreadName)),
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      history_client_(client),
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_(profile),
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      visitedlink_master_(new visitedlink::VisitedLinkMaster(
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          profile, this, true)),
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_loaded_(false),
2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      no_db_(false) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(profile_);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<Profile>(profile_));
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_TEMPLATE_URL_REMOVED,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<Profile>(profile_));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::~HistoryService() {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shutdown the backend. This does nothing if Cleanup was already invoked.
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cleanup();
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::BackendLoaded() {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_loaded_;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::Cleanup() {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thread_) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We've already cleaned up.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  weak_ptr_factory_.InvalidateWeakPtrs();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unload the backend.
235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (history_backend_) {
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Get rid of the in-memory backend.
237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    in_memory_backend_.reset();
238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Give the InMemoryURLIndex a chance to shutdown.
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // NOTE: In tests, there may be no index.
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (in_memory_url_index_)
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      in_memory_url_index_->ShutDown();
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // The backend's destructor must run on the history thread since it is not
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // threadsafe. So this thread must not be the last thread holding a
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // reference to the backend, or a crash could happen.
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    //
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // We have a reference to the history backend. There is also an extra
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // reference held by our delegate installed in the backend, which
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // HistoryBackend::Closing will release. This means if we scheduled a call
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // to HistoryBackend::Closing and *then* released our backend reference,
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // there will be a race between us and the backend's Closing function to see
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // who is the last holder of a reference. If the backend thread's Closing
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // manages to run before we release our backend refptr, the last reference
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // will be held by this thread and the destructor will be called from here.
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    //
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Therefore, we create a closure to run the Closing operation first. This
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // holds a reference to the backend. Then we release our reference, then we
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // schedule the task to run. After the task runs, it will delete its
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // reference from the history thread, ensuring everything works properly.
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    //
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // TODO(ajwong): Cleanup HistoryBackend lifetime issues.
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    //     See http://crbug.com/99767.
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    history_backend_->AddRef();
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Closure closing_task =
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&HistoryBackend::Closing, history_backend_.get());
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ScheduleTask(PRIORITY_NORMAL, closing_task);
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    closing_task.Reset();
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    HistoryBackend* raw_ptr = history_backend_.get();
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    history_backend_ = NULL;
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    thread_->message_loop()->ReleaseSoon(FROM_HERE, raw_ptr);
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete the thread, which joins with the background thread. We defensively
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NULL the pointer before deleting it in case somebody tries to use it
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // during shutdown, but this shouldn't happen.
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Thread* thread = thread_;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thread_ = NULL;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete thread;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::NotifyRenderProcessHostDestruction(const void* host) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::NotifyRenderProcessHostDestruction, host);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)history::URLDatabase* HistoryService::InMemoryDatabase() {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return in_memory_backend_ ? in_memory_backend_->db() : NULL;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::GetTypedCountForURL(const GURL& url, int* typed_count) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRow url_row;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetRowForURL(url, &url_row))
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *typed_count = url_row.typed_count();
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::GetLastVisitTimeForURL(const GURL& url,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            base::Time* last_visit) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRow url_row;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetRowForURL(url, &url_row))
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *last_visit = url_row.last_visit();
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::GetVisitCountForURL(const GURL& url, int* visit_count) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRow url_row;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetRowForURL(url, &url_row))
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *visit_count = url_row.visit_count();
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
321b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)history::TypedUrlSyncableService* HistoryService::GetTypedUrlSyncableService()
322b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const {
323b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return history_backend_->GetTypedUrlSyncableService();
324b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
325b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::Shutdown() {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cleanup();
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetKeywordSearchTermsForURL(const GURL& url,
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 TemplateURLID keyword_id,
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                 const base::string16& term) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::SetKeywordSearchTermsForURL,
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    url, keyword_id, term);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::DeleteAllSearchTermsForKeyword(
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TemplateURLID keyword_id) {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI,
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::DeleteAllSearchTermsForKeyword,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    keyword_id);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::GetMostRecentKeywordSearchTerms(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TemplateURLID keyword_id,
350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& prefix,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int max_count,
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GetMostRecentKeywordSearchTermsCallback& callback) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_UI, &HistoryBackend::GetMostRecentKeywordSearchTerms,
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  consumer,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  new history::GetMostRecentKeywordSearchTermsRequest(callback),
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  keyword_id, prefix, max_count);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void HistoryService::DeleteKeywordSearchTermForURL(const GURL& url) {
3620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI, &HistoryBackend::DeleteKeywordSearchTermForURL,
3640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                    url);
3650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
3660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void HistoryService::DeleteMatchingURLsForKeyword(TemplateURLID keyword_id,
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                  const base::string16& term) {
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI, &HistoryBackend::DeleteMatchingURLsForKeyword,
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    keyword_id, term);
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::URLsNoLongerBookmarked(const std::set<GURL>& urls) {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::URLsNoLongerBookmarked,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    urls);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::ScheduleDBTask(history::HistoryDBTask* task,
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    CancelableRequestConsumerBase* consumer) {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::HistoryDBTaskRequest* request = new history::HistoryDBTaskRequest(
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&history::HistoryDBTask::DoneRunOnMainThread, task));
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request->value = task;  // The value is the task to execute.
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Schedule(PRIORITY_UI, &HistoryBackend::ProcessDBTask, consumer, request);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QuerySegmentUsageSince(
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Time from_time,
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int max_result_count,
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SegmentQueryCallback& callback) {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_UI, &HistoryBackend::QuerySegmentUsage,
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  consumer, new history::QuerySegmentUsageRequest(callback),
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  from_time, max_result_count);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HistoryService::FlushForTest(const base::Closure& flushed) {
4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  thread_->message_loop_proxy()->PostTaskAndReply(
4027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      FROM_HERE, base::Bind(&base::DoNothing), flushed);
4037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetOnBackendDestroyTask(const base::Closure& task) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetOnBackendDestroyTask,
40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                    base::MessageLoop::current(), task);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPage(const GURL& url,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             Time time,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const void* id_scope,
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int32 page_id,
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const GURL& referrer,
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const history::RedirectList& redirects,
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             content::PageTransition transition,
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::VisitSource visit_source,
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool did_replace_entry) {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddPage(
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::HistoryAddPageArgs(url, time, id_scope, page_id, referrer,
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  redirects, transition, visit_source,
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  did_replace_entry));
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPage(const GURL& url,
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             base::Time time,
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::VisitSource visit_source) {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddPage(
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::HistoryAddPageArgs(url, time, NULL, 0, GURL(),
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  history::RedirectList(),
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  content::PAGE_TRANSITION_LINK,
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  visit_source, false));
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPage(const history::HistoryAddPageArgs& add_page_args) {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Filter out unwanted URLs. We don't add auto-subframe URLs. They are a
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // large part of history (think iframes for ads) and we never display them in
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // history UI. We will still add manual subframes, which are ones the user
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has clicked on to get.
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(add_page_args.url))
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add link & all redirects to visited link list.
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visitedlink_master_) {
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitedlink_master_->AddURL(add_page_args.url);
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!add_page_args.redirects.empty()) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We should not be asked to add a page in the middle of a redirect chain.
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK_EQ(add_page_args.url,
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                add_page_args.redirects[add_page_args.redirects.size() - 1]);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We need the !redirects.empty() condition above since size_t is unsigned
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // and will wrap around when we subtract one from a 0 size.
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (size_t i = 0; i < add_page_args.redirects.size() - 1; i++)
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        visitedlink_master_->AddURL(add_page_args.redirects[i]);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::AddPage, add_page_args);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPageNoVisitForBookmark(const GURL& url,
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                               const base::string16& title) {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(url))
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::AddPageNoVisitForBookmark, url, title);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetPageTitle(const GURL& url,
479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  const base::string16& title) {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetPageTitle, url, title);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::UpdateWithPageEndTime(const void* host,
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           int32 page_id,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const GURL& url,
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           Time end_ts) {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::UpdateWithPageEndTime,
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    host, page_id, url, end_ts);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPageWithDetails(const GURL& url,
494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        const base::string16& title,
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int visit_count,
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int typed_count,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        Time last_visit,
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        bool hidden,
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        history::VisitSource visit_source) {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Filter out unwanted URLs.
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(url))
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add to the visited links system.
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visitedlink_master_)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitedlink_master_->AddURL(url);
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRow row(url);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_title(title);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_visit_count(visit_count);
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_typed_count(typed_count);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_last_visit(last_visit);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_hidden(hidden);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRows rows;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rows.push_back(row);
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::AddPagesWithDetails, rows, visit_source);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPagesWithDetails(const history::URLRows& info,
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         history::VisitSource visit_source) {
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add to the visited links system.
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visitedlink_master_) {
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<GURL> urls;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    urls.reserve(info.size());
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (history::URLRows::const_iterator i = info.begin(); i != info.end();
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         ++i)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      urls.push_back(i->url());
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitedlink_master_->AddURLs(urls);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::AddPagesWithDetails, info, visit_source);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId HistoryService::GetFavicons(
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<GURL>& icon_urls,
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int icon_types,
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int desired_size_in_dip,
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<ui::ScaleFactor>& desired_scale_factors,
546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const favicon_base::FaviconResultsCallback& callback,
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<favicon_base::FaviconBitmapResult>* results =
5510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new std::vector<favicon_base::FaviconBitmapResult>();
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tracker->PostTaskAndReply(
5537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      thread_->message_loop_proxy().get(),
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::GetFavicons,
5567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 history_backend_.get(),
5577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 icon_urls,
5587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 icon_types,
5597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 desired_size_in_dip,
5607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 desired_scale_factors,
5617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 results),
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId HistoryService::GetFaviconsForURL(
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int icon_types,
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int desired_size_in_dip,
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<ui::ScaleFactor>& desired_scale_factors,
570cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const favicon_base::FaviconResultsCallback& callback,
5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<favicon_base::FaviconBitmapResult>* results =
5750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new std::vector<favicon_base::FaviconBitmapResult>();
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tracker->PostTaskAndReply(
5777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      thread_->message_loop_proxy().get(),
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::GetFaviconsForURL,
5807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 history_backend_.get(),
5817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 page_url,
5827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 icon_types,
5837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 desired_size_in_dip,
5847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 desired_scale_factors,
5857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 results),
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId HistoryService::GetLargestFaviconForURL(
5908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const GURL& page_url,
5918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::vector<int>& icon_types,
5928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    int minimum_size_in_pixels,
593cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const favicon_base::FaviconRawCallback& callback,
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
5958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
5968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  favicon_base::FaviconBitmapResult* result =
5980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new favicon_base::FaviconBitmapResult();
5998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return tracker->PostTaskAndReply(
6008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      thread_->message_loop_proxy().get(),
6018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE,
6028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Bind(&HistoryBackend::GetLargestFaviconForURL,
6038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 history_backend_.get(),
6048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 page_url,
6058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 icon_types,
6068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 minimum_size_in_pixels,
6078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 result),
6088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Bind(&RunWithFaviconResult, callback, base::Owned(result)));
6098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
6108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId HistoryService::GetFaviconForID(
6120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    favicon_base::FaviconID favicon_id,
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int desired_size_in_dip,
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::ScaleFactor desired_scale_factor,
615cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const favicon_base::FaviconResultsCallback& callback,
6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<favicon_base::FaviconBitmapResult>* results =
6200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new std::vector<favicon_base::FaviconBitmapResult>();
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tracker->PostTaskAndReply(
6227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      thread_->message_loop_proxy().get(),
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::GetFaviconForID,
6257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 history_backend_.get(),
6267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 favicon_id,
6277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 desired_size_in_dip,
6287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 desired_scale_factor,
6297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 results),
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)HistoryService::UpdateFaviconMappingsAndFetch(
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<GURL>& icon_urls,
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int icon_types,
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int desired_size_in_dip,
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<ui::ScaleFactor>& desired_scale_factors,
640cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const favicon_base::FaviconResultsCallback& callback,
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<favicon_base::FaviconBitmapResult>* results =
6450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new std::vector<favicon_base::FaviconBitmapResult>();
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tracker->PostTaskAndReply(
6477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      thread_->message_loop_proxy().get(),
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::UpdateFaviconMappingsAndFetch,
6507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 history_backend_.get(),
6517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 page_url,
6527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 icon_urls,
6537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 icon_types,
6547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 desired_size_in_dip,
6557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 desired_scale_factors,
6567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 results),
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::MergeFavicon(
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& icon_url,
6630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    favicon_base::IconType icon_type,
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::RefCountedMemory> bitmap_data,
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& pixel_size) {
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(page_url))
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::MergeFavicon, page_url,
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    icon_url, icon_type, bitmap_data, pixel_size);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetFavicons(
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
6760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    favicon_base::IconType icon_type,
6770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::vector<favicon_base::FaviconBitmapData>& favicon_bitmap_data) {
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(page_url))
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetFavicons, page_url,
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      icon_type, favicon_bitmap_data);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetFaviconsOutOfDateForPage(const GURL& page_url) {
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::SetFaviconsOutOfDateForPage, page_url);
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::CloneFavicons(const GURL& old_page_url,
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const GURL& new_page_url) {
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::CloneFavicons,
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    old_page_url, new_page_url);
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetImportedFavicons(
700a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const std::vector<ImportedFaviconUsage>& favicon_usage) {
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::SetImportedFavicons, favicon_usage);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryURL(
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool want_visits,
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryURLCallback& callback) {
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_UI, &HistoryBackend::QueryURL, consumer,
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  new history::QueryURLRequest(callback), url, want_visits);
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Downloads -------------------------------------------------------------------
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handle creation of a download by creating an entry in the history service's
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 'downloads' table.
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::CreateDownload(
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const history::DownloadRow& create_info,
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HistoryService::DownloadCreateCallback& callback) {
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
725a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PostTaskAndReplyWithResult(
726a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      thread_->message_loop_proxy(), FROM_HERE,
727a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&HistoryBackend::CreateDownload, history_backend_.get(),
728a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 create_info),
729a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      callback);
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HistoryService::GetNextDownloadId(
7337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const content::DownloadIdCallback& callback) {
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
736a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PostTaskAndReplyWithResult(
737a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      thread_->message_loop_proxy(), FROM_HERE,
738a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&HistoryBackend::GetNextDownloadId, history_backend_.get()),
739a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      callback);
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handle queries for a list of all downloads in the history database's
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 'downloads' table.
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::QueryDownloads(
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const DownloadQueryCallback& callback) {
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<history::DownloadRow>* rows =
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new std::vector<history::DownloadRow>();
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<std::vector<history::DownloadRow> > scoped_rows(rows);
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Beware! The first Bind() does not simply |scoped_rows.get()| because
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // base::Passed(&scoped_rows) nullifies |scoped_rows|, and compilers do not
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // guarantee that the first Bind's arguments are evaluated before the second
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Bind's arguments.
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  thread_->message_loop_proxy()->PostTaskAndReply(
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::QueryDownloads, history_backend_.get(), rows),
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(callback, base::Passed(&scoped_rows)));
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handle updates for a particular download. This is a 'fire and forget'
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// operation, so we don't need to be called back.
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::UpdateDownload(const history::DownloadRow& data) {
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::UpdateDownload, data);
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HistoryService::RemoveDownloads(const std::set<uint32>& ids) {
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
7717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    &HistoryBackend::RemoveDownloads, ids);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryHistory(
775a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& text_query,
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const history::QueryOptions& options,
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryHistoryCallback& callback) {
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_UI, &HistoryBackend::QueryHistory, consumer,
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  new history::QueryHistoryRequest(callback),
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  text_query, options);
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryRedirectsFrom(
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& from_url,
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryRedirectsCallback& callback) {
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_UI, &HistoryBackend::QueryRedirectsFrom, consumer,
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new history::QueryRedirectsRequest(callback), from_url);
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryRedirectsTo(
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& to_url,
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryRedirectsCallback& callback) {
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryRedirectsTo, consumer,
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new history::QueryRedirectsRequest(callback), to_url);
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::GetVisibleVisitCountToHost(
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GetVisibleVisitCountToHostCallback& callback) {
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_UI, &HistoryBackend::GetVisibleVisitCountToHost,
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      consumer, new history::GetVisibleVisitCountToHostRequest(callback), url);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryTopURLsAndRedirects(
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int result_count,
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryTopURLsAndRedirectsCallback& callback) {
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryTopURLsAndRedirects,
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      consumer, new history::QueryTopURLsAndRedirectsRequest(callback),
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_count);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryMostVisitedURLs(
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int result_count,
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int days_back,
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryMostVisitedURLsCallback& callback) {
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryMostVisitedURLs,
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  consumer,
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  new history::QueryMostVisitedURLsRequest(callback),
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  result_count, days_back);
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryFilteredURLs(
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int result_count,
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const history::VisitFilter& filter,
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool extended_info,
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryFilteredURLsCallback& callback) {
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_NORMAL,
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &HistoryBackend::QueryFilteredURLs,
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  consumer,
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  new history::QueryFilteredURLsRequest(callback),
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  result_count, filter, extended_info);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::Observe(int type,
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const content::NotificationSource& source,
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const content::NotificationDetails& details) {
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thread_)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_HISTORY_URLS_DELETED: {
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Update the visited link system for deleted URLs. We will update the
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // visited link system for added URLs as soon as we get the add
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // notification (we don't have to wait for the backend, which allows us to
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // be faster to update the state).
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      //
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // For deleted URLs, we don't typically know what will be deleted since
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // delete notifications are by time. We would also like to be more
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // respectful of privacy and never tell the user something is gone when it
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // isn't. Therefore, we update the delete URLs after the fact.
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (visitedlink_master_) {
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::Details<history::URLsDeletedDetails> deleted_details(details);
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (deleted_details->all_history) {
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          visitedlink_master_->DeleteAllURLs();
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else {
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          URLIteratorFromURLRows iterator(deleted_details->rows);
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          visitedlink_master_->DeleteURLs(&iterator);
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_TEMPLATE_URL_REMOVED:
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DeleteAllSearchTermsForKeyword(
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          *(content::Details<TemplateURLID>(details).ptr()));
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::RebuildTable(
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const scoped_refptr<URLEnumerator>& enumerator) {
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::IterateURLs, enumerator);
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
89546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool HistoryService::Init(const base::FilePath& history_dir, bool no_db) {
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thread_->Start()) {
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Cleanup();
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_dir_ = history_dir;
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  no_db_ = no_db;
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (profile_) {
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string languages =
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
90846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    in_memory_url_index_.reset(new history::InMemoryURLIndex(
90946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        profile_, history_dir_, languages, history_client_));
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    in_memory_url_index_->Init();
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the history backend.
914a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<HistoryBackend> backend(
915a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new HistoryBackend(history_dir_,
916a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         new BackendDelegate(
917a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             weak_ptr_factory_.GetWeakPtr(),
918a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             base::ThreadTaskRunnerHandle::Get(),
919a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             profile_),
92046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                         history_client_));
921a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  history_backend_.swap(backend);
922a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
923a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // There may not be a profile when unit testing.
924a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string languages;
925a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (profile_) {
926a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PrefService* prefs = profile_->GetPrefs();
927a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    languages = prefs->GetString(prefs::kAcceptLanguages);
928a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
929a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI, &HistoryBackend::Init, languages, no_db_);
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visitedlink_master_) {
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool result = visitedlink_master_->Init();
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(result);
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::ScheduleAutocomplete(HistoryURLProvider* provider,
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          HistoryURLProviderParams* params) {
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI, &HistoryBackend::ScheduleAutocomplete,
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    scoped_refptr<HistoryURLProvider>(provider), params);
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::ScheduleTask(SchedulePriority priority,
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const base::Closure& task) {
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(thread_);
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(thread_->message_loop());
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(brettw): Do prioritization.
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thread_->message_loop()->PostTask(FROM_HERE, task);
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::CanAddURL(const GURL& url) {
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url.is_valid())
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO: We should allow kChromeUIScheme URLs if they have been explicitly
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // typed.  Right now, however, these are marked as typed even when triggered
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by a shortcut or menu action.
963cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (url.SchemeIs(url::kJavaScriptScheme) ||
9645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      url.SchemeIs(content::kChromeDevToolsScheme) ||
9655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      url.SchemeIs(content::kChromeUIScheme) ||
9665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      url.SchemeIs(content::kViewSourceScheme) ||
96758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      url.SchemeIs(chrome::kChromeNativeScheme) ||
968d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      url.SchemeIs(chrome::kChromeSearchScheme) ||
9695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      url.SchemeIs(chrome::kDomDistillerScheme))
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allow all about: and chrome: URLs except about:blank, since the user may
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // like to see "chrome://memory/", etc. in their history and autocomplete.
97490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (url == GURL(content::kAboutBlankURL))
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::WeakPtr<HistoryService> HistoryService::AsWeakPtr() {
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return weak_ptr_factory_.GetWeakPtr();
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)syncer::SyncMergeResult HistoryService::MergeDataAndStartSyncing(
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type,
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::SyncDataList& initial_sync_data,
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<syncer::SyncErrorFactory> error_handler) {
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(type, syncer::HISTORY_DELETE_DIRECTIVES);
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete_directive_handler_.Start(this, initial_sync_data,
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_processor.Pass());
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return syncer::SyncMergeResult(type);
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::StopSyncing(syncer::ModelType type) {
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(type, syncer::HISTORY_DELETE_DIRECTIVES);
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete_directive_handler_.Stop();
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncDataList HistoryService::GetAllSyncData(
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type) const {
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(type, syncer::HISTORY_DELETE_DIRECTIVES);
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(akalin): Keep track of existing delete directives.
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return syncer::SyncDataList();
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncError HistoryService::ProcessSyncChanges(
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const tracked_objects::Location& from_here,
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::SyncChangeList& change_list) {
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete_directive_handler_.ProcessSyncChanges(this, change_list);
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return syncer::SyncError();
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)syncer::SyncError HistoryService::ProcessLocalDeleteDirective(
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const sync_pb::HistoryDeleteDirectiveSpecifics& delete_directive) {
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return delete_directive_handler_.ProcessLocalDeleteDirective(
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delete_directive);
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1025eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid HistoryService::SetInMemoryBackend(
1026a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<history::InMemoryHistoryBackend> mem_backend) {
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1028b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(!in_memory_backend_) << "Setting mem DB twice";
1029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  in_memory_backend_.reset(mem_backend.release());
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The database requires additional initialization once we own it.
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  in_memory_backend_->AttachToHistoryService(profile_);
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void HistoryService::NotifyProfileError(sql::InitStatus init_status) {
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShowProfileErrorDialog(
1038a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      PROFILE_ERROR_HISTORY,
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (init_status == sql::INIT_FAILURE) ?
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_COULDNT_OPEN_PROFILE_ERROR : IDS_PROFILE_TOO_NEW_ERROR);
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::DeleteURL(const GURL& url) {
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We will update the visited links when we observe the delete notifications.
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::DeleteURL, url);
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::DeleteURLsForTest(const std::vector<GURL>& urls) {
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We will update the visited links when we observe the delete
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notifications.
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::DeleteURLs, urls);
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::ExpireHistoryBetween(
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::set<GURL>& restrict_urls,
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Time begin_time,
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Time end_time,
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback,
10615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_);
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1064868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(history_backend_.get());
10657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  tracker->PostTaskAndReply(thread_->message_loop_proxy().get(),
1066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                            FROM_HERE,
1067868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                            base::Bind(&HistoryBackend::ExpireHistoryBetween,
1068868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       history_backend_,
1069868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       restrict_urls,
1070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       begin_time,
1071868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       end_time),
1072868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                            callback);
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::ExpireHistory(
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<history::ExpireHistoryArgs>& expire_list,
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback,
10785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_);
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1081868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(history_backend_.get());
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tracker->PostTaskAndReply(
10837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      thread_->message_loop_proxy().get(),
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::ExpireHistory, history_backend_, expire_list),
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback);
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::ExpireLocalAndRemoteHistoryBetween(
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::set<GURL>& restrict_urls,
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Time begin_time,
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Time end_time,
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback,
10945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(dubroy): This should be factored out into a separate class that
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // dispatches deletions to the proper places.
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  history::WebHistoryService* web_history =
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebHistoryServiceFactory::GetForProfile(profile_);
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (web_history) {
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(dubroy): This API does not yet support deletion of specific URLs.
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(restrict_urls.empty());
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete_directive_handler_.CreateDeleteDirectives(
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::set<int64>(), begin_time, end_time);
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Attempt online deletion from the history server, but ignore the result.
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Deletion directives ensure that the results will eventually be deleted.
1109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    //
1110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // TODO(davidben): |callback| should not run until this operation completes
1111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // too.
1112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    web_history->ExpireHistoryBetween(
1113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        restrict_urls, begin_time, end_time,
1114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&ExpireWebHistoryComplete));
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpireHistoryBetween(restrict_urls, begin_time, end_time, callback, tracker);
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::BroadcastNotificationsHelper(
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
1121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<history::HistoryDetails> details) {
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(evanm): this is currently necessitated by generate_profile, which
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // runs without a browser process. generate_profile should really create
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a browser process, at which point this check can then be nuked.
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_browser_process)
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thread_)
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The source of all of our notifications is the profile. Note that this
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pointer is NULL in unit tests.
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::Source<Profile> source(profile_);
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The details object just contains the pointer to the object that the
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // backend has allocated for us. The receiver of the notification will cast
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this to the proper type.
1139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  content::Details<history::HistoryDetails> det(details.get());
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(type, source, det);
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void HistoryService::OnDBLoaded() {
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_loaded_ = true;
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_HISTORY_LOADED,
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<Profile>(profile_),
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Details<HistoryService>(this));
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::GetRowForURL(const GURL& url, history::URLRow* url_row) {
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLDatabase* db = InMemoryDatabase();
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return db && (db->GetRowForURL(url, url_row) != 0);
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddVisitDatabaseObserver(
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::VisitDatabaseObserver* observer) {
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visit_database_observers_.AddObserver(observer);
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::RemoveVisitDatabaseObserver(
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::VisitDatabaseObserver* observer) {
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visit_database_observers_.RemoveObserver(observer);
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::NotifyVisitDBObserversOnAddVisit(
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const history::BriefVisitInfo& info) {
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(history::VisitDatabaseObserver, visit_database_observers_,
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnAddVisit(info));
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1177