OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
Randy Smith (Not in Mondays)
2012/08/15 20:47:44
Explanatory comment at top of file about basic arc
benjhayden
2012/08/17 18:20:45
I had hoped that the code could speak for itself,
Randy Smith (Not in Mondays)
2012/08/20 18:57:04
L G T M; thanks.
| |
5 #include "chrome/browser/download/download_history.h" | 5 #include "chrome/browser/download/download_history.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/metrics/histogram.h" |
8 #include "chrome/browser/cancelable_request.h" | |
8 #include "chrome/browser/download/download_crx_util.h" | 9 #include "chrome/browser/download/download_crx_util.h" |
9 #include "chrome/browser/history/history_marshaling.h" | 10 #include "chrome/browser/download/download_persistent_store_info.h" |
10 #include "chrome/browser/history/history_service_factory.h" | 11 #include "content/public/browser/browser_thread.h" |
11 #include "chrome/browser/profiles/profile.h" | |
12 #include "content/public/browser/download_item.h" | 12 #include "content/public/browser/download_item.h" |
13 #include "content/public/browser/download_persistent_store_info.h" | 13 #include "content/public/browser/download_manager.h" |
14 | 14 |
15 using content::BrowserThread; | |
15 using content::DownloadItem; | 16 using content::DownloadItem; |
16 using content::DownloadPersistentStoreInfo; | 17 using content::DownloadManager; |
17 | 18 |
18 DownloadHistory::DownloadHistory(Profile* profile) | 19 namespace { |
19 : profile_(profile), | 20 |
20 next_fake_db_handle_(DownloadItem::kUninitializedHandle - 1) { | 21 class DownloadHistoryData : public base::SupportsUserData::Data { |
Randy Smith (Not in Mondays)
2012/08/15 20:47:44
Comment documenting purpose and use?
benjhayden
2012/08/17 18:20:45
Done.
| |
21 DCHECK(profile); | 22 public: |
22 } | 23 static const int64 kUninitializedHandle = -1; |
Randy Smith (Not in Mondays)
2012/08/15 20:47:44
Why here? I would think this would be a DownloadH
benjhayden
2012/08/17 18:20:45
Moved it out into the anonymous namespace.
Randy Smith (Not in Mondays)
2012/08/20 18:57:04
I think I was just confused in my earlier comment.
| |
23 | 24 |
24 DownloadHistory::~DownloadHistory() {} | 25 static DownloadHistoryData* Get(DownloadItem* item) { |
25 | 26 base::SupportsUserData::Data* data = item->GetUserData(kKey); |
26 void DownloadHistory::GetNextId( | 27 return (data == NULL) ? NULL : |
27 const HistoryService::DownloadNextIdCallback& callback) { | 28 static_cast<DownloadHistoryData*>(data); |
28 HistoryService* hs = HistoryServiceFactory::GetForProfileIfExists( | 29 } |
29 profile_, Profile::EXPLICIT_ACCESS); | 30 |
30 if (!hs) | 31 explicit DownloadHistoryData(DownloadItem* item) |
31 return; | 32 : is_adding_(false), |
32 | 33 is_persisted_(false), |
33 hs->GetNextDownloadId(&history_consumer_, callback); | 34 db_handle_(kUninitializedHandle), |
34 } | 35 info_(NULL) { |
35 | 36 item->SetUserData(kKey, this); |
36 void DownloadHistory::Load( | 37 } |
38 | |
39 virtual ~DownloadHistoryData() { | |
40 } | |
41 | |
42 // Whether this item is currently being added to the database. | |
43 bool is_adding() const { return is_adding_; } | |
44 void set_is_adding(bool a) { is_adding_ = a; } | |
45 | |
46 // Whether this item is already persisted in the database. | |
47 bool is_persisted() const { return is_persisted_; } | |
48 void set_is_persisted(bool p) { is_persisted_ = p; } | |
49 | |
50 int64 db_handle() const { return db_handle_; } | |
51 void set_db_handle(int64 h) { db_handle_ = h; } | |
52 | |
53 // This allows OnDownloadUpdated() to see what changed in a DownloadItem if | |
54 // anything, in order to prevent writing to the database unnecessarily. It is | |
55 // nullified when the item is no longer in progress in order to save memory. | |
56 DownloadPersistentStoreInfo* info() { return info_.get(); } | |
57 void set_info(const DownloadPersistentStoreInfo& i) { | |
58 info_.reset(new DownloadPersistentStoreInfo(i)); | |
59 } | |
60 void clear_info() { | |
61 info_.reset(); | |
62 } | |
63 | |
64 private: | |
65 static const char kKey[]; | |
66 | |
67 bool is_adding_; | |
68 bool is_persisted_; | |
69 int64 db_handle_; | |
70 scoped_ptr<DownloadPersistentStoreInfo> info_; | |
71 | |
72 DISALLOW_COPY_AND_ASSIGN(DownloadHistoryData); | |
73 }; | |
74 | |
75 const char DownloadHistoryData::kKey[] = | |
76 "DownloadItem DownloadHistoryData"; | |
77 | |
78 DownloadPersistentStoreInfo GetPersistentStoreInfo(DownloadItem* item) { | |
79 DownloadHistoryData* data = DownloadHistoryData::Get(item); | |
80 int64 db_handle = ((data != NULL) ? | |
81 data->db_handle() : | |
82 DownloadHistoryData::kUninitializedHandle); | |
83 return DownloadPersistentStoreInfo( | |
84 item->GetFullPath(), | |
85 item->GetURL(), | |
86 item->GetReferrerUrl(), | |
87 item->GetStartTime(), | |
88 item->GetEndTime(), | |
89 item->GetReceivedBytes(), | |
90 item->GetTotalBytes(), | |
91 item->GetState(), | |
92 db_handle, | |
93 item->GetOpened()); | |
94 } | |
95 | |
96 } // anonymous namespace | |
97 | |
98 HistoryServiceDownloadAdapter::HistoryServiceDownloadAdapter( | |
99 HistoryService* history_service) | |
100 : history_service_(history_service) { | |
101 } | |
102 | |
103 HistoryServiceDownloadAdapter::~HistoryServiceDownloadAdapter() {} | |
104 | |
105 void HistoryServiceDownloadAdapter::QueryDownloads( | |
37 const HistoryService::DownloadQueryCallback& callback) { | 106 const HistoryService::DownloadQueryCallback& callback) { |
38 HistoryService* hs = HistoryServiceFactory::GetForProfileIfExists( | 107 history_service_->QueryDownloads(&history_consumer_, callback); |
39 profile_, Profile::EXPLICIT_ACCESS); | 108 history_service_->CleanUpInProgressEntries(); |
40 if (!hs) | 109 } |
41 return; | 110 |
42 | 111 HistoryService::Handle |
43 hs->QueryDownloads(&history_consumer_, callback); | 112 HistoryServiceDownloadAdapter::GetVisibleVisitCountToHost( |
44 | 113 const GURL& referrer_url, |
45 // This is the initial load, so do a cleanup of corrupt in-progress entries. | 114 const HistoryService::GetVisibleVisitCountToHostCallback& |
46 hs->CleanUpInProgressEntries(); | 115 callback) { |
116 return history_service_->GetVisibleVisitCountToHost( | |
117 referrer_url, &history_consumer_, callback); | |
118 } | |
119 | |
120 void HistoryServiceDownloadAdapter::CreateDownload( | |
121 int32 id, | |
122 const DownloadPersistentStoreInfo& info, | |
123 const HistoryService::DownloadCreateCallback& callback) { | |
124 history_service_->CreateDownload(id, info, &history_consumer_, callback); | |
125 } | |
126 | |
127 void HistoryServiceDownloadAdapter::UpdateDownload( | |
128 const DownloadPersistentStoreInfo& info) { | |
129 history_service_->UpdateDownload(info); | |
130 } | |
131 | |
132 void HistoryServiceDownloadAdapter::RemoveDownloads( | |
133 const std::set<int64>& handles) { | |
134 history_service_->RemoveDownloads(handles); | |
135 } | |
136 | |
137 void HistoryServiceDownloadAdapter::OnDownloadHistoryDestroyed() { | |
138 delete this; | |
139 } | |
140 | |
141 DownloadHistory::DownloadHistory( | |
142 DownloadManager* manager, | |
143 HistoryServiceDownloadAdapter* history) | |
144 : manager_(manager), | |
145 history_(history), | |
146 loading_(false), | |
147 history_size_(0) { | |
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
149 DCHECK(manager_); | |
150 manager_->AddObserver(this); | |
151 history_->QueryDownloads(base::Bind( | |
152 &DownloadHistory::QueryCallback, AsWeakPtr())); | |
153 } | |
154 | |
155 DownloadHistory::~DownloadHistory() { | |
156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
157 history_->OnDownloadHistoryDestroyed(); | |
158 if (manager_) | |
159 manager_->RemoveObserver(this); | |
Randy Smith (Not in Mondays)
2012/08/15 20:47:44
DCHECK that the manager has no items on it?
benjhayden
2012/08/17 18:20:45
Did the observing_items_ set trick instead.
I'll s
| |
160 } | |
161 | |
162 void DownloadHistory::QueryCallback( | |
163 DownloadHistory::InfoVector* infos) { | |
Randy Smith (Not in Mondays)
2012/08/15 20:47:44
Who owns the storage in the vector pointed to by I
benjhayden
2012/08/17 18:20:45
HistoryService::QueryDownloads() creates a history
| |
164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
165 // We may have caught ManagerGoingDown() before the history loaded. | |
166 if (manager_ == NULL) | |
167 return; | |
168 // OnDownloadCreated() is called inside DownloadManager::CreateDownloadItem(), | |
169 // before we have a chance to attach a DownloadHistoryData, so temporarily | |
170 // disable adding new unpersisted items to the history. All methods run on | |
171 // the UI thread and CreateDownloadItem() is synchronous, so it is impossible | |
172 // for an OnDownloadCreated() to come in for another DownloadItem while we are | |
173 // processing the database. | |
174 loading_ = true; | |
175 for (InfoVector::const_iterator it = infos->begin(); | |
176 it != infos->end(); ++it) { | |
177 DownloadItem* download_item = manager_->CreateDownloadItem( | |
178 it->path, | |
179 it->url, | |
180 it->referrer_url, | |
181 it->start_time, | |
182 it->end_time, | |
183 it->received_bytes, | |
184 it->total_bytes, | |
185 it->state, | |
186 it->opened); | |
187 DownloadHistoryData* data = DownloadHistoryData::Get(download_item); | |
188 data->set_is_persisted(true); | |
189 data->set_db_handle(it->db_handle); | |
190 ++history_size_; | |
191 } | |
192 loading_ = false; | |
193 } | |
194 | |
195 void DownloadHistory::OnDownloadCreated( | |
196 DownloadManager* manager, DownloadItem* item) { | |
197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
198 | |
199 // Observe even temporary downloads in case they are marked not temporary. | |
200 item->AddObserver(this); | |
201 // All downloads should pass through OnDownloadCreated exactly once. | |
202 CHECK(!DownloadHistoryData::Get(item)); | |
203 DownloadHistoryData* data = new DownloadHistoryData(item); | |
204 if (item->GetState() == DownloadItem::IN_PROGRESS) { | |
205 data->set_info(GetPersistentStoreInfo(item)); | |
206 } | |
207 MaybeAddToHistory(item); | |
208 } | |
209 | |
210 void DownloadHistory::MaybeAddToHistory(DownloadItem* item) { | |
211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
212 int32 download_id = item->GetId(); | |
213 DownloadHistoryData* data = DownloadHistoryData::Get(item); | |
214 bool removing = (removing_.find(data->db_handle()) != removing_.end()); | |
Randy Smith (Not in Mondays)
2012/08/15 20:47:44
Should this be a DCHECK?
benjhayden
2012/08/17 18:20:45
I could imagine DownloadItem sending one or two fi
| |
215 if (!loading_ && | |
216 !download_crx_util::IsExtensionDownload(*item) && | |
217 !data->is_persisted() && | |
218 !item->IsTemporary() && | |
219 !removing && | |
220 !data->is_adding()) { | |
221 data->set_is_adding(true); | |
222 if (data->info() == NULL) { | |
223 // Keep the info here regardless of whether the item is in progress so | |
224 // that, when ItemAdded() calls OnDownloadUpdated(), it can choose more | |
225 // intelligently whether to Update the db and/or discard the info. | |
226 data->set_info(GetPersistentStoreInfo(item)); | |
227 } | |
228 history_->CreateDownload( | |
229 download_id, | |
230 *data->info(), | |
231 base::Bind(&DownloadHistory::ItemAdded, AsWeakPtr())); | |
232 } | |
233 } | |
234 | |
235 void DownloadHistory::ItemAdded(int32 download_id, int64 db_handle) { | |
236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
237 | |
238 if (!manager_) | |
239 return; | |
240 | |
241 DownloadItem* item = manager_->GetDownload(download_id); | |
242 if (!item) { | |
243 // We should have caught OnDownloadDestroyed(). If the item should have | |
Randy Smith (Not in Mondays)
2012/08/15 20:47:44
Does this mean we could have a DCHECK() here?
benjhayden
2012/08/17 18:20:45
Nope. There's no mechanism that cancels this parti
Randy Smith (Not in Mondays)
2012/08/20 18:57:04
Hmmm. Then I think the comment's a little confusi
| |
244 // been removed from history, then OnDownloadRemoved() put |download_id| in | |
245 // removed_while_adding_. | |
246 if (removed_while_adding_.find(download_id) != | |
247 removed_while_adding_.end()) { | |
248 removed_while_adding_.erase(download_id); | |
249 if (removing_.empty()) { | |
250 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
251 base::Bind(&DownloadHistory::RemoveDownloadsBatch, AsWeakPtr())); | |
252 } | |
253 removing_.insert(db_handle); | |
254 } | |
255 return; | |
256 } | |
257 | |
258 UMA_HISTOGRAM_CUSTOM_COUNTS("Download.HistorySize2", | |
259 history_size_, | |
260 0/*min*/, | |
261 (1 << 23)/*max*/, | |
262 (1 << 7)/*num_buckets*/); | |
263 ++history_size_; | |
264 | |
265 DownloadHistoryData* data = DownloadHistoryData::Get(item); | |
266 data->set_is_adding(false); | |
267 data->set_is_persisted(true); | |
268 data->set_db_handle(db_handle); | |
269 | |
270 // In case the item changed or became temporary while it was being added. | |
271 // Don't just UpdateObservers() because we're the only observer that can also | |
272 // see is_persisted/db_handle, which is the only thing that we changed. | |
273 OnDownloadUpdated(item); | |
274 } | |
275 | |
276 void DownloadHistory::OnDownloadUpdated(DownloadItem* item) { | |
277 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
278 | |
279 DownloadHistoryData* data = DownloadHistoryData::Get(item); | |
280 if (!data->is_persisted()) { | |
281 MaybeAddToHistory(item); | |
282 return; | |
283 } | |
284 if (item->IsTemporary()) { | |
285 OnDownloadRemoved(item); | |
286 return; | |
287 } | |
288 | |
289 // TODO(asanka): Persist GetTargetFilePath() as well. | |
290 DownloadPersistentStoreInfo current_info(GetPersistentStoreInfo(item)); | |
291 DownloadPersistentStoreInfo* previous_info = data->info(); | |
292 bool do_update = ( | |
293 (previous_info == NULL) || | |
294 (previous_info->path != current_info.path) || | |
295 (previous_info->end_time != current_info.end_time) || | |
296 (previous_info->received_bytes != current_info.received_bytes) || | |
297 (previous_info->total_bytes != current_info.total_bytes) || | |
298 (previous_info->state != current_info.state) || | |
299 (previous_info->opened != current_info.opened)); | |
300 UMA_HISTOGRAM_ENUMERATION("Download.HistoryPropagatedUpdate", do_update, 2); | |
301 if (do_update) { | |
302 history_->UpdateDownload(current_info); | |
303 } | |
304 if (item->GetState() == DownloadItem::IN_PROGRESS) { | |
305 data->set_info(current_info); | |
306 } else { | |
307 data->clear_info(); | |
308 } | |
309 } | |
310 | |
311 // Downloads may be opened after they are completed. | |
312 void DownloadHistory::OnDownloadOpened(DownloadItem* item) { | |
313 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
314 DownloadHistoryData* data = DownloadHistoryData::Get(item); | |
315 if (!data->is_persisted()) { | |
316 MaybeAddToHistory(item); | |
317 return; | |
318 } | |
319 if (item->IsTemporary()) { | |
320 OnDownloadRemoved(item); | |
321 return; | |
322 } | |
323 | |
324 DownloadPersistentStoreInfo current_info(GetPersistentStoreInfo(item)); | |
325 history_->UpdateDownload(current_info); | |
326 if (item->GetState() == DownloadItem::IN_PROGRESS) { | |
Randy Smith (Not in Mondays)
2012/08/15 20:47:44
Can they be opened before they're completed? I.e.
benjhayden
2012/08/17 18:20:45
Wasn't there some chatter about streaming download
Randy Smith (Not in Mondays)
2012/08/20 18:57:04
Fair enough. We're well short of streaming data t
| |
327 data->set_info(current_info); | |
328 } | |
329 } | |
330 | |
331 void DownloadHistory::OnDownloadRemoved(DownloadItem* item) { | |
332 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
333 | |
334 DownloadHistoryData* data = DownloadHistoryData::Get(item); | |
335 if ((data == NULL) || | |
336 !data->is_persisted() || | |
337 (data->db_handle() <= DownloadHistoryData::kUninitializedHandle)) { | |
338 if (data->is_adding()) { | |
339 removed_while_adding_.insert(item->GetId()); | |
340 } | |
341 return; | |
342 } | |
343 | |
344 // For database efficiency, batch removals together if they happen all at | |
345 // once. | |
346 if (removing_.empty()) { | |
347 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
348 base::Bind(&DownloadHistory::RemoveDownloadsBatch, AsWeakPtr())); | |
349 } | |
350 removing_.insert(data->db_handle()); | |
351 data->set_db_handle(DownloadHistoryData::kUninitializedHandle); | |
352 data->set_is_persisted(false); | |
353 --history_size_; | |
354 } | |
355 | |
356 void DownloadHistory::RemoveDownloadsBatch() { | |
357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
358 HandleSet remove_handles; | |
359 removing_.swap(remove_handles); | |
360 history_->RemoveDownloads(remove_handles); | |
361 } | |
362 | |
363 void DownloadHistory::ManagerGoingDown(DownloadManager* manager) { | |
364 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
365 DCHECK_EQ(manager_, manager); | |
366 manager_->RemoveObserver(this); | |
367 manager_ = NULL; | |
368 } | |
369 | |
370 | |
371 void DownloadHistory::OnDownloadDestroyed(DownloadItem* item) { | |
372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
373 item->RemoveObserver(this); | |
47 } | 374 } |
48 | 375 |
49 void DownloadHistory::CheckVisitedReferrerBefore( | 376 void DownloadHistory::CheckVisitedReferrerBefore( |
50 int32 download_id, | 377 int32 download_id, |
51 const GURL& referrer_url, | 378 const GURL& referrer_url, |
52 const VisitedBeforeDoneCallback& callback) { | 379 const VisitedBeforeDoneCallback& callback) { |
380 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
53 if (referrer_url.is_valid()) { | 381 if (referrer_url.is_valid()) { |
54 HistoryService* hs = HistoryServiceFactory::GetForProfileIfExists( | 382 HistoryService::Handle handle = history_->GetVisibleVisitCountToHost( |
55 profile_, Profile::EXPLICIT_ACCESS); | 383 referrer_url, |
56 if (hs) { | 384 base::Bind(&DownloadHistory::OnGotVisitCountToHost, |
57 HistoryService::Handle handle = | 385 AsWeakPtr())); |
58 hs->GetVisibleVisitCountToHost(referrer_url, &history_consumer_, | 386 visited_before_requests_[handle] = callback; |
59 base::Bind(&DownloadHistory::OnGotVisitCountToHost, | 387 return; |
60 base::Unretained(this))); | |
61 visited_before_requests_[handle] = callback; | |
62 return; | |
63 } | |
64 } | 388 } |
65 callback.Run(false); | 389 callback.Run(false); |
66 } | 390 } |
67 | 391 |
68 void DownloadHistory::AddEntry( | 392 void DownloadHistory::OnGotVisitCountToHost( |
69 DownloadItem* download_item, | 393 HistoryService::Handle handle, |
70 const HistoryService::DownloadCreateCallback& callback) { | 394 bool found_visits, |
71 DCHECK(download_item); | 395 int count, |
72 // Do not store the download in the history database for a few special cases: | 396 base::Time first_visit) { |
73 // - incognito mode (that is the point of this mode) | 397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
74 // - extensions (users don't think of extension installation as 'downloading') | |
75 // - temporary download, like in drag-and-drop | |
76 // - history service is not available (e.g. in tests) | |
77 // We have to make sure that these handles don't collide with normal db | |
78 // handles, so we use a negative value. Eventually, they could overlap, but | |
79 // you'd have to do enough downloading that your ISP would likely stab you in | |
80 // the neck first. YMMV. | |
81 HistoryService* hs = HistoryServiceFactory::GetForProfileIfExists( | |
82 profile_, Profile::EXPLICIT_ACCESS); | |
83 if (download_crx_util::IsExtensionDownload(*download_item) || | |
84 download_item->IsTemporary() || !hs) { | |
85 callback.Run(download_item->GetId(), GetNextFakeDbHandle()); | |
86 return; | |
87 } | |
88 | |
89 int32 id = download_item->GetId(); | |
90 DownloadPersistentStoreInfo history_info = | |
91 download_item->GetPersistentStoreInfo(); | |
92 hs->CreateDownload(id, history_info, &history_consumer_, callback); | |
93 } | |
94 | |
95 void DownloadHistory::UpdateEntry(DownloadItem* download_item) { | |
96 // Don't store info in the database if the download was initiated while in | |
97 // incognito mode or if it hasn't been initialized in our database table. | |
98 if (download_item->GetDbHandle() <= DownloadItem::kUninitializedHandle) | |
99 return; | |
100 | |
101 HistoryService* hs = HistoryServiceFactory::GetForProfileIfExists( | |
102 profile_, Profile::EXPLICIT_ACCESS); | |
103 if (!hs) | |
104 return; | |
105 hs->UpdateDownload(download_item->GetPersistentStoreInfo()); | |
106 } | |
107 | |
108 void DownloadHistory::UpdateDownloadPath(DownloadItem* download_item, | |
109 const FilePath& new_path) { | |
110 // No update necessary if the download was initiated while in incognito mode. | |
111 if (download_item->GetDbHandle() <= DownloadItem::kUninitializedHandle) | |
112 return; | |
113 | |
114 HistoryService* hs = HistoryServiceFactory::GetForProfileIfExists( | |
115 profile_, Profile::EXPLICIT_ACCESS); | |
116 if (hs) | |
117 hs->UpdateDownloadPath(new_path, download_item->GetDbHandle()); | |
118 } | |
119 | |
120 void DownloadHistory::RemoveEntry(DownloadItem* download_item) { | |
121 // No update necessary if the download was initiated while in incognito mode. | |
122 if (download_item->GetDbHandle() <= DownloadItem::kUninitializedHandle) | |
123 return; | |
124 | |
125 HistoryService* hs = HistoryServiceFactory::GetForProfileIfExists( | |
126 profile_, Profile::EXPLICIT_ACCESS); | |
127 if (hs) | |
128 hs->RemoveDownload(download_item->GetDbHandle()); | |
129 } | |
130 | |
131 void DownloadHistory::RemoveEntriesBetween(const base::Time remove_begin, | |
132 const base::Time remove_end) { | |
133 HistoryService* hs = HistoryServiceFactory::GetForProfileIfExists( | |
134 profile_, Profile::EXPLICIT_ACCESS); | |
135 if (hs) | |
136 hs->RemoveDownloadsBetween(remove_begin, remove_end); | |
137 } | |
138 | |
139 int64 DownloadHistory::GetNextFakeDbHandle() { | |
140 return next_fake_db_handle_--; | |
141 } | |
142 | |
143 void DownloadHistory::OnGotVisitCountToHost(HistoryService::Handle handle, | |
144 bool found_visits, | |
145 int count, | |
146 base::Time first_visit) { | |
147 VisitedBeforeRequestsMap::iterator request = | 398 VisitedBeforeRequestsMap::iterator request = |
148 visited_before_requests_.find(handle); | 399 visited_before_requests_.find(handle); |
149 DCHECK(request != visited_before_requests_.end()); | 400 DCHECK(request != visited_before_requests_.end()); |
150 VisitedBeforeDoneCallback callback = request->second; | 401 VisitedBeforeDoneCallback callback = request->second; |
151 visited_before_requests_.erase(request); | 402 visited_before_requests_.erase(request); |
152 callback.Run(found_visits && count && | 403 callback.Run(found_visits && count && |
153 (first_visit.LocalMidnight() < base::Time::Now().LocalMidnight())); | 404 (first_visit.LocalMidnight() < base::Time::Now().LocalMidnight())); |
154 } | 405 } |
OLD | NEW |