1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The history system runs on a background thread so that potentially slow
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// database operations don't delay the browser. This backend processing is
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// represented by HistoryBackend. The HistoryService's job is to dispatch to
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// that thread.
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Main thread                       History thread
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// -----------                       --------------
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HistoryService <----------------> HistoryBackend
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//                                   -> HistoryDatabase
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//                                      -> SQLite connection to History
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//                                   -> ArchivedDatabase
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//                                      -> SQLite connection to Archived History
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//                                   -> TextDatabaseManager
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//                                      -> SQLite connection to one month's data
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//                                      -> SQLite connection to one month's data
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//                                      ...
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//                                   -> ThumbnailDatabase
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//                                      -> SQLite connection to Thumbnails
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//                                         (and favicons)
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h"
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h"
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_util.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/task.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autocomplete/history_url_provider.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h"
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/history/download_create_info.h"
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history_backend.h"
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history_notifications.h"
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history_types.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/in_memory_database.h"
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/in_memory_history_backend.h"
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/top_sites.h"
42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/prefs/pref_service.h"
4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/profile_error_dialog.h"
4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/visitedlink/visitedlink_master.h"
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_constants.h"
47731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/common/pref_names.h"
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/thumbnail_score.h"
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h"
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/skia/include/core/SkBitmap.h"
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time;
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing history::HistoryBackend;
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char* kHistoryThreadName = "Chrome_HistoryThread";
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Sends messages from the backend to us on the main thread. This must be a
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// separate class from the history service so that it can hold a reference to
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the history service (otherwise we would have to manually AddRef and
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Release when the Backend has a reference to us).
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass HistoryService::BackendDelegate : public HistoryBackend::Delegate {
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit BackendDelegate(HistoryService* history_service)
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : history_service_(history_service),
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        message_loop_(MessageLoop::current()) {
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void NotifyProfileError(sql::InitStatus init_status) OVERRIDE {
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Send to the history service on the main thread.
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop_->PostTask(FROM_HERE, NewRunnableMethod(history_service_.get(),
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &HistoryService::NotifyProfileError, init_status));
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void SetInMemoryBackend(
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      history::InMemoryHistoryBackend* backend) OVERRIDE {
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Send the backend to the history service on the main thread.
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop_->PostTask(FROM_HERE, NewRunnableMethod(history_service_.get(),
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        &HistoryService::SetInMemoryBackend, backend));
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void BroadcastNotifications(
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NotificationType type,
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      history::HistoryDetails* details) OVERRIDE {
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Send the notification on the history thread.
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (NotificationService::current()) {
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Details<history::HistoryDetails> det(details);
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::current()->Notify(type,
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             NotificationService::AllSources(),
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             det);
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Send the notification to the history service on the main thread.
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop_->PostTask(FROM_HERE, NewRunnableMethod(history_service_.get(),
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        &HistoryService::BroadcastNotifications, type, details));
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void DBLoaded() OVERRIDE {
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop_->PostTask(FROM_HERE, NewRunnableMethod(history_service_.get(),
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        &HistoryService::OnDBLoaded));
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void StartTopSitesMigration() OVERRIDE {
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop_->PostTask(FROM_HERE, NewRunnableMethod(history_service_.get(),
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        &HistoryService::StartTopSitesMigration));
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<HistoryService> history_service_;
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop* message_loop_;
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst history::StarID HistoryService::kBookmarkBarID = 1;
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// The history thread is intentionally not a BrowserThread because the
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// sync integration unit tests depend on being able to create more than one
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// history thread.
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::HistoryService()
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : thread_(new base::Thread(kHistoryThreadName)),
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_(NULL),
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      backend_loaded_(false),
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      bookmark_service_(NULL),
130513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      no_db_(false),
131513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      needs_top_sites_migration_(false) {
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::HistoryService(Profile* profile)
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : thread_(new base::Thread(kHistoryThreadName)),
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_(profile),
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      backend_loaded_(false),
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      bookmark_service_(NULL),
139513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      no_db_(false),
140513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      needs_top_sites_migration_(false) {
141513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DCHECK(profile_);
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::HISTORY_URLS_DELETED,
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 Source<Profile>(profile_));
144513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  registrar_.Add(this, NotificationType::TEMPLATE_URL_REMOVED,
145513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                 Source<Profile>(profile_));
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::~HistoryService() {
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Shutdown the backend. This does nothing if Cleanup was already invoked.
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Cleanup();
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool HistoryService::BackendLoaded() {
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // NOTE: We start the backend loading even though it completes asynchronously
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and thus won't affect the return value of this function.  This is because
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // callers of this assume that if the backend isn't yet loaded it will be
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // soon, so they will either listen for notifications or just retry this call
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // later.  If we've purged the backend, we haven't necessarily restarted it
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // loading by now, so we need to trigger the load in order to maintain that
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // expectation.
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadBackendIfNecessary();
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return backend_loaded_;
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::UnloadBackend() {
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!history_backend_)
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;  // Already unloaded.
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get rid of the in-memory backend.
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  in_memory_backend_.reset();
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The backend's destructor must run on the history thread since it is not
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // threadsafe. So this thread must not be the last thread holding a reference
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to the backend, or a crash could happen.
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We have a reference to the history backend. There is also an extra
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // reference held by our delegate installed in the backend, which
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // HistoryBackend::Closing will release. This means if we scheduled a call
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to HistoryBackend::Closing and *then* released our backend reference, there
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // will be a race between us and the backend's Closing function to see who is
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the last holder of a reference. If the backend thread's Closing manages to
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // run before we release our backend refptr, the last reference will be held
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // by this thread and the destructor will be called from here.
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Therefore, we create a task to run the Closing operation first. This holds
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // a reference to the backend. Then we release our reference, then we schedule
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the task to run. After the task runs, it will delete its reference from
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the history thread, ensuring everything works properly.
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Task* closing_task =
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(history_backend_.get(), &HistoryBackend::Closing);
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  history_backend_ = NULL;
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleTask(PRIORITY_NORMAL, closing_task);
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::Cleanup() {
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!thread_) {
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We've already cleaned up.
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Unload the backend.
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UnloadBackend();
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Delete the thread, which joins with the background thread. We defensively
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // NULL the pointer before deleting it in case somebody tries to use it
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // during shutdown, but this shouldn't happen.
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::Thread* thread = thread_;
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  thread_ = NULL;
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete thread;
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::NotifyRenderProcessHostDestruction(const void* host) {
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL,
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    &HistoryBackend::NotifyRenderProcessHostDestruction, host);
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochhistory::URLDatabase* HistoryService::InMemoryDatabase() {
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // NOTE: See comments in BackendLoaded() as to why we call
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // LoadBackendIfNecessary() here even though it won't affect the return value
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // for this call.
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadBackendIfNecessary();
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (in_memory_backend_.get())
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return in_memory_backend_->db();
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickhistory::InMemoryURLIndex* HistoryService::InMemoryIndex() {
2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // NOTE: See comments in BackendLoaded() as to why we call
2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // LoadBackendIfNecessary() here even though it won't affect the return value
2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // for this call.
2313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  LoadBackendIfNecessary();
2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (in_memory_backend_.get())
233731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return in_memory_backend_->InMemoryIndex();
2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return NULL;
2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::SetSegmentPresentationIndex(int64 segment_id, int index) {
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_UI,
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    &HistoryBackend::SetSegmentPresentationIndex,
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    segment_id, index);
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::SetKeywordSearchTermsForURL(const GURL& url,
2443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                 TemplateURLID keyword_id,
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 const string16& term) {
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_UI,
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    &HistoryBackend::SetKeywordSearchTermsForURL,
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    url, keyword_id, term);
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::DeleteAllSearchTermsForKeyword(
2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TemplateURLID keyword_id) {
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_UI,
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    &HistoryBackend::DeleteAllSearchTermsForKeyword,
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    keyword_id);
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::Handle HistoryService::GetMostRecentKeywordSearchTerms(
2593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TemplateURLID keyword_id,
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const string16& prefix,
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int max_count,
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer,
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GetMostRecentKeywordSearchTermsCallback* callback) {
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Schedule(PRIORITY_UI, &HistoryBackend::GetMostRecentKeywordSearchTerms,
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  consumer,
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  new history::GetMostRecentKeywordSearchTermsRequest(callback),
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  keyword_id, prefix, max_count);
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::URLsNoLongerBookmarked(const std::set<GURL>& urls) {
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::URLsNoLongerBookmarked,
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    urls);
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::Handle HistoryService::ScheduleDBTask(
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HistoryDBTask* task,
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer) {
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  history::HistoryDBTaskRequest* request = new history::HistoryDBTaskRequest(
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(task, &HistoryDBTask::DoneRunOnMainThread));
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  request->value = task;  // The value is the task to execute.
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Schedule(PRIORITY_UI, &HistoryBackend::ProcessDBTask, consumer,
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  request);
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::Handle HistoryService::QuerySegmentUsageSince(
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer,
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const Time from_time,
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int max_result_count,
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SegmentQueryCallback* callback) {
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Schedule(PRIORITY_UI, &HistoryBackend::QuerySegmentUsage,
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  consumer, new history::QuerySegmentUsageRequest(callback),
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  from_time, max_result_count);
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::SetOnBackendDestroyTask(Task* task) {
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetOnBackendDestroyTask,
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    MessageLoop::current(), task);
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::AddPage(const GURL& url,
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const void* id_scope,
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             int32 page_id,
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const GURL& referrer,
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             PageTransition::Type transition,
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const history::RedirectList& redirects,
3063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             history::VisitSource visit_source,
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             bool did_replace_entry) {
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddPage(url, Time::Now(), id_scope, page_id, referrer, transition, redirects,
3093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          visit_source, did_replace_entry);
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::AddPage(const GURL& url,
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             Time time,
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const void* id_scope,
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             int32 page_id,
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const GURL& referrer,
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             PageTransition::Type transition,
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const history::RedirectList& redirects,
3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             history::VisitSource visit_source,
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             bool did_replace_entry) {
3213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_refptr<history::HistoryAddPageArgs> request(
3223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new history::HistoryAddPageArgs(url, time, id_scope, page_id, referrer,
3233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                      redirects, transition, visit_source,
3243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                      did_replace_entry));
3253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AddPage(*request);
3263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
3273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid HistoryService::AddPage(const history::HistoryAddPageArgs& add_page_args) {
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(thread_) << "History service being called after cleanup";
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Filter out unwanted URLs. We don't add auto-subframe URLs. They are a
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // large part of history (think iframes for ads) and we never display them in
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // history UI. We will still add manual subframes, which are ones the user
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // has clicked on to get.
3353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!CanAddURL(add_page_args.url))
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add link & all redirects to visited link list.
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VisitedLinkMaster* visited_links;
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (profile_ && (visited_links = profile_->GetVisitedLinkMaster())) {
3413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    visited_links->AddURL(add_page_args.url);
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (!add_page_args.redirects.empty()) {
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // We should not be asked to add a page in the middle of a redirect chain.
3453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      DCHECK_EQ(add_page_args.url,
3463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                add_page_args.redirects[add_page_args.redirects.size() - 1]);
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // We need the !redirects.empty() condition above since size_t is unsigned
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // and will wrap around when we subtract one from a 0 size.
3503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      for (size_t i = 0; i < add_page_args.redirects.size() - 1; i++)
3513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        visited_links->AddURL(add_page_args.redirects[i]);
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::AddPage,
3563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    scoped_refptr<history::HistoryAddPageArgs>(
3573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        add_page_args.Clone()));
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
36021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid HistoryService::AddPageNoVisitForBookmark(const GURL& url) {
36121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!CanAddURL(url))
36221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
36321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
36421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ScheduleAndForget(PRIORITY_NORMAL,
36521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                    &HistoryBackend::AddPageNoVisitForBookmark, url);
36621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
36721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::SetPageTitle(const GURL& url,
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  const string16& title) {
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetPageTitle, url, title);
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::AddPageWithDetails(const GURL& url,
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        const string16& title,
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        int visit_count,
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        int typed_count,
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        Time last_visit,
3783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        bool hidden,
3793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        history::VisitSource visit_source) {
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Filter out unwanted URLs.
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!CanAddURL(url))
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add to the visited links system.
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VisitedLinkMaster* visited_links;
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (profile_ && (visited_links = profile_->GetVisitedLinkMaster()))
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    visited_links->AddURL(url);
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  history::URLRow row(url);
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  row.set_title(title);
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  row.set_visit_count(visit_count);
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  row.set_typed_count(typed_count);
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  row.set_last_visit(last_visit);
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  row.set_hidden(hidden);
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<history::URLRow> rows;
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rows.push_back(row);
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL,
4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    &HistoryBackend::AddPagesWithDetails, rows, visit_source);
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::AddPagesWithDetails(
4043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::vector<history::URLRow>& info,
4053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    history::VisitSource visit_source) {
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add to the visited links system.
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VisitedLinkMaster* visited_links;
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (profile_ && (visited_links = profile_->GetVisitedLinkMaster())) {
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<GURL> urls;
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    urls.reserve(info.size());
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (std::vector<history::URLRow>::const_iterator i = info.begin();
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         i != info.end();
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         ++i)
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      urls.push_back(i->url());
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    visited_links->AddURLs(urls);
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL,
4213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    &HistoryBackend::AddPagesWithDetails, info, visit_source);
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::SetPageContents(const GURL& url,
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     const string16& contents) {
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!CanAddURL(url))
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_LOW, &HistoryBackend::SetPageContents,
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    url, contents);
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::SetPageThumbnail(const GURL& page_url,
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      const SkBitmap& thumbnail,
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      const ThumbnailScore& score) {
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!CanAddURL(page_url))
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetPageThumbnail,
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    page_url, thumbnail, score);
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::Handle HistoryService::GetPageThumbnail(
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& page_url,
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer,
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ThumbnailDataCallback* callback) {
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Schedule(PRIORITY_NORMAL, &HistoryBackend::GetPageThumbnail, consumer,
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  new history::GetPageThumbnailRequest(callback), page_url);
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::GetFavicon(FaviconService::GetFaviconRequest* request,
452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                const GURL& icon_url,
453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                history::IconType icon_type) {
454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Schedule(PRIORITY_NORMAL, &HistoryBackend::GetFavicon, NULL, request,
455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           icon_url, icon_type);
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::UpdateFaviconMappingAndFetch(
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FaviconService::GetFaviconRequest* request,
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& page_url,
461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const GURL& icon_url,
462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    history::IconType icon_type) {
463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Schedule(PRIORITY_NORMAL, &HistoryBackend::UpdateFaviconMappingAndFetch, NULL,
464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           request, page_url, icon_url, history::FAVICON);
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::GetFaviconForURL(
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FaviconService::GetFaviconRequest* request,
469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const GURL& page_url,
470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int icon_types) {
471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Schedule(PRIORITY_NORMAL, &HistoryBackend::GetFaviconForURL, NULL, request,
472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           page_url, icon_types);
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::SetFavicon(const GURL& page_url,
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                const GURL& icon_url,
477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                const std::vector<unsigned char>& image_data,
478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                history::IconType icon_type) {
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!CanAddURL(page_url))
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetFavicon,
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      page_url, icon_url,
484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      scoped_refptr<RefCountedMemory>(new RefCountedBytes(image_data)),
485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      icon_type);
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::SetFaviconOutOfDateForPage(const GURL& page_url) {
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL,
490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    &HistoryBackend::SetFaviconOutOfDateForPage, page_url);
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::SetImportedFavicons(
494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::vector<history::ImportedFaviconUsage>& favicon_usage) {
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL,
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    &HistoryBackend::SetImportedFavicons, favicon_usage);
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::IterateURLs(URLEnumerator* enumerator) {
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::IterateURLs, enumerator);
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::Handle HistoryService::QueryURL(
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& url,
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool want_visits,
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer,
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    QueryURLCallback* callback) {
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Schedule(PRIORITY_UI, &HistoryBackend::QueryURL, consumer,
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  new history::QueryURLRequest(callback), url, want_visits);
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Downloads -------------------------------------------------------------------
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Handle creation of a download by creating an entry in the history service's
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 'downloads' table.
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::Handle HistoryService::CreateDownload(
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const DownloadCreateInfo& create_info,
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer,
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HistoryService::DownloadCreateCallback* callback) {
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Schedule(PRIORITY_NORMAL, &HistoryBackend::CreateDownload, consumer,
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  new history::DownloadCreateRequest(callback), create_info);
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Handle queries for a list of all downloads in the history database's
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 'downloads' table.
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::Handle HistoryService::QueryDownloads(
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer,
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DownloadQueryCallback* callback) {
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryDownloads, consumer,
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  new history::DownloadQueryRequest(callback));
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Changes all IN_PROGRESS in the database entries to CANCELED.
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// IN_PROGRESS entries are the corrupted entries, not updated by next function
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// because of the crash or some other extremal exit.
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::CleanUpInProgressEntries() {
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::CleanUpInProgressEntries);
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Handle updates for a particular download. This is a 'fire and forget'
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// operation, so we don't need to be called back.
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::UpdateDownload(int64 received_bytes,
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    int32 state,
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    int64 db_handle) {
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::UpdateDownload,
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    received_bytes, state, db_handle);
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::UpdateDownloadPath(const FilePath& path,
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        int64 db_handle) {
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::UpdateDownloadPath,
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    path, db_handle);
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::RemoveDownload(int64 db_handle) {
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL,
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    &HistoryBackend::RemoveDownload, db_handle);
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::RemoveDownloadsBetween(Time remove_begin,
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            Time remove_end) {
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL,
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    &HistoryBackend::RemoveDownloadsBetween,
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    remove_begin,
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    remove_end);
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::Handle HistoryService::QueryHistory(
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const string16& text_query,
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const history::QueryOptions& options,
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer,
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    QueryHistoryCallback* callback) {
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Schedule(PRIORITY_UI, &HistoryBackend::QueryHistory, consumer,
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  new history::QueryHistoryRequest(callback),
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  text_query, options);
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::Handle HistoryService::QueryRedirectsFrom(
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& from_url,
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer,
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    QueryRedirectsCallback* callback) {
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Schedule(PRIORITY_UI, &HistoryBackend::QueryRedirectsFrom, consumer,
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new history::QueryRedirectsRequest(callback), from_url);
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::Handle HistoryService::QueryRedirectsTo(
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& to_url,
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer,
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    QueryRedirectsCallback* callback) {
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryRedirectsTo, consumer,
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new history::QueryRedirectsRequest(callback), to_url);
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::Handle HistoryService::GetVisitCountToHost(
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& url,
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer,
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GetVisitCountToHostCallback* callback) {
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Schedule(PRIORITY_UI, &HistoryBackend::GetVisitCountToHost, consumer,
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new history::GetVisitCountToHostRequest(callback), url);
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::Handle HistoryService::QueryTopURLsAndRedirects(
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int result_count,
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer,
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    QueryTopURLsAndRedirectsCallback* callback) {
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryTopURLsAndRedirects,
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      consumer, new history::QueryTopURLsAndRedirectsRequest(callback),
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      result_count);
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryService::Handle HistoryService::QueryMostVisitedURLs(
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int result_count,
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int days_back,
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer,
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    QueryMostVisitedURLsCallback* callback) {
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Schedule(PRIORITY_NORMAL, &HistoryBackend::QueryMostVisitedURLs,
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  consumer,
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  new history::QueryMostVisitedURLsRequest(callback),
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  result_count, days_back);
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::Observe(NotificationType type,
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const NotificationSource& source,
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const NotificationDetails& details) {
625513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (!thread_)
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
628513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  switch (type.value) {
629513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case NotificationType::HISTORY_URLS_DELETED: {
630513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      // Update the visited link system for deleted URLs. We will update the
631513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      // visited link system for added URLs as soon as we get the add
632513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      // notification (we don't have to wait for the backend, which allows us to
633513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      // be faster to update the state).
634513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      //
635513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      // For deleted URLs, we don't typically know what will be deleted since
636513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      // delete notifications are by time. We would also like to be more
637513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      // respectful of privacy and never tell the user something is gone when it
638513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      // isn't. Therefore, we update the delete URLs after the fact.
639513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      if (!profile_)
640513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        return;  // No profile, probably unit testing.
641513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      Details<history::URLsDeletedDetails> deleted_details(details);
642513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      VisitedLinkMaster* visited_links = profile_->GetVisitedLinkMaster();
643513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      if (!visited_links)
644513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        return;  // Nobody to update.
645513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      if (deleted_details->all_history)
646513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        visited_links->DeleteAllURLs();
647513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      else  // Delete individual ones.
648513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        visited_links->DeleteURLs(deleted_details->urls);
649513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
650513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    }
651513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
652513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case NotificationType::TEMPLATE_URL_REMOVED:
653513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      DeleteAllSearchTermsForKeyword(*(Details<TemplateURLID>(details).ptr()));
654513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
655513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
656513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    default:
657513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      NOTREACHED();
658513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool HistoryService::Init(const FilePath& history_dir,
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          BookmarkService* bookmark_service,
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          bool no_db) {
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!thread_->Start()) {
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Cleanup();
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  history_dir_ = history_dir;
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bookmark_service_ = bookmark_service;
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  no_db_ = no_db;
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create the history backend.
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoadBackendIfNecessary();
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::ScheduleAutocomplete(HistoryURLProvider* provider,
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          HistoryURLProviderParams* params) {
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_UI, &HistoryBackend::ScheduleAutocomplete,
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    scoped_refptr<HistoryURLProvider>(provider), params);
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::ScheduleTask(SchedulePriority priority,
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  Task* task) {
686731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(brettw): do prioritization.
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  thread_->message_loop()->PostTask(FROM_HERE, task);
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool HistoryService::CanAddURL(const GURL& url) {
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!url.is_valid())
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO: We should allow kChromeUIScheme URLs if they have been explicitly
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // typed.  Right now, however, these are marked as typed even when triggered
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // by a shortcut or menu action.
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (url.SchemeIs(chrome::kJavaScriptScheme) ||
699513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      url.SchemeIs(chrome::kChromeDevToolsScheme) ||
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url.SchemeIs(chrome::kChromeUIScheme) ||
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url.SchemeIs(chrome::kViewSourceScheme) ||
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url.SchemeIs(chrome::kChromeInternalScheme))
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (url.SchemeIs(chrome::kAboutScheme)) {
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (LowerCaseEqualsASCII(url.path(), "blank"))
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We allow all other about URLs since the user may like to see things
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // like "about:memory" or "about:histograms" in their history and
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // autocomplete.
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::SetInMemoryBackend(
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    history::InMemoryHistoryBackend* mem_backend) {
718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!in_memory_backend_.get()) << "Setting mem DB twice";
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  in_memory_backend_.reset(mem_backend);
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The database requires additional initialization once we own it.
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  in_memory_backend_->AttachToHistoryService(profile_);
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid HistoryService::NotifyProfileError(sql::InitStatus init_status) {
726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ShowProfileErrorDialog(
727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      (init_status == sql::INIT_FAILURE) ?
728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      IDS_COULDNT_OPEN_PROFILE_ERROR : IDS_PROFILE_TOO_NEW_ERROR);
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::DeleteURL(const GURL& url) {
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We will update the visited links when we observe the delete notifications.
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::DeleteURL, url);
734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::ExpireHistoryBetween(
737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::set<GURL>& restrict_urls,
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Time begin_time, Time end_time,
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer,
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExpireHistoryCallback* callback) {
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We will update the visited links when we observe the delete notifications.
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Schedule(PRIORITY_UI, &HistoryBackend::ExpireHistoryBetween, consumer,
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           new history::ExpireHistoryRequest(callback),
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           restrict_urls, begin_time, end_time);
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::BroadcastNotifications(
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type,
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    history::HistoryDetails* details_deleted) {
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We take ownership of the passed-in pointer and delete it. It was made for
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // us on another thread, so the caller doesn't know when we will handle it.
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<history::HistoryDetails> details(details_deleted);
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(evanm): this is currently necessitated by generate_profile, which
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // runs without a browser process. generate_profile should really create
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // a browser process, at which point this check can then be nuked.
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!g_browser_process)
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
760513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (!thread_)
761513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return;
762513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The source of all of our notifications is the profile. Note that this
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // pointer is NULL in unit tests.
765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Source<Profile> source(profile_);
766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The details object just contains the pointer to the object that the
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // backend has allocated for us. The receiver of the notification will cast
769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // this to the proper type.
770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Details<history::HistoryDetails> det(details_deleted);
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationService::current()->Notify(type, source, det);
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::LoadBackendIfNecessary() {
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!thread_ || history_backend_)
777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;  // Failed to init, or already started loading.
778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<HistoryBackend> backend(
780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new HistoryBackend(history_dir_,
781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         new BackendDelegate(this),
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         bookmark_service_));
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  history_backend_.swap(backend);
784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
785731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // There may not be a profile when unit testing.
786731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::string languages;
787731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (profile_) {
788731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    PrefService* prefs = profile_->GetPrefs();
789731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    languages = prefs->GetString(prefs::kAcceptLanguages);
790731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
791731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ScheduleAndForget(PRIORITY_UI, &HistoryBackend::Init, languages, no_db_);
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::OnDBLoaded() {
795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  backend_loaded_ = true;
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationService::current()->Notify(NotificationType::HISTORY_LOADED,
797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         Source<Profile>(profile_),
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         Details<HistoryService>(this));
79972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (thread_ && profile_) {
800513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // We don't want to force creation of TopSites.
801513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    history::TopSites* ts = profile_->GetTopSitesWithoutCreating();
802513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    if (ts)
803513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      ts->HistoryLoaded();
804513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::StartTopSitesMigration() {
808513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  needs_top_sites_migration_ = true;
80972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (thread_ && profile_) {
810513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // We don't want to force creation of TopSites.
811513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    history::TopSites* ts = profile_->GetTopSitesWithoutCreating();
812513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    if (ts)
813513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      ts->MigrateFromHistory();
814731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryService::OnTopSitesReady() {
818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAndForget(PRIORITY_NORMAL,
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    &HistoryBackend::MigrateThumbnailsDatabase);
820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
821