Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: chrome/browser/download/download_history.cc

Issue 10665049: Make DownloadHistory observe manager, items (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
5 // DownloadHistory observes a single DownloadManager and all its DownloadItems.
Randy Smith (Not in Mondays) 2012/08/20 18:57:04 Very good; thanks. Minor tweak: Can you start wit
benjhayden 2012/08/24 15:32:15 Done.
6 // DownloadHistory decides whether and when to add items to, remove items from,
7 // and update items in the database. DownloadHistory uses DownloadHistoryData to
8 // store per-DownloadItem data such as its db_handle, whether the item is being
9 // added and waiting for its db_handle, and the last DownloadPersistentStoreInfo
10 // that was passed to the database. When the DownloadManager and its delegate
11 // (ChromeDownloadManagerDelegate) are initialized, DownloadHistory is created
12 // and queries the HistoryService. When the HistoryService calls back from
13 // QueryDownloads() to QueryCallback(), DownloadHistory uses
14 // DownloadManager::CreateDownloadItem() to inform DownloadManager of these
15 // persisted DownloadItems. CreateDownloadItem() internally calls
16 // OnDownloadCreated(), which normally adds items to the database, so
17 // QueryCallback() uses |loading_| to disable adding items to the database.
18 // If a download is removed via OnDownloadRemoved() while the item is still
19 // being added to the database, DownloadHistory uses |removed_while_adding_| to
20 // remember to remove the item when its ItemAdded() callback is called.
Randy Smith (Not in Mondays) 2012/08/20 18:57:04 Destruction context so that we can reason about re
benjhayden 2012/08/24 15:32:15 Done.
21 // All callbacks are bound with a weak pointer to DownloadHistory to prevent
22 // use-after-free bugs, even though CancelableRequestConsumer should guarantee
23 // the same thing.
Randy Smith (Not in Mondays) 2012/08/20 18:57:04 This probably should be done in another CL, but if
benjhayden 2012/08/24 15:32:15 It required changing our HistoryService/HistoryBac
Randy Smith (Not in Mondays) 2012/08/27 19:28:19 I didn't follow what you meant here when I first r
24
5 #include "chrome/browser/download/download_history.h" 25 #include "chrome/browser/download/download_history.h"
6 26
7 #include "base/logging.h" 27 #include "base/metrics/histogram.h"
28 #include "chrome/browser/cancelable_request.h"
8 #include "chrome/browser/download/download_crx_util.h" 29 #include "chrome/browser/download/download_crx_util.h"
9 #include "chrome/browser/history/history_marshaling.h" 30 #include "chrome/browser/download/download_persistent_store_info.h"
10 #include "chrome/browser/history/history_service_factory.h" 31 #include "content/public/browser/browser_thread.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "content/public/browser/download_item.h" 32 #include "content/public/browser/download_item.h"
13 #include "content/public/browser/download_persistent_store_info.h" 33 #include "content/public/browser/download_manager.h"
14 34
35 using content::BrowserThread;
15 using content::DownloadItem; 36 using content::DownloadItem;
16 using content::DownloadPersistentStoreInfo; 37 using content::DownloadManager;
17 38
18 DownloadHistory::DownloadHistory(Profile* profile) 39 namespace {
19 : profile_(profile), 40
20 next_fake_db_handle_(DownloadItem::kUninitializedHandle - 1) { 41 // The value of |db_handle| indicating that the associated DownloadItem is not
21 DCHECK(profile); 42 // yet persisted.
22 } 43 static const int64 kUninitializedHandle = -1;
23 44
24 DownloadHistory::~DownloadHistory() {} 45 // Per-DownloadItem data. This information does not belong inside DownloadItem,
25 46 // and keeping maps in DownloadHistory from DownloadItem to this information is
26 void DownloadHistory::GetNextId( 47 // error-prone and complicated. Unfortunately, DownloadHistory::removing_ and
27 const HistoryService::DownloadNextIdCallback& callback) { 48 // removed_while_adding_ cannot be moved into this class partly because
28 HistoryService* hs = HistoryServiceFactory::GetForProfile( 49 // DownloadHistoryData is destroyed when DownloadItems are destroyed, and we
29 profile_, Profile::EXPLICIT_ACCESS); 50 // have no control over when DownloadItems are destroyed.
30 if (!hs) 51 class DownloadHistoryData : public base::SupportsUserData::Data {
31 return; 52 public:
32 53
33 hs->GetNextDownloadId(&history_consumer_, callback); 54 static DownloadHistoryData* Get(DownloadItem* item) {
34 } 55 base::SupportsUserData::Data* data = item->GetUserData(kKey);
35 56 return (data == NULL) ? NULL :
36 void DownloadHistory::Load( 57 static_cast<DownloadHistoryData*>(data);
58 }
59
60 DownloadHistoryData(
61 DownloadItem* item,
62 const base::WeakPtr<DownloadHistory>& history)
63 : is_adding_(false),
64 is_disabled_(false),
65 history_(history),
66 db_handle_(kUninitializedHandle),
67 info_(NULL) {
68 item->SetUserData(kKey, this);
69 }
70
71 virtual ~DownloadHistoryData() {
72 }
73
74 // Whether this item is currently being added to the database.
75 bool is_adding() const { return is_adding_; }
76 void set_is_adding(bool a) { is_adding_ = a; }
77
78 bool is_disabled() const { return is_disabled_; }
79 void set_is_disabled(bool d, DownloadItem* item) {
80 if (is_disabled_ == d)
81 return;
82 is_disabled_ = d;
83 // May either add item to db or remove it.
84 // Could also call item->NotifyObservers(), but that interface should not be
85 // public, and DH is the only observer that knows and cares about
86 // is_disabled().
87 if (history_.get())
Randy Smith (Not in Mondays) 2012/08/20 18:57:04 Can you think of any contexts in which a DownloadI
benjhayden 2012/08/24 15:32:15 This was part of DownloadHistory::Disable, which w
88 history_->OnDownloadUpdated(item);
89 }
90
91 // Whether this item is already persisted in the database.
92 bool is_persisted() const { return db_handle_ > kUninitializedHandle; }
93
94 int64 db_handle() const { return db_handle_; }
95 void set_db_handle(int64 h) { db_handle_ = h; }
96
97 // This allows OnDownloadUpdated() to see what changed in a DownloadItem if
98 // anything, in order to prevent writing to the database unnecessarily. It is
99 // nullified when the item is no longer in progress in order to save memory.
100 DownloadPersistentStoreInfo* info() { return info_.get(); }
101 void set_info(const DownloadPersistentStoreInfo& i) {
102 info_.reset(new DownloadPersistentStoreInfo(i));
103 }
104 void clear_info() {
105 info_.reset();
106 }
107
108 private:
109 static const char kKey[];
110
111 bool is_adding_;
112 bool is_disabled_;
113 base::WeakPtr<DownloadHistory> history_;
114 int64 db_handle_;
115 scoped_ptr<DownloadPersistentStoreInfo> info_;
116
117 DISALLOW_COPY_AND_ASSIGN(DownloadHistoryData);
118 };
119
120 const char DownloadHistoryData::kKey[] =
121 "DownloadItem DownloadHistoryData";
122
123 DownloadPersistentStoreInfo GetPersistentStoreInfo(DownloadItem* item) {
124 DownloadHistoryData* dhd = DownloadHistoryData::Get(item);
125 return DownloadPersistentStoreInfo(
126 item->GetFullPath(),
127 item->GetURL(),
128 item->GetReferrerUrl(),
129 item->GetStartTime(),
130 item->GetEndTime(),
131 item->GetReceivedBytes(),
132 item->GetTotalBytes(),
133 item->GetState(),
134 ((dhd != NULL) ? dhd->db_handle() : kUninitializedHandle),
135 item->GetOpened());
136 }
137
138 } // anonymous namespace
139
140 HistoryServiceDownloadAdapter::HistoryServiceDownloadAdapter(
141 HistoryService* history_service)
142 : history_service_(history_service) {
143 }
144
145 HistoryServiceDownloadAdapter::~HistoryServiceDownloadAdapter() {}
146
147 void HistoryServiceDownloadAdapter::QueryDownloads(
37 const HistoryService::DownloadQueryCallback& callback) { 148 const HistoryService::DownloadQueryCallback& callback) {
38 HistoryService* hs = HistoryServiceFactory::GetForProfile( 149 history_service_->QueryDownloads(&history_consumer_, callback);
39 profile_, Profile::EXPLICIT_ACCESS); 150 history_service_->CleanUpInProgressEntries();
40 if (!hs) 151 }
41 return; 152
42 153 HistoryService::Handle
43 hs->QueryDownloads(&history_consumer_, callback); 154 HistoryServiceDownloadAdapter::GetVisibleVisitCountToHost(
44 155 const GURL& referrer_url,
45 // This is the initial load, so do a cleanup of corrupt in-progress entries. 156 const HistoryService::GetVisibleVisitCountToHostCallback&
46 hs->CleanUpInProgressEntries(); 157 callback) {
158 return history_service_->GetVisibleVisitCountToHost(
159 referrer_url, &history_consumer_, callback);
160 }
161
162 void HistoryServiceDownloadAdapter::CreateDownload(
163 int32 id,
164 const DownloadPersistentStoreInfo& info,
165 const HistoryService::DownloadCreateCallback& callback) {
166 history_service_->CreateDownload(id, info, &history_consumer_, callback);
167 }
168
169 void HistoryServiceDownloadAdapter::UpdateDownload(
170 const DownloadPersistentStoreInfo& info) {
171 history_service_->UpdateDownload(info);
Randy Smith (Not in Mondays) 2012/08/27 19:28:19 So the fact that this does not take a db handle in
172 }
173
174 void HistoryServiceDownloadAdapter::RemoveDownloads(
175 const std::set<int64>& handles) {
176 history_service_->RemoveDownloads(handles);
177 }
178
179 void HistoryServiceDownloadAdapter::OnDownloadHistoryDestroyed() {
180 delete this;
181 }
182
183 // static
184 void DownloadHistory::Disable(content::DownloadItem* download_item) {
185 DownloadHistoryData* dhd = DownloadHistoryData::Get(download_item);
186 // If the item has been created, then it has a DHD.
187 dhd->set_is_disabled(true, download_item);
188 }
189
190 DownloadHistory::DownloadHistory(
191 DownloadManager* manager,
192 HistoryServiceDownloadAdapter* history)
193 : manager_(manager),
194 history_(history),
195 loading_(false),
196 history_size_(0),
197 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
199 DCHECK(manager_);
200 manager_->AddObserver(this);
201 history_->QueryDownloads(base::Bind(
202 &DownloadHistory::QueryCallback, weak_ptr_factory_.GetWeakPtr()));
203 }
204
205 DownloadHistory::~DownloadHistory() {
206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
207 history_->OnDownloadHistoryDestroyed();
Randy Smith (Not in Mondays) 2012/08/20 18:57:04 Why isn't this just a scoped_ptr<>?
benjhayden 2012/08/24 15:32:15 Done.
208 for (ItemSet::const_iterator iter = observing_items_.begin();
Randy Smith (Not in Mondays) 2012/08/20 18:57:04 Shouldn't this list always be null at this point,
benjhayden 2012/08/24 15:32:15 Yes, DownloadManager::Shutdown() deletes the items
Randy Smith (Not in Mondays) 2012/08/27 18:25:11 Hmmm. Ok. What I hear you saying here is that Do
209 iter != observing_items_.end(); ++iter) {
210 (*iter)->RemoveObserver(this);
211 }
212 observing_items_.clear();
213 if (manager_)
214 manager_->RemoveObserver(this);
215 }
216
217 void DownloadHistory::QueryCallback(
218 DownloadHistory::InfoVector* infos) {
219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
220 // We may have caught ManagerGoingDown() before the history loaded.
221 if (!manager_)
222 return;
223 // OnDownloadCreated() is called inside DownloadManager::CreateDownloadItem(),
224 // before we have a chance to attach a DownloadHistoryData, so temporarily
225 // disable adding new unpersisted items to the history. All methods run on
226 // the UI thread and CreateDownloadItem() is synchronous, so it is impossible
227 // for an OnDownloadCreated() to come in for another DownloadItem while we are
228 // processing the database.
229 loading_ = true;
230 for (InfoVector::const_iterator it = infos->begin();
231 it != infos->end(); ++it) {
232 DownloadItem* download_item = manager_->CreateDownloadItem(
233 it->path,
234 it->url,
235 it->referrer_url,
236 it->start_time,
237 it->end_time,
238 it->received_bytes,
239 it->total_bytes,
240 it->state,
241 it->opened);
242 DownloadHistoryData* dhd = DownloadHistoryData::Get(download_item);
243 DCHECK(it->db_handle > kUninitializedHandle);
244 dhd->set_db_handle(it->db_handle);
245 ++history_size_;
246 }
247 manager_->CheckForHistoryFilesRemoval();
248 loading_ = false;
249 }
250
251 void DownloadHistory::OnDownloadCreated(
252 DownloadManager* manager, DownloadItem* item) {
253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
254
255 // Observe even temporary downloads in case they are marked not temporary.
256 item->AddObserver(this);
257 observing_items_.insert(item);
258 // All downloads should pass through OnDownloadCreated exactly once.
259 CHECK(!DownloadHistoryData::Get(item));
260 DownloadHistoryData* dhd = new DownloadHistoryData(
261 item, weak_ptr_factory_.GetWeakPtr());
262 if (item->GetState() == DownloadItem::IN_PROGRESS) {
263 dhd->set_info(GetPersistentStoreInfo(item));
264 }
265 MaybeAddToHistory(item);
266 }
267
268 void DownloadHistory::MaybeAddToHistory(DownloadItem* item) {
269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
270 int32 download_id = item->GetId();
271 DownloadHistoryData* dhd = DownloadHistoryData::Get(item);
272 bool removing = (removing_.find(dhd->db_handle()) != removing_.end());
273 // TODO(benjhayden): Remove IsTemporary().
274 if (!loading_ &&
Randy Smith (Not in Mondays) 2012/08/20 18:57:04 Suggestion: Reverse the sense of the tests and ret
benjhayden 2012/08/24 15:32:15 Done.
275 !download_crx_util::IsExtensionDownload(*item) &&
276 !dhd->is_persisted() &&
277 !dhd->is_disabled() &&
278 !item->IsTemporary() &&
279 !removing &&
280 !dhd->is_adding()) {
281 dhd->set_is_adding(true);
282 if (dhd->info() == NULL) {
283 // Keep the info here regardless of whether the item is in progress so
284 // that, when ItemAdded() calls OnDownloadUpdated(), it can choose more
285 // intelligently whether to Update the db and/or discard the info.
286 dhd->set_info(GetPersistentStoreInfo(item));
287 }
288 HistoryService::DownloadCreateCallback callback = base::Bind(
289 &DownloadHistory::ItemAdded, weak_ptr_factory_.GetWeakPtr());
290 history_->CreateDownload(download_id, *dhd->info(), callback);
291 }
292 }
293
294 void DownloadHistory::ItemAdded(int32 download_id, int64 db_handle) {
295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
296
297 if (!manager_)
298 return;
299
300 if (removed_while_adding_.find(download_id) !=
301 removed_while_adding_.end()) {
302 removed_while_adding_.erase(download_id);
303 if (removing_.empty()) {
304 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
305 base::Bind(&DownloadHistory::RemoveDownloadsBatch,
306 weak_ptr_factory_.GetWeakPtr()));
307 }
308 removing_.insert(db_handle);
309 return;
310 }
311
312 DownloadItem* item = manager_->GetDownload(download_id);
313 if (!item) {
314 // We should have caught OnDownloadDestroyed(). If the item should have
315 // been removed from history, then OnDownloadRemoved() put |download_id| in
316 // removed_while_adding_.
317 return;
318 }
319
320 UMA_HISTOGRAM_CUSTOM_COUNTS("Download.HistorySize2",
321 history_size_,
322 0/*min*/,
323 (1 << 23)/*max*/,
324 (1 << 7)/*num_buckets*/);
325 ++history_size_;
326
327 DownloadHistoryData* dhd = DownloadHistoryData::Get(item);
328 dhd->set_is_adding(false);
329 DCHECK(db_handle > kUninitializedHandle);
330 dhd->set_db_handle(db_handle);
331
332 // In case the item changed or became temporary while it was being added.
333 // Don't just UpdateObservers() because we're the only observer that can also
334 // see db_handle, which is the only thing that we changed.
335 OnDownloadUpdated(item);
336 }
337
338 void DownloadHistory::OnDownloadUpdated(DownloadItem* item) {
339 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
340
341 DownloadHistoryData* dhd = DownloadHistoryData::Get(item);
342 if (!dhd->is_persisted()) {
343 MaybeAddToHistory(item);
Randy Smith (Not in Mondays) 2012/08/20 18:57:04 Under what circumstances would we actually want to
benjhayden 2012/08/24 15:32:15 Transition from Temporary to not Temporary. (In th
Randy Smith (Not in Mondays) 2012/08/27 18:25:11 Yuck; I had adding state transitions for transitio
Randy Smith (Not in Mondays) 2012/08/27 19:28:19 Also: You have the same call to MaybeAddToHistory(
344 return;
345 }
346 if (item->IsTemporary() ||
347 dhd->is_disabled()) {
348 OnDownloadRemoved(item);
349 return;
350 }
351
352 // TODO(asanka): Persist GetTargetFilePath() as well.
353 DownloadPersistentStoreInfo current_info(GetPersistentStoreInfo(item));
354 DownloadPersistentStoreInfo* previous_info = dhd->info();
355 bool do_update = (
356 (previous_info == NULL) ||
357 (previous_info->path != current_info.path) ||
358 (previous_info->end_time != current_info.end_time) ||
359 (previous_info->received_bytes != current_info.received_bytes) ||
360 (previous_info->total_bytes != current_info.total_bytes) ||
361 (previous_info->state != current_info.state) ||
362 (previous_info->opened != current_info.opened));
363 UMA_HISTOGRAM_ENUMERATION("Download.HistoryPropagatedUpdate", do_update, 2);
364 if (do_update) {
365 history_->UpdateDownload(current_info);
366 }
367 if (item->GetState() == DownloadItem::IN_PROGRESS) {
368 dhd->set_info(current_info);
369 } else {
370 dhd->clear_info();
371 }
372 }
373
374 // Downloads may be opened after they are completed.
375 void DownloadHistory::OnDownloadOpened(DownloadItem* item) {
376 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
377 DownloadHistoryData* dhd = DownloadHistoryData::Get(item);
378 if (!dhd->is_persisted()) {
379 MaybeAddToHistory(item);
380 return;
381 }
382 if (item->IsTemporary() ||
383 dhd->is_disabled()) {
384 OnDownloadRemoved(item);
385 return;
386 }
387
388 DownloadPersistentStoreInfo current_info(GetPersistentStoreInfo(item));
389 history_->UpdateDownload(current_info);
390 if (item->GetState() == DownloadItem::IN_PROGRESS) {
391 dhd->set_info(current_info);
392 }
393 }
394
395 void DownloadHistory::OnDownloadRemoved(DownloadItem* item) {
396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
397
398 DownloadHistoryData* dhd = DownloadHistoryData::Get(item);
399 if (dhd == NULL)
Randy Smith (Not in Mondays) 2012/08/20 18:57:04 How could this happen?
benjhayden 2012/08/24 15:32:15 Done.
400 return;
401 if (!dhd->is_persisted()) {
402 if (dhd->is_adding()) {
403 removed_while_adding_.insert(item->GetId());
404 }
405 return;
406 }
407
408 // For database efficiency, batch removals together if they happen all at
409 // once.
410 if (removing_.empty()) {
411 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
412 base::Bind(&DownloadHistory::RemoveDownloadsBatch,
413 weak_ptr_factory_.GetWeakPtr()));
414 }
415 removing_.insert(dhd->db_handle());
416 dhd->set_db_handle(kUninitializedHandle);
417 --history_size_;
418 }
419
420 void DownloadHistory::RemoveDownloadsBatch() {
421 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
422 HandleSet remove_handles;
423 removing_.swap(remove_handles);
424 history_->RemoveDownloads(remove_handles);
425 }
426
427 void DownloadHistory::ManagerGoingDown(DownloadManager* manager) {
428 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
429 DCHECK_EQ(manager_, manager);
430 manager_->RemoveObserver(this);
431 manager_ = NULL;
432 }
433
434 void DownloadHistory::OnDownloadDestroyed(DownloadItem* item) {
435 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
436 item->RemoveObserver(this);
437 observing_items_.erase(item);
47 } 438 }
48 439
49 void DownloadHistory::CheckVisitedReferrerBefore( 440 void DownloadHistory::CheckVisitedReferrerBefore(
50 int32 download_id, 441 int32 download_id,
51 const GURL& referrer_url, 442 const GURL& referrer_url,
52 const VisitedBeforeDoneCallback& callback) { 443 const VisitedBeforeDoneCallback& callback) {
444 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
53 if (referrer_url.is_valid()) { 445 if (referrer_url.is_valid()) {
54 HistoryService* hs = HistoryServiceFactory::GetForProfileIfExists( 446 HistoryService::Handle handle = history_->GetVisibleVisitCountToHost(
55 profile_, Profile::EXPLICIT_ACCESS); 447 referrer_url,
56 if (hs) { 448 base::Bind(&DownloadHistory::OnGotVisitCountToHost,
57 HistoryService::Handle handle = 449 weak_ptr_factory_.GetWeakPtr()));
58 hs->GetVisibleVisitCountToHost(referrer_url, &history_consumer_, 450 visited_before_requests_[handle] = callback;
59 base::Bind(&DownloadHistory::OnGotVisitCountToHost, 451 return;
60 base::Unretained(this)));
61 visited_before_requests_[handle] = callback;
62 return;
63 }
64 } 452 }
65 callback.Run(false); 453 callback.Run(false);
66 } 454 }
67 455
68 void DownloadHistory::AddEntry( 456 void DownloadHistory::OnGotVisitCountToHost(
69 DownloadItem* download_item, 457 HistoryService::Handle handle,
70 const HistoryService::DownloadCreateCallback& callback) { 458 bool found_visits,
71 DCHECK(download_item); 459 int count,
72 // Do not store the download in the history database for a few special cases: 460 base::Time first_visit) {
73 // - incognito mode (that is the point of this mode) 461 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 = 462 VisitedBeforeRequestsMap::iterator request =
148 visited_before_requests_.find(handle); 463 visited_before_requests_.find(handle);
149 DCHECK(request != visited_before_requests_.end()); 464 DCHECK(request != visited_before_requests_.end());
150 VisitedBeforeDoneCallback callback = request->second; 465 VisitedBeforeDoneCallback callback = request->second;
151 visited_before_requests_.erase(request); 466 visited_before_requests_.erase(request);
152 callback.Run(found_visits && count && 467 callback.Run(found_visits && count &&
153 (first_visit.LocalMidnight() < base::Time::Now().LocalMidnight())); 468 (first_visit.LocalMidnight() < base::Time::Now().LocalMidnight()));
154 } 469 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698