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/profiles/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
18 const int DownloadHistory::kUninitializedHandle = 0;
19
DownloadHistory(Profile * profile)20 DownloadHistory::DownloadHistory(Profile* profile)
21 : profile_(profile),
22 next_fake_db_handle_(kUninitializedHandle - 1) {
23 DCHECK(profile);
24 }
25
~DownloadHistory()26 DownloadHistory::~DownloadHistory() {
27 }
28
Load(HistoryService::DownloadQueryCallback * callback)29 void 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
AddEntry(const DownloadCreateInfo & info,DownloadItem * download_item,HistoryService::DownloadCreateCallback * callback)42 void 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
UpdateEntry(DownloadItem * download_item)68 void 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
UpdateDownloadPath(DownloadItem * download_item,const FilePath & new_path)84 void 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
RemoveEntry(DownloadItem * download_item)96 void 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
RemoveEntriesBetween(const base::Time remove_begin,const base::Time remove_end)107 void 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
GetNextFakeDbHandle()115 int64 DownloadHistory::GetNextFakeDbHandle() {
116 return next_fake_db_handle_--;
117 }
118