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