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

Side by Side Diff: content/browser/download/download_manager.cc

Issue 8351052: Created a DownloadManager interface, for use in unit tests.. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moved comment. Created 9 years, 1 month 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #include "content/browser/download/download_manager.h" 5 #include "content/browser/download/download_manager.h"
6 6
7 #include <iterator> 7 #include <iterator>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 resource_dispatcher_host->BeginDownload( 65 resource_dispatcher_host->BeginDownload(
66 request, save_info, true, 66 request, save_info, true,
67 DownloadResourceHandler::OnStartedCallback(), 67 DownloadResourceHandler::OnStartedCallback(),
68 render_params.render_process_id_, 68 render_params.render_process_id_,
69 render_params.render_view_id_, 69 render_params.render_view_id_,
70 *context); 70 *context);
71 } 71 }
72 72
73 } // namespace 73 } // namespace
74 74
75 DownloadManager::DownloadManager(content::DownloadManagerDelegate* delegate, 75 DownloadManagerImpl::DownloadManagerImpl(
76 DownloadIdFactory* id_factory, 76 content::DownloadManagerDelegate* delegate,
77 DownloadStatusUpdater* status_updater) 77 DownloadIdFactory* id_factory,
78 : shutdown_needed_(false), 78 DownloadStatusUpdater* status_updater)
79 browser_context_(NULL), 79 : shutdown_needed_(false),
80 file_manager_(NULL), 80 browser_context_(NULL),
81 status_updater_((status_updater != NULL) 81 file_manager_(NULL),
82 ? status_updater->AsWeakPtr() 82 status_updater_((status_updater != NULL)
83 : base::WeakPtr<DownloadStatusUpdater>()), 83 ? status_updater->AsWeakPtr()
84 delegate_(delegate), 84 : base::WeakPtr<DownloadStatusUpdater>()),
85 id_factory_(id_factory), 85 delegate_(delegate),
86 largest_db_handle_in_history_(DownloadItem::kUninitializedHandle) { 86 id_factory_(id_factory),
87 largest_db_handle_in_history_(DownloadItem::kUninitializedHandle) {
87 // NOTE(benjhayden): status_updater may be NULL when using 88 // NOTE(benjhayden): status_updater may be NULL when using
88 // TestingBrowserProcess. 89 // TestingBrowserProcess.
89 if (status_updater_.get() != NULL) 90 if (status_updater_.get() != NULL)
90 status_updater_->AddDelegate(this); 91 status_updater_->AddDelegate(this);
91 } 92 }
92 93
93 DownloadManager::~DownloadManager() { 94 DownloadManagerImpl::~DownloadManagerImpl() {
94 DCHECK(!shutdown_needed_); 95 DCHECK(!shutdown_needed_);
95 if (status_updater_.get() != NULL) 96 if (status_updater_.get() != NULL)
96 status_updater_->RemoveDelegate(this); 97 status_updater_->RemoveDelegate(this);
97 } 98 }
98 99
99 DownloadId DownloadManager::GetNextId() { 100 DownloadId DownloadManagerImpl::GetNextId() {
100 return id_factory_->GetNextId(); 101 return id_factory_->GetNextId();
101 } 102 }
102 103
103 void DownloadManager::Shutdown() { 104 void DownloadManagerImpl::Shutdown() {
104 VLOG(20) << __FUNCTION__ << "()" 105 VLOG(20) << __FUNCTION__ << "()"
105 << " shutdown_needed_ = " << shutdown_needed_; 106 << " shutdown_needed_ = " << shutdown_needed_;
106 if (!shutdown_needed_) 107 if (!shutdown_needed_)
107 return; 108 return;
108 shutdown_needed_ = false; 109 shutdown_needed_ = false;
109 110
110 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown()); 111 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown());
111 // TODO(benjhayden): Consider clearing observers_. 112 // TODO(benjhayden): Consider clearing observers_.
112 113
113 if (file_manager_) { 114 if (file_manager_) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 STLDeleteElements(&downloads_to_delete); 161 STLDeleteElements(&downloads_to_delete);
161 162
162 DCHECK(save_page_downloads_.empty()); 163 DCHECK(save_page_downloads_.empty());
163 164
164 file_manager_ = NULL; 165 file_manager_ = NULL;
165 delegate_->Shutdown(); 166 delegate_->Shutdown();
166 167
167 shutdown_needed_ = false; 168 shutdown_needed_ = false;
168 } 169 }
169 170
170 void DownloadManager::GetTemporaryDownloads( 171 void DownloadManagerImpl::GetTemporaryDownloads(
171 const FilePath& dir_path, DownloadVector* result) { 172 const FilePath& dir_path, DownloadVector* result) {
172 DCHECK(result); 173 DCHECK(result);
173 174
174 for (DownloadMap::iterator it = history_downloads_.begin(); 175 for (DownloadMap::iterator it = history_downloads_.begin();
175 it != history_downloads_.end(); ++it) { 176 it != history_downloads_.end(); ++it) {
176 if (it->second->is_temporary() && 177 if (it->second->is_temporary() &&
177 it->second->full_path().DirName() == dir_path) 178 it->second->full_path().DirName() == dir_path)
178 result->push_back(it->second); 179 result->push_back(it->second);
179 } 180 }
180 } 181 }
181 182
182 void DownloadManager::GetAllDownloads( 183 void DownloadManagerImpl::GetAllDownloads(
183 const FilePath& dir_path, DownloadVector* result) { 184 const FilePath& dir_path, DownloadVector* result) {
184 DCHECK(result); 185 DCHECK(result);
185 186
186 for (DownloadMap::iterator it = history_downloads_.begin(); 187 for (DownloadMap::iterator it = history_downloads_.begin();
187 it != history_downloads_.end(); ++it) { 188 it != history_downloads_.end(); ++it) {
188 if (!it->second->is_temporary() && 189 if (!it->second->is_temporary() &&
189 (dir_path.empty() || it->second->full_path().DirName() == dir_path)) 190 (dir_path.empty() || it->second->full_path().DirName() == dir_path))
190 result->push_back(it->second); 191 result->push_back(it->second);
191 } 192 }
192 } 193 }
193 194
194 void DownloadManager::SearchDownloads(const string16& query, 195 void DownloadManagerImpl::SearchDownloads(const string16& query,
195 DownloadVector* result) { 196 DownloadVector* result) {
196 string16 query_lower(base::i18n::ToLower(query)); 197 string16 query_lower(base::i18n::ToLower(query));
197 198
198 for (DownloadMap::iterator it = history_downloads_.begin(); 199 for (DownloadMap::iterator it = history_downloads_.begin();
199 it != history_downloads_.end(); ++it) { 200 it != history_downloads_.end(); ++it) {
200 DownloadItem* download_item = it->second; 201 DownloadItem* download_item = it->second;
201 202
202 if (download_item->is_temporary()) 203 if (download_item->is_temporary())
203 continue; 204 continue;
204 205
205 // Display Incognito downloads only in Incognito window, and vice versa. 206 // Display Incognito downloads only in Incognito window, and vice versa.
206 // The Incognito Downloads page will get the list of non-Incognito downloads 207 // The Incognito Downloads page will get the list of non-Incognito downloads
207 // from its parent profile. 208 // from its parent profile.
208 if (browser_context_->IsOffTheRecord() != download_item->is_otr()) 209 if (browser_context_->IsOffTheRecord() != download_item->is_otr())
209 continue; 210 continue;
210 211
211 if (download_item->MatchesQuery(query_lower)) 212 if (download_item->MatchesQuery(query_lower))
212 result->push_back(download_item); 213 result->push_back(download_item);
213 } 214 }
214 } 215 }
215 216
216 // Query the history service for information about all persisted downloads. 217 // Query the history service for information about all persisted downloads.
217 bool DownloadManager::Init(content::BrowserContext* browser_context) { 218 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) {
218 DCHECK(browser_context); 219 DCHECK(browser_context);
219 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; 220 DCHECK(!shutdown_needed_) << "DownloadManager already initialized.";
220 shutdown_needed_ = true; 221 shutdown_needed_ = true;
221 222
222 browser_context_ = browser_context; 223 browser_context_ = browser_context;
223 224
224 // In test mode, there may be no ResourceDispatcherHost. In this case it's 225 // In test mode, there may be no ResourceDispatcherHost. In this case it's
225 // safe to avoid setting |file_manager_| because we only call a small set of 226 // safe to avoid setting |file_manager_| because we only call a small set of
226 // functions, none of which need it. 227 // functions, none of which need it.
227 ResourceDispatcherHost* rdh = 228 ResourceDispatcherHost* rdh =
228 content::GetContentClient()->browser()->GetResourceDispatcherHost(); 229 content::GetContentClient()->browser()->GetResourceDispatcherHost();
229 if (rdh) { 230 if (rdh) {
230 file_manager_ = rdh->download_file_manager(); 231 file_manager_ = rdh->download_file_manager();
231 DCHECK(file_manager_); 232 DCHECK(file_manager_);
232 } 233 }
233 234
234 return true; 235 return true;
235 } 236 }
236 237
237 // We have received a message from DownloadFileManager about a new download. 238 // We have received a message from DownloadFileManager about a new download.
238 void DownloadManager::StartDownload(int32 download_id) { 239 void DownloadManagerImpl::StartDownload(int32 download_id) {
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
240 241
241 if (delegate_->ShouldStartDownload(download_id)) 242 if (delegate_->ShouldStartDownload(download_id))
242 RestartDownload(download_id); 243 RestartDownload(download_id);
243 } 244 }
244 245
245 void DownloadManager::CheckForHistoryFilesRemoval() { 246 void DownloadManagerImpl::CheckForHistoryFilesRemoval() {
246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
247 for (DownloadMap::iterator it = history_downloads_.begin(); 248 for (DownloadMap::iterator it = history_downloads_.begin();
248 it != history_downloads_.end(); ++it) { 249 it != history_downloads_.end(); ++it) {
249 CheckForFileRemoval(it->second); 250 CheckForFileRemoval(it->second);
250 } 251 }
251 } 252 }
252 253
253 void DownloadManager::CheckForFileRemoval(DownloadItem* download_item) { 254 void DownloadManagerImpl::CheckForFileRemoval(DownloadItem* download_item) {
254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
255 if (download_item->IsComplete() && 256 if (download_item->IsComplete() &&
256 !download_item->file_externally_removed()) { 257 !download_item->file_externally_removed()) {
257 BrowserThread::PostTask( 258 BrowserThread::PostTask(
258 BrowserThread::FILE, FROM_HERE, 259 BrowserThread::FILE, FROM_HERE,
259 base::Bind(&DownloadManager::CheckForFileRemovalOnFileThread, 260 base::Bind(&DownloadManagerImpl::CheckForFileRemovalOnFileThread,
260 this, download_item->db_handle(), 261 this, download_item->db_handle(),
261 download_item->GetTargetFilePath())); 262 download_item->GetTargetFilePath()));
262 } 263 }
263 } 264 }
264 265
265 void DownloadManager::CheckForFileRemovalOnFileThread( 266 void DownloadManagerImpl::CheckForFileRemovalOnFileThread(
266 int64 db_handle, const FilePath& path) { 267 int64 db_handle, const FilePath& path) {
267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
268 if (!file_util::PathExists(path)) { 269 if (!file_util::PathExists(path)) {
269 BrowserThread::PostTask( 270 BrowserThread::PostTask(
270 BrowserThread::UI, FROM_HERE, 271 BrowserThread::UI, FROM_HERE,
271 base::Bind(&DownloadManager::OnFileRemovalDetected, this, db_handle)); 272 base::Bind(&DownloadManagerImpl::OnFileRemovalDetected,
273 this,
274 db_handle));
272 } 275 }
273 } 276 }
274 277
275 void DownloadManager::OnFileRemovalDetected(int64 db_handle) { 278 void DownloadManagerImpl::OnFileRemovalDetected(int64 db_handle) {
276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
277 DownloadMap::iterator it = history_downloads_.find(db_handle); 280 DownloadMap::iterator it = history_downloads_.find(db_handle);
278 if (it != history_downloads_.end()) { 281 if (it != history_downloads_.end()) {
279 DownloadItem* download_item = it->second; 282 DownloadItem* download_item = it->second;
280 download_item->OnDownloadedFileRemoved(); 283 download_item->OnDownloadedFileRemoved();
281 } 284 }
282 } 285 }
283 286
284 void DownloadManager::RestartDownload( 287 void DownloadManagerImpl::RestartDownload(
285 int32 download_id) { 288 int32 download_id) {
286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 289 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
287 290
288 DownloadItem* download = GetActiveDownloadItem(download_id); 291 DownloadItem* download = GetActiveDownloadItem(download_id);
289 if (!download) 292 if (!download)
290 return; 293 return;
291 294
292 VLOG(20) << __FUNCTION__ << "()" 295 VLOG(20) << __FUNCTION__ << "()"
293 << " download = " << download->DebugString(true); 296 << " download = " << download->DebugString(true);
294 297
(...skipping 12 matching lines...) Expand all
307 contents, suggested_path, reinterpret_cast<void*>(id_ptr)); 310 contents, suggested_path, reinterpret_cast<void*>(id_ptr));
308 311
309 FOR_EACH_OBSERVER(Observer, observers_, 312 FOR_EACH_OBSERVER(Observer, observers_,
310 SelectFileDialogDisplayed(download_id)); 313 SelectFileDialogDisplayed(download_id));
311 } else { 314 } else {
312 // No prompting for download, just continue with the suggested name. 315 // No prompting for download, just continue with the suggested name.
313 ContinueDownloadWithPath(download, suggested_path); 316 ContinueDownloadWithPath(download, suggested_path);
314 } 317 }
315 } 318 }
316 319
317 void DownloadManager::CreateDownloadItem( 320 content::BrowserContext* DownloadManagerImpl::BrowserContext() {
321 return browser_context_;
322 }
323
324 FilePath DownloadManagerImpl::LastDownloadPath() {
325 return last_download_path_;
326 }
327
328 void DownloadManagerImpl::CreateDownloadItem(
318 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) { 329 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) {
319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 330 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
320 331
321 DownloadItem* download = new DownloadItem( 332 DownloadItem* download = new DownloadItem(
322 this, *info, new DownloadRequestHandle(request_handle), 333 this, *info, new DownloadRequestHandle(request_handle),
323 browser_context_->IsOffTheRecord()); 334 browser_context_->IsOffTheRecord());
324 int32 download_id = info->download_id.local(); 335 int32 download_id = info->download_id.local();
325 DCHECK(!ContainsKey(in_progress_, download_id)); 336 DCHECK(!ContainsKey(in_progress_, download_id));
326 337
327 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. 338 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved.
328 CHECK(!ContainsKey(active_downloads_, download_id)); 339 CHECK(!ContainsKey(active_downloads_, download_id));
329 downloads_.insert(download); 340 downloads_.insert(download);
330 active_downloads_[download_id] = download; 341 active_downloads_[download_id] = download;
331 } 342 }
332 343
333 void DownloadManager::ContinueDownloadWithPath(DownloadItem* download, 344 void DownloadManagerImpl::ContinueDownloadWithPath(
334 const FilePath& chosen_file) { 345 DownloadItem* download, const FilePath& chosen_file) {
335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
336 DCHECK(download); 347 DCHECK(download);
337 348
338 int32 download_id = download->id(); 349 int32 download_id = download->id();
339 350
340 // NOTE(ahendrickson) Eventually |active_downloads_| will replace 351 // NOTE(ahendrickson) Eventually |active_downloads_| will replace
341 // |in_progress_|, but we don't want to change the semantics yet. 352 // |in_progress_|, but we don't want to change the semantics yet.
342 DCHECK(!ContainsKey(in_progress_, download_id)); 353 DCHECK(!ContainsKey(in_progress_, download_id));
343 DCHECK(ContainsKey(downloads_, download)); 354 DCHECK(ContainsKey(downloads_, download));
344 DCHECK(ContainsKey(active_downloads_, download_id)); 355 DCHECK(ContainsKey(active_downloads_, download_id));
(...skipping 15 matching lines...) Expand all
360 BrowserThread::PostTask( 371 BrowserThread::PostTask(
361 BrowserThread::FILE, FROM_HERE, 372 BrowserThread::FILE, FROM_HERE,
362 base::Bind(&DownloadFileManager::RenameInProgressDownloadFile, 373 base::Bind(&DownloadFileManager::RenameInProgressDownloadFile,
363 file_manager_, download->global_id(), download_path)); 374 file_manager_, download->global_id(), download_path));
364 375
365 download->Rename(download_path); 376 download->Rename(download_path);
366 377
367 delegate_->AddItemToPersistentStore(download); 378 delegate_->AddItemToPersistentStore(download);
368 } 379 }
369 380
370 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { 381 void DownloadManagerImpl::UpdateDownload(int32 download_id, int64 size) {
371 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 382 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
372 DownloadMap::iterator it = active_downloads_.find(download_id); 383 DownloadMap::iterator it = active_downloads_.find(download_id);
373 if (it != active_downloads_.end()) { 384 if (it != active_downloads_.end()) {
374 DownloadItem* download = it->second; 385 DownloadItem* download = it->second;
375 if (download->IsInProgress()) { 386 if (download->IsInProgress()) {
376 download->Update(size); 387 download->Update(size);
377 UpdateDownloadProgress(); // Reflect size updates. 388 UpdateDownloadProgress(); // Reflect size updates.
378 delegate_->UpdateItemInPersistentStore(download); 389 delegate_->UpdateItemInPersistentStore(download);
379 } 390 }
380 } 391 }
381 } 392 }
382 393
383 void DownloadManager::OnResponseCompleted(int32 download_id, 394 void DownloadManagerImpl::OnResponseCompleted(int32 download_id,
384 int64 size, 395 int64 size,
385 const std::string& hash) { 396 const std::string& hash) {
386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
387 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id 398 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id
388 << " size = " << size; 399 << " size = " << size;
389 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 400 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
390 401
391 // If it's not in active_downloads_, that means it was cancelled; just 402 // If it's not in active_downloads_, that means it was cancelled; just
392 // ignore the notification. 403 // ignore the notification.
393 if (active_downloads_.count(download_id) == 0) 404 if (active_downloads_.count(download_id) == 0)
394 return; 405 return;
395 406
396 DownloadItem* download = active_downloads_[download_id]; 407 DownloadItem* download = active_downloads_[download_id];
397 download->OnAllDataSaved(size); 408 download->OnAllDataSaved(size);
398 409
399 delegate_->OnResponseCompleted(download, hash); 410 delegate_->OnResponseCompleted(download, hash);
400 411
401 MaybeCompleteDownload(download); 412 MaybeCompleteDownload(download);
402 } 413 }
403 414
404 void DownloadManager::AssertQueueStateConsistent(DownloadItem* download) { 415 void DownloadManagerImpl::AssertQueueStateConsistent(DownloadItem* download) {
405 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. 416 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved.
406 if (download->state() == DownloadItem::REMOVING) { 417 if (download->state() == DownloadItem::REMOVING) {
407 CHECK(!ContainsKey(downloads_, download)); 418 CHECK(!ContainsKey(downloads_, download));
408 CHECK(!ContainsKey(active_downloads_, download->id())); 419 CHECK(!ContainsKey(active_downloads_, download->id()));
409 CHECK(!ContainsKey(in_progress_, download->id())); 420 CHECK(!ContainsKey(in_progress_, download->id()));
410 CHECK(!ContainsKey(history_downloads_, download->db_handle())); 421 CHECK(!ContainsKey(history_downloads_, download->db_handle()));
411 return; 422 return;
412 } 423 }
413 424
414 // Should be in downloads_ if we're not REMOVING. 425 // Should be in downloads_ if we're not REMOVING.
(...skipping 16 matching lines...) Expand all
431 if (ContainsKey(active_downloads_, download->id())) { 442 if (ContainsKey(active_downloads_, download->id())) {
432 if (download->db_handle() != DownloadItem::kUninitializedHandle) 443 if (download->db_handle() != DownloadItem::kUninitializedHandle)
433 CHECK_EQ(DownloadItem::IN_PROGRESS, download->state()); 444 CHECK_EQ(DownloadItem::IN_PROGRESS, download->state());
434 if (DownloadItem::IN_PROGRESS != download->state()) 445 if (DownloadItem::IN_PROGRESS != download->state())
435 CHECK_EQ(DownloadItem::kUninitializedHandle, download->db_handle()); 446 CHECK_EQ(DownloadItem::kUninitializedHandle, download->db_handle());
436 } 447 }
437 if (DownloadItem::IN_PROGRESS == download->state()) 448 if (DownloadItem::IN_PROGRESS == download->state())
438 CHECK(ContainsKey(active_downloads_, download->id())); 449 CHECK(ContainsKey(active_downloads_, download->id()));
439 } 450 }
440 451
441 bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) { 452 bool DownloadManagerImpl::IsDownloadReadyForCompletion(DownloadItem* download) {
442 // If we don't have all the data, the download is not ready for 453 // If we don't have all the data, the download is not ready for
443 // completion. 454 // completion.
444 if (!download->all_data_saved()) 455 if (!download->all_data_saved())
445 return false; 456 return false;
446 457
447 // If the download is dangerous, but not yet validated, it's not ready for 458 // If the download is dangerous, but not yet validated, it's not ready for
448 // completion. 459 // completion.
449 if (download->safety_state() == DownloadItem::DANGEROUS) 460 if (download->safety_state() == DownloadItem::DANGEROUS)
450 return false; 461 return false;
451 462
452 // If the download isn't active (e.g. has been cancelled) it's not 463 // If the download isn't active (e.g. has been cancelled) it's not
453 // ready for completion. 464 // ready for completion.
454 if (active_downloads_.count(download->id()) == 0) 465 if (active_downloads_.count(download->id()) == 0)
455 return false; 466 return false;
456 467
457 // If the download hasn't been inserted into the history system 468 // If the download hasn't been inserted into the history system
458 // (which occurs strictly after file name determination, intermediate 469 // (which occurs strictly after file name determination, intermediate
459 // file rename, and UI display) then it's not ready for completion. 470 // file rename, and UI display) then it's not ready for completion.
460 if (download->db_handle() == DownloadItem::kUninitializedHandle) 471 if (download->db_handle() == DownloadItem::kUninitializedHandle)
461 return false; 472 return false;
462 473
463 return true; 474 return true;
464 } 475 }
465 476
466 void DownloadManager::MaybeCompleteDownload(DownloadItem* download) { 477 void DownloadManagerImpl::MaybeCompleteDownload(DownloadItem* download) {
467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 478 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
468 VLOG(20) << __FUNCTION__ << "()" << " download = " 479 VLOG(20) << __FUNCTION__ << "()" << " download = "
469 << download->DebugString(false); 480 << download->DebugString(false);
470 481
471 if (!IsDownloadReadyForCompletion(download)) 482 if (!IsDownloadReadyForCompletion(download))
472 return; 483 return;
473 484
474 // TODO(rdsmith): DCHECK that we only pass through this point 485 // TODO(rdsmith): DCHECK that we only pass through this point
475 // once per download. The natural way to do this is by a state 486 // once per download. The natural way to do this is by a state
476 // transition on the DownloadItem. 487 // transition on the DownloadItem.
(...skipping 16 matching lines...) Expand all
493 // Remove the id from in_progress 504 // Remove the id from in_progress
494 in_progress_.erase(download->id()); 505 in_progress_.erase(download->id());
495 UpdateDownloadProgress(); // Reflect removal from in_progress_. 506 UpdateDownloadProgress(); // Reflect removal from in_progress_.
496 507
497 delegate_->UpdateItemInPersistentStore(download); 508 delegate_->UpdateItemInPersistentStore(download);
498 509
499 // Finish the download. 510 // Finish the download.
500 download->OnDownloadCompleting(file_manager_); 511 download->OnDownloadCompleting(file_manager_);
501 } 512 }
502 513
503 void DownloadManager::DownloadCompleted(int32 download_id) { 514 void DownloadManagerImpl::DownloadCompleted(int32 download_id) {
504 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
505 DownloadItem* download = GetDownloadItem(download_id); 516 DownloadItem* download = GetDownloadItem(download_id);
506 DCHECK(download); 517 DCHECK(download);
507 delegate_->UpdateItemInPersistentStore(download); 518 delegate_->UpdateItemInPersistentStore(download);
508 active_downloads_.erase(download_id); 519 active_downloads_.erase(download_id);
509 AssertQueueStateConsistent(download); 520 AssertQueueStateConsistent(download);
510 } 521 }
511 522
512 void DownloadManager::OnDownloadRenamedToFinalName(int download_id, 523 void DownloadManagerImpl::OnDownloadRenamedToFinalName(
513 const FilePath& full_path, 524 int download_id,
514 int uniquifier) { 525 const FilePath& full_path,
526 int uniquifier) {
515 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id 527 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id
516 << " full_path = \"" << full_path.value() << "\"" 528 << " full_path = \"" << full_path.value() << "\""
517 << " uniquifier = " << uniquifier; 529 << " uniquifier = " << uniquifier;
518 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 530 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
519 531
520 DownloadItem* item = GetDownloadItem(download_id); 532 DownloadItem* item = GetDownloadItem(download_id);
521 if (!item) 533 if (!item)
522 return; 534 return;
523 535
524 if (item->safety_state() == DownloadItem::SAFE) { 536 if (item->safety_state() == DownloadItem::SAFE) {
525 DCHECK_EQ(0, uniquifier) << "We should not uniquify SAFE downloads twice"; 537 DCHECK_EQ(0, uniquifier) << "We should not uniquify SAFE downloads twice";
526 } 538 }
527 539
528 BrowserThread::PostTask( 540 BrowserThread::PostTask(
529 BrowserThread::FILE, FROM_HERE, 541 BrowserThread::FILE, FROM_HERE,
530 base::Bind(&DownloadFileManager::CompleteDownload, 542 base::Bind(&DownloadFileManager::CompleteDownload,
531 file_manager_, item->global_id())); 543 file_manager_, item->global_id()));
532 544
533 if (uniquifier) 545 if (uniquifier)
534 item->set_path_uniquifier(uniquifier); 546 item->set_path_uniquifier(uniquifier);
535 547
536 item->OnDownloadRenamedToFinalName(full_path); 548 item->OnDownloadRenamedToFinalName(full_path);
537 delegate_->UpdatePathForItemInPersistentStore(item, full_path); 549 delegate_->UpdatePathForItemInPersistentStore(item, full_path);
538 } 550 }
539 551
540 void DownloadManager::CancelDownload(int32 download_id) { 552 void DownloadManagerImpl::CancelDownload(int32 download_id) {
541 DownloadItem* download = GetActiveDownload(download_id); 553 DownloadItem* download = GetActiveDownload(download_id);
542 // A cancel at the right time could remove the download from the 554 // A cancel at the right time could remove the download from the
543 // |active_downloads_| map before we get here. 555 // |active_downloads_| map before we get here.
544 if (!download) 556 if (!download)
545 return; 557 return;
546 558
547 download->Cancel(true); 559 download->Cancel(true);
548 } 560 }
549 561
550 void DownloadManager::DownloadCancelledInternal(DownloadItem* download) { 562 void DownloadManagerImpl::DownloadCancelledInternal(DownloadItem* download) {
551 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 563 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
552 564
553 VLOG(20) << __FUNCTION__ << "()" 565 VLOG(20) << __FUNCTION__ << "()"
554 << " download = " << download->DebugString(true); 566 << " download = " << download->DebugString(true);
555 567
556 RemoveFromActiveList(download); 568 RemoveFromActiveList(download);
557 // This function is called from the DownloadItem, so DI state 569 // This function is called from the DownloadItem, so DI state
558 // should already have been updated. 570 // should already have been updated.
559 AssertQueueStateConsistent(download); 571 AssertQueueStateConsistent(download);
560 572
561 if (file_manager_) 573 if (file_manager_)
562 download->OffThreadCancel(file_manager_); 574 download->OffThreadCancel(file_manager_);
563 } 575 }
564 576
565 void DownloadManager::OnDownloadInterrupted(int32 download_id, 577 void DownloadManagerImpl::OnDownloadInterrupted(int32 download_id,
566 int64 size, 578 int64 size,
567 InterruptReason reason) { 579 InterruptReason reason) {
568 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 580 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
569 581
570 DownloadItem* download = GetActiveDownload(download_id); 582 DownloadItem* download = GetActiveDownload(download_id);
571 if (!download) 583 if (!download)
572 return; 584 return;
573 585
574 VLOG(20) << __FUNCTION__ << "()" 586 VLOG(20) << __FUNCTION__ << "()"
575 << " reason " << InterruptReasonDebugString(reason) 587 << " reason " << InterruptReasonDebugString(reason)
576 << " at offset " << download->received_bytes() 588 << " at offset " << download->received_bytes()
577 << " size = " << size 589 << " size = " << size
578 << " download = " << download->DebugString(true); 590 << " download = " << download->DebugString(true);
579 591
580 RemoveFromActiveList(download); 592 RemoveFromActiveList(download);
581 download->Interrupted(size, reason); 593 download->Interrupted(size, reason);
582 download->OffThreadCancel(file_manager_); 594 download->OffThreadCancel(file_manager_);
583 } 595 }
584 596
585 DownloadItem* DownloadManager::GetActiveDownload(int32 download_id) { 597 DownloadItem* DownloadManagerImpl::GetActiveDownload(int32 download_id) {
586 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 598 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
587 DownloadMap::iterator it = active_downloads_.find(download_id); 599 DownloadMap::iterator it = active_downloads_.find(download_id);
588 if (it == active_downloads_.end()) 600 if (it == active_downloads_.end())
589 return NULL; 601 return NULL;
590 602
591 DownloadItem* download = it->second; 603 DownloadItem* download = it->second;
592 604
593 DCHECK(download); 605 DCHECK(download);
594 DCHECK_EQ(download_id, download->id()); 606 DCHECK_EQ(download_id, download->id());
595 607
596 return download; 608 return download;
597 } 609 }
598 610
599 void DownloadManager::RemoveFromActiveList(DownloadItem* download) { 611 void DownloadManagerImpl::RemoveFromActiveList(DownloadItem* download) {
600 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 612 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
601 DCHECK(download); 613 DCHECK(download);
602 614
603 // Clean up will happen when the history system create callback runs if we 615 // Clean up will happen when the history system create callback runs if we
604 // don't have a valid db_handle yet. 616 // don't have a valid db_handle yet.
605 if (download->db_handle() != DownloadItem::kUninitializedHandle) { 617 if (download->db_handle() != DownloadItem::kUninitializedHandle) {
606 in_progress_.erase(download->id()); 618 in_progress_.erase(download->id());
607 active_downloads_.erase(download->id()); 619 active_downloads_.erase(download->id());
608 UpdateDownloadProgress(); // Reflect removal from in_progress_. 620 UpdateDownloadProgress(); // Reflect removal from in_progress_.
609 delegate_->UpdateItemInPersistentStore(download); 621 delegate_->UpdateItemInPersistentStore(download);
610 } 622 }
611 } 623 }
612 624
613 void DownloadManager::SetDownloadManagerDelegate( 625 content::DownloadManagerDelegate* DownloadManagerImpl::delegate() const {
626 return delegate_;
627 }
628
629 void DownloadManagerImpl::SetDownloadManagerDelegate(
614 content::DownloadManagerDelegate* delegate) { 630 content::DownloadManagerDelegate* delegate) {
615 delegate_ = delegate; 631 delegate_ = delegate;
616 } 632 }
617 633
618 void DownloadManager::UpdateDownloadProgress() { 634 void DownloadManagerImpl::UpdateDownloadProgress() {
619 delegate_->DownloadProgressUpdated(); 635 delegate_->DownloadProgressUpdated();
620 } 636 }
621 637
622 int DownloadManager::RemoveDownloadItems( 638 int DownloadManagerImpl::RemoveDownloadItems(
623 const DownloadVector& pending_deletes) { 639 const DownloadVector& pending_deletes) {
624 if (pending_deletes.empty()) 640 if (pending_deletes.empty())
625 return 0; 641 return 0;
626 642
627 // Delete from internal maps. 643 // Delete from internal maps.
628 for (DownloadVector::const_iterator it = pending_deletes.begin(); 644 for (DownloadVector::const_iterator it = pending_deletes.begin();
629 it != pending_deletes.end(); 645 it != pending_deletes.end();
630 ++it) { 646 ++it) {
631 DownloadItem* download = *it; 647 DownloadItem* download = *it;
632 DCHECK(download); 648 DCHECK(download);
633 history_downloads_.erase(download->db_handle()); 649 history_downloads_.erase(download->db_handle());
634 save_page_downloads_.erase(download->id()); 650 save_page_downloads_.erase(download->id());
635 downloads_.erase(download); 651 downloads_.erase(download);
636 } 652 }
637 653
638 // Tell observers to refresh their views. 654 // Tell observers to refresh their views.
639 NotifyModelChanged(); 655 NotifyModelChanged();
640 656
641 // Delete the download items themselves. 657 // Delete the download items themselves.
642 const int num_deleted = static_cast<int>(pending_deletes.size()); 658 const int num_deleted = static_cast<int>(pending_deletes.size());
643 STLDeleteContainerPointers(pending_deletes.begin(), pending_deletes.end()); 659 STLDeleteContainerPointers(pending_deletes.begin(), pending_deletes.end());
644 return num_deleted; 660 return num_deleted;
645 } 661 }
646 662
647 void DownloadManager::RemoveDownload(int64 download_handle) { 663 void DownloadManagerImpl::RemoveDownload(int64 download_handle) {
648 DownloadMap::iterator it = history_downloads_.find(download_handle); 664 DownloadMap::iterator it = history_downloads_.find(download_handle);
649 if (it == history_downloads_.end()) 665 if (it == history_downloads_.end())
650 return; 666 return;
651 667
652 // Make history update. 668 // Make history update.
653 DownloadItem* download = it->second; 669 DownloadItem* download = it->second;
654 delegate_->RemoveItemFromPersistentStore(download); 670 delegate_->RemoveItemFromPersistentStore(download);
655 671
656 // Remove from our tables and delete. 672 // Remove from our tables and delete.
657 int downloads_count = RemoveDownloadItems(DownloadVector(1, download)); 673 int downloads_count = RemoveDownloadItems(DownloadVector(1, download));
658 DCHECK_EQ(1, downloads_count); 674 DCHECK_EQ(1, downloads_count);
659 } 675 }
660 676
661 int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin, 677 int DownloadManagerImpl::RemoveDownloadsBetween(const base::Time remove_begin,
662 const base::Time remove_end) { 678 const base::Time remove_end) {
663 delegate_->RemoveItemsFromPersistentStoreBetween(remove_begin, remove_end); 679 delegate_->RemoveItemsFromPersistentStoreBetween(remove_begin, remove_end);
664 680
665 // All downloads visible to the user will be in the history, 681 // All downloads visible to the user will be in the history,
666 // so scan that map. 682 // so scan that map.
667 DownloadVector pending_deletes; 683 DownloadVector pending_deletes;
668 for (DownloadMap::const_iterator it = history_downloads_.begin(); 684 for (DownloadMap::const_iterator it = history_downloads_.begin();
669 it != history_downloads_.end(); 685 it != history_downloads_.end();
670 ++it) { 686 ++it) {
671 DownloadItem* download = it->second; 687 DownloadItem* download = it->second;
672 if (download->start_time() >= remove_begin && 688 if (download->start_time() >= remove_begin &&
673 (remove_end.is_null() || download->start_time() < remove_end) && 689 (remove_end.is_null() || download->start_time() < remove_end) &&
674 (download->IsComplete() || download->IsCancelled())) { 690 (download->IsComplete() || download->IsCancelled())) {
675 AssertQueueStateConsistent(download); 691 AssertQueueStateConsistent(download);
676 pending_deletes.push_back(download); 692 pending_deletes.push_back(download);
677 } 693 }
678 } 694 }
679 return RemoveDownloadItems(pending_deletes); 695 return RemoveDownloadItems(pending_deletes);
680 } 696 }
681 697
682 int DownloadManager::RemoveDownloads(const base::Time remove_begin) { 698 int DownloadManagerImpl::RemoveDownloads(const base::Time remove_begin) {
683 return RemoveDownloadsBetween(remove_begin, base::Time()); 699 return RemoveDownloadsBetween(remove_begin, base::Time());
684 } 700 }
685 701
686 int DownloadManager::RemoveAllDownloads() { 702 int DownloadManagerImpl::RemoveAllDownloads() {
687 download_stats::RecordClearAllSize(history_downloads_.size()); 703 download_stats::RecordClearAllSize(history_downloads_.size());
688 // The null times make the date range unbounded. 704 // The null times make the date range unbounded.
689 return RemoveDownloadsBetween(base::Time(), base::Time()); 705 return RemoveDownloadsBetween(base::Time(), base::Time());
690 } 706 }
691 707
692 // Initiate a download of a specific URL. We send the request to the 708 // Initiate a download of a specific URL. We send the request to the
693 // ResourceDispatcherHost, and let it send us responses like a regular 709 // ResourceDispatcherHost, and let it send us responses like a regular
694 // download. 710 // download.
695 void DownloadManager::DownloadUrl(const GURL& url, 711 void DownloadManagerImpl::DownloadUrl(const GURL& url,
696 const GURL& referrer, 712 const GURL& referrer,
697 const std::string& referrer_charset, 713 const std::string& referrer_charset,
698 TabContents* tab_contents) { 714 TabContents* tab_contents) {
699 DownloadUrlToFile(url, referrer, referrer_charset, DownloadSaveInfo(), 715 DownloadUrlToFile(url, referrer, referrer_charset, DownloadSaveInfo(),
700 tab_contents); 716 tab_contents);
701 } 717 }
702 718
703 void DownloadManager::DownloadUrlToFile(const GURL& url, 719 void DownloadManagerImpl::DownloadUrlToFile(const GURL& url,
704 const GURL& referrer, 720 const GURL& referrer,
705 const std::string& referrer_charset, 721 const std::string& referrer_charset,
706 const DownloadSaveInfo& save_info, 722 const DownloadSaveInfo& save_info,
707 TabContents* tab_contents) { 723 TabContents* tab_contents) {
708 DCHECK(tab_contents); 724 DCHECK(tab_contents);
709 ResourceDispatcherHost* resource_dispatcher_host = 725 ResourceDispatcherHost* resource_dispatcher_host =
710 content::GetContentClient()->browser()->GetResourceDispatcherHost(); 726 content::GetContentClient()->browser()->GetResourceDispatcherHost();
711 // We send a pointer to content::ResourceContext, instead of the usual 727 // We send a pointer to content::ResourceContext, instead of the usual
712 // reference, so that a copy of the object isn't made. 728 // reference, so that a copy of the object isn't made.
713 // base::Bind can't handle 7 args, so we use URLParams and RenderParams. 729 // base::Bind can't handle 7 args, so we use URLParams and RenderParams.
714 BrowserThread::PostTask( 730 BrowserThread::PostTask(
715 BrowserThread::IO, FROM_HERE, 731 BrowserThread::IO, FROM_HERE,
716 base::Bind(&BeginDownload, 732 base::Bind(&BeginDownload,
717 URLParams(url, referrer), save_info, resource_dispatcher_host, 733 URLParams(url, referrer), save_info, resource_dispatcher_host,
718 RenderParams(tab_contents->GetRenderProcessHost()->id(), 734 RenderParams(tab_contents->GetRenderProcessHost()->id(),
719 tab_contents->render_view_host()->routing_id()), 735 tab_contents->render_view_host()->routing_id()),
720 &tab_contents->browser_context()->GetResourceContext())); 736 &tab_contents->browser_context()->GetResourceContext()));
721 } 737 }
722 738
723 void DownloadManager::AddObserver(Observer* observer) { 739 void DownloadManagerImpl::AddObserver(Observer* observer) {
724 observers_.AddObserver(observer); 740 observers_.AddObserver(observer);
725 observer->ModelChanged(); 741 observer->ModelChanged();
726 } 742 }
727 743
728 void DownloadManager::RemoveObserver(Observer* observer) { 744 void DownloadManagerImpl::RemoveObserver(Observer* observer) {
729 observers_.RemoveObserver(observer); 745 observers_.RemoveObserver(observer);
730 } 746 }
731 747
732 bool DownloadManager::IsDownloadProgressKnown() const { 748 bool DownloadManagerImpl::IsDownloadProgressKnown() const {
733 for (DownloadMap::const_iterator i = in_progress_.begin(); 749 for (DownloadMap::const_iterator i = in_progress_.begin();
734 i != in_progress_.end(); ++i) { 750 i != in_progress_.end(); ++i) {
735 if (i->second->total_bytes() <= 0) 751 if (i->second->total_bytes() <= 0)
736 return false; 752 return false;
737 } 753 }
738 754
739 return true; 755 return true;
740 } 756 }
741 757
742 int64 DownloadManager::GetInProgressDownloadCount() const { 758 int64 DownloadManagerImpl::GetInProgressDownloadCount() const {
743 return in_progress_.size(); 759 return in_progress_.size();
744 } 760 }
745 761
746 int64 DownloadManager::GetReceivedDownloadBytes() const { 762 int64 DownloadManagerImpl::GetReceivedDownloadBytes() const {
747 DCHECK(IsDownloadProgressKnown()); 763 DCHECK(IsDownloadProgressKnown());
748 int64 received_bytes = 0; 764 int64 received_bytes = 0;
749 for (DownloadMap::const_iterator i = in_progress_.begin(); 765 for (DownloadMap::const_iterator i = in_progress_.begin();
750 i != in_progress_.end(); ++i) { 766 i != in_progress_.end(); ++i) {
751 received_bytes += i->second->received_bytes(); 767 received_bytes += i->second->received_bytes();
752 } 768 }
753 return received_bytes; 769 return received_bytes;
754 } 770 }
755 771
756 int64 DownloadManager::GetTotalDownloadBytes() const { 772 int64 DownloadManagerImpl::GetTotalDownloadBytes() const {
757 DCHECK(IsDownloadProgressKnown()); 773 DCHECK(IsDownloadProgressKnown());
758 int64 total_bytes = 0; 774 int64 total_bytes = 0;
759 for (DownloadMap::const_iterator i = in_progress_.begin(); 775 for (DownloadMap::const_iterator i = in_progress_.begin();
760 i != in_progress_.end(); ++i) { 776 i != in_progress_.end(); ++i) {
761 total_bytes += i->second->total_bytes(); 777 total_bytes += i->second->total_bytes();
762 } 778 }
763 return total_bytes; 779 return total_bytes;
764 } 780 }
765 781
766 void DownloadManager::FileSelected(const FilePath& path, void* params) { 782 void DownloadManagerImpl::FileSelected(const FilePath& path, void* params) {
767 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 783 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
768 784
769 int32* id_ptr = reinterpret_cast<int32*>(params); 785 int32* id_ptr = reinterpret_cast<int32*>(params);
770 DCHECK(id_ptr != NULL); 786 DCHECK(id_ptr != NULL);
771 int32 download_id = *id_ptr; 787 int32 download_id = *id_ptr;
772 delete id_ptr; 788 delete id_ptr;
773 789
774 DownloadItem* download = GetActiveDownloadItem(download_id); 790 DownloadItem* download = GetActiveDownloadItem(download_id);
775 if (!download) 791 if (!download)
776 return; 792 return;
777 VLOG(20) << __FUNCTION__ << "()" << " path = \"" << path.value() << "\"" 793 VLOG(20) << __FUNCTION__ << "()" << " path = \"" << path.value() << "\""
778 << " download = " << download->DebugString(true); 794 << " download = " << download->DebugString(true);
779 795
780 if (download->prompt_user_for_save_location()) 796 if (download->prompt_user_for_save_location())
781 last_download_path_ = path.DirName(); 797 last_download_path_ = path.DirName();
782 798
783 // Make sure the initial file name is set only once. 799 // Make sure the initial file name is set only once.
784 ContinueDownloadWithPath(download, path); 800 ContinueDownloadWithPath(download, path);
785 } 801 }
786 802
787 void DownloadManager::FileSelectionCanceled(void* params) { 803 void DownloadManagerImpl::FileSelectionCanceled(void* params) {
788 // The user didn't pick a place to save the file, so need to cancel the 804 // The user didn't pick a place to save the file, so need to cancel the
789 // download that's already in progress to the temporary location. 805 // download that's already in progress to the temporary location.
790 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 806 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
791 int32* id_ptr = reinterpret_cast<int32*>(params); 807 int32* id_ptr = reinterpret_cast<int32*>(params);
792 DCHECK(id_ptr != NULL); 808 DCHECK(id_ptr != NULL);
793 int32 download_id = *id_ptr; 809 int32 download_id = *id_ptr;
794 delete id_ptr; 810 delete id_ptr;
795 811
796 DownloadItem* download = GetActiveDownloadItem(download_id); 812 DownloadItem* download = GetActiveDownloadItem(download_id);
797 if (!download) 813 if (!download)
798 return; 814 return;
799 815
800 VLOG(20) << __FUNCTION__ << "()" 816 VLOG(20) << __FUNCTION__ << "()"
801 << " download = " << download->DebugString(true); 817 << " download = " << download->DebugString(true);
802 818
803 // TODO(ahendrickson) -- This currently has no effect, as the download is 819 // TODO(ahendrickson) -- This currently has no effect, as the download is
804 // not put on the active list until the file selection is complete. Need 820 // not put on the active list until the file selection is complete. Need
805 // to put it on the active list earlier in the process. 821 // to put it on the active list earlier in the process.
806 RemoveFromActiveList(download); 822 RemoveFromActiveList(download);
807 823
808 download->OffThreadCancel(file_manager_); 824 download->OffThreadCancel(file_manager_);
809 } 825 }
810 826
811 // Operations posted to us from the history service ---------------------------- 827 // Operations posted to us from the history service ----------------------------
812 828
813 // The history service has retrieved all download entries. 'entries' contains 829 // The history service has retrieved all download entries. 'entries' contains
814 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). 830 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time).
815 void DownloadManager::OnPersistentStoreQueryComplete( 831 void DownloadManagerImpl::OnPersistentStoreQueryComplete(
816 std::vector<DownloadPersistentStoreInfo>* entries) { 832 std::vector<DownloadPersistentStoreInfo>* entries) {
817 // TODO(rdsmith): Remove this and related logic when 833 // TODO(rdsmith): Remove this and related logic when
818 // http://crbug.com/85408 is fixed. 834 // http://crbug.com/85408 is fixed.
819 largest_db_handle_in_history_ = 0; 835 largest_db_handle_in_history_ = 0;
820 836
821 for (size_t i = 0; i < entries->size(); ++i) { 837 for (size_t i = 0; i < entries->size(); ++i) {
822 DownloadItem* download = new DownloadItem(this, entries->at(i)); 838 DownloadItem* download = new DownloadItem(this, entries->at(i));
823 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. 839 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved.
824 CHECK(!ContainsKey(history_downloads_, download->db_handle())); 840 CHECK(!ContainsKey(history_downloads_, download->db_handle()));
825 downloads_.insert(download); 841 downloads_.insert(download);
826 history_downloads_[download->db_handle()] = download; 842 history_downloads_[download->db_handle()] = download;
827 VLOG(20) << __FUNCTION__ << "()" << i << ">" 843 VLOG(20) << __FUNCTION__ << "()" << i << ">"
828 << " download = " << download->DebugString(true); 844 << " download = " << download->DebugString(true);
829 845
830 if (download->db_handle() > largest_db_handle_in_history_) 846 if (download->db_handle() > largest_db_handle_in_history_)
831 largest_db_handle_in_history_ = download->db_handle(); 847 largest_db_handle_in_history_ = download->db_handle();
832 } 848 }
833 NotifyModelChanged(); 849 NotifyModelChanged();
834 CheckForHistoryFilesRemoval(); 850 CheckForHistoryFilesRemoval();
835 } 851 }
836 852
837 void DownloadManager::AddDownloadItemToHistory(DownloadItem* download, 853 void DownloadManagerImpl::AddDownloadItemToHistory(DownloadItem* download,
838 int64 db_handle) { 854 int64 db_handle) {
839 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 855 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
840 856
841 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/85408 857 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/85408
842 // is fixed. 858 // is fixed.
843 CHECK_NE(DownloadItem::kUninitializedHandle, db_handle); 859 CHECK_NE(DownloadItem::kUninitializedHandle, db_handle);
844 860
845 download_stats::RecordHistorySize(history_downloads_.size()); 861 download_stats::RecordHistorySize(history_downloads_.size());
846 862
847 DCHECK(download->db_handle() == DownloadItem::kUninitializedHandle); 863 DCHECK(download->db_handle() == DownloadItem::kUninitializedHandle);
848 download->set_db_handle(db_handle); 864 download->set_db_handle(db_handle);
849 865
850 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/85408 866 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/85408
851 // is fixed. 867 // is fixed.
852 CHECK(!ContainsKey(history_downloads_, download->db_handle())); 868 CHECK(!ContainsKey(history_downloads_, download->db_handle()));
853 history_downloads_[download->db_handle()] = download; 869 history_downloads_[download->db_handle()] = download;
854 870
855 // Show in the appropriate browser UI. 871 // Show in the appropriate browser UI.
856 // This includes buttons to save or cancel, for a dangerous download. 872 // This includes buttons to save or cancel, for a dangerous download.
857 ShowDownloadInBrowser(download); 873 ShowDownloadInBrowser(download);
858 874
859 // Inform interested objects about the new download. 875 // Inform interested objects about the new download.
860 NotifyModelChanged(); 876 NotifyModelChanged();
861 } 877 }
862 878
863 879
864 void DownloadManager::OnItemAddedToPersistentStore(int32 download_id, 880 void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id,
865 int64 db_handle) { 881 int64 db_handle) {
866 if (save_page_downloads_.count(download_id)) { 882 if (save_page_downloads_.count(download_id)) {
867 OnSavePageItemAddedToPersistentStore(download_id, db_handle); 883 OnSavePageItemAddedToPersistentStore(download_id, db_handle);
868 } else if (active_downloads_.count(download_id)) { 884 } else if (active_downloads_.count(download_id)) {
869 OnDownloadItemAddedToPersistentStore(download_id, db_handle); 885 OnDownloadItemAddedToPersistentStore(download_id, db_handle);
870 } 886 }
871 // It's valid that we don't find a matching item, i.e. on shutdown. 887 // It's valid that we don't find a matching item, i.e. on shutdown.
872 } 888 }
873 889
874 // Once the new DownloadItem's creation info has been committed to the history 890 // Once the new DownloadItem's creation info has been committed to the history
875 // service, we associate the DownloadItem with the db handle, update our 891 // service, we associate the DownloadItem with the db handle, update our
876 // 'history_downloads_' map and inform observers. 892 // 'history_downloads_' map and inform observers.
877 void DownloadManager::OnDownloadItemAddedToPersistentStore(int32 download_id, 893 void DownloadManagerImpl::OnDownloadItemAddedToPersistentStore(
878 int64 db_handle) { 894 int32 download_id, int64 db_handle) {
879 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 895 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
880 DownloadItem* download = GetActiveDownloadItem(download_id); 896 DownloadItem* download = GetActiveDownloadItem(download_id);
881 if (!download) 897 if (!download)
882 return; 898 return;
883 899
884 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle 900 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle
885 << " download_id = " << download_id 901 << " download_id = " << download_id
886 << " download = " << download->DebugString(true); 902 << " download = " << download->DebugString(true);
887 903
888 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. 904 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved.
(...skipping 22 matching lines...) Expand all
911 // is fixed. 927 // is fixed.
912 CHECK(download->IsCancelled()) 928 CHECK(download->IsCancelled())
913 << " download = " << download->DebugString(true); 929 << " download = " << download->DebugString(true);
914 in_progress_.erase(download_id); 930 in_progress_.erase(download_id);
915 active_downloads_.erase(download_id); 931 active_downloads_.erase(download_id);
916 delegate_->UpdateItemInPersistentStore(download); 932 delegate_->UpdateItemInPersistentStore(download);
917 download->UpdateObservers(); 933 download->UpdateObservers();
918 } 934 }
919 } 935 }
920 936
921 void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) { 937 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItem* download) {
922 // The 'contents' may no longer exist if the user closed the tab before we 938 // The 'contents' may no longer exist if the user closed the tab before we
923 // get this start completion event. 939 // get this start completion event.
924 TabContents* content = download->GetTabContents(); 940 TabContents* content = download->GetTabContents();
925 941
926 // If the contents no longer exists, we ask the embedder to suggest another 942 // If the contents no longer exists, we ask the embedder to suggest another
927 // tab. 943 // tab.
928 if (!content) 944 if (!content)
929 content = delegate_->GetAlternativeTabContentsToNotifyForDownload(); 945 content = delegate_->GetAlternativeTabContentsToNotifyForDownload();
930 946
931 if (content) 947 if (content)
932 content->OnStartDownload(download); 948 content->OnStartDownload(download);
933 } 949 }
934 950
951 int DownloadManagerImpl::InProgressCount() const {
952 return static_cast<int>(in_progress_.size());
953 }
954
935 // Clears the last download path, used to initialize "save as" dialogs. 955 // Clears the last download path, used to initialize "save as" dialogs.
936 void DownloadManager::ClearLastDownloadPath() { 956 void DownloadManagerImpl::ClearLastDownloadPath() {
937 last_download_path_ = FilePath(); 957 last_download_path_ = FilePath();
938 } 958 }
939 959
940 void DownloadManager::NotifyModelChanged() { 960 void DownloadManagerImpl::NotifyModelChanged() {
941 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged()); 961 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged());
942 } 962 }
943 963
944 DownloadItem* DownloadManager::GetDownloadItem(int download_id) { 964 DownloadItem* DownloadManagerImpl::GetDownloadItem(int download_id) {
945 // The |history_downloads_| map is indexed by the download's db_handle, 965 // The |history_downloads_| map is indexed by the download's db_handle,
946 // not its id, so we have to iterate. 966 // not its id, so we have to iterate.
947 for (DownloadMap::iterator it = history_downloads_.begin(); 967 for (DownloadMap::iterator it = history_downloads_.begin();
948 it != history_downloads_.end(); ++it) { 968 it != history_downloads_.end(); ++it) {
949 DownloadItem* item = it->second; 969 DownloadItem* item = it->second;
950 if (item->id() == download_id) 970 if (item->id() == download_id)
951 return item; 971 return item;
952 } 972 }
953 return NULL; 973 return NULL;
954 } 974 }
955 975
956 DownloadItem* DownloadManager::GetActiveDownloadItem(int download_id) { 976 DownloadItem* DownloadManagerImpl::GetActiveDownloadItem(int download_id) {
957 DCHECK(ContainsKey(active_downloads_, download_id)); 977 DCHECK(ContainsKey(active_downloads_, download_id));
958 DownloadItem* download = active_downloads_[download_id]; 978 DownloadItem* download = active_downloads_[download_id];
959 DCHECK(download != NULL); 979 DCHECK(download != NULL);
960 return download; 980 return download;
961 } 981 }
962 982
963 // Confirm that everything in all maps is also in |downloads_|, and that 983 // Confirm that everything in all maps is also in |downloads_|, and that
964 // everything in |downloads_| is also in some other map. 984 // everything in |downloads_| is also in some other map.
965 void DownloadManager::AssertContainersConsistent() const { 985 void DownloadManagerImpl::AssertContainersConsistent() const {
966 #if !defined(NDEBUG) 986 #if !defined(NDEBUG)
967 // Turn everything into sets. 987 // Turn everything into sets.
968 const DownloadMap* input_maps[] = {&active_downloads_, 988 const DownloadMap* input_maps[] = {&active_downloads_,
969 &history_downloads_, 989 &history_downloads_,
970 &save_page_downloads_}; 990 &save_page_downloads_};
971 DownloadSet active_set, history_set, save_page_set; 991 DownloadSet active_set, history_set, save_page_set;
972 DownloadSet* all_sets[] = {&active_set, &history_set, &save_page_set}; 992 DownloadSet* all_sets[] = {&active_set, &history_set, &save_page_set};
973 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(all_sets)); 993 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(all_sets));
974 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) { 994 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) {
975 for (DownloadMap::const_iterator it = input_maps[i]->begin(); 995 for (DownloadMap::const_iterator it = input_maps[i]->begin();
(...skipping 22 matching lines...) Expand all
998 DownloadSet remainder; 1018 DownloadSet remainder;
999 std::insert_iterator<DownloadSet> 1019 std::insert_iterator<DownloadSet>
1000 insert_remainder(remainder, remainder.begin()); 1020 insert_remainder(remainder, remainder.begin());
1001 std::set_difference(downloads_.begin(), downloads_.end(), 1021 std::set_difference(downloads_.begin(), downloads_.end(),
1002 downloads_union.begin(), downloads_union.end(), 1022 downloads_union.begin(), downloads_union.end(),
1003 insert_remainder); 1023 insert_remainder);
1004 DCHECK(remainder.empty()); 1024 DCHECK(remainder.empty());
1005 #endif 1025 #endif
1006 } 1026 }
1007 1027
1008 void DownloadManager::SavePageDownloadStarted(DownloadItem* download) { 1028 void DownloadManagerImpl::SavePageDownloadStarted(DownloadItem* download) {
1009 DCHECK(!ContainsKey(save_page_downloads_, download->id())); 1029 DCHECK(!ContainsKey(save_page_downloads_, download->id()));
1010 downloads_.insert(download); 1030 downloads_.insert(download);
1011 save_page_downloads_[download->id()] = download; 1031 save_page_downloads_[download->id()] = download;
1012 1032
1013 // Add this entry to the history service. 1033 // Add this entry to the history service.
1014 // Additionally, the UI is notified in the callback. 1034 // Additionally, the UI is notified in the callback.
1015 delegate_->AddItemToPersistentStore(download); 1035 delegate_->AddItemToPersistentStore(download);
1016 } 1036 }
1017 1037
1018 // SavePackage will call SavePageDownloadFinished upon completion/cancellation. 1038 // SavePackage will call SavePageDownloadFinished upon completion/cancellation.
1019 // The history callback will call OnSavePageItemAddedToPersistentStore. 1039 // The history callback will call OnSavePageItemAddedToPersistentStore.
1020 // If the download finishes before the history callback, 1040 // If the download finishes before the history callback,
1021 // OnSavePageItemAddedToPersistentStore calls SavePageDownloadFinished, ensuring 1041 // OnSavePageItemAddedToPersistentStore calls SavePageDownloadFinished, ensuring
1022 // that the history event is update regardless of the order in which these two 1042 // that the history event is update regardless of the order in which these two
1023 // events complete. 1043 // events complete.
1024 // If something removes the download item from the download manager (Remove, 1044 // If something removes the download item from the download manager (Remove,
1025 // Shutdown) the result will be that the SavePage system will not be able to 1045 // Shutdown) the result will be that the SavePage system will not be able to
1026 // properly update the download item (which no longer exists) or the download 1046 // properly update the download item (which no longer exists) or the download
1027 // history, but the action will complete properly anyway. This may lead to the 1047 // history, but the action will complete properly anyway. This may lead to the
1028 // history entry being wrong on a reload of chrome (specifically in the case of 1048 // history entry being wrong on a reload of chrome (specifically in the case of
1029 // Initiation -> History Callback -> Removal -> Completion), but there's no way 1049 // Initiation -> History Callback -> Removal -> Completion), but there's no way
1030 // to solve that without canceling on Remove (which would then update the DB). 1050 // to solve that without canceling on Remove (which would then update the DB).
1031 1051
1032 void DownloadManager::OnSavePageItemAddedToPersistentStore(int32 download_id, 1052 void DownloadManagerImpl::OnSavePageItemAddedToPersistentStore(
1033 int64 db_handle) { 1053 int32 download_id, int64 db_handle) {
1034 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1054 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1035 1055
1036 DownloadMap::const_iterator it = save_page_downloads_.find(download_id); 1056 DownloadMap::const_iterator it = save_page_downloads_.find(download_id);
1037 // This can happen if the download manager is shutting down and all maps 1057 // This can happen if the download manager is shutting down and all maps
1038 // have been cleared. 1058 // have been cleared.
1039 if (it == save_page_downloads_.end()) 1059 if (it == save_page_downloads_.end())
1040 return; 1060 return;
1041 1061
1042 DownloadItem* download = it->second; 1062 DownloadItem* download = it->second;
1043 if (!download) { 1063 if (!download) {
1044 NOTREACHED(); 1064 NOTREACHED();
1045 return; 1065 return;
1046 } 1066 }
1047 1067
1048 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. 1068 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved.
1049 int64 largest_handle = largest_db_handle_in_history_; 1069 int64 largest_handle = largest_db_handle_in_history_;
1050 base::debug::Alias(&largest_handle); 1070 base::debug::Alias(&largest_handle);
1051 CHECK(!ContainsKey(history_downloads_, db_handle)); 1071 CHECK(!ContainsKey(history_downloads_, db_handle));
1052 1072
1053 AddDownloadItemToHistory(download, db_handle); 1073 AddDownloadItemToHistory(download, db_handle);
1054 1074
1055 // Finalize this download if it finished before the history callback. 1075 // Finalize this download if it finished before the history callback.
1056 if (!download->IsInProgress()) 1076 if (!download->IsInProgress())
1057 SavePageDownloadFinished(download); 1077 SavePageDownloadFinished(download);
1058 } 1078 }
1059 1079
1060 void DownloadManager::SavePageDownloadFinished(DownloadItem* download) { 1080 void DownloadManagerImpl::SavePageDownloadFinished(DownloadItem* download) {
1061 if (download->db_handle() != DownloadItem::kUninitializedHandle) { 1081 if (download->db_handle() != DownloadItem::kUninitializedHandle) {
1062 delegate_->UpdateItemInPersistentStore(download); 1082 delegate_->UpdateItemInPersistentStore(download);
1063 DCHECK(ContainsKey(save_page_downloads_, download->id())); 1083 DCHECK(ContainsKey(save_page_downloads_, download->id()));
1064 save_page_downloads_.erase(download->id()); 1084 save_page_downloads_.erase(download->id());
1065 1085
1066 if (download->IsComplete()) 1086 if (download->IsComplete())
1067 content::NotificationService::current()->Notify( 1087 content::NotificationService::current()->Notify(
1068 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, 1088 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
1069 content::Source<DownloadManager>(this), 1089 content::Source<DownloadManager>(this),
1070 content::Details<DownloadItem>(download)); 1090 content::Details<DownloadItem>(download));
1071 } 1091 }
1072 } 1092 }
1073 1093
1074 void DownloadManager::MarkDownloadOpened(DownloadItem* download) { 1094 void DownloadManagerImpl::MarkDownloadOpened(DownloadItem* download) {
1075 delegate_->UpdateItemInPersistentStore(download); 1095 delegate_->UpdateItemInPersistentStore(download);
1076 int num_unopened = 0; 1096 int num_unopened = 0;
1077 for (DownloadMap::iterator it = history_downloads_.begin(); 1097 for (DownloadMap::iterator it = history_downloads_.begin();
1078 it != history_downloads_.end(); ++it) { 1098 it != history_downloads_.end(); ++it) {
1079 if (it->second->IsComplete() && !it->second->opened()) 1099 if (it->second->IsComplete() && !it->second->opened())
1080 ++num_unopened; 1100 ++num_unopened;
1081 } 1101 }
1082 download_stats::RecordOpensOutstanding(num_unopened); 1102 download_stats::RecordOpensOutstanding(num_unopened);
1083 } 1103 }
1104
1105 void DownloadManagerImpl::SetFileManager(DownloadFileManager* file_manager) {
1106 file_manager_ = file_manager;
1107 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698