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

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

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

Powered by Google App Engine
This is Rietveld 408576698