history_service.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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)//                                   -> ArchivedDatabase
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                      -> SQLite connection to Archived History
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                   -> TextDatabaseManager
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                      -> SQLite connection to one month's data
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                      -> SQLite connection to one month's data
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                      ...
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                   -> ThumbnailDatabase
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                      -> SQLite connection to Thumbnails
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                         (and favicons)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind_helpers.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/location.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/thread_task_runner_handle.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/time.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/history_url_provider.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/download_row.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_backend.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_notifications.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_types.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_database.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_history_backend.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/in_memory_url_index.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/top_sites.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/visit_database.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/visit_filter.h"
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/web_history_service.h"
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/web_history_service_factory.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/profile_error_dialog.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_notification_types.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/thumbnail_score.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/visitedlink/browser/visitedlink_master.h"
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/sync_error_factory.h"
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using history::HistoryBackend;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kHistoryThreadName = "Chrome_HistoryThread";
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DerefDownloadDbHandle(
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const HistoryService::DownloadCreateCallback& callback,
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64* db_handle) {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(*db_handle);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DerefDownloadId(
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const HistoryService::DownloadNextIdCallback& callback,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int* id) {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(*id);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RunWithFaviconResults(
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconService::FaviconResultsCallback& callback,
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<history::FaviconBitmapResult>* bitmap_results) {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(*bitmap_results);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Extract history::URLRows into GURLs for VisitedLinkMaster.
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class URLIteratorFromURLRows
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public components::VisitedLinkMaster::URLIterator {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit URLIteratorFromURLRows(const history::URLRows& url_rows)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : itr_(url_rows.begin()),
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        end_(url_rows.end()) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const GURL& NextURL() OVERRIDE {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (itr_++)->url();
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool HasNextURL() const OVERRIDE {
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return itr_ != end_;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  history::URLRows::const_iterator itr_;
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  history::URLRows::const_iterator end_;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(URLIteratorFromURLRows);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Callback from WebHistoryService::ExpireWebHistory().
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExpireWebHistoryComplete(
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    history::WebHistoryService::Request* request,
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success) {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ignore the result and delete the request.
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete request;
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sends messages from the backend to us on the main thread. This must be a
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// separate class from the history service so that it can hold a reference to
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the history service (otherwise we would have to manually AddRef and
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Release when the Backend has a reference to us).
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistoryService::BackendDelegate : public HistoryBackend::Delegate {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackendDelegate(
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::WeakPtr<HistoryService>& history_service,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const scoped_refptr<base::SequencedTaskRunner>& service_task_runner,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Profile* profile)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : history_service_(history_service),
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        service_task_runner_(service_task_runner),
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        profile_(profile) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void NotifyProfileError(int backend_id,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  sql::InitStatus init_status) OVERRIDE {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send to the history service on the main thread.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::NotifyProfileError, history_service_,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   backend_id, init_status));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetInMemoryBackend(int backend_id,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::InMemoryHistoryBackend* backend) OVERRIDE {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send the backend to the history service on the main thread.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::SetInMemoryBackend, history_service_,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   backend_id, backend));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void BroadcastNotifications(
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int type,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::HistoryDetails* details) OVERRIDE {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send the notification on the history thread.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (content::NotificationService::current()) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Details<history::HistoryDetails> det(details);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::current()->Notify(
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          type, content::Source<Profile>(profile_), det);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Send the notification to the history service on the main thread.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::BroadcastNotificationsHelper,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   history_service_, type, base::Owned(details)));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DBLoaded(int backend_id) OVERRIDE {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::OnDBLoaded, history_service_,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   backend_id));
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StartTopSitesMigration(int backend_id) OVERRIDE {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::StartTopSitesMigration,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   history_service_, backend_id));
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void NotifyVisitDBObserversOnAddVisit(
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const history::BriefVisitInfo& info) OVERRIDE {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_task_runner_->PostTask(
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HistoryService::NotifyVisitDBObserversOnAddVisit,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   history_service_, info));
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::WeakPtr<HistoryService> history_service_;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_refptr<base::SequencedTaskRunner> service_task_runner_;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* const profile_;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The history thread is intentionally not a BrowserThread because the
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sync integration unit tests depend on being able to create more than one
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// history thread.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::HistoryService()
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      thread_(new base::Thread(kHistoryThreadName)),
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_(NULL),
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_loaded_(false),
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_backend_id_(-1),
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bookmark_service_(NULL),
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      no_db_(false),
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      needs_top_sites_migration_(false) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::HistoryService(Profile* profile)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      thread_(new base::Thread(kHistoryThreadName)),
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_(profile),
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      visitedlink_master_(new components::VisitedLinkMaster(
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          profile, ALLOW_THIS_IN_INITIALIZER_LIST(this), true)),
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_loaded_(false),
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_backend_id_(-1),
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bookmark_service_(NULL),
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      no_db_(false),
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      needs_top_sites_migration_(false) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(profile_);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<Profile>(profile_));
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_TEMPLATE_URL_REMOVED,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<Profile>(profile_));
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::~HistoryService() {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shutdown the backend. This does nothing if Cleanup was already invoked.
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cleanup();
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::BackendLoaded() {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: We start the backend loading even though it completes asynchronously
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and thus won't affect the return value of this function.  This is because
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callers of this assume that if the backend isn't yet loaded it will be
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // soon, so they will either listen for notifications or just retry this call
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // later.  If we've purged the backend, we haven't necessarily restarted it
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // loading by now, so we need to trigger the load in order to maintain that
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // expectation.
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadBackendIfNecessary();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend_loaded_;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::UnloadBackend() {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!history_backend_)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;  // Already unloaded.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get rid of the in-memory backend.
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  in_memory_backend_.reset();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Give the InMemoryURLIndex a chance to shutdown.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (in_memory_url_index_.get())
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    in_memory_url_index_->ShutDown();
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The backend's destructor must run on the history thread since it is not
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // threadsafe. So this thread must not be the last thread holding a reference
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the backend, or a crash could happen.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We have a reference to the history backend. There is also an extra
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reference held by our delegate installed in the backend, which
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HistoryBackend::Closing will release. This means if we scheduled a call
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to HistoryBackend::Closing and *then* released our backend reference, there
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will be a race between us and the backend's Closing function to see who is
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the last holder of a reference. If the backend thread's Closing manages to
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // run before we release our backend refptr, the last reference will be held
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by this thread and the destructor will be called from here.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Therefore, we create a closure to run the Closing operation first. This
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // holds a reference to the backend. Then we release our reference, then we
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // schedule the task to run. After the task runs, it will delete its reference
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the history thread, ensuring everything works properly.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ajwong): Cleanup HistoryBackend lifetime issues.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     See http://crbug.com/99767.
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_backend_->AddRef();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure closing_task =
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&HistoryBackend::Closing, history_backend_.get());
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleTask(PRIORITY_NORMAL, closing_task);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  closing_task.Reset();
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryBackend* raw_ptr = history_backend_.get();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_backend_ = NULL;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thread_->message_loop()->ReleaseSoon(FROM_HERE, raw_ptr);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::Cleanup() {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thread_) {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We've already cleaned up.
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  weak_ptr_factory_.InvalidateWeakPtrs();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unload the backend.
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UnloadBackend();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete the thread, which joins with the background thread. We defensively
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NULL the pointer before deleting it in case somebody tries to use it
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // during shutdown, but this shouldn't happen.
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Thread* thread = thread_;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thread_ = NULL;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete thread;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::NotifyRenderProcessHostDestruction(const void* host) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::NotifyRenderProcessHostDestruction, host);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)history::URLDatabase* HistoryService::InMemoryDatabase() {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: See comments in BackendLoaded() as to why we call
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // LoadBackendIfNecessary() here even though it won't affect the return value
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for this call.
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadBackendIfNecessary();
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (in_memory_backend_.get())
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return in_memory_backend_->db();
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::GetTypedCountForURL(const GURL& url, int* typed_count) {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRow url_row;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetRowForURL(url, &url_row))
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *typed_count = url_row.typed_count();
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::GetLastVisitTimeForURL(const GURL& url,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            base::Time* last_visit) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRow url_row;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetRowForURL(url, &url_row))
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *last_visit = url_row.last_visit();
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::GetVisitCountForURL(const GURL& url, int* visit_count) {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRow url_row;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetRowForURL(url, &url_row))
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *visit_count = url_row.visit_count();
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::Shutdown() {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It's possible that bookmarks haven't loaded and history is waiting for
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bookmarks to complete loading. In such a situation history can't shutdown
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (meaning if we invoked history_service_->Cleanup now, we would
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deadlock). To break the deadlock we tell BookmarkModel it's about to be
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deleted so that it can release the signal history is waiting on, allowing
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // history to shutdown (history_service_->Cleanup to complete). In such a
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scenario history sees an incorrect view of bookmarks, but it's better
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // than a deadlock.
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BookmarkModel* bookmark_model = static_cast<BookmarkModel*>(
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BookmarkModelFactory::GetForProfileIfExists(profile_));
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bookmark_model)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bookmark_model->Shutdown();
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cleanup();
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetKeywordSearchTermsForURL(const GURL& url,
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 TemplateURLID keyword_id,
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 const string16& term) {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI,
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::SetKeywordSearchTermsForURL,
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    url, keyword_id, term);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::DeleteAllSearchTermsForKeyword(
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TemplateURLID keyword_id) {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI,
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::DeleteAllSearchTermsForKeyword,
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    keyword_id);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::GetMostRecentKeywordSearchTerms(
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TemplateURLID keyword_id,
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& prefix,
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int max_count,
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GetMostRecentKeywordSearchTermsCallback& callback) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_UI, &HistoryBackend::GetMostRecentKeywordSearchTerms,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  consumer,
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  new history::GetMostRecentKeywordSearchTermsRequest(callback),
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  keyword_id, prefix, max_count);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::URLsNoLongerBookmarked(const std::set<GURL>& urls) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::URLsNoLongerBookmarked,
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    urls);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::ScheduleDBTask(history::HistoryDBTask* task,
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    CancelableRequestConsumerBase* consumer) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::HistoryDBTaskRequest* request = new history::HistoryDBTaskRequest(
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&history::HistoryDBTask::DoneRunOnMainThread, task));
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request->value = task;  // The value is the task to execute.
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Schedule(PRIORITY_UI, &HistoryBackend::ProcessDBTask, consumer, request);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QuerySegmentUsageSince(
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Time from_time,
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int max_result_count,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SegmentQueryCallback& callback) {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_UI, &HistoryBackend::QuerySegmentUsage,
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  consumer, new history::QuerySegmentUsageRequest(callback),
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  from_time, max_result_count);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::IncreaseSegmentDuration(const GURL& url,
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             Time time,
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             base::TimeDelta delta) {
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::IncreaseSegmentDuration,
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    url, time, delta);
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HistoryService::Handle HistoryService::QuerySegmentDurationSince(
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CancelableRequestConsumerBase* consumer,
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::Time from_time,
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int max_result_count,
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const SegmentQueryCallback& callback) {
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Schedule(PRIORITY_UI, &HistoryBackend::QuerySegmentDuration,
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  consumer, new history::QuerySegmentUsageRequest(callback),
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  from_time, max_result_count);
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetOnBackendDestroyTask(const base::Closure& task) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetOnBackendDestroyTask,
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    MessageLoop::current(), task);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPage(const GURL& url,
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             Time time,
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const void* id_scope,
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int32 page_id,
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const GURL& referrer,
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const history::RedirectList& redirects,
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             content::PageTransition transition,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::VisitSource visit_source,
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool did_replace_entry) {
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddPage(
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::HistoryAddPageArgs(url, time, id_scope, page_id, referrer,
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  redirects, transition, visit_source,
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  did_replace_entry));
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPage(const GURL& url,
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             base::Time time,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::VisitSource visit_source) {
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddPage(
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::HistoryAddPageArgs(url, time, NULL, 0, GURL(),
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  history::RedirectList(),
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  content::PAGE_TRANSITION_LINK,
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  visit_source, false));
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPage(const history::HistoryAddPageArgs& add_page_args) {
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Filter out unwanted URLs. We don't add auto-subframe URLs. They are a
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // large part of history (think iframes for ads) and we never display them in
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // history UI. We will still add manual subframes, which are ones the user
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has clicked on to get.
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(add_page_args.url))
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add link & all redirects to visited link list.
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visitedlink_master_) {
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitedlink_master_->AddURL(add_page_args.url);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!add_page_args.redirects.empty()) {
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We should not be asked to add a page in the middle of a redirect chain.
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK_EQ(add_page_args.url,
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                add_page_args.redirects[add_page_args.redirects.size() - 1]);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We need the !redirects.empty() condition above since size_t is unsigned
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // and will wrap around when we subtract one from a 0 size.
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (size_t i = 0; i < add_page_args.redirects.size() - 1; i++)
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        visitedlink_master_->AddURL(add_page_args.redirects[i]);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::AddPage, add_page_args);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPageNoVisitForBookmark(const GURL& url,
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               const string16& title) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(url))
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::AddPageNoVisitForBookmark, url, title);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetPageTitle(const GURL& url,
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const string16& title) {
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetPageTitle, url, title);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::UpdateWithPageEndTime(const void* host,
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           int32 page_id,
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const GURL& url,
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           Time end_ts) {
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::UpdateWithPageEndTime,
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    host, page_id, url, end_ts);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPageWithDetails(const GURL& url,
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const string16& title,
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int visit_count,
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int typed_count,
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        Time last_visit,
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        bool hidden,
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        history::VisitSource visit_source) {
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Filter out unwanted URLs.
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(url))
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add to the visited links system.
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visitedlink_master_)
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitedlink_master_->AddURL(url);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRow row(url);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_title(title);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_visit_count(visit_count);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_typed_count(typed_count);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_last_visit(last_visit);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row.set_hidden(hidden);
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRows rows;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rows.push_back(row);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::AddPagesWithDetails, rows, visit_source);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddPagesWithDetails(const history::URLRows& info,
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         history::VisitSource visit_source) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add to the visited links system.
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visitedlink_master_) {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<GURL> urls;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    urls.reserve(info.size());
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (history::URLRows::const_iterator i = info.begin(); i != info.end();
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         ++i)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      urls.push_back(i->url());
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitedlink_master_->AddURLs(urls);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::AddPagesWithDetails, info, visit_source);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetPageContents(const GURL& url,
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const string16& contents) {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(url))
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_LOW, &HistoryBackend::SetPageContents,
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    url, contents);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::GetPageThumbnail(
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ThumbnailDataCallback& callback) {
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_NORMAL, &HistoryBackend::GetPageThumbnail, consumer,
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  new history::GetPageThumbnailRequest(callback), page_url);
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId HistoryService::GetFavicons(
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<GURL>& icon_urls,
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int icon_types,
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int desired_size_in_dip,
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<ui::ScaleFactor>& desired_scale_factors,
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconService::FaviconResultsCallback& callback,
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CancelableTaskTracker* tracker) {
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadBackendIfNecessary();
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<history::FaviconBitmapResult>* results =
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new std::vector<history::FaviconBitmapResult>();
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tracker->PostTaskAndReply(
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      thread_->message_loop_proxy(),
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::GetFavicons,
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 history_backend_.get(), icon_urls, icon_types,
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 desired_size_in_dip, desired_scale_factors, results),
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId HistoryService::GetFaviconsForURL(
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int icon_types,
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int desired_size_in_dip,
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<ui::ScaleFactor>& desired_scale_factors,
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconService::FaviconResultsCallback& callback,
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CancelableTaskTracker* tracker) {
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadBackendIfNecessary();
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<history::FaviconBitmapResult>* results =
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new std::vector<history::FaviconBitmapResult>();
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tracker->PostTaskAndReply(
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      thread_->message_loop_proxy(),
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::GetFaviconsForURL,
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 history_backend_.get(), page_url, icon_types,
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 desired_size_in_dip, desired_scale_factors, results),
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId HistoryService::GetFaviconForID(
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    history::FaviconID favicon_id,
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int desired_size_in_dip,
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::ScaleFactor desired_scale_factor,
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconService::FaviconResultsCallback& callback,
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CancelableTaskTracker* tracker) {
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadBackendIfNecessary();
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<history::FaviconBitmapResult>* results =
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new std::vector<history::FaviconBitmapResult>();
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tracker->PostTaskAndReply(
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      thread_->message_loop_proxy(),
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::GetFaviconForID,
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 history_backend_.get(), favicon_id,
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 desired_size_in_dip, desired_scale_factor, results),
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId HistoryService::UpdateFaviconMappingsAndFetch(
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<GURL>& icon_urls,
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int icon_types,
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int desired_size_in_dip,
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<ui::ScaleFactor>& desired_scale_factors,
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FaviconService::FaviconResultsCallback& callback,
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CancelableTaskTracker* tracker) {
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadBackendIfNecessary();
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<history::FaviconBitmapResult>* results =
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new std::vector<history::FaviconBitmapResult>();
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tracker->PostTaskAndReply(
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      thread_->message_loop_proxy(),
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::UpdateFaviconMappingsAndFetch,
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 history_backend_.get(), page_url, icon_urls, icon_types,
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 desired_size_in_dip, desired_scale_factors, results),
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::MergeFavicon(
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& icon_url,
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::IconType icon_type,
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::RefCountedMemory> bitmap_data,
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& pixel_size) {
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(page_url))
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::MergeFavicon, page_url,
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    icon_url, icon_type, bitmap_data, pixel_size);
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetFavicons(
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& page_url,
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::IconType icon_type,
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<history::FaviconBitmapData>& favicon_bitmap_data) {
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanAddURL(page_url))
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetFavicons, page_url,
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      icon_type, favicon_bitmap_data);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetFaviconsOutOfDateForPage(const GURL& page_url) {
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::SetFaviconsOutOfDateForPage, page_url);
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::CloneFavicons(const GURL& old_page_url,
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const GURL& new_page_url) {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::CloneFavicons,
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    old_page_url, new_page_url);
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetImportedFavicons(
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<history::ImportedFaviconUsage>& favicon_usage) {
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::SetImportedFavicons, favicon_usage);
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryURL(
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool want_visits,
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryURLCallback& callback) {
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_UI, &HistoryBackend::QueryURL, consumer,
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  new history::QueryURLRequest(callback), url, want_visits);
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Downloads -------------------------------------------------------------------
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handle creation of a download by creating an entry in the history service's
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 'downloads' table.
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::CreateDownload(
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const history::DownloadRow& create_info,
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HistoryService::DownloadCreateCallback& callback) {
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadBackendIfNecessary();
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64* db_handle = new int64(
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      history::DownloadDatabase::kUninitializedHandle);
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  thread_->message_loop_proxy()->PostTaskAndReply(
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::CreateDownload,
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 history_backend_.get(),
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 create_info,
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 db_handle),
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&DerefDownloadDbHandle, callback, base::Owned(db_handle)));
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::GetNextDownloadId(const DownloadNextIdCallback& callback) {
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadBackendIfNecessary();
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int* id = new int(history::DownloadDatabase::kUninitializedHandle);
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  thread_->message_loop_proxy()->PostTaskAndReply(
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::GetNextDownloadId,
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 history_backend_.get(),
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 id),
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&DerefDownloadId, callback, base::Owned(id)));
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handle queries for a list of all downloads in the history database's
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 'downloads' table.
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::QueryDownloads(
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const DownloadQueryCallback& callback) {
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_) << "History service being called after cleanup";
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadBackendIfNecessary();
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<history::DownloadRow>* rows =
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new std::vector<history::DownloadRow>();
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<std::vector<history::DownloadRow> > scoped_rows(rows);
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Beware! The first Bind() does not simply |scoped_rows.get()| because
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // base::Passed(&scoped_rows) nullifies |scoped_rows|, and compilers do not
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // guarantee that the first Bind's arguments are evaluated before the second
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Bind's arguments.
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  thread_->message_loop_proxy()->PostTaskAndReply(
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::QueryDownloads, history_backend_.get(), rows),
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(callback, base::Passed(&scoped_rows)));
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Changes all IN_PROGRESS in the database entries to CANCELED.
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IN_PROGRESS entries are the corrupted entries, not updated by next function
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// because of the crash or some other extremal exit.
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::CleanUpInProgressEntries() {
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::CleanUpInProgressEntries);
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handle updates for a particular download. This is a 'fire and forget'
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// operation, so we don't need to be called back.
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::UpdateDownload(const history::DownloadRow& data) {
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::UpdateDownload, data);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::RemoveDownloads(const std::set<int64>& db_handles) {
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    &HistoryBackend::RemoveDownloads, db_handles);
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryHistory(
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& text_query,
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const history::QueryOptions& options,
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryHistoryCallback& callback) {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_UI, &HistoryBackend::QueryHistory, consumer,
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  new history::QueryHistoryRequest(callback),
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  text_query, options);
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryRedirectsFrom(
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& from_url,
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryRedirectsCallback& callback) {
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_UI, &HistoryBackend::QueryRedirectsFrom, consumer,
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new history::QueryRedirectsRequest(callback), from_url);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryRedirectsTo(
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& to_url,
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryRedirectsCallback& callback) {
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryRedirectsTo, consumer,
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new history::QueryRedirectsRequest(callback), to_url);
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::GetVisibleVisitCountToHost(
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GetVisibleVisitCountToHostCallback& callback) {
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_UI, &HistoryBackend::GetVisibleVisitCountToHost,
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      consumer, new history::GetVisibleVisitCountToHostRequest(callback), url);
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryTopURLsAndRedirects(
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int result_count,
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryTopURLsAndRedirectsCallback& callback) {
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryTopURLsAndRedirects,
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      consumer, new history::QueryTopURLsAndRedirectsRequest(callback),
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_count);
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryMostVisitedURLs(
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int result_count,
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int days_back,
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryMostVisitedURLsCallback& callback) {
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryMostVisitedURLs,
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  consumer,
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  new history::QueryMostVisitedURLsRequest(callback),
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  result_count, days_back);
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService::Handle HistoryService::QueryFilteredURLs(
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int result_count,
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const history::VisitFilter& filter,
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool extended_info,
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CancelableRequestConsumerBase* consumer,
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QueryFilteredURLsCallback& callback) {
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Schedule(PRIORITY_NORMAL,
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &HistoryBackend::QueryFilteredURLs,
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  consumer,
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  new history::QueryFilteredURLsRequest(callback),
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  result_count, filter, extended_info);
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::Observe(int type,
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const content::NotificationSource& source,
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const content::NotificationDetails& details) {
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thread_)
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_HISTORY_URLS_DELETED: {
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Update the visited link system for deleted URLs. We will update the
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // visited link system for added URLs as soon as we get the add
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // notification (we don't have to wait for the backend, which allows us to
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // be faster to update the state).
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      //
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // For deleted URLs, we don't typically know what will be deleted since
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // delete notifications are by time. We would also like to be more
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // respectful of privacy and never tell the user something is gone when it
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // isn't. Therefore, we update the delete URLs after the fact.
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (visitedlink_master_) {
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::Details<history::URLsDeletedDetails> deleted_details(details);
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (deleted_details->all_history) {
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          visitedlink_master_->DeleteAllURLs();
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else {
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          URLIteratorFromURLRows iterator(deleted_details->rows);
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          visitedlink_master_->DeleteURLs(&iterator);
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_TEMPLATE_URL_REMOVED:
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DeleteAllSearchTermsForKeyword(
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          *(content::Details<TemplateURLID>(details).ptr()));
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::RebuildTable(
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const scoped_refptr<URLEnumerator>& enumerator) {
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::IterateURLs, enumerator);
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HistoryService::Init(const base::FilePath& history_dir,
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          BookmarkService* bookmark_service,
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          bool no_db) {
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thread_->Start()) {
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Cleanup();
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_dir_ = history_dir;
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bookmark_service_ = bookmark_service;
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  no_db_ = no_db;
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (profile_) {
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string languages =
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    in_memory_url_index_.reset(
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new history::InMemoryURLIndex(profile_, history_dir_, languages));
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    in_memory_url_index_->Init();
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the history backend.
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadBackendIfNecessary();
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visitedlink_master_) {
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool result = visitedlink_master_->Init();
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(result);
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::ScheduleAutocomplete(HistoryURLProvider* provider,
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          HistoryURLProviderParams* params) {
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI, &HistoryBackend::ScheduleAutocomplete,
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    scoped_refptr<HistoryURLProvider>(provider), params);
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::ScheduleTask(SchedulePriority priority,
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const base::Closure& task) {
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(thread_);
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(thread_->message_loop());
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(brettw): Do prioritization.
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thread_->message_loop()->PostTask(FROM_HERE, task);
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::CanAddURL(const GURL& url) {
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url.is_valid())
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO: We should allow kChromeUIScheme URLs if they have been explicitly
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // typed.  Right now, however, these are marked as typed even when triggered
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by a shortcut or menu action.
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (url.SchemeIs(chrome::kJavaScriptScheme) ||
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url.SchemeIs(chrome::kChromeDevToolsScheme) ||
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url.SchemeIs(chrome::kChromeUIScheme) ||
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url.SchemeIs(chrome::kViewSourceScheme) ||
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url.SchemeIs(chrome::kChromeInternalScheme))
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allow all about: and chrome: URLs except about:blank, since the user may
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // like to see "chrome://memory/", etc. in their history and autocomplete.
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (url == GURL(chrome::kAboutBlankURL))
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::WeakPtr<HistoryService> HistoryService::AsWeakPtr() {
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return weak_ptr_factory_.GetWeakPtr();
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)syncer::SyncMergeResult HistoryService::MergeDataAndStartSyncing(
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type,
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::SyncDataList& initial_sync_data,
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<syncer::SyncErrorFactory> error_handler) {
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(type, syncer::HISTORY_DELETE_DIRECTIVES);
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete_directive_handler_.Start(this, initial_sync_data,
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_processor.Pass());
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return syncer::SyncMergeResult(type);
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::StopSyncing(syncer::ModelType type) {
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(type, syncer::HISTORY_DELETE_DIRECTIVES);
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete_directive_handler_.Stop();
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncDataList HistoryService::GetAllSyncData(
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::ModelType type) const {
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(type, syncer::HISTORY_DELETE_DIRECTIVES);
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(akalin): Keep track of existing delete directives.
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return syncer::SyncDataList();
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncError HistoryService::ProcessSyncChanges(
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const tracked_objects::Location& from_here,
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::SyncChangeList& change_list) {
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete_directive_handler_.ProcessSyncChanges(this, change_list);
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return syncer::SyncError();
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)syncer::SyncError HistoryService::ProcessLocalDeleteDirective(
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const sync_pb::HistoryDeleteDirectiveSpecifics& delete_directive) {
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return delete_directive_handler_.ProcessLocalDeleteDirective(
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delete_directive);
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::SetInMemoryBackend(int backend_id,
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::InMemoryHistoryBackend* mem_backend) {
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!history_backend_ || current_backend_id_ != backend_id) {
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DVLOG(1) << "Message from obsolete backend";
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Cleaning up the memory backend.
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete mem_backend;
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!in_memory_backend_.get()) << "Setting mem DB twice";
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  in_memory_backend_.reset(mem_backend);
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The database requires additional initialization once we own it.
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  in_memory_backend_->AttachToHistoryService(profile_);
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::NotifyProfileError(int backend_id,
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        sql::InitStatus init_status) {
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!history_backend_ || current_backend_id_ != backend_id) {
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DVLOG(1) << "Message from obsolete backend";
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShowProfileErrorDialog(
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (init_status == sql::INIT_FAILURE) ?
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_COULDNT_OPEN_PROFILE_ERROR : IDS_PROFILE_TOO_NEW_ERROR);
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::DeleteURL(const GURL& url) {
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We will update the visited links when we observe the delete notifications.
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::DeleteURL, url);
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::DeleteURLsForTest(const std::vector<GURL>& urls) {
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We will update the visited links when we observe the delete
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notifications.
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::DeleteURLs, urls);
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::ExpireHistoryBetween(
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::set<GURL>& restrict_urls,
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Time begin_time,
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Time end_time,
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback,
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CancelableTaskTracker* tracker) {
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_);
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(history_backend_.get());
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tracker->PostTaskAndReply(
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      thread_->message_loop_proxy(),
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::ExpireHistoryBetween,
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 history_backend_, restrict_urls, begin_time, end_time),
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback);
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::ExpireHistory(
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<history::ExpireHistoryArgs>& expire_list,
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback,
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CancelableTaskTracker* tracker) {
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_);
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(history_backend_.get());
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tracker->PostTaskAndReply(
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      thread_->message_loop_proxy(),
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HistoryBackend::ExpireHistory, history_backend_, expire_list),
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback);
11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HistoryService::ExpireLocalAndRemoteHistoryBetween(
11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::set<GURL>& restrict_urls,
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Time begin_time,
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Time end_time,
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback,
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CancelableTaskTracker* tracker) {
11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(dubroy): This should be factored out into a separate class that
11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // dispatches deletions to the proper places.
11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  history::WebHistoryService* web_history =
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebHistoryServiceFactory::GetForProfile(profile_);
11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (web_history) {
11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(dubroy): This API does not yet support deletion of specific URLs.
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(restrict_urls.empty());
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete_directive_handler_.CreateDeleteDirectives(
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::set<int64>(), begin_time, end_time);
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Attempt online deletion from the history server, but ignore the result.
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Deletion directives ensure that the results will eventually be deleted.
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pass ownership of the request to the callback.
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<history::WebHistoryService::Request> request =
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        web_history->ExpireHistoryBetween(
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            restrict_urls, begin_time, end_time,
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            base::Bind(&ExpireWebHistoryComplete));
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The request will be freed when the callback is called.
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CHECK(request.release());
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpireHistoryBetween(restrict_urls, begin_time, end_time, callback, tracker);
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::BroadcastNotificationsHelper(
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::HistoryDetails* details) {
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(evanm): this is currently necessitated by generate_profile, which
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // runs without a browser process. generate_profile should really create
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a browser process, at which point this check can then be nuked.
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_browser_process)
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thread_)
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The source of all of our notifications is the profile. Note that this
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pointer is NULL in unit tests.
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::Source<Profile> source(profile_);
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The details object just contains the pointer to the object that the
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // backend has allocated for us. The receiver of the notification will cast
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this to the proper type.
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::Details<history::HistoryDetails> det(details);
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(type, source, det);
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::LoadBackendIfNecessary() {
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thread_ || history_backend_)
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;  // Failed to init, or already started loading.
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++current_backend_id_;
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HistoryBackend> backend(
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HistoryBackend(history_dir_,
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         current_backend_id_,
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         new BackendDelegate(
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             weak_ptr_factory_.GetWeakPtr(),
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             base::ThreadTaskRunnerHandle::Get(),
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             profile_),
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         bookmark_service_));
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history_backend_.swap(backend);
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There may not be a profile when unit testing.
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string languages;
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (profile_) {
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefService* prefs = profile_->GetPrefs();
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    languages = prefs->GetString(prefs::kAcceptLanguages);
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_UI, &HistoryBackend::Init, languages, no_db_);
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::OnDBLoaded(int backend_id) {
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!history_backend_ || current_backend_id_ != backend_id) {
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DVLOG(1) << "Message from obsolete backend";
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_loaded_ = true;
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_HISTORY_LOADED,
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<Profile>(profile_),
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Details<HistoryService>(this));
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (thread_ && profile_) {
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We don't want to force creation of TopSites.
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::TopSites* ts = profile_->GetTopSitesWithoutCreating();
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ts)
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ts->HistoryLoaded();
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HistoryService::GetRowForURL(const GURL& url, history::URLRow* url_row) {
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLDatabase* db = InMemoryDatabase();
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return db && (db->GetRowForURL(url, url_row) != 0);
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::StartTopSitesMigration(int backend_id) {
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!history_backend_ || current_backend_id_ != backend_id) {
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DVLOG(1) << "Message from obsolete backend";
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  needs_top_sites_migration_ = true;
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (thread_ && profile_) {
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We don't want to force creation of TopSites.
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::TopSites* ts = profile_->GetTopSitesWithoutCreating();
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ts)
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ts->MigrateFromHistory();
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::OnTopSitesReady() {
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAndForget(PRIORITY_NORMAL,
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &HistoryBackend::MigrateThumbnailsDatabase);
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::AddVisitDatabaseObserver(
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::VisitDatabaseObserver* observer) {
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visit_database_observers_.AddObserver(observer);
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::RemoveVisitDatabaseObserver(
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::VisitDatabaseObserver* observer) {
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visit_database_observers_.RemoveObserver(observer);
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryService::NotifyVisitDBObserversOnAddVisit(
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const history::BriefVisitInfo& info) {
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(history::VisitDatabaseObserver, visit_database_observers_,
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnAddVisit(info));
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1283