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

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, 3 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 manages persisting DownloadItems to the history service by
6 // observing a single DownloadManager and all its DownloadItems.
7 // DownloadHistory decides whether and when to add items to, remove items from,
8 // and update items in the database. DownloadHistory uses DownloadHistoryData to
9 // store per-DownloadItem data such as its db_handle, whether the item is being
10 // added and waiting for its db_handle, and the last DownloadPersistentStoreInfo
11 // that was passed to the database. When the DownloadManager and its delegate
12 // (ChromeDownloadManagerDelegate) are initialized, DownloadHistory is created
13 // and queries the HistoryService. When the HistoryService calls back from
14 // QueryDownloads() to QueryCallback(), DownloadHistory uses
15 // DownloadManager::CreateDownloadItem() to inform DownloadManager of these
16 // persisted DownloadItems. CreateDownloadItem() internally calls
17 // OnDownloadCreated(), which normally adds items to the database, so
18 // QueryCallback() uses |loading_| to disable adding items to the database. If
19 // a download is removed via OnDownloadRemoved() while the item is still being
20 // added to the database, DownloadHistory uses |removed_while_adding_| to
21 // remember to remove the item when its ItemAdded() callback is called. All
22 // callbacks are bound with a weak pointer to DownloadHistory to prevent
23 // use-after-free bugs.
24 // ChromeDownloadManagerDelegate owns DownloadHistory, and deletes it in
25 // Shutdown(), which is called by DownloadManagerImpl::Shutdown() after all
26 // DownloadItems are destroyed.
27
5 #include "chrome/browser/download/download_history.h" 28 #include "chrome/browser/download/download_history.h"
6 29
7 #include "base/logging.h" 30 #include "base/metrics/histogram.h"
31 #include "chrome/browser/cancelable_request.h"
8 #include "chrome/browser/download/download_crx_util.h" 32 #include "chrome/browser/download/download_crx_util.h"
9 #include "chrome/browser/history/history_marshaling.h" 33 #include "chrome/browser/history/download_persistent_store_info.h"
10 #include "chrome/browser/history/history_service_factory.h" 34 #include "content/public/browser/browser_thread.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "content/public/browser/download_item.h" 35 #include "content/public/browser/download_item.h"
13 #include "content/public/browser/download_persistent_store_info.h" 36 #include "content/public/browser/download_manager.h"
14 37
38 using content::BrowserThread;
15 using content::DownloadItem; 39 using content::DownloadItem;
16 using content::DownloadPersistentStoreInfo; 40 using content::DownloadManager;
17 41
18 DownloadHistory::DownloadHistory(Profile* profile) 42 namespace {
19 : profile_(profile), 43
20 next_fake_db_handle_(DownloadItem::kUninitializedHandle - 1) { 44 // The value of |db_handle| indicating that the associated DownloadItem is not
21 DCHECK(profile); 45 // yet persisted.
22 } 46 static const int64 kUninitializedHandle = -1;
23 47
24 DownloadHistory::~DownloadHistory() {} 48 // Per-DownloadItem data. This information does not belong inside DownloadItem,
25 49 // and keeping maps in DownloadHistory from DownloadItem to this information is
26 void DownloadHistory::GetNextId( 50 // error-prone and complicated. Unfortunately, DownloadHistory::removing_ and
27 const HistoryService::DownloadNextIdCallback& callback) { 51 // removed_while_adding_ cannot be moved into this class partly because
28 HistoryService* hs = HistoryServiceFactory::GetForProfile( 52 // DownloadHistoryData is destroyed when DownloadItems are destroyed, and we
29 profile_, Profile::EXPLICIT_ACCESS); 53 // have no control over when DownloadItems are destroyed.
30 if (!hs) 54 class DownloadHistoryData : public base::SupportsUserData::Data {
31 return; 55 public:
32 56 static DownloadHistoryData* Get(DownloadItem* item) {
33 hs->GetNextDownloadId(&history_consumer_, callback); 57 base::SupportsUserData::Data* data = item->GetUserData(kKey);
34 } 58 return (data == NULL) ? NULL :
35 59 static_cast<DownloadHistoryData*>(data);
36 void DownloadHistory::Load( 60 }
61
62 explicit DownloadHistoryData(DownloadItem* item)
63 : is_adding_(false),
64 db_handle_(kUninitializedHandle),
65 info_(NULL) {
66 item->SetUserData(kKey, this);
67 }
68
69 virtual ~DownloadHistoryData() {
70 }
71
72 // Whether this item is currently being added to the database.
73 bool is_adding() const { return is_adding_; }
74 void set_is_adding(bool a) { is_adding_ = a; }
75
76 // Whether this item is already persisted in the database.
77 bool is_persisted() const { return db_handle_ > kUninitializedHandle; }
Randy Smith (Not in Mondays) 2012/08/27 18:25:11 As noted elsewhere, I'd sorta like download_databa
benjhayden 2012/09/10 19:02:56 Done.
78
79 int64 db_handle() const { return db_handle_; }
80 void set_db_handle(int64 h) { db_handle_ = h; }
81
82 // This allows OnDownloadUpdated() to see what changed in a DownloadItem if
83 // anything, in order to prevent writing to the database unnecessarily. It is
84 // nullified when the item is no longer in progress in order to save memory.
85 DownloadPersistentStoreInfo* info() { return info_.get(); }
86 void set_info(const DownloadPersistentStoreInfo& i) {
87 info_.reset(new DownloadPersistentStoreInfo(i));
88 }
89 void clear_info() {
90 info_.reset();
91 }
92
93 private:
94 static const char kKey[];
95
96 bool is_adding_;
97 int64 db_handle_;
98 scoped_ptr<DownloadPersistentStoreInfo> info_;
99
100 DISALLOW_COPY_AND_ASSIGN(DownloadHistoryData);
101 };
102
103 const char DownloadHistoryData::kKey[] =
104 "DownloadItem DownloadHistoryData";
105
106 DownloadPersistentStoreInfo GetPersistentStoreInfo(DownloadItem* item) {
107 DownloadHistoryData* dhd = DownloadHistoryData::Get(item);
108 return DownloadPersistentStoreInfo(
109 item->GetFullPath(),
110 item->GetURL(),
111 item->GetReferrerUrl(),
112 item->GetStartTime(),
113 item->GetEndTime(),
114 item->GetReceivedBytes(),
115 item->GetTotalBytes(),
116 item->GetState(),
117 ((dhd != NULL) ? dhd->db_handle() : kUninitializedHandle),
118 item->GetOpened());
119 }
120
121 typedef std::vector<DownloadPersistentStoreInfo> InfoVector;
122
123 // CancelableRequestConsumer would normally ensure that callbacks from the
Randy Smith (Not in Mondays) 2012/08/27 18:25:11 How about "The HistoryService normally uses Cancel
benjhayden 2012/09/10 19:02:56 Done.
124 // HistoryService are run on the same thread that issued the request, but
125 // DownloadHistory has opted for less magic, so it uses Ensure*OnUI to
Randy Smith (Not in Mondays) 2012/08/27 18:25:11 "... less magic by relying on WeakPtrs instead ...
benjhayden 2012/09/10 19:02:56 Done.
126 // explicitly bounce to the UI thread. These methods are static to avoid
127 // creating WeakPtrs on the wrong thread.
Randy Smith (Not in Mondays) 2012/08/27 18:25:11 I don't understand the weak pointer reference in t
benjhayden 2012/09/10 19:02:56 If these functions were methods on DownloadHistory
128 void EnsureQueryOnUI(
129 const base::Callback<void(scoped_ptr<InfoVector>)>& callback,
130 scoped_ptr<InfoVector> infos) {
131 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
132 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
133 callback, base::Passed(infos.Pass())));
134 return;
135 }
136 callback.Run(infos.Pass());
137 }
138
139 void EnsureItemAddedOnUI(const base::Callback<void(int64)>& callback,
140 int64 handle) {
141 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
142 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
143 callback, handle));
144 return;
145 }
146 callback.Run(handle);
147 }
148
149 void EnsureVisitedOnUI(
150 const base::Callback<void(bool, int, base::Time)>& callback,
151 bool success, int count, base::Time first_visit) {
152 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
153 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
154 callback, success, count, first_visit));
155 return;
156 }
157 callback.Run(success, count, first_visit);
158 }
159
160 } // anonymous namespace
161
162 HistoryServiceDownloadAdapter::HistoryServiceDownloadAdapter(
163 HistoryService* history_service)
164 : history_service_(history_service) {
165 }
166
167 HistoryServiceDownloadAdapter::~HistoryServiceDownloadAdapter() {}
168
169 void HistoryServiceDownloadAdapter::QueryDownloads(
37 const HistoryService::DownloadQueryCallback& callback) { 170 const HistoryService::DownloadQueryCallback& callback) {
38 HistoryService* hs = HistoryServiceFactory::GetForProfile( 171 history_service_->QueryDownloads(callback);
39 profile_, Profile::EXPLICIT_ACCESS); 172 history_service_->CleanUpInProgressEntries();
40 if (!hs) 173 }
41 return; 174
42 175 void HistoryServiceDownloadAdapter::GetVisibleVisitCountToHost(
43 hs->QueryDownloads(&history_consumer_, callback); 176 const GURL& referrer_url,
44 177 const HistoryService::GetVisibleVisitCountToHostSimpleCallback& callback) {
45 // This is the initial load, so do a cleanup of corrupt in-progress entries. 178 history_service_->GetVisibleVisitCountToHostSimple(
46 hs->CleanUpInProgressEntries(); 179 referrer_url, callback);
180 }
181
182 void HistoryServiceDownloadAdapter::CreateDownload(
183 const DownloadPersistentStoreInfo& info,
184 const HistoryService::DownloadCreateCallback& callback) {
185 history_service_->CreateDownload(info, callback);
186 }
187
188 void HistoryServiceDownloadAdapter::UpdateDownload(
189 const DownloadPersistentStoreInfo& info) {
190 history_service_->UpdateDownload(info);
191 }
192
193 void HistoryServiceDownloadAdapter::RemoveDownloads(
194 const std::set<int64>& handles) {
195 history_service_->RemoveDownloads(handles);
196 }
197
198 DownloadHistory::DownloadHistory(
199 DownloadManager* manager,
200 scoped_ptr<HistoryServiceDownloadAdapter> history)
201 : manager_(manager),
202 history_(history.Pass()),
203 loading_(false),
204 history_size_(0),
205 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
207 DCHECK(manager_);
208 manager_->AddObserver(this);
209 history_->QueryDownloads(base::Bind(&EnsureQueryOnUI, base::Bind(
210 &DownloadHistory::QueryCallback, weak_ptr_factory_.GetWeakPtr())));
211 }
212
213 DownloadHistory::~DownloadHistory() {
214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
215 for (ItemSet::const_iterator iter = observing_items_.begin();
216 iter != observing_items_.end(); ++iter) {
217 (*iter)->RemoveObserver(this);
218 }
219 observing_items_.clear();
220 if (manager_)
221 manager_->RemoveObserver(this);
222 }
223
224 void DownloadHistory::QueryCallback(scoped_ptr<InfoVector> infos) {
225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
226 // ManagerGoingDown() may have happened before the history loaded.
227 if (!manager_)
228 return;
229 // OnDownloadCreated() is called inside DownloadManager::CreateDownloadItem(),
230 // so temporarily disable adding new unpersisted items to the history. All
231 // methods run on the UI thread and CreateDownloadItem() is synchronous, so it
232 // is impossible for an OnDownloadCreated() to come in for another
233 // DownloadItem while QueryCallback() is processing the database.
Randy Smith (Not in Mondays) 2012/08/27 18:25:11 This is actually not strictly speaking true, or at
benjhayden 2012/09/10 19:02:56 Done.
234 loading_ = true;
235 for (InfoVector::const_iterator it = infos->begin();
236 it != infos->end(); ++it) {
237 DownloadItem* download_item = manager_->CreateDownloadItem(
238 it->path,
239 it->url,
240 it->referrer_url,
241 it->start_time,
242 it->end_time,
243 it->received_bytes,
244 it->total_bytes,
245 it->state,
246 it->opened);
247 DownloadHistoryData* dhd = DownloadHistoryData::Get(download_item);
248 DCHECK(it->db_handle > kUninitializedHandle);
249 dhd->set_db_handle(it->db_handle);
250 ++history_size_;
251 }
252 manager_->CheckForHistoryFilesRemoval();
253 loading_ = false;
254 }
255
256 void DownloadHistory::OnDownloadCreated(
257 DownloadManager* manager, DownloadItem* item) {
258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
259
260 // Observe even temporary downloads in case they are marked not temporary.
261 item->AddObserver(this);
262 observing_items_.insert(item);
263 // All downloads should pass through OnDownloadCreated exactly once.
264 CHECK(!DownloadHistoryData::Get(item));
265 DownloadHistoryData* dhd = new DownloadHistoryData(item);
266 if (item->GetState() == DownloadItem::IN_PROGRESS) {
267 dhd->set_info(GetPersistentStoreInfo(item));
268 }
269 MaybeAddToHistory(item);
270 }
271
272 void DownloadHistory::MaybeAddToHistory(DownloadItem* item) {
273 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
274 int32 download_id = item->GetId();
275 DownloadHistoryData* dhd = DownloadHistoryData::Get(item);
276 bool removing = (removing_.find(dhd->db_handle()) != removing_.end());
277 // TODO(benjhayden): Remove IsTemporary().
278 if (loading_ ||
279 download_crx_util::IsExtensionDownload(*item) ||
280 dhd->is_persisted() ||
281 item->IsTemporary() ||
282 removing ||
283 dhd->is_adding())
284 return;
285 dhd->set_is_adding(true);
286 if (dhd->info() == NULL) {
287 // Keep the info here regardless of whether the item is in progress so
288 // that, when ItemAdded() calls OnDownloadUpdated(), it can choose more
289 // intelligently whether to Update the db and/or discard the info.
290 dhd->set_info(GetPersistentStoreInfo(item));
291 }
292 history_->CreateDownload(*dhd->info(), base::Bind(
293 &EnsureItemAddedOnUI, base::Bind(
294 &DownloadHistory::ItemAdded, weak_ptr_factory_.GetWeakPtr(),
295 download_id)));
296 }
297
298 void DownloadHistory::ItemAdded(int32 download_id, int64 db_handle) {
299 if (!manager_)
300 return;
301
302 if (removed_while_adding_.find(download_id) !=
303 removed_while_adding_.end()) {
304 removed_while_adding_.erase(download_id);
305 if (removing_.empty()) {
306 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
307 base::Bind(&DownloadHistory::RemoveDownloadsBatch,
308 weak_ptr_factory_.GetWeakPtr()));
309 }
310 removing_.insert(db_handle);
311 return;
312 }
313
314 DownloadItem* item = manager_->GetDownload(download_id);
315 if (!item) {
316 // This item will have called OnDownloadDestroyed(). If the item should
317 // have been removed from history, then t would have also called
Randy Smith (Not in Mondays) 2012/08/27 18:25:11 nit: t -> it
benjhayden 2012/09/10 19:02:56 Done.
318 // OnDownloadRemoved(), which would have put |download_id| in
319 // removed_while_adding_, handled above.
320 return;
321 }
322
323 UMA_HISTOGRAM_CUSTOM_COUNTS("Download.HistorySize2",
324 history_size_,
325 0/*min*/,
326 (1 << 23)/*max*/,
327 (1 << 7)/*num_buckets*/);
328 ++history_size_;
329
330 DownloadHistoryData* dhd = DownloadHistoryData::Get(item);
331 dhd->set_is_adding(false);
332 DCHECK(db_handle > kUninitializedHandle);
333 dhd->set_db_handle(db_handle);
334
335 // In case the item changed or became temporary while it was being added.
336 // Don't just update all of the item's observers because we're the only
337 // observer that can also see db_handle, which is the only thing that
338 // ItemAdded changed.
339 OnDownloadUpdated(item);
340 }
341
342 void DownloadHistory::OnDownloadUpdated(DownloadItem* item) {
343 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
344
345 DownloadHistoryData* dhd = DownloadHistoryData::Get(item);
346 if (!dhd->is_persisted()) {
347 MaybeAddToHistory(item);
348 return;
349 }
350 if (item->IsTemporary()) {
351 OnDownloadRemoved(item);
352 return;
353 }
354
355 // TODO(asanka): Persist GetTargetFilePath() as well.
356 DownloadPersistentStoreInfo current_info(GetPersistentStoreInfo(item));
357 DownloadPersistentStoreInfo* previous_info = dhd->info();
358 bool do_update = (
359 (previous_info == NULL) ||
360 (previous_info->path != current_info.path) ||
361 (previous_info->end_time != current_info.end_time) ||
362 (previous_info->received_bytes != current_info.received_bytes) ||
363 (previous_info->total_bytes != current_info.total_bytes) ||
364 (previous_info->state != current_info.state) ||
365 (previous_info->opened != current_info.opened));
366 UMA_HISTOGRAM_ENUMERATION("Download.HistoryPropagatedUpdate", do_update, 2);
367 if (do_update) {
368 history_->UpdateDownload(current_info);
369 }
370 if (item->GetState() == DownloadItem::IN_PROGRESS) {
371 dhd->set_info(current_info);
372 } else {
373 dhd->clear_info();
374 }
375 }
376
377 // Downloads may be opened after they are completed.
378 void DownloadHistory::OnDownloadOpened(DownloadItem* item) {
379 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
380 DownloadHistoryData* dhd = DownloadHistoryData::Get(item);
381 if (!dhd->is_persisted()) {
382 MaybeAddToHistory(item);
383 return;
384 }
385 if (item->IsTemporary()) {
386 OnDownloadRemoved(item);
387 return;
388 }
389
390 DownloadPersistentStoreInfo current_info(GetPersistentStoreInfo(item));
391 history_->UpdateDownload(current_info);
392 if (item->GetState() == DownloadItem::IN_PROGRESS) {
393 dhd->set_info(current_info);
394 }
395 }
396
397 void DownloadHistory::OnDownloadRemoved(DownloadItem* item) {
398 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
399
400 DownloadHistoryData* dhd = DownloadHistoryData::Get(item);
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) {
53 if (referrer_url.is_valid()) { 444 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
54 HistoryService* hs = HistoryServiceFactory::GetForProfileIfExists( 445 if (!referrer_url.is_valid()) {
55 profile_, Profile::EXPLICIT_ACCESS); 446 callback.Run(false);
56 if (hs) { 447 return;
57 HistoryService::Handle handle = 448 }
58 hs->GetVisibleVisitCountToHost(referrer_url, &history_consumer_, 449 history_->GetVisibleVisitCountToHost(
59 base::Bind(&DownloadHistory::OnGotVisitCountToHost, 450 referrer_url,
60 base::Unretained(this))); 451 base::Bind(&EnsureVisitedOnUI, base::Bind(
61 visited_before_requests_[handle] = callback; 452 &DownloadHistory::OnGotVisitCountToHost,
62 return; 453 weak_ptr_factory_.GetWeakPtr(), callback)));
63 } 454 }
64 } 455
65 callback.Run(false); 456 void DownloadHistory::OnGotVisitCountToHost(
66 } 457 const VisitedBeforeDoneCallback& callback,
67 458 bool found_visits,
68 void DownloadHistory::AddEntry( 459 int count,
69 DownloadItem* download_item, 460 base::Time first_visit) {
70 const HistoryService::DownloadCreateCallback& callback) {
71 DCHECK(download_item);
72 // Do not store the download in the history database for a few special cases:
73 // - incognito mode (that is the point of this mode)
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 =
148 visited_before_requests_.find(handle);
149 DCHECK(request != visited_before_requests_.end());
150 VisitedBeforeDoneCallback callback = request->second;
151 visited_before_requests_.erase(request);
152 callback.Run(found_visits && count && 461 callback.Run(found_visits && count &&
153 (first_visit.LocalMidnight() < base::Time::Now().LocalMidnight())); 462 (first_visit.LocalMidnight() < base::Time::Now().LocalMidnight()));
154 } 463 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698