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

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

Issue 6969009: Reduced the lifetime of DownloadCreateInfo. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged with trunk Created 9 years, 7 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) 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 "chrome/browser/download/download_manager.h" 5 #include "chrome/browser/download/download_manager.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/i18n/case_conversion.h" 9 #include "base/i18n/case_conversion.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/path_service.h" 11 #include "base/path_service.h"
12 #include "base/rand_util.h" 12 #include "base/rand_util.h"
13 #include "base/stl_util-inl.h" 13 #include "base/stl_util-inl.h"
14 #include "base/stringprintf.h" 14 #include "base/stringprintf.h"
15 #include "base/sys_string_conversions.h" 15 #include "base/sys_string_conversions.h"
16 #include "base/task.h" 16 #include "base/task.h"
17 #include "base/utf_string_conversions.h" 17 #include "base/utf_string_conversions.h"
18 #include "build/build_config.h" 18 #include "build/build_config.h"
19 #include "chrome/browser/browser_process.h" 19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/download/download_create_info.h"
20 #include "chrome/browser/download/download_extensions.h" 21 #include "chrome/browser/download/download_extensions.h"
21 #include "chrome/browser/download/download_file_manager.h" 22 #include "chrome/browser/download/download_file_manager.h"
22 #include "chrome/browser/download/download_history.h" 23 #include "chrome/browser/download/download_history.h"
23 #include "chrome/browser/download/download_item.h" 24 #include "chrome/browser/download/download_item.h"
24 #include "chrome/browser/download/download_prefs.h" 25 #include "chrome/browser/download/download_prefs.h"
25 #include "chrome/browser/download/download_process_handle.h" 26 #include "chrome/browser/download/download_process_handle.h"
26 #include "chrome/browser/download/download_safe_browsing_client.h" 27 #include "chrome/browser/download/download_safe_browsing_client.h"
27 #include "chrome/browser/download/download_status_updater.h" 28 #include "chrome/browser/download/download_status_updater.h"
28 #include "chrome/browser/download/download_util.h" 29 #include "chrome/browser/download/download_util.h"
29 #include "chrome/browser/extensions/extension_service.h" 30 #include "chrome/browser/extensions/extension_service.h"
30 #include "chrome/browser/history/download_create_info.h" 31 #include "chrome/browser/history/download_history_info.h"
31 #include "chrome/browser/platform_util.h" 32 #include "chrome/browser/platform_util.h"
32 #include "chrome/browser/profiles/profile.h" 33 #include "chrome/browser/profiles/profile.h"
33 #include "chrome/browser/tab_contents/tab_util.h" 34 #include "chrome/browser/tab_contents/tab_util.h"
34 #include "chrome/browser/ui/browser.h" 35 #include "chrome/browser/ui/browser.h"
35 #include "chrome/browser/ui/browser_list.h" 36 #include "chrome/browser/ui/browser_list.h"
36 #include "chrome/browser/ui/download/download_tab_helper.h" 37 #include "chrome/browser/ui/download/download_tab_helper.h"
37 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 38 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
38 #include "chrome/common/chrome_paths.h" 39 #include "chrome/common/chrome_paths.h"
39 #include "content/browser/browser_thread.h" 40 #include "content/browser/browser_thread.h"
40 #include "content/browser/renderer_host/render_process_host.h" 41 #include "content/browser/renderer_host/render_process_host.h"
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 } 247 }
247 248
248 // We have received a message from DownloadFileManager about a new download. We 249 // We have received a message from DownloadFileManager about a new download. We
249 // create a download item and store it in our download map, and inform the 250 // create a download item and store it in our download map, and inform the
250 // history system of a new download. Since this method can be called while the 251 // history system of a new download. Since this method can be called while the
251 // history service thread is still reading the persistent state, we do not 252 // history service thread is still reading the persistent state, we do not
252 // insert the new DownloadItem into 'history_downloads_' or inform our 253 // insert the new DownloadItem into 'history_downloads_' or inform our
253 // observers at this point. OnCreateDownloadEntryComplete() handles that 254 // observers at this point. OnCreateDownloadEntryComplete() handles that
254 // finalization of the the download creation as a callback from the 255 // finalization of the the download creation as a callback from the
255 // history thread. 256 // history thread.
256 void DownloadManager::StartDownload(DownloadCreateInfo* info) { 257 void DownloadManager::StartDownload(int32 download_id) {
257 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
258 259
260 DownloadItem* download = GetActiveDownloadItem(download_id);
261 if (!download)
262 return;
263
259 // Create a client to verify download URL with safebrowsing. 264 // Create a client to verify download URL with safebrowsing.
260 // It deletes itself after the callback. 265 // It deletes itself after the callback.
261 scoped_refptr<DownloadSBClient> sb_client = new DownloadSBClient( 266 scoped_refptr<DownloadSBClient> sb_client = new DownloadSBClient(
262 info->download_id, info->url_chain, info->referrer_url); 267 download_id, download->url_chain(), download->referrer_url());
263 sb_client->CheckDownloadUrl( 268 sb_client->CheckDownloadUrl(
264 info, NewCallback(this, &DownloadManager::CheckDownloadUrlDone)); 269 NewCallback(this, &DownloadManager::CheckDownloadUrlDone));
265 } 270 }
266 271
267 void DownloadManager::CheckDownloadUrlDone(DownloadCreateInfo* info, 272 void DownloadManager::CheckDownloadUrlDone(int32 download_id,
268 bool is_dangerous_url) { 273 bool is_dangerous_url) {
269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 274 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
270 DCHECK(info);
271 275
272 info->is_dangerous_url = is_dangerous_url; 276 DownloadItem* download = GetActiveDownloadItem(download_id);
277 if (!download)
278 return;
279
280 download->set_dangerous_url(is_dangerous_url);
281
282 DownloadItem::DownloadStateInfo state(*download);
Paweł Hajdan Jr. 2011/05/19 16:18:25 This is strange. DownloadItem has a DownloadStateI
Randy Smith (Not in Mondays) 2011/05/19 17:05:27 This was at my request. I'm ok with having an acc
Paweł Hajdan Jr. 2011/05/19 19:11:24 I'd prefer an accessor that returns a copy then.
ahendrickson 2011/05/19 20:16:49 Done.
273 283
274 // Check whether this download is for an extension install or not. 284 // Check whether this download is for an extension install or not.
275 // Allow extensions to be explicitly saved. 285 // Allow extensions to be explicitly saved.
276 if (!info->prompt_user_for_save_location) { 286 if (!state.prompt_user_for_save_location) {
277 if (UserScript::IsURLUserScript(info->url(), info->mime_type) || 287 if (UserScript::IsURLUserScript(download->url(), download->mime_type()) ||
278 info->mime_type == Extension::kMimeType) { 288 (download->mime_type() == Extension::kMimeType)) {
279 info->is_extension_install = true; 289 state.is_extension_install = true;
280 } 290 }
281 } 291 }
282 292
283 if (info->save_info.file_path.empty()) { 293 if (state.force_file_name.empty()) {
284 FilePath generated_name; 294 FilePath generated_name;
285 download_util::GenerateFileNameFromInfo(info, &generated_name); 295 download_util::GenerateFileNameFromRequest(download->url(),
296 download->content_disposition(),
297 download->referrer_charset(),
298 download->mime_type(),
299 &generated_name);
286 300
287 // Freeze the user's preference for showing a Save As dialog. We're going 301 // Freeze the user's preference for showing a Save As dialog. We're going
288 // to bounce around a bunch of threads and we don't want to worry about race 302 // to bounce around a bunch of threads and we don't want to worry about race
289 // conditions where the user changes this pref out from under us. 303 // conditions where the user changes this pref out from under us.
290 if (download_prefs_->PromptForDownload()) { 304 if (download_prefs_->PromptForDownload()) {
291 // But ignore the user's preference for the following scenarios: 305 // But ignore the user's preference for the following scenarios:
292 // 1) Extension installation. Note that we only care here about the case 306 // 1) Extension installation. Note that we only care here about the case
293 // where an extension is installed, not when one is downloaded with 307 // where an extension is installed, not when one is downloaded with
294 // "save as...". 308 // "save as...".
295 // 2) Filetypes marked "always open." If the user just wants this file 309 // 2) Filetypes marked "always open." If the user just wants this file
296 // opened, don't bother asking where to keep it. 310 // opened, don't bother asking where to keep it.
297 if (!info->is_extension_install && 311 if (!state.is_extension_install &&
298 !ShouldOpenFileBasedOnExtension(generated_name)) 312 !ShouldOpenFileBasedOnExtension(generated_name))
299 info->prompt_user_for_save_location = true; 313 state.prompt_user_for_save_location = true;
300 } 314 }
301 if (download_prefs_->IsDownloadPathManaged()) { 315 if (download_prefs_->IsDownloadPathManaged()) {
302 info->prompt_user_for_save_location = false; 316 state.prompt_user_for_save_location = false;
303 } 317 }
304 318
305 // Determine the proper path for a download, by either one of the following: 319 // Determine the proper path for a download, by either one of the following:
306 // 1) using the default download directory. 320 // 1) using the default download directory.
307 // 2) prompting the user. 321 // 2) prompting the user.
308 if (info->prompt_user_for_save_location && !last_download_path_.empty()) { 322 if (state.prompt_user_for_save_location && !last_download_path_.empty()) {
309 info->suggested_path = last_download_path_; 323 state.suggested_path = last_download_path_;
310 } else { 324 } else {
311 info->suggested_path = download_prefs_->download_path(); 325 state.suggested_path = download_prefs_->download_path();
312 } 326 }
313 info->suggested_path = info->suggested_path.Append(generated_name); 327 state.suggested_path = state.suggested_path.Append(generated_name);
314 } else { 328 } else {
315 info->suggested_path = info->save_info.file_path; 329 state.suggested_path = state.force_file_name;
316 } 330 }
317 331
318 if (!info->prompt_user_for_save_location && 332 if (!state.prompt_user_for_save_location && state.force_file_name.empty()) {
319 info->save_info.file_path.empty()) { 333 state.is_dangerous_file = download_util::IsDangerous(
320 info->is_dangerous_file = download_util::IsDangerous( 334 download->url(),
321 info, profile(), ShouldOpenFileBasedOnExtension(info->suggested_path)); 335 download->referrer_url(),
336 state.suggested_path,
337 state.has_user_gesture,
338 state.is_extension_install,
339 profile(),
340 ShouldOpenFileBasedOnExtension(state.suggested_path));
322 } 341 }
323 342
324 // We need to move over to the download thread because we don't want to stat 343 // We need to move over to the download thread because we don't want to stat
325 // the suggested path on the UI thread. 344 // the suggested path on the UI thread.
326 // We can only access preferences on the UI thread, so check the download path 345 // We can only access preferences on the UI thread, so check the download path
327 // now and pass the value to the FILE thread. 346 // now and pass the value to the FILE thread.
328 BrowserThread::PostTask( 347 BrowserThread::PostTask(
329 BrowserThread::FILE, FROM_HERE, 348 BrowserThread::FILE, FROM_HERE,
330 NewRunnableMethod( 349 NewRunnableMethod(
331 this, 350 this,
332 &DownloadManager::CheckIfSuggestedPathExists, 351 &DownloadManager::CheckIfSuggestedPathExists,
333 info, 352 download_id,
353 state,
334 download_prefs()->download_path())); 354 download_prefs()->download_path()));
335 } 355 }
336 356
337 void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info, 357 void DownloadManager::CheckIfSuggestedPathExists(
338 const FilePath& default_path) { 358 int32 download_id,
359 DownloadItem::DownloadStateInfo state,
360 const FilePath& default_path) {
339 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 361 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
340 DCHECK(info);
341 362
342 // Make sure the default download directory exists. 363 // Make sure the default download directory exists.
343 // TODO(phajdan.jr): only create the directory when we're sure the user 364 // TODO(phajdan.jr): only create the directory when we're sure the user
344 // is going to save there and not to another directory of his choice. 365 // is going to save there and not to another directory of his choice.
345 file_util::CreateDirectory(default_path); 366 file_util::CreateDirectory(default_path);
346 367
347 // Check writability of the suggested path. If we can't write to it, default 368 // Check writability of the suggested path. If we can't write to it, default
348 // to the user's "My Documents" directory. We'll prompt them in this case. 369 // to the user's "My Documents" directory. We'll prompt them in this case.
349 FilePath dir = info->suggested_path.DirName(); 370 FilePath dir = state.suggested_path.DirName();
350 FilePath filename = info->suggested_path.BaseName(); 371 FilePath filename = state.suggested_path.BaseName();
351 if (!file_util::PathIsWritable(dir)) { 372 if (!file_util::PathIsWritable(dir)) {
352 VLOG(1) << "Unable to write to directory \"" << dir.value() << "\""; 373 VLOG(1) << "Unable to write to directory \"" << dir.value() << "\"";
353 info->prompt_user_for_save_location = true; 374 state.prompt_user_for_save_location = true;
354 PathService::Get(chrome::DIR_USER_DOCUMENTS, &info->suggested_path); 375 PathService::Get(chrome::DIR_USER_DOCUMENTS, &state.suggested_path);
355 info->suggested_path = info->suggested_path.Append(filename); 376 state.suggested_path = state.suggested_path.Append(filename);
356 } 377 }
357 378
358 // If the download is deemed dangerous, we'll use a temporary name for it. 379 // If the download is deemed dangerous, we'll use a temporary name for it.
359 if (info->IsDangerous()) { 380 if (state.IsDangerous()) {
360 info->original_name = FilePath(info->suggested_path).BaseName(); 381 state.target_name = FilePath(state.suggested_path).BaseName();
361 // Create a temporary file to hold the file until the user approves its 382 // Create a temporary file to hold the file until the user approves its
362 // download. 383 // download.
363 FilePath::StringType file_name; 384 FilePath::StringType file_name;
364 FilePath path; 385 FilePath path;
365 #if defined(OS_WIN) 386 #if defined(OS_WIN)
366 string16 unconfirmed_prefix = 387 string16 unconfirmed_prefix =
367 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); 388 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX);
368 #else 389 #else
369 std::string unconfirmed_prefix = 390 std::string unconfirmed_prefix =
370 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); 391 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX);
371 #endif 392 #endif
372 393
373 while (path.empty()) { 394 while (path.empty()) {
374 base::SStringPrintf( 395 base::SStringPrintf(
375 &file_name, 396 &file_name,
376 unconfirmed_prefix.append( 397 unconfirmed_prefix.append(
377 FILE_PATH_LITERAL(" %d.crdownload")).c_str(), 398 FILE_PATH_LITERAL(" %d.crdownload")).c_str(),
378 base::RandInt(0, 100000)); 399 base::RandInt(0, 100000));
379 path = dir.Append(file_name); 400 path = dir.Append(file_name);
380 if (file_util::PathExists(path)) 401 if (file_util::PathExists(path))
381 path = FilePath(); 402 path = FilePath();
382 } 403 }
383 info->suggested_path = path; 404 state.suggested_path = path;
384 } else { 405 } else {
385 // Do not add the path uniquifier if we are saving to a specific path as in 406 // Do not add the path uniquifier if we are saving to a specific path as in
386 // the drag-out case. 407 // the drag-out case.
387 if (info->save_info.file_path.empty()) { 408 if (state.force_file_name.empty()) {
388 info->path_uniquifier = download_util::GetUniquePathNumberWithCrDownload( 409 state.path_uniquifier = download_util::GetUniquePathNumberWithCrDownload(
389 info->suggested_path); 410 state.suggested_path);
390 } 411 }
391 // We know the final path, build it if necessary. 412 // We know the final path, build it if necessary.
392 if (info->path_uniquifier > 0) { 413 if (state.path_uniquifier > 0) {
393 download_util::AppendNumberToPath(&(info->suggested_path), 414 download_util::AppendNumberToPath(&(state.suggested_path),
394 info->path_uniquifier); 415 state.path_uniquifier);
395 // Setting path_uniquifier to 0 to make sure we don't try to unique it 416 // Setting path_uniquifier to 0 to make sure we don't try to unique it
396 // later on. 417 // later on.
397 info->path_uniquifier = 0; 418 state.path_uniquifier = 0;
398 } else if (info->path_uniquifier == -1) { 419 } else if (state.path_uniquifier == -1) {
399 // We failed to find a unique path. We have to prompt the user. 420 // We failed to find a unique path. We have to prompt the user.
400 VLOG(1) << "Unable to find a unique path for suggested path \"" 421 VLOG(1) << "Unable to find a unique path for suggested path \""
401 << info->suggested_path.value() << "\""; 422 << state.suggested_path.value() << "\"";
402 info->prompt_user_for_save_location = true; 423 state.prompt_user_for_save_location = true;
403 } 424 }
404 } 425 }
405 426
406 // Create an empty file at the suggested path so that we don't allocate the 427 // Create an empty file at the suggested path so that we don't allocate the
407 // same "non-existant" path to multiple downloads. 428 // same "non-existant" path to multiple downloads.
408 // See: http://code.google.com/p/chromium/issues/detail?id=3662 429 // See: http://code.google.com/p/chromium/issues/detail?id=3662
409 if (!info->prompt_user_for_save_location && 430 if (!state.prompt_user_for_save_location &&
410 info->save_info.file_path.empty()) { 431 state.force_file_name.empty()) {
411 if (info->IsDangerous()) 432 if (state.IsDangerous())
412 file_util::WriteFile(info->suggested_path, "", 0); 433 file_util::WriteFile(state.suggested_path, "", 0);
413 else 434 else
414 file_util::WriteFile(download_util::GetCrDownloadPath( 435 file_util::WriteFile(download_util::GetCrDownloadPath(
415 info->suggested_path), "", 0); 436 state.suggested_path), "", 0);
416 } 437 }
417 438
418 BrowserThread::PostTask( 439 BrowserThread::PostTask(
419 BrowserThread::UI, FROM_HERE, 440 BrowserThread::UI, FROM_HERE,
420 NewRunnableMethod(this, 441 NewRunnableMethod(this,
421 &DownloadManager::OnPathExistenceAvailable, 442 &DownloadManager::OnPathExistenceAvailable,
422 info)); 443 download_id,
444 state));
423 } 445 }
424 446
425 void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) { 447 void DownloadManager::OnPathExistenceAvailable(
426 VLOG(20) << __FUNCTION__ << "()" << " info = " << info->DebugString(); 448 int32 download_id, DownloadItem::DownloadStateInfo new_state) {
427 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 449 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
428 DCHECK(info);
429 450
430 if (info->prompt_user_for_save_location) { 451 DownloadItem* download = GetActiveDownloadItem(download_id);
452 if (!download)
453 return;
454
455 VLOG(20) << __FUNCTION__ << "()"
456 << " download = " << download->DebugString(true);
457
458 download->SetFileCheckResults(new_state);
459
460 DownloadItem::DownloadStateInfo state(*download);
Randy Smith (Not in Mondays) 2011/05/19 17:05:27 At this point, is there any need for another objec
ahendrickson 2011/05/19 20:16:49 I was trying to avoid adding more accessors to Dow
461
462 if (state.prompt_user_for_save_location) {
431 // We must ask the user for the place to put the download. 463 // We must ask the user for the place to put the download.
432 if (!select_file_dialog_.get()) 464 if (!select_file_dialog_.get())
433 select_file_dialog_ = SelectFileDialog::Create(this); 465 select_file_dialog_ = SelectFileDialog::Create(this);
434 466
435 TabContents* contents = info->process_handle.GetTabContents(); 467 DownloadProcessHandle process_handle = download->process_handle();
468 TabContents* contents = process_handle.GetTabContents();
436 SelectFileDialog::FileTypeInfo file_type_info; 469 SelectFileDialog::FileTypeInfo file_type_info;
437 FilePath::StringType extension = info->suggested_path.Extension(); 470 FilePath::StringType extension = state.suggested_path.Extension();
438 if (!extension.empty()) { 471 if (!extension.empty()) {
439 extension.erase(extension.begin()); // drop the . 472 extension.erase(extension.begin()); // drop the .
440 file_type_info.extensions.resize(1); 473 file_type_info.extensions.resize(1);
441 file_type_info.extensions[0].push_back(extension); 474 file_type_info.extensions[0].push_back(extension);
442 } 475 }
443 file_type_info.include_all_files = true; 476 file_type_info.include_all_files = true;
444 gfx::NativeWindow owning_window = 477 gfx::NativeWindow owning_window =
445 contents ? platform_util::GetTopLevel(contents->GetNativeView()) : NULL; 478 contents ? platform_util::GetTopLevel(contents->GetNativeView()) : NULL;
479 // |id_ptr| will be deleted in either FileSelected() or
Paweł Hajdan Jr. 2011/05/19 16:18:25 After thinking more about it - if we're using rein
Randy Smith (Not in Mondays) 2011/05/19 17:05:27 I thought about requesting this, and have no objec
Paweł Hajdan Jr. 2011/05/19 19:11:24 I code-searched the source, and it seems most invo
achuithb 2011/05/19 19:47:36 I think download_manager may be the only case of p
ahendrickson 2011/05/19 20:16:49 I actually tried this first, and got GCC complaint
ahendrickson 2011/05/19 20:16:49 NULL won't work, because we need the download ID i
Paweł Hajdan Jr. 2011/05/20 09:04:42 I see - hm, I think that means the current version
Paweł Hajdan Jr. 2011/05/20 09:04:42 I see, thank you for checking.
480 // FileSelectionCancelled().
481 int32* id_ptr = new int32;
482 *id_ptr = download_id;
446 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE, 483 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE,
447 string16(), 484 string16(),
448 info->suggested_path, 485 state.suggested_path,
449 &file_type_info, 0, FILE_PATH_LITERAL(""), 486 &file_type_info, 0, FILE_PATH_LITERAL(""),
450 contents, owning_window, info); 487 contents, owning_window,
488 reinterpret_cast<void *>(id_ptr));
451 FOR_EACH_OBSERVER(Observer, observers_, 489 FOR_EACH_OBSERVER(Observer, observers_,
452 SelectFileDialogDisplayed(info->download_id)); 490 SelectFileDialogDisplayed(download_id));
453 } else { 491 } else {
454 // No prompting for download, just continue with the suggested name. 492 // No prompting for download, just continue with the suggested name.
455 info->path = info->suggested_path; 493 ContinueDownloadWithPath(download_id, state.suggested_path);
456 AttachDownloadItem(info);
457 } 494 }
458 } 495 }
459 496
460 void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info) { 497 void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info) {
461 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 498 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
462 499
463 DownloadItem* download = new DownloadItem(this, *info, 500 DownloadItem* download = new DownloadItem(this, *info,
464 profile_->IsOffTheRecord()); 501 profile_->IsOffTheRecord());
465 DCHECK(!ContainsKey(in_progress_, info->download_id)); 502 int32 download_id = info->download_id;
466 DCHECK(!ContainsKey(active_downloads_, info->download_id)); 503 DCHECK(!ContainsKey(in_progress_, download_id));
504 DCHECK(!ContainsKey(active_downloads_, download_id));
467 downloads_.insert(download); 505 downloads_.insert(download);
468 active_downloads_[info->download_id] = download; 506 active_downloads_[download_id] = download;
469 } 507 }
470 508
471 void DownloadManager::AttachDownloadItem(DownloadCreateInfo* info) { 509 void DownloadManager::ContinueDownloadWithPath(int32 download_id,
472 VLOG(20) << __FUNCTION__ << "()" << " info = " << info->DebugString(); 510 const FilePath& chosen_file) {
473
474 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 511 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
475 512
476 // Life of |info| ends here. No more references to it after this method.
477 scoped_ptr<DownloadCreateInfo> infop(info);
478
479 // NOTE(ahendrickson) Eventually |active_downloads_| will replace 513 // NOTE(ahendrickson) Eventually |active_downloads_| will replace
480 // |in_progress_|, but we don't want to change the semantics yet. 514 // |in_progress_|, but we don't want to change the semantics yet.
481 DCHECK(!ContainsKey(in_progress_, info->download_id)); 515 DCHECK(!ContainsKey(in_progress_, download_id));
482 DCHECK(ContainsKey(active_downloads_, info->download_id)); 516 DownloadItem* download = GetActiveDownloadItem(download_id);
483 DownloadItem* download = active_downloads_[info->download_id];
484 DCHECK(download != NULL);
485 DCHECK(ContainsKey(downloads_, download)); 517 DCHECK(ContainsKey(downloads_, download));
518 if (!download)
Paweł Hajdan Jr. 2011/05/19 16:18:25 If we return here, the DCHECK above should have fi
Randy Smith (Not in Mondays) 2011/05/19 17:05:27 Both the routines that call ContinueDownloadWithPa
ahendrickson 2011/05/19 20:16:49 Done.
ahendrickson 2011/05/19 20:16:49 Done.
519 return;
486 520
487 download->SetFileCheckResults(info->path, 521 // Make sure the initial file name is set only once.
488 info->is_dangerous_file, 522 DCHECK(download->full_path().empty());
Randy Smith (Not in Mondays) 2011/05/19 17:05:27 Doesn't the drag-n-drop initiation set the full_pa
ahendrickson 2011/05/19 20:16:49 I don't believe so; I think it sets save_info.
489 info->is_dangerous_url, 523 download->set_path(chosen_file);
490 info->path_uniquifier, 524 download->UpdateTarget();
491 info->prompt_user_for_save_location, 525
492 info->is_extension_install, 526 VLOG(20) << __FUNCTION__ << "()"
493 info->original_name); 527 << " download = " << download->DebugString(true);
494 in_progress_[info->download_id] = download; 528
529 in_progress_[download_id] = download;
495 UpdateAppIcon(); // Reflect entry into in_progress_. 530 UpdateAppIcon(); // Reflect entry into in_progress_.
496 531
497 // Rename to intermediate name. 532 // Rename to intermediate name.
498 FilePath download_path; 533 FilePath download_path;
499 if (info->IsDangerous()) { 534 if (download->IsDangerous()) {
500 // The download is not safe. We can now rename the file to its 535 // The download is not safe. We can now rename the file to its
501 // tentative name using RenameInProgressDownloadFile. 536 // tentative name using RenameInProgressDownloadFile.
502 // NOTE: The |Rename| below will be a no-op for dangerous files, as we're 537 // NOTE: The |Rename| below will be a no-op for dangerous files, as we're
503 // renaming it to the same name. 538 // renaming it to the same name.
504 download_path = info->path; 539 download_path = download->full_path();
505 } else { 540 } else {
506 // The download is a safe download. We need to 541 // The download is a safe download. We need to
507 // rename it to its intermediate '.crdownload' path. The final 542 // rename it to its intermediate '.crdownload' path. The final
508 // name after user confirmation will be set from 543 // name after user confirmation will be set from
509 // DownloadItem::OnDownloadCompleting. 544 // DownloadItem::OnDownloadCompleting.
510 download_path = download_util::GetCrDownloadPath(info->path); 545 download_path =
546 download_util::GetCrDownloadPath(download->full_path());
511 } 547 }
512 548
513 BrowserThread::PostTask( 549 BrowserThread::PostTask(
514 BrowserThread::FILE, FROM_HERE, 550 BrowserThread::FILE, FROM_HERE,
515 NewRunnableMethod( 551 NewRunnableMethod(
516 file_manager_, &DownloadFileManager::RenameInProgressDownloadFile, 552 file_manager_, &DownloadFileManager::RenameInProgressDownloadFile,
517 download->id(), download_path)); 553 download->id(), download_path));
518 554
519 download->Rename(download_path); 555 download->Rename(download_path);
520 556
521 download_history_->AddEntry(*info, download, 557 download_history_->AddEntry(download,
522 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete)); 558 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete));
523 } 559 }
524 560
525 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { 561 void DownloadManager::UpdateDownload(int32 download_id, int64 size) {
526 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 562 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
527 DownloadMap::iterator it = active_downloads_.find(download_id); 563 DownloadMap::iterator it = active_downloads_.find(download_id);
528 if (it != active_downloads_.end()) { 564 if (it != active_downloads_.end()) {
529 DownloadItem* download = it->second; 565 DownloadItem* download = it->second;
530 if (download->IsInProgress()) { 566 if (download->IsInProgress()) {
531 download->Update(size); 567 download->Update(size);
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 int os_error) { 761 int os_error) {
726 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 762 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
727 DownloadMap::iterator it = active_downloads_.find(download_id); 763 DownloadMap::iterator it = active_downloads_.find(download_id);
728 // A cancel at the right time could remove the download from the 764 // A cancel at the right time could remove the download from the
729 // |active_downloads_| map before we get here. 765 // |active_downloads_| map before we get here.
730 if (it == active_downloads_.end()) 766 if (it == active_downloads_.end())
731 return; 767 return;
732 768
733 DownloadItem* download = it->second; 769 DownloadItem* download = it->second;
734 770
735 VLOG(20) << "Error " << os_error << " at offset " 771 VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error
736 << download->received_bytes() << " for download = " 772 << " at offset " << download->received_bytes()
737 << download->DebugString(true); 773 << " for download = " << download->DebugString(true);
774
775 download->Interrupted(size, os_error);
738 776
739 // TODO(ahendrickson) - Remove this when we add resuming of interrupted 777 // TODO(ahendrickson) - Remove this when we add resuming of interrupted
740 // downloads, as we will keep the download item around in that case. 778 // downloads, as we will keep the download item around in that case.
741 // 779 //
742 // Clean up will happen when the history system create callback runs if we 780 // Clean up will happen when the history system create callback runs if we
743 // don't have a valid db_handle yet. 781 // don't have a valid db_handle yet.
744 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { 782 if (download->db_handle() != DownloadHistory::kUninitializedHandle) {
745 in_progress_.erase(download_id); 783 in_progress_.erase(download_id);
746 active_downloads_.erase(download_id); 784 active_downloads_.erase(download_id);
747 UpdateAppIcon(); // Reflect removal from in_progress_. 785 UpdateAppIcon(); // Reflect removal from in_progress_.
748 download_history_->UpdateEntry(download); 786 download_history_->UpdateEntry(download);
749 } 787 }
750 788
751 download->Interrupted(size, os_error);
752
753 BrowserThread::PostTask( 789 BrowserThread::PostTask(
754 BrowserThread::FILE, FROM_HERE, 790 BrowserThread::FILE, FROM_HERE,
755 NewRunnableMethod( 791 NewRunnableMethod(
756 file_manager_, &DownloadFileManager::CancelDownload, download_id)); 792 file_manager_, &DownloadFileManager::CancelDownload, download_id));
757 } 793 }
758 794
759 void DownloadManager::PauseDownload(int32 download_id, bool pause) { 795 void DownloadManager::PauseDownload(int32 download_id, bool pause) {
760 DownloadMap::iterator it = in_progress_.find(download_id); 796 DownloadMap::iterator it = in_progress_.find(download_id);
761 if (it == in_progress_.end()) 797 if (it == in_progress_.end())
762 return; 798 return;
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 int64 total_bytes = 0; 995 int64 total_bytes = 0;
960 for (DownloadMap::iterator i = in_progress_.begin(); 996 for (DownloadMap::iterator i = in_progress_.begin();
961 i != in_progress_.end(); ++i) { 997 i != in_progress_.end(); ++i) {
962 total_bytes += i->second->total_bytes(); 998 total_bytes += i->second->total_bytes();
963 } 999 }
964 return total_bytes; 1000 return total_bytes;
965 } 1001 }
966 1002
967 void DownloadManager::FileSelected(const FilePath& path, 1003 void DownloadManager::FileSelected(const FilePath& path,
968 int index, void* params) { 1004 int index, void* params) {
969 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); 1005 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
970 if (info->prompt_user_for_save_location) 1006
1007 int32* id_ptr = reinterpret_cast<int32 *>(params);
1008 DCHECK(id_ptr != NULL);
1009 int32 download_id = *id_ptr;
1010 delete id_ptr;
1011 DCHECK_EQ(index, download_id);
Randy Smith (Not in Mondays) 2011/05/19 17:05:27 Why are we expecting the index and the download_id
ahendrickson 2011/05/19 20:16:49 Oops, my bad. I was confusing it with the history
1012
1013 DownloadItem* download = GetActiveDownloadItem(download_id);
1014 if (!download)
1015 return;
1016 VLOG(20) << __FUNCTION__ << "()" << " path = \"" << path.value() << "\""
1017 << " download = " << download->DebugString(true);
1018
1019 if (download->save_as())
971 last_download_path_ = path.DirName(); 1020 last_download_path_ = path.DirName();
972 1021
973 info->path = path; 1022 // Make sure the initial file name is set only once.
974 AttachDownloadItem(info); 1023 ContinueDownloadWithPath(download_id, path);
975 } 1024 }
976 1025
977 void DownloadManager::FileSelectionCanceled(void* params) { 1026 void DownloadManager::FileSelectionCanceled(void* params) {
978 // The user didn't pick a place to save the file, so need to cancel the 1027 // The user didn't pick a place to save the file, so need to cancel the
979 // download that's already in progress to the temporary location. 1028 // download that's already in progress to the temporary location.
980 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); 1029 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
981 DownloadCancelledInternal(info->download_id, info->process_handle); 1030 int32* id_ptr = reinterpret_cast<int32 *>(params);
1031 DCHECK(id_ptr != NULL);
1032 int32 download_id = *id_ptr;
1033 delete id_ptr;
1034
1035 DownloadItem* download = GetActiveDownloadItem(download_id);
1036 if (!download)
1037 return;
1038
1039 VLOG(20) << __FUNCTION__ << "()"
1040 << " download = " << download->DebugString(true);
1041
1042 DownloadCancelledInternal(download_id, download->process_handle());
982 } 1043 }
983 1044
984 void DownloadManager::DangerousDownloadValidated(DownloadItem* download) { 1045 void DownloadManager::DangerousDownloadValidated(DownloadItem* download) {
985 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1046 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
986 DCHECK_EQ(DownloadItem::DANGEROUS, download->safety_state()); 1047 DCHECK_EQ(DownloadItem::DANGEROUS, download->safety_state());
987 download->set_safety_state(DownloadItem::DANGEROUS_BUT_VALIDATED); 1048 download->set_safety_state(DownloadItem::DANGEROUS_BUT_VALIDATED);
988 download->UpdateObservers(); 1049 download->UpdateObservers();
989 1050
990 MaybeCompleteDownload(download); 1051 MaybeCompleteDownload(download);
991 } 1052 }
992 1053
993 // Operations posted to us from the history service ---------------------------- 1054 // Operations posted to us from the history service ----------------------------
994 1055
995 // The history service has retrieved all download entries. 'entries' contains 1056 // The history service has retrieved all download entries. 'entries' contains
996 // 'DownloadCreateInfo's in sorted order (by ascending start_time). 1057 // 'DownloadHistoryInfo's in sorted order (by ascending start_time).
997 void DownloadManager::OnQueryDownloadEntriesComplete( 1058 void DownloadManager::OnQueryDownloadEntriesComplete(
998 std::vector<DownloadCreateInfo>* entries) { 1059 std::vector<DownloadHistoryInfo>* entries) {
999 for (size_t i = 0; i < entries->size(); ++i) { 1060 for (size_t i = 0; i < entries->size(); ++i) {
1000 DownloadItem* download = new DownloadItem(this, entries->at(i)); 1061 DownloadItem* download = new DownloadItem(this, entries->at(i));
1001 DCHECK(!ContainsKey(history_downloads_, download->db_handle())); 1062 DCHECK(!ContainsKey(history_downloads_, download->db_handle()));
1002 downloads_.insert(download); 1063 downloads_.insert(download);
1003 history_downloads_[download->db_handle()] = download; 1064 history_downloads_[download->db_handle()] = download;
1004 VLOG(20) << __FUNCTION__ << "()" << i << ">" 1065 VLOG(20) << __FUNCTION__ << "()" << i << ">"
1005 << " download = " << download->DebugString(true); 1066 << " download = " << download->DebugString(true);
1006 } 1067 }
1007 NotifyModelChanged(); 1068 NotifyModelChanged();
1008 } 1069 }
1009 1070
1010 // Once the new DownloadItem's creation info has been committed to the history 1071 // Once the new DownloadItem's creation info has been committed to the history
1011 // service, we associate the DownloadItem with the db handle, update our 1072 // service, we associate the DownloadItem with the db handle, update our
1012 // 'history_downloads_' map and inform observers. 1073 // 'history_downloads_' map and inform observers.
1013 void DownloadManager::OnCreateDownloadEntryComplete( 1074 void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id,
1014 DownloadCreateInfo info, 1075 int64 db_handle) {
1015 int64 db_handle) {
1016 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1076 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1017 DownloadMap::iterator it = in_progress_.find(info.download_id); 1077 DownloadItem* download = GetActiveDownloadItem(download_id);
1018 DCHECK(it != in_progress_.end()); 1078 if (!download)
1079 return;
1019 1080
1020 DownloadItem* download = it->second;
1021 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle 1081 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle
1022 << " download_id = " << info.download_id 1082 << " download_id = " << download_id
1023 << " download = " << download->DebugString(true); 1083 << " download = " << download->DebugString(true);
1024 1084
1025 // It's not immediately obvious, but HistoryBackend::CreateDownload() can 1085 // It's not immediately obvious, but HistoryBackend::CreateDownload() can
1026 // call this function with an invalid |db_handle|. For instance, this can 1086 // call this function with an invalid |db_handle|. For instance, this can
1027 // happen when the history database is offline. We cannot have multiple 1087 // happen when the history database is offline. We cannot have multiple
1028 // DownloadItems with the same invalid db_handle, so we need to assign a 1088 // DownloadItems with the same invalid db_handle, so we need to assign a
1029 // unique |db_handle| here. 1089 // unique |db_handle| here.
1030 if (db_handle == DownloadHistory::kUninitializedHandle) 1090 if (db_handle == DownloadHistory::kUninitializedHandle)
1031 db_handle = download_history_->GetNextFakeDbHandle(); 1091 db_handle = download_history_->GetNextFakeDbHandle();
1032 1092
1033 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle); 1093 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle);
1034 download->set_db_handle(db_handle); 1094 download->set_db_handle(db_handle);
1035 1095
1036 DCHECK(!ContainsKey(history_downloads_, download->db_handle())); 1096 DCHECK(!ContainsKey(history_downloads_, download->db_handle()));
1037 history_downloads_[download->db_handle()] = download; 1097 history_downloads_[download->db_handle()] = download;
1038 1098
1039 // Show in the appropriate browser UI. 1099 // Show in the appropriate browser UI.
1040 // This includes buttons to save or cancel, for a dangerous download. 1100 // This includes buttons to save or cancel, for a dangerous download.
1041 ShowDownloadInBrowser(&info.process_handle, download); 1101 ShowDownloadInBrowser(download);
1042 1102
1043 // Inform interested objects about the new download. 1103 // Inform interested objects about the new download.
1044 NotifyModelChanged(); 1104 NotifyModelChanged();
1045 1105
1046 // If the download is still in progress, try to complete it. 1106 // If the download is still in progress, try to complete it.
1047 // 1107 //
1048 // Otherwise, download has been cancelled or interrupted before we've 1108 // Otherwise, download has been cancelled or interrupted before we've
1049 // received the DB handle. We post one final message to the history 1109 // received the DB handle. We post one final message to the history
1050 // service so that it can be properly in sync with the DownloadItem's 1110 // service so that it can be properly in sync with the DownloadItem's
1051 // completion status, and also inform any observers so that they get 1111 // completion status, and also inform any observers so that they get
1052 // more than just the start notification. 1112 // more than just the start notification.
1053 if (download->IsInProgress()) { 1113 if (download->IsInProgress()) {
1054 MaybeCompleteDownload(download); 1114 MaybeCompleteDownload(download);
1055 } else { 1115 } else {
1056 DCHECK(download->IsCancelled()) 1116 DCHECK(download->IsCancelled())
1057 << " download = " << download->DebugString(true); 1117 << " download = " << download->DebugString(true);
1058 in_progress_.erase(it); 1118 in_progress_.erase(download_id);
1059 active_downloads_.erase(info.download_id); 1119 active_downloads_.erase(download_id);
1060 download_history_->UpdateEntry(download); 1120 download_history_->UpdateEntry(download);
1061 download->UpdateObservers(); 1121 download->UpdateObservers();
1062 } 1122 }
1063 } 1123 }
1064 1124
1065 void DownloadManager::ShowDownloadInBrowser( 1125 void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) {
1066 DownloadProcessHandle* process_handle, DownloadItem* download) {
1067 if (!process_handle)
1068 return;
1069 1126
1070 // The 'contents' may no longer exist if the user closed the tab before we 1127 // The 'contents' may no longer exist if the user closed the tab before we
1071 // get this start completion event. If it does, tell the origin TabContents 1128 // get this start completion event. If it does, tell the origin TabContents
1072 // to display its download shelf. 1129 // to display its download shelf.
1073 TabContents* contents = process_handle->GetTabContents(); 1130 DownloadProcessHandle process_handle = download->process_handle();
1131 TabContents* contents = process_handle.GetTabContents();
1074 TabContentsWrapper* wrapper = NULL; 1132 TabContentsWrapper* wrapper = NULL;
1075 if (contents) 1133 if (contents)
1076 wrapper = TabContentsWrapper::GetCurrentWrapperForContents(contents); 1134 wrapper = TabContentsWrapper::GetCurrentWrapperForContents(contents);
1077 1135
1078 // If the contents no longer exists, we start the download in the last active 1136 // If the contents no longer exists, we start the download in the last active
1079 // browser. This is not ideal but better than fully hiding the download from 1137 // browser. This is not ideal but better than fully hiding the download from
1080 // the user. 1138 // the user.
1081 if (!wrapper) { 1139 if (!wrapper) {
1082 Browser* last_active = BrowserList::GetLastActive(); 1140 Browser* last_active = BrowserList::GetLastActive();
1083 if (last_active) 1141 if (last_active)
1084 wrapper = last_active->GetSelectedTabContentsWrapper(); 1142 wrapper = last_active->GetSelectedTabContentsWrapper();
1085 } 1143 }
1086 1144
1087 if (!wrapper) 1145 if (!wrapper)
1088 return; 1146 return;
1089 1147
1090 wrapper->download_tab_helper()->OnStartDownload(download); 1148 wrapper->download_tab_helper()->OnStartDownload(download);
1091 } 1149 }
1092 1150
1093 // Clears the last download path, used to initialize "save as" dialogs. 1151 // Clears the last download path, used to initialize "save as" dialogs.
1094 void DownloadManager::ClearLastDownloadPath() { 1152 void DownloadManager::ClearLastDownloadPath() {
1095 last_download_path_ = FilePath(); 1153 last_download_path_ = FilePath();
1096 } 1154 }
1097 1155
1098 void DownloadManager::NotifyModelChanged() { 1156 void DownloadManager::NotifyModelChanged() {
1099 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged()); 1157 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged());
1100 } 1158 }
1101 1159
1102 DownloadItem* DownloadManager::GetDownloadItem(int id) { 1160 DownloadItem* DownloadManager::GetDownloadItem(int download_id) {
1103 for (DownloadMap::iterator it = history_downloads_.begin(); 1161 for (DownloadMap::iterator it = history_downloads_.begin();
1104 it != history_downloads_.end(); ++it) { 1162 it != history_downloads_.end(); ++it) {
1105 DownloadItem* item = it->second; 1163 DownloadItem* item = it->second;
1106 if (item->id() == id) 1164 if (item->id() == download_id)
1107 return item; 1165 return item;
1108 } 1166 }
1109 return NULL; 1167 return NULL;
1110 } 1168 }
1111 1169
1170 DownloadItem* DownloadManager::GetActiveDownloadItem(int download_id) {
1171 DCHECK(ContainsKey(active_downloads_, download_id));
Paweł Hajdan Jr. 2011/05/19 16:18:25 Is it possible to make GetDownloadItem and GetActi
ahendrickson 2011/05/19 20:16:49 I don't think so, because |history_downloads_| is
Paweł Hajdan Jr. 2011/05/20 09:04:42 Ah, I see. Could you add a comment (probably in Ge
ahendrickson 2011/05/20 18:31:24 Done.
Randy Smith (Not in Mondays) 2011/05/20 19:49:29 Sorry to keep this thread going, but my scan of th
ahendrickson 2011/05/20 22:12:44 It's used in download_manager_unittest.cc, after t
1172 DownloadItem* download = active_downloads_[download_id];
1173 DCHECK(download != NULL);
1174 return download;
1175 }
1176
1112 // Confirm that everything in all maps is also in |downloads_|, and that 1177 // Confirm that everything in all maps is also in |downloads_|, and that
1113 // everything in |downloads_| is also in some other map. 1178 // everything in |downloads_| is also in some other map.
1114 void DownloadManager::AssertContainersConsistent() const { 1179 void DownloadManager::AssertContainersConsistent() const {
1115 #if !defined(NDEBUG) 1180 #if !defined(NDEBUG)
1116 // Turn everything into sets. 1181 // Turn everything into sets.
1117 DownloadSet active_set, history_set; 1182 DownloadSet active_set, history_set;
1118 const DownloadMap* input_maps[] = {&active_downloads_, &history_downloads_}; 1183 const DownloadMap* input_maps[] = {&active_downloads_, &history_downloads_};
1119 DownloadSet* local_sets[] = {&active_set, &history_set}; 1184 DownloadSet* local_sets[] = {&active_set, &history_set};
1120 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(local_sets)); 1185 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(local_sets));
1121 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) { 1186 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 observed_download_manager_->RemoveObserver(this); 1240 observed_download_manager_->RemoveObserver(this);
1176 } 1241 }
1177 1242
1178 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { 1243 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() {
1179 observing_download_manager_->NotifyModelChanged(); 1244 observing_download_manager_->NotifyModelChanged();
1180 } 1245 }
1181 1246
1182 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { 1247 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() {
1183 observed_download_manager_ = NULL; 1248 observed_download_manager_ = NULL;
1184 } 1249 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698