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/browser_process.h"
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/download_row.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_backend.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_notifications.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_history_backend.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_url_index.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/top_sites.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/visit_database.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/visit_filter.h"
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/web_history_service.h"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/web_history_service_factory.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/importer/imported_favicon_usage.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/dom_distiller/core/url_constants.h"
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/history/core/browser/history_client.h"
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/history/core/browser/history_types.h"
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/history/core/browser/in_memory_database.h"
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/history/core/browser/keyword_search_term.h"
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/history/core/common/thumbnail_score.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 "sync/api/sync_error_factory.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using history::HistoryBackend;
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing history::KeywordID;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kHistoryThreadName = "Chrome_HistoryThread";
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RunWithFaviconResults(
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const favicon_base::FaviconResultsCallback& callback,
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(*bitmap_results);
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void RunWithFaviconResult(
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const favicon_base::FaviconRawBitmapCallback& callback,
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    favicon_base::FaviconRawBitmapResult* bitmap_result) {
818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  callback.Run(*bitmap_result);
828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void RunWithQueryURLResult(const HistoryService::QueryURLCallback& callback,
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           const history::QueryURLResult* result) {
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  callback.Run(result->success, result->row, result->visits);
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid RunWithVisibleVisitCountToHostResult(
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const HistoryService::GetVisibleVisitCountToHostCallback& callback,
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const history::VisibleVisitCountToHostResult* result) {
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  callback.Run(result->success, result->count, result->first_visit);
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Extract history::URLRows into GURLs for VisitedLinkMaster.
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class URLIteratorFromURLRows
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : public visitedlink::VisitedLinkMaster::URLIterator {
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit URLIteratorFromURLRows(const history::URLRows& url_rows)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : itr_(url_rows.begin()),
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        end_(url_rows.end()) {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const GURL& NextURL() OVERRIDE {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (itr_++)->url();
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool HasNextURL() const OVERRIDE {
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return itr_ != end_;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  history::URLRows::const_iterator itr_;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  history::URLRows::const_iterator end_;
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(URLIteratorFromURLRows);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Callback from WebHistoryService::ExpireWebHistory().
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ExpireWebHistoryComplete(bool success) {
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Ignore the result.
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  //
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(davidben): ExpireLocalAndRemoteHistoryBetween callback should not fire
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // until this completes.
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sends messages from the backend to us on the main thread. This must be a
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// separate class from the history service so that it can hold a reference to
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the history service (otherwise we would have to manually AddRef and
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Release when the Backend has a reference to us).
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistoryService::BackendDelegate : public HistoryBackend::Delegate {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackendDelegate(
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::WeakPtr<HistoryService>& history_service,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const scoped_refptr<base::SequencedTaskRunner>& service_task_runner,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Profile* profile)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : history_service_(history_service),
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        service_task_runner_(service_task_runner),
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        profile_(profile) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void NotifyProfileError(sql::InitStatus init_status) OVERRIDE {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send to the history service on the main thread.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::NotifyProfileError, history_service_,
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   init_status));
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void SetInMemoryBackend(
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      scoped_ptr<history::InMemoryHistoryBackend> backend) OVERRIDE {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send the backend to the history service on the main thread.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::SetInMemoryBackend, history_service_,
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   base::Passed(&backend)));
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void NotifyFaviconChanged(const std::set<GURL>& urls) OVERRIDE {
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Send the notification to the history service on the main thread.
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    service_task_runner_->PostTask(
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        FROM_HERE,
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            &HistoryService::NotifyFaviconChanged, history_service_, urls));
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void BroadcastNotifications(
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int type,
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      scoped_ptr<history::HistoryDetails> details) OVERRIDE {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send the notification on the history thread.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (content::NotificationService::current()) {
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      content::Details<history::HistoryDetails> det(details.get());
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::current()->Notify(
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          type, content::Source<Profile>(profile_), det);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send the notification to the history service on the main thread.
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::BroadcastNotificationsHelper,
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   history_service_, type, base::Passed(&details)));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void DBLoaded() OVERRIDE {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&HistoryService::OnDBLoaded, history_service_));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void NotifyVisitDBObserversOnAddVisit(
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const history::BriefVisitInfo& info) OVERRIDE {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::NotifyVisitDBObserversOnAddVisit,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   history_service_, info));
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::WeakPtr<HistoryService> history_service_;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_refptr<base::SequencedTaskRunner> service_task_runner_;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* const profile_;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The history thread is intentionally not a BrowserThread because the
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sync integration unit tests depend on being able to create more than one
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// history thread.
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::HistoryService()
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : thread_(new base::Thread(kHistoryThreadName)),
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      history_client_(NULL),
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_(NULL),
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_loaded_(false),
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      no_db_(false),
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_ptr_factory_(this) {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)HistoryService::HistoryService(history::HistoryClient* client, Profile* profile)
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : thread_(new base::Thread(kHistoryThreadName)),
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      history_client_(client),
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_(profile),
22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      visitedlink_master_(new visitedlink::VisitedLinkMaster(
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          profile, this, true)),
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_loaded_(false),
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      no_db_(false),
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_ptr_factory_(this) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(profile_);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<Profile>(profile_));
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::~HistoryService() {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shutdown the backend. This does nothing if Cleanup was already invoked.
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cleanup();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::BackendLoaded() {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_loaded_;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void HistoryService::ClearCachedDataForContextID(
243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    history::ContextID context_id) {
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                    &HistoryBackend::ClearCachedDataForContextID, context_id);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)history::URLDatabase* HistoryService::InMemoryDatabase() {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return in_memory_backend_ ? in_memory_backend_->db() : NULL;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::GetTypedCountForURL(const GURL& url, int* typed_count) {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRow url_row;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetRowForURL(url, &url_row))
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *typed_count = url_row.typed_count();
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::GetLastVisitTimeForURL(const GURL& url,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            base::Time* last_visit) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRow url_row;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetRowForURL(url, &url_row))
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *last_visit = url_row.last_visit();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::GetVisitCountForURL(const GURL& url, int* visit_count) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRow url_row;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetRowForURL(url, &url_row))
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *visit_count = url_row.visit_count();
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
283b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)history::TypedUrlSyncableService* HistoryService::GetTypedUrlSyncableService()
284b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const {
285b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return history_backend_->GetTypedUrlSyncableService();
286b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
287b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::Shutdown() {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cleanup();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetKeywordSearchTermsForURL(const GURL& url,
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                 KeywordID keyword_id,
295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                 const base::string16& term) {
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::SetKeywordSearchTermsForURL,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    url, keyword_id, term);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HistoryService::DeleteAllSearchTermsForKeyword(KeywordID keyword_id) {
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (in_memory_backend_)
308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    in_memory_backend_->DeleteAllSearchTermsForKeyword(keyword_id);
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::DeleteAllSearchTermsForKeyword,
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    keyword_id);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void HistoryService::DeleteKeywordSearchTermForURL(const GURL& url) {
3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
3170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI, &HistoryBackend::DeleteKeywordSearchTermForURL,
3190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                    url);
3200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
3210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
322116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HistoryService::DeleteMatchingURLsForKeyword(KeywordID keyword_id,
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                  const base::string16& term) {
3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI, &HistoryBackend::DeleteMatchingURLsForKeyword,
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    keyword_id, term);
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::URLsNoLongerBookmarked(const std::set<GURL>& urls) {
3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::URLsNoLongerBookmarked,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    urls);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void HistoryService::ScheduleDBTask(scoped_ptr<history::HistoryDBTask> task,
338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    base::CancelableTaskTracker* tracker) {
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::CancelableTaskTracker::IsCanceledCallback is_canceled;
342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  tracker->NewTrackedTaskId(&is_canceled);
343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Use base::ThreadTaskRunnerHandler::Get() to get a message loop proxy to
344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the current message loop so that we can forward the call to the method
345116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // HistoryDBTask::DoneRunOnMainThread in the correct thread.
346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  thread_->message_loop_proxy()->PostTask(
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&HistoryBackend::ProcessDBTask,
349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 history_backend_.get(),
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 base::Passed(&task),
351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::ThreadTaskRunnerHandle::Get(),
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 is_canceled));
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HistoryService::FlushForTest(const base::Closure& flushed) {
3567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  thread_->message_loop_proxy()->PostTaskAndReply(
3577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      FROM_HERE, base::Bind(&base::DoNothing), flushed);
3587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetOnBackendDestroyTask(const base::Closure& task) {
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetOnBackendDestroyTask,
36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                    base::MessageLoop::current(), task);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPage(const GURL& url,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             Time time,
369f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                             history::ContextID context_id,
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int32 page_id,
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const GURL& referrer,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const history::RedirectList& redirects,
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             ui::PageTransition transition,
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::VisitSource visit_source,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool did_replace_entry) {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddPage(
378f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      history::HistoryAddPageArgs(url, time, context_id, page_id, referrer,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  redirects, transition, visit_source,
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  did_replace_entry));
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPage(const GURL& url,
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             base::Time time,
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::VisitSource visit_source) {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddPage(
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::HistoryAddPageArgs(url, time, NULL, 0, GURL(),
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  history::RedirectList(),
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  ui::PAGE_TRANSITION_LINK,
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  visit_source, false));
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPage(const history::HistoryAddPageArgs& add_page_args) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Filter out unwanted URLs. We don't add auto-subframe URLs. They are a
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // large part of history (think iframes for ads) and we never display them in
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // history UI. We will still add manual subframes, which are ones the user
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has clicked on to get.
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(add_page_args.url))
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add link & all redirects to visited link list.
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visitedlink_master_) {
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitedlink_master_->AddURL(add_page_args.url);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!add_page_args.redirects.empty()) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We should not be asked to add a page in the middle of a redirect chain.
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK_EQ(add_page_args.url,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                add_page_args.redirects[add_page_args.redirects.size() - 1]);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We need the !redirects.empty() condition above since size_t is unsigned
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // and will wrap around when we subtract one from a 0 size.
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (size_t i = 0; i < add_page_args.redirects.size() - 1; i++)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        visitedlink_master_->AddURL(add_page_args.redirects[i]);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::AddPage, add_page_args);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPageNoVisitForBookmark(const GURL& url,
425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                               const base::string16& title) {
4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(url))
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::AddPageNoVisitForBookmark, url, title);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetPageTitle(const GURL& url,
436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  const base::string16& title) {
4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetPageTitle, url, title);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void HistoryService::UpdateWithPageEndTime(history::ContextID context_id,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           int32 page_id,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const GURL& url,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           Time end_ts) {
4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::UpdateWithPageEndTime,
449f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                    context_id, page_id, url, end_ts);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPageWithDetails(const GURL& url,
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        const base::string16& title,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int visit_count,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int typed_count,
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        Time last_visit,
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        bool hidden,
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        history::VisitSource visit_source) {
4595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Filter out unwanted URLs.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(url))
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add to the visited links system.
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visitedlink_master_)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitedlink_master_->AddURL(url);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRow row(url);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_title(title);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_visit_count(visit_count);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_typed_count(typed_count);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_last_visit(last_visit);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_hidden(hidden);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRows rows;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rows.push_back(row);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::AddPagesWithDetails, rows, visit_source);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPagesWithDetails(const history::URLRows& info,
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         history::VisitSource visit_source) {
4855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add to the visited links system.
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visitedlink_master_) {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<GURL> urls;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    urls.reserve(info.size());
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (history::URLRows::const_iterator i = info.begin(); i != info.end();
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         ++i)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      urls.push_back(i->url());
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitedlink_master_->AddURLs(urls);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::AddPagesWithDetails, info, visit_source);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId HistoryService::GetFavicons(
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<GURL>& icon_urls,
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int icon_types,
5056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const std::vector<int>& desired_sizes,
506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const favicon_base::FaviconResultsCallback& callback,
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
510f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::vector<favicon_base::FaviconRawBitmapResult>* results =
511f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new std::vector<favicon_base::FaviconRawBitmapResult>();
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tracker->PostTaskAndReply(
5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      thread_->message_loop_proxy().get(),
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::GetFavicons,
5167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 history_backend_.get(),
5177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 icon_urls,
5187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 icon_types,
5196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                 desired_sizes,
5207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 results),
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId HistoryService::GetFaviconsForURL(
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int icon_types,
5276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const std::vector<int>& desired_sizes,
528cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const favicon_base::FaviconResultsCallback& callback,
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
532f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::vector<favicon_base::FaviconRawBitmapResult>* results =
533f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new std::vector<favicon_base::FaviconRawBitmapResult>();
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tracker->PostTaskAndReply(
5357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      thread_->message_loop_proxy().get(),
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::GetFaviconsForURL,
5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 history_backend_.get(),
5397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 page_url,
5407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 icon_types,
5416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                 desired_sizes,
5427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 results),
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId HistoryService::GetLargestFaviconForURL(
5478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const GURL& page_url,
5488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::vector<int>& icon_types,
5498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    int minimum_size_in_pixels,
550f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const favicon_base::FaviconRawBitmapCallback& callback,
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
5525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
5538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
554f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  favicon_base::FaviconRawBitmapResult* result =
555f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new favicon_base::FaviconRawBitmapResult();
5568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return tracker->PostTaskAndReply(
5578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      thread_->message_loop_proxy().get(),
5588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE,
5598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Bind(&HistoryBackend::GetLargestFaviconForURL,
5608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 history_backend_.get(),
5618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 page_url,
5628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 icon_types,
5638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 minimum_size_in_pixels,
5648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 result),
5658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Bind(&RunWithFaviconResult, callback, base::Owned(result)));
5668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId HistoryService::GetFaviconForID(
5690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    favicon_base::FaviconID favicon_id,
5706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    int desired_size,
571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const favicon_base::FaviconResultsCallback& callback,
5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
575f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::vector<favicon_base::FaviconRawBitmapResult>* results =
576f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new std::vector<favicon_base::FaviconRawBitmapResult>();
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tracker->PostTaskAndReply(
5787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      thread_->message_loop_proxy().get(),
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::GetFaviconForID,
5817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 history_backend_.get(),
5827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 favicon_id,
5836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                 desired_size,
5847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 results),
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)HistoryService::UpdateFaviconMappingsAndFetch(
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<GURL>& icon_urls,
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int icon_types,
5936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const std::vector<int>& desired_sizes,
594cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const favicon_base::FaviconResultsCallback& callback,
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
598f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::vector<favicon_base::FaviconRawBitmapResult>* results =
599f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new std::vector<favicon_base::FaviconRawBitmapResult>();
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tracker->PostTaskAndReply(
6017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      thread_->message_loop_proxy().get(),
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::UpdateFaviconMappingsAndFetch,
6047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 history_backend_.get(),
6057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 page_url,
6067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 icon_urls,
6077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 icon_types,
6086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                 desired_sizes,
6097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 results),
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::MergeFavicon(
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& icon_url,
6160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    favicon_base::IconType icon_type,
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::RefCountedMemory> bitmap_data,
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& pixel_size) {
6195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(page_url))
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::MergeFavicon, page_url,
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    icon_url, icon_type, bitmap_data, pixel_size);
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetFavicons(
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
6300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    favicon_base::IconType icon_type,
6311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const GURL& icon_url,
6321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::vector<SkBitmap>& bitmaps) {
6335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(page_url))
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetFavicons, page_url,
6391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      icon_type, icon_url, bitmaps);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetFaviconsOutOfDateForPage(const GURL& page_url) {
6435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::SetFaviconsOutOfDateForPage, page_url);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::CloneFavicons(const GURL& old_page_url,
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const GURL& new_page_url) {
6515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::CloneFavicons,
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    old_page_url, new_page_url);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void HistoryService::SetImportedFavicons(
6585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::vector<ImportedFaviconUsage>& favicon_usage) {
6595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
6605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
6625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    &HistoryBackend::SetImportedFavicons, favicon_usage);
6635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
6645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
665f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)base::CancelableTaskTracker::TaskId HistoryService::QueryURL(
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool want_visits,
668f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const QueryURLCallback& callback,
669f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
6705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
672116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  history::QueryURLResult* query_url_result = new history::QueryURLResult();
673116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return tracker->PostTaskAndReply(
674f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      thread_->message_loop_proxy().get(),
675f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      FROM_HERE,
676116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&HistoryBackend::QueryURL,
677116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 history_backend_.get(),
678116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 url,
679116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 want_visits,
680116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(query_url_result)),
681f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(
682116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          &RunWithQueryURLResult, callback, base::Owned(query_url_result)));
683116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
684116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Downloads -------------------------------------------------------------------
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handle creation of a download by creating an entry in the history service's
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 'downloads' table.
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::CreateDownload(
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const history::DownloadRow& create_info,
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HistoryService::DownloadCreateCallback& callback) {
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
694a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PostTaskAndReplyWithResult(
6951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      thread_->message_loop_proxy().get(),
6961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      FROM_HERE,
6971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(
6981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          &HistoryBackend::CreateDownload, history_backend_.get(), create_info),
699a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      callback);
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HistoryService::GetNextDownloadId(
7037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const content::DownloadIdCallback& callback) {
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PostTaskAndReplyWithResult(
7071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      thread_->message_loop_proxy().get(),
7081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      FROM_HERE,
709a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&HistoryBackend::GetNextDownloadId, history_backend_.get()),
710a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      callback);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handle queries for a list of all downloads in the history database's
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 'downloads' table.
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::QueryDownloads(
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const DownloadQueryCallback& callback) {
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<history::DownloadRow>* rows =
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new std::vector<history::DownloadRow>();
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<std::vector<history::DownloadRow> > scoped_rows(rows);
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Beware! The first Bind() does not simply |scoped_rows.get()| because
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // base::Passed(&scoped_rows) nullifies |scoped_rows|, and compilers do not
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // guarantee that the first Bind's arguments are evaluated before the second
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Bind's arguments.
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  thread_->message_loop_proxy()->PostTaskAndReply(
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::QueryDownloads, history_backend_.get(), rows),
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(callback, base::Passed(&scoped_rows)));
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handle updates for a particular download. This is a 'fire and forget'
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// operation, so we don't need to be called back.
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::UpdateDownload(const history::DownloadRow& data) {
7355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::UpdateDownload, data);
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HistoryService::RemoveDownloads(const std::set<uint32>& ids) {
7415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
7447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    &HistoryBackend::RemoveDownloads, ids);
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
747116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::CancelableTaskTracker::TaskId HistoryService::QueryHistory(
748a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& text_query,
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const history::QueryOptions& options,
750116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const QueryHistoryCallback& callback,
751116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::CancelableTaskTracker* tracker) {
7525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
754116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  history::QueryResults* query_results = new history::QueryResults();
755116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return tracker->PostTaskAndReply(
756116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      thread_->message_loop_proxy().get(),
757116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
758116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&HistoryBackend::QueryHistory,
759116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 history_backend_.get(),
760116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 text_query,
761116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 options,
762116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(query_results)),
763116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(callback, base::Owned(query_results)));
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
766116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::CancelableTaskTracker::TaskId HistoryService::QueryRedirectsFrom(
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& from_url,
768116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const QueryRedirectsCallback& callback,
769116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::CancelableTaskTracker* tracker) {
7705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
772116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  history::RedirectList* result = new history::RedirectList();
773116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return tracker->PostTaskAndReply(
774116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      thread_->message_loop_proxy().get(),
775116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
776116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&HistoryBackend::QueryRedirectsFrom,
777116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 history_backend_.get(),
778116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 from_url,
779116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(result)),
780116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(callback, base::Owned(result)));
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
783116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::CancelableTaskTracker::TaskId HistoryService::QueryRedirectsTo(
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& to_url,
785116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const QueryRedirectsCallback& callback,
786116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::CancelableTaskTracker* tracker) {
7875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
789116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  history::RedirectList* result = new history::RedirectList();
790116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return tracker->PostTaskAndReply(thread_->message_loop_proxy().get(),
791116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   FROM_HERE,
792116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   base::Bind(&HistoryBackend::QueryRedirectsTo,
793116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                              history_backend_.get(),
794116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                              to_url,
795116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                              base::Unretained(result)),
796116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   base::Bind(callback, base::Owned(result)));
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
799116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::CancelableTaskTracker::TaskId HistoryService::GetVisibleVisitCountToHost(
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
801116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GetVisibleVisitCountToHostCallback& callback,
802116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::CancelableTaskTracker* tracker) {
8035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
805116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  history::VisibleVisitCountToHostResult* result =
806116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new history::VisibleVisitCountToHostResult();
807116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return tracker->PostTaskAndReply(
808116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      thread_->message_loop_proxy().get(),
809116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
810116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&HistoryBackend::GetVisibleVisitCountToHost,
811116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 history_backend_.get(),
812116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 url,
813116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(result)),
814116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&RunWithVisibleVisitCountToHostResult,
815116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 callback,
816116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Owned(result)));
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
819116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::CancelableTaskTracker::TaskId HistoryService::QueryMostVisitedURLs(
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int result_count,
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int days_back,
822116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const QueryMostVisitedURLsCallback& callback,
823116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::CancelableTaskTracker* tracker) {
8245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
826116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  history::MostVisitedURLList* result = new history::MostVisitedURLList();
827116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return tracker->PostTaskAndReply(
828116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      thread_->message_loop_proxy().get(),
829116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
830116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&HistoryBackend::QueryMostVisitedURLs,
831116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 history_backend_.get(),
832116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 result_count,
833116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 days_back,
834116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(result)),
835116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(callback, base::Owned(result)));
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
838116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::CancelableTaskTracker::TaskId HistoryService::QueryFilteredURLs(
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int result_count,
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const history::VisitFilter& filter,
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool extended_info,
842116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const QueryFilteredURLsCallback& callback,
843116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::CancelableTaskTracker* tracker) {
8445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
846116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  history::FilteredURLList* result = new history::FilteredURLList();
847116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return tracker->PostTaskAndReply(
848116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      thread_->message_loop_proxy().get(),
849116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
850116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&HistoryBackend::QueryFilteredURLs,
851116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 history_backend_.get(),
852116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 result_count,
853116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 filter,
854116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 extended_info,
855116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(result)),
856116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(callback, base::Owned(result)));
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid HistoryService::Cleanup() {
8601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
8611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!thread_) {
8621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // We've already cleaned up.
8631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
8641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
8651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
8661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  weak_ptr_factory_.InvalidateWeakPtrs();
8671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
8681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Unload the backend.
8691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (history_backend_.get()) {
8701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Get rid of the in-memory backend.
8711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    in_memory_backend_.reset();
8721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
8731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Give the InMemoryURLIndex a chance to shutdown.
8741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // NOTE: In tests, there may be no index.
8751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (in_memory_url_index_)
8761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      in_memory_url_index_->ShutDown();
8771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
8781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // The backend's destructor must run on the history thread since it is not
8791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // threadsafe. So this thread must not be the last thread holding a
8801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // reference to the backend, or a crash could happen.
8811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    //
8821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // We have a reference to the history backend. There is also an extra
8831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // reference held by our delegate installed in the backend, which
8841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // HistoryBackend::Closing will release. This means if we scheduled a call
8851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // to HistoryBackend::Closing and *then* released our backend reference,
8861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // there will be a race between us and the backend's Closing function to see
8871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // who is the last holder of a reference. If the backend thread's Closing
8881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // manages to run before we release our backend refptr, the last reference
8891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // will be held by this thread and the destructor will be called from here.
8901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    //
8911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Therefore, we create a closure to run the Closing operation first. This
8921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // holds a reference to the backend. Then we release our reference, then we
8931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // schedule the task to run. After the task runs, it will delete its
8941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // reference from the history thread, ensuring everything works properly.
8951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    //
8961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // TODO(ajwong): Cleanup HistoryBackend lifetime issues.
8971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    //     See http://crbug.com/99767.
8981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    history_backend_->AddRef();
8991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::Closure closing_task =
9001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&HistoryBackend::Closing, history_backend_.get());
9011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ScheduleTask(PRIORITY_NORMAL, closing_task);
9021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    closing_task.Reset();
9031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    HistoryBackend* raw_ptr = history_backend_.get();
9041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    history_backend_ = NULL;
9051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    thread_->message_loop()->ReleaseSoon(FROM_HERE, raw_ptr);
9061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
9071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Delete the thread, which joins with the background thread. We defensively
9091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // NULL the pointer before deleting it in case somebody tries to use it
9101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // during shutdown, but this shouldn't happen.
9111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::Thread* thread = thread_;
9121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  thread_ = NULL;
9131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  delete thread;
9141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
9151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::Observe(int type,
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const content::NotificationSource& source,
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const content::NotificationDetails& details) {
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thread_)
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_HISTORY_URLS_DELETED: {
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Update the visited link system for deleted URLs. We will update the
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // visited link system for added URLs as soon as we get the add
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // notification (we don't have to wait for the backend, which allows us to
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // be faster to update the state).
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      //
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // For deleted URLs, we don't typically know what will be deleted since
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // delete notifications are by time. We would also like to be more
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // respectful of privacy and never tell the user something is gone when it
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // isn't. Therefore, we update the delete URLs after the fact.
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (visitedlink_master_) {
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::Details<history::URLsDeletedDetails> deleted_details(details);
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (deleted_details->all_history) {
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          visitedlink_master_->DeleteAllURLs();
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else {
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          URLIteratorFromURLRows iterator(deleted_details->rows);
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          visitedlink_master_->DeleteURLs(&iterator);
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::RebuildTable(
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const scoped_refptr<URLEnumerator>& enumerator) {
9545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::IterateURLs, enumerator);
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
95946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool HistoryService::Init(const base::FilePath& history_dir, bool no_db) {
9605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
962116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::Thread::Options options;
963116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  options.timer_slack = base::TIMER_SLACK_MAXIMUM;
964116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!thread_->StartWithOptions(options)) {
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Cleanup();
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_dir_ = history_dir;
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  no_db_ = no_db;
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (profile_) {
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string languages =
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
97546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    in_memory_url_index_.reset(new history::InMemoryURLIndex(
97646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        profile_, history_dir_, languages, history_client_));
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    in_memory_url_index_->Init();
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the history backend.
981a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<HistoryBackend> backend(
982a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new HistoryBackend(history_dir_,
983a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         new BackendDelegate(
984a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             weak_ptr_factory_.GetWeakPtr(),
985a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             base::ThreadTaskRunnerHandle::Get(),
986a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             profile_),
98746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                         history_client_));
988a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  history_backend_.swap(backend);
989a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
990a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // There may not be a profile when unit testing.
991a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string languages;
992a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (profile_) {
993a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PrefService* prefs = profile_->GetPrefs();
994a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    languages = prefs->GetString(prefs::kAcceptLanguages);
995a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
996a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI, &HistoryBackend::Init, languages, no_db_);
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visitedlink_master_) {
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool result = visitedlink_master_->Init();
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(result);
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1006116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HistoryService::ScheduleAutocomplete(const base::Callback<
1007116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    void(history::HistoryBackend*, history::URLDatabase*)>& callback) {
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1009116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScheduleAndForget(
1010116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      PRIORITY_UI, &HistoryBackend::ScheduleAutocomplete, callback);
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::ScheduleTask(SchedulePriority priority,
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const base::Closure& task) {
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(thread_);
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(thread_->message_loop());
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(brettw): Do prioritization.
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thread_->message_loop()->PostTask(FROM_HERE, task);
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::CanAddURL(const GURL& url) {
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url.is_valid())
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO: We should allow kChromeUIScheme URLs if they have been explicitly
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // typed.  Right now, however, these are marked as typed even when triggered
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by a shortcut or menu action.
1030cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (url.SchemeIs(url::kJavaScriptScheme) ||
10315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      url.SchemeIs(content::kChromeDevToolsScheme) ||
10325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      url.SchemeIs(content::kChromeUIScheme) ||
10335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      url.SchemeIs(content::kViewSourceScheme) ||
103458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      url.SchemeIs(chrome::kChromeNativeScheme) ||
1035d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      url.SchemeIs(chrome::kChromeSearchScheme) ||
10365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      url.SchemeIs(dom_distiller::kDomDistillerScheme))
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allow all about: and chrome: URLs except about:blank, since the user may
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // like to see "chrome://memory/", etc. in their history and autocomplete.
1041f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (url == GURL(url::kAboutBlankURL))
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::WeakPtr<HistoryService> HistoryService::AsWeakPtr() {
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return weak_ptr_factory_.GetWeakPtr();
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)syncer::SyncMergeResult HistoryService::MergeDataAndStartSyncing(
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type,
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::SyncDataList& initial_sync_data,
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<syncer::SyncErrorFactory> error_handler) {
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(type, syncer::HISTORY_DELETE_DIRECTIVES);
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete_directive_handler_.Start(this, initial_sync_data,
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_processor.Pass());
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return syncer::SyncMergeResult(type);
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::StopSyncing(syncer::ModelType type) {
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(type, syncer::HISTORY_DELETE_DIRECTIVES);
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete_directive_handler_.Stop();
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncDataList HistoryService::GetAllSyncData(
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type) const {
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(type, syncer::HISTORY_DELETE_DIRECTIVES);
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(akalin): Keep track of existing delete directives.
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return syncer::SyncDataList();
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncError HistoryService::ProcessSyncChanges(
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const tracked_objects::Location& from_here,
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::SyncChangeList& change_list) {
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete_directive_handler_.ProcessSyncChanges(this, change_list);
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return syncer::SyncError();
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)syncer::SyncError HistoryService::ProcessLocalDeleteDirective(
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const sync_pb::HistoryDeleteDirectiveSpecifics& delete_directive) {
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return delete_directive_handler_.ProcessLocalDeleteDirective(
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delete_directive);
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid HistoryService::SetInMemoryBackend(
1093a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<history::InMemoryHistoryBackend> mem_backend) {
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1095b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(!in_memory_backend_) << "Setting mem DB twice";
1096eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  in_memory_backend_.reset(mem_backend.release());
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The database requires additional initialization once we own it.
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  in_memory_backend_->AttachToHistoryService(profile_);
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void HistoryService::NotifyProfileError(sql::InitStatus init_status) {
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (history_client_)
1105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    history_client_->NotifyProfileError(init_status);
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::DeleteURL(const GURL& url) {
11095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We will update the visited links when we observe the delete notifications.
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::DeleteURL, url);
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::DeleteURLsForTest(const std::vector<GURL>& urls) {
11165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We will update the visited links when we observe the delete
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notifications.
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::DeleteURLs, urls);
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::ExpireHistoryBetween(
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::set<GURL>& restrict_urls,
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Time begin_time,
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Time end_time,
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback,
11285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
11295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  tracker->PostTaskAndReply(thread_->message_loop_proxy().get(),
1132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                            FROM_HERE,
1133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                            base::Bind(&HistoryBackend::ExpireHistoryBetween,
1134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       history_backend_,
1135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       restrict_urls,
1136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       begin_time,
1137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       end_time),
1138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                            callback);
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::ExpireHistory(
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<history::ExpireHistoryArgs>& expire_list,
11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback,
11445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
11455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tracker->PostTaskAndReply(
11487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      thread_->message_loop_proxy().get(),
11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::ExpireHistory, history_backend_, expire_list),
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback);
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::ExpireLocalAndRemoteHistoryBetween(
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::set<GURL>& restrict_urls,
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Time begin_time,
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Time end_time,
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback,
11595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::CancelableTaskTracker* tracker) {
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(dubroy): This should be factored out into a separate class that
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // dispatches deletions to the proper places.
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  history::WebHistoryService* web_history =
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebHistoryServiceFactory::GetForProfile(profile_);
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (web_history) {
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(dubroy): This API does not yet support deletion of specific URLs.
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(restrict_urls.empty());
11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete_directive_handler_.CreateDeleteDirectives(
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::set<int64>(), begin_time, end_time);
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Attempt online deletion from the history server, but ignore the result.
11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Deletion directives ensure that the results will eventually be deleted.
1174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    //
1175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // TODO(davidben): |callback| should not run until this operation completes
1176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // too.
1177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    web_history->ExpireHistoryBetween(
1178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        restrict_urls, begin_time, end_time,
1179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&ExpireWebHistoryComplete));
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpireHistoryBetween(restrict_urls, begin_time, end_time, callback, tracker);
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::BroadcastNotificationsHelper(
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
1186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<history::HistoryDetails> details) {
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(evanm): this is currently necessitated by generate_profile, which
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // runs without a browser process. generate_profile should really create
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a browser process, at which point this check can then be nuked.
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_browser_process)
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thread_)
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The source of all of our notifications is the profile. Note that this
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pointer is NULL in unit tests.
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::Source<Profile> source(profile_);
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The details object just contains the pointer to the object that the
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // backend has allocated for us. The receiver of the notification will cast
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this to the proper type.
1204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  content::Details<history::HistoryDetails> det(details.get());
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(type, source, det);
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void HistoryService::OnDBLoaded() {
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_loaded_ = true;
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_HISTORY_LOADED,
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<Profile>(profile_),
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Details<HistoryService>(this));
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::GetRowForURL(const GURL& url, history::URLRow* url_row) {
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLDatabase* db = InMemoryDatabase();
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return db && (db->GetRowForURL(url, url_row) != 0);
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddVisitDatabaseObserver(
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::VisitDatabaseObserver* observer) {
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visit_database_observers_.AddObserver(observer);
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::RemoveVisitDatabaseObserver(
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::VisitDatabaseObserver* observer) {
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visit_database_observers_.RemoveObserver(observer);
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::NotifyVisitDBObserversOnAddVisit(
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const history::BriefVisitInfo& info) {
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(history::VisitDatabaseObserver, visit_database_observers_,
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnAddVisit(info));
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
12431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<base::CallbackList<void(const std::set<GURL>&)>::Subscription>
12441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciHistoryService::AddFaviconChangedCallback(
12451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const HistoryService::OnFaviconChangedCallback& callback) {
12461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
12471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return favicon_changed_callback_list_.Add(callback);
12481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
12491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
12501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid HistoryService::NotifyFaviconChanged(
12511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::set<GURL>& changed_favicons) {
12521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
12531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  favicon_changed_callback_list_.Notify(changed_favicons);
12541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1255