1bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file.
4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/download/download_history.h"
6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
7bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/logging.h"
8bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/history/download_create_info.h"
9bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/history/history_marshaling.h"
10bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/download/download_item.h"
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
12bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Our download table ID starts at 1, so we use 0 to represent a download that
14bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// has started, but has not yet had its data persisted in the table. We use fake
15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// database handles in incognito mode starting at -1 and progressively getting
16bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// more negative.
17bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// static
18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int DownloadHistory::kUninitializedHandle = 0;
19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
20bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenDownloadHistory::DownloadHistory(Profile* profile)
21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    : profile_(profile),
22bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      next_fake_db_handle_(kUninitializedHandle - 1) {
23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(profile);
24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
25bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenDownloadHistory::~DownloadHistory() {
27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
29bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid DownloadHistory::Load(HistoryService::DownloadQueryCallback* callback) {
30bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(callback);
31bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (!hs) {
33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    delete callback;
34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  hs->QueryDownloads(&history_consumer_, callback);
37bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
38bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // This is the initial load, so do a cleanup of corrupt in-progress entries.
39bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  hs->CleanUpInProgressEntries();
40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
41bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
42bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid DownloadHistory::AddEntry(
43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    const DownloadCreateInfo& info,
44bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    DownloadItem* download_item,
45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    HistoryService::DownloadCreateCallback* callback) {
46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Do not store the download in the history database for a few special cases:
47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // - incognito mode (that is the point of this mode)
48bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // - extensions (users don't think of extension installation as 'downloading')
49bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // - temporary download, like in drag-and-drop
50bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // - history service is not available (e.g. in tests)
51bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // We have to make sure that these handles don't collide with normal db
52bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // handles, so we use a negative value. Eventually, they could overlap, but
53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // you'd have to do enough downloading that your ISP would likely stab you in
54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // the neck first. YMMV.
55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (download_item->is_otr() || download_item->is_extension_install() ||
58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      download_item->is_temporary() || !hs) {
59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    callback->RunWithParams(
60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        history::DownloadCreateRequest::TupleType(info, GetNextFakeDbHandle()));
61bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    delete callback;
62bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
63bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
64bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  hs->CreateDownload(info, &history_consumer_, callback);
66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid DownloadHistory::UpdateEntry(DownloadItem* download_item) {
69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Don't store info in the database if the download was initiated while in
70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // incognito mode or if it hasn't been initialized in our database table.
71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (download_item->db_handle() <= kUninitializedHandle)
72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (!hs)
77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  hs->UpdateDownload(download_item->received_bytes(),
80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                     download_item->state(),
81bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                     download_item->db_handle());
82bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
83bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
84bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid DownloadHistory::UpdateDownloadPath(DownloadItem* download_item,
85bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                         const FilePath& new_path) {
86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // No update necessary if the download was initiated while in incognito mode.
87bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (download_item->db_handle() <= kUninitializedHandle)
88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
90731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
92bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (hs)
93bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    hs->UpdateDownloadPath(new_path, download_item->db_handle());
94bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid DownloadHistory::RemoveEntry(DownloadItem* download_item) {
97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // No update necessary if the download was initiated while in incognito mode.
98bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (download_item->db_handle() <= kUninitializedHandle)
99bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
100bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
102bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (hs)
104bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    hs->RemoveDownload(download_item->db_handle());
105bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
106bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid DownloadHistory::RemoveEntriesBetween(const base::Time remove_begin,
108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                           const base::Time remove_end) {
109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
110bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
111bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (hs)
112bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    hs->RemoveDownloadsBetween(remove_begin, remove_end);
113bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
114bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
115bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenint64 DownloadHistory::GetNextFakeDbHandle() {
116bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return next_fake_db_handle_--;
117bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
118