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

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: Stupid clang! 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 if (is_dangerous_url)
281 download->MarkUrlDangerous();
282
283 DownloadStateInfo state = download->state_info();
273 284
274 // Check whether this download is for an extension install or not. 285 // Check whether this download is for an extension install or not.
275 // Allow extensions to be explicitly saved. 286 // Allow extensions to be explicitly saved.
276 if (!info->prompt_user_for_save_location) { 287 if (!state.prompt_user_for_save_location) {
277 if (UserScript::IsURLUserScript(info->url(), info->mime_type) || 288 if (UserScript::IsURLUserScript(download->GetURL(),
278 info->mime_type == Extension::kMimeType) { 289 download->mime_type()) ||
279 info->is_extension_install = true; 290 (download->mime_type() == Extension::kMimeType)) {
291 state.is_extension_install = true;
280 } 292 }
281 } 293 }
282 294
283 if (info->save_info.file_path.empty()) { 295 if (state.force_file_name.empty()) {
284 FilePath generated_name; 296 FilePath generated_name;
285 download_util::GenerateFileNameFromInfo(info, &generated_name); 297 download_util::GenerateFileNameFromRequest(download->GetURL(),
298 download->content_disposition(),
299 download->referrer_charset(),
300 download->mime_type(),
301 &generated_name);
286 302
287 // Freeze the user's preference for showing a Save As dialog. We're going 303 // 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 304 // 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. 305 // conditions where the user changes this pref out from under us.
290 if (download_prefs_->PromptForDownload()) { 306 if (download_prefs_->PromptForDownload()) {
291 // But ignore the user's preference for the following scenarios: 307 // But ignore the user's preference for the following scenarios:
292 // 1) Extension installation. Note that we only care here about the case 308 // 1) Extension installation. Note that we only care here about the case
293 // where an extension is installed, not when one is downloaded with 309 // where an extension is installed, not when one is downloaded with
294 // "save as...". 310 // "save as...".
295 // 2) Filetypes marked "always open." If the user just wants this file 311 // 2) Filetypes marked "always open." If the user just wants this file
296 // opened, don't bother asking where to keep it. 312 // opened, don't bother asking where to keep it.
297 if (!info->is_extension_install && 313 if (!state.is_extension_install &&
298 !ShouldOpenFileBasedOnExtension(generated_name)) 314 !ShouldOpenFileBasedOnExtension(generated_name))
299 info->prompt_user_for_save_location = true; 315 state.prompt_user_for_save_location = true;
300 } 316 }
301 if (download_prefs_->IsDownloadPathManaged()) { 317 if (download_prefs_->IsDownloadPathManaged()) {
302 info->prompt_user_for_save_location = false; 318 state.prompt_user_for_save_location = false;
303 } 319 }
304 320
305 // Determine the proper path for a download, by either one of the following: 321 // Determine the proper path for a download, by either one of the following:
306 // 1) using the default download directory. 322 // 1) using the default download directory.
307 // 2) prompting the user. 323 // 2) prompting the user.
308 if (info->prompt_user_for_save_location && !last_download_path_.empty()) { 324 if (state.prompt_user_for_save_location && !last_download_path_.empty()) {
309 info->suggested_path = last_download_path_; 325 state.suggested_path = last_download_path_;
310 } else { 326 } else {
311 info->suggested_path = download_prefs_->download_path(); 327 state.suggested_path = download_prefs_->download_path();
312 } 328 }
313 info->suggested_path = info->suggested_path.Append(generated_name); 329 state.suggested_path = state.suggested_path.Append(generated_name);
314 } else { 330 } else {
315 info->suggested_path = info->save_info.file_path; 331 state.suggested_path = state.force_file_name;
316 } 332 }
317 333
318 if (!info->prompt_user_for_save_location && 334 if (!state.prompt_user_for_save_location && state.force_file_name.empty())
319 info->save_info.file_path.empty()) { 335 state.is_dangerous_file = IsDangerous(*download, state);
320 info->is_dangerous_file = download_util::IsDangerous(
321 info, profile(), ShouldOpenFileBasedOnExtension(info->suggested_path));
322 }
323 336
324 // We need to move over to the download thread because we don't want to stat 337 // We need to move over to the download thread because we don't want to stat
325 // the suggested path on the UI thread. 338 // the suggested path on the UI thread.
326 // We can only access preferences on the UI thread, so check the download path 339 // We can only access preferences on the UI thread, so check the download path
327 // now and pass the value to the FILE thread. 340 // now and pass the value to the FILE thread.
328 BrowserThread::PostTask( 341 BrowserThread::PostTask(
329 BrowserThread::FILE, FROM_HERE, 342 BrowserThread::FILE, FROM_HERE,
330 NewRunnableMethod( 343 NewRunnableMethod(
331 this, 344 this,
332 &DownloadManager::CheckIfSuggestedPathExists, 345 &DownloadManager::CheckIfSuggestedPathExists,
333 info, 346 download_id,
347 state,
334 download_prefs()->download_path())); 348 download_prefs()->download_path()));
335 } 349 }
336 350
337 void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info, 351 void DownloadManager::CheckIfSuggestedPathExists(int32 download_id,
352 DownloadStateInfo state,
338 const FilePath& default_path) { 353 const FilePath& default_path) {
339 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 354 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
340 DCHECK(info);
341 355
342 // Make sure the default download directory exists. 356 // Make sure the default download directory exists.
343 // TODO(phajdan.jr): only create the directory when we're sure the user 357 // 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. 358 // is going to save there and not to another directory of his choice.
345 file_util::CreateDirectory(default_path); 359 file_util::CreateDirectory(default_path);
346 360
347 // Check writability of the suggested path. If we can't write to it, default 361 // 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. 362 // to the user's "My Documents" directory. We'll prompt them in this case.
349 FilePath dir = info->suggested_path.DirName(); 363 FilePath dir = state.suggested_path.DirName();
350 FilePath filename = info->suggested_path.BaseName(); 364 FilePath filename = state.suggested_path.BaseName();
351 if (!file_util::PathIsWritable(dir)) { 365 if (!file_util::PathIsWritable(dir)) {
352 VLOG(1) << "Unable to write to directory \"" << dir.value() << "\""; 366 VLOG(1) << "Unable to write to directory \"" << dir.value() << "\"";
353 info->prompt_user_for_save_location = true; 367 state.prompt_user_for_save_location = true;
354 PathService::Get(chrome::DIR_USER_DOCUMENTS, &info->suggested_path); 368 PathService::Get(chrome::DIR_USER_DOCUMENTS, &state.suggested_path);
355 info->suggested_path = info->suggested_path.Append(filename); 369 state.suggested_path = state.suggested_path.Append(filename);
356 } 370 }
357 371
358 // If the download is deemed dangerous, we'll use a temporary name for it. 372 // If the download is deemed dangerous, we'll use a temporary name for it.
359 if (info->IsDangerous()) { 373 if (state.IsDangerous()) {
360 info->original_name = FilePath(info->suggested_path).BaseName(); 374 state.target_name = FilePath(state.suggested_path).BaseName();
361 // Create a temporary file to hold the file until the user approves its 375 // Create a temporary file to hold the file until the user approves its
362 // download. 376 // download.
363 FilePath::StringType file_name; 377 FilePath::StringType file_name;
364 FilePath path; 378 FilePath path;
365 #if defined(OS_WIN) 379 #if defined(OS_WIN)
366 string16 unconfirmed_prefix = 380 string16 unconfirmed_prefix =
367 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); 381 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX);
368 #else 382 #else
369 std::string unconfirmed_prefix = 383 std::string unconfirmed_prefix =
370 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); 384 l10n_util::GetStringUTF8(IDS_DOWNLOAD_UNCONFIRMED_PREFIX);
371 #endif 385 #endif
372 386
373 while (path.empty()) { 387 while (path.empty()) {
374 base::SStringPrintf( 388 base::SStringPrintf(
375 &file_name, 389 &file_name,
376 unconfirmed_prefix.append( 390 unconfirmed_prefix.append(
377 FILE_PATH_LITERAL(" %d.crdownload")).c_str(), 391 FILE_PATH_LITERAL(" %d.crdownload")).c_str(),
378 base::RandInt(0, 100000)); 392 base::RandInt(0, 100000));
379 path = dir.Append(file_name); 393 path = dir.Append(file_name);
380 if (file_util::PathExists(path)) 394 if (file_util::PathExists(path))
381 path = FilePath(); 395 path = FilePath();
382 } 396 }
383 info->suggested_path = path; 397 state.suggested_path = path;
384 } else { 398 } else {
385 // Do not add the path uniquifier if we are saving to a specific path as in 399 // Do not add the path uniquifier if we are saving to a specific path as in
386 // the drag-out case. 400 // the drag-out case.
387 if (info->save_info.file_path.empty()) { 401 if (state.force_file_name.empty()) {
388 info->path_uniquifier = download_util::GetUniquePathNumberWithCrDownload( 402 state.path_uniquifier = download_util::GetUniquePathNumberWithCrDownload(
389 info->suggested_path); 403 state.suggested_path);
390 } 404 }
391 // We know the final path, build it if necessary. 405 // We know the final path, build it if necessary.
392 if (info->path_uniquifier > 0) { 406 if (state.path_uniquifier > 0) {
393 download_util::AppendNumberToPath(&(info->suggested_path), 407 download_util::AppendNumberToPath(&(state.suggested_path),
394 info->path_uniquifier); 408 state.path_uniquifier);
395 // Setting path_uniquifier to 0 to make sure we don't try to unique it 409 // Setting path_uniquifier to 0 to make sure we don't try to unique it
396 // later on. 410 // later on.
397 info->path_uniquifier = 0; 411 state.path_uniquifier = 0;
398 } else if (info->path_uniquifier == -1) { 412 } else if (state.path_uniquifier == -1) {
399 // We failed to find a unique path. We have to prompt the user. 413 // 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 \"" 414 VLOG(1) << "Unable to find a unique path for suggested path \""
401 << info->suggested_path.value() << "\""; 415 << state.suggested_path.value() << "\"";
402 info->prompt_user_for_save_location = true; 416 state.prompt_user_for_save_location = true;
403 } 417 }
404 } 418 }
405 419
406 // Create an empty file at the suggested path so that we don't allocate the 420 // Create an empty file at the suggested path so that we don't allocate the
407 // same "non-existant" path to multiple downloads. 421 // same "non-existant" path to multiple downloads.
408 // See: http://code.google.com/p/chromium/issues/detail?id=3662 422 // See: http://code.google.com/p/chromium/issues/detail?id=3662
409 if (!info->prompt_user_for_save_location && 423 if (!state.prompt_user_for_save_location &&
410 info->save_info.file_path.empty()) { 424 state.force_file_name.empty()) {
411 if (info->IsDangerous()) 425 if (state.IsDangerous())
412 file_util::WriteFile(info->suggested_path, "", 0); 426 file_util::WriteFile(state.suggested_path, "", 0);
413 else 427 else
414 file_util::WriteFile(download_util::GetCrDownloadPath( 428 file_util::WriteFile(download_util::GetCrDownloadPath(
415 info->suggested_path), "", 0); 429 state.suggested_path), "", 0);
416 } 430 }
417 431
418 BrowserThread::PostTask( 432 BrowserThread::PostTask(
419 BrowserThread::UI, FROM_HERE, 433 BrowserThread::UI, FROM_HERE,
420 NewRunnableMethod(this, 434 NewRunnableMethod(this,
421 &DownloadManager::OnPathExistenceAvailable, 435 &DownloadManager::OnPathExistenceAvailable,
422 info)); 436 download_id,
437 state));
423 } 438 }
424 439
425 void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) { 440 void DownloadManager::OnPathExistenceAvailable(
426 VLOG(20) << __FUNCTION__ << "()" << " info = " << info->DebugString(); 441 int32 download_id, DownloadStateInfo new_state) {
427 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 442 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
428 DCHECK(info);
429 443
430 if (info->prompt_user_for_save_location) { 444 DownloadItem* download = GetActiveDownloadItem(download_id);
445 if (!download)
446 return;
447
448 VLOG(20) << __FUNCTION__ << "()"
449 << " download = " << download->DebugString(true);
450
451 download->SetFileCheckResults(new_state);
452
453 FilePath suggested_path = download->suggested_path();
454
455 if (download->save_as()) {
431 // We must ask the user for the place to put the download. 456 // We must ask the user for the place to put the download.
432 if (!select_file_dialog_.get()) 457 if (!select_file_dialog_.get())
433 select_file_dialog_ = SelectFileDialog::Create(this); 458 select_file_dialog_ = SelectFileDialog::Create(this);
434 459
435 TabContents* contents = info->process_handle.GetTabContents(); 460 DownloadProcessHandle process_handle = download->process_handle();
461 TabContents* contents = process_handle.GetTabContents();
436 SelectFileDialog::FileTypeInfo file_type_info; 462 SelectFileDialog::FileTypeInfo file_type_info;
437 FilePath::StringType extension = info->suggested_path.Extension(); 463 FilePath::StringType extension = suggested_path.Extension();
438 if (!extension.empty()) { 464 if (!extension.empty()) {
439 extension.erase(extension.begin()); // drop the . 465 extension.erase(extension.begin()); // drop the .
440 file_type_info.extensions.resize(1); 466 file_type_info.extensions.resize(1);
441 file_type_info.extensions[0].push_back(extension); 467 file_type_info.extensions[0].push_back(extension);
442 } 468 }
443 file_type_info.include_all_files = true; 469 file_type_info.include_all_files = true;
444 gfx::NativeWindow owning_window = 470 gfx::NativeWindow owning_window =
445 contents ? platform_util::GetTopLevel(contents->GetNativeView()) : NULL; 471 contents ? platform_util::GetTopLevel(contents->GetNativeView()) : NULL;
472 // |id_ptr| will be deleted in either FileSelected() or
473 // FileSelectionCancelled().
474 int32* id_ptr = new int32;
475 *id_ptr = download_id;
446 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE, 476 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE,
447 string16(), 477 string16(),
448 info->suggested_path, 478 suggested_path,
449 &file_type_info, 0, FILE_PATH_LITERAL(""), 479 &file_type_info, 0, FILE_PATH_LITERAL(""),
450 contents, owning_window, info); 480 contents, owning_window,
481 reinterpret_cast<void*>(id_ptr));
451 FOR_EACH_OBSERVER(Observer, observers_, 482 FOR_EACH_OBSERVER(Observer, observers_,
452 SelectFileDialogDisplayed(info->download_id)); 483 SelectFileDialogDisplayed(download_id));
453 } else { 484 } else {
454 // No prompting for download, just continue with the suggested name. 485 // No prompting for download, just continue with the suggested name.
455 info->path = info->suggested_path; 486 ContinueDownloadWithPath(download, suggested_path);
456 AttachDownloadItem(info);
457 } 487 }
458 } 488 }
459 489
460 void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info) { 490 void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info) {
461 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 491 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
462 492
463 DownloadItem* download = new DownloadItem(this, *info, 493 DownloadItem* download = new DownloadItem(this, *info,
464 profile_->IsOffTheRecord()); 494 profile_->IsOffTheRecord());
465 DCHECK(!ContainsKey(in_progress_, info->download_id)); 495 int32 download_id = info->download_id;
466 DCHECK(!ContainsKey(active_downloads_, info->download_id)); 496 DCHECK(!ContainsKey(in_progress_, download_id));
497 DCHECK(!ContainsKey(active_downloads_, download_id));
467 downloads_.insert(download); 498 downloads_.insert(download);
468 active_downloads_[info->download_id] = download; 499 active_downloads_[download_id] = download;
469 } 500 }
470 501
471 void DownloadManager::AttachDownloadItem(DownloadCreateInfo* info) { 502 void DownloadManager::ContinueDownloadWithPath(DownloadItem* download,
472 VLOG(20) << __FUNCTION__ << "()" << " info = " << info->DebugString(); 503 const FilePath& chosen_file) {
504 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
505 DCHECK(download);
473 506
474 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 507 int32 download_id = download->id();
475
476 // Life of |info| ends here. No more references to it after this method.
477 scoped_ptr<DownloadCreateInfo> infop(info);
478 508
479 // NOTE(ahendrickson) Eventually |active_downloads_| will replace 509 // NOTE(ahendrickson) Eventually |active_downloads_| will replace
480 // |in_progress_|, but we don't want to change the semantics yet. 510 // |in_progress_|, but we don't want to change the semantics yet.
481 DCHECK(!ContainsKey(in_progress_, info->download_id)); 511 DCHECK(!ContainsKey(in_progress_, download_id));
482 DCHECK(ContainsKey(active_downloads_, info->download_id));
483 DownloadItem* download = active_downloads_[info->download_id];
484 DCHECK(download != NULL);
485 DCHECK(ContainsKey(downloads_, download)); 512 DCHECK(ContainsKey(downloads_, download));
513 DCHECK(ContainsKey(active_downloads_, download_id));
486 514
487 download->SetFileCheckResults(info->path, 515 // Make sure the initial file name is set only once.
488 info->is_dangerous_file, 516 DCHECK(download->full_path().empty());
489 info->is_dangerous_url, 517 download->OnPathDetermined(chosen_file);
490 info->path_uniquifier, 518 download->UpdateTarget();
491 info->prompt_user_for_save_location, 519
492 info->is_extension_install, 520 VLOG(20) << __FUNCTION__ << "()"
493 info->original_name); 521 << " download = " << download->DebugString(true);
494 in_progress_[info->download_id] = download; 522
523 in_progress_[download_id] = download;
495 UpdateAppIcon(); // Reflect entry into in_progress_. 524 UpdateAppIcon(); // Reflect entry into in_progress_.
496 525
497 // Rename to intermediate name. 526 // Rename to intermediate name.
498 FilePath download_path; 527 FilePath download_path;
499 if (info->IsDangerous()) { 528 if (download->IsDangerous()) {
500 // The download is not safe. We can now rename the file to its 529 // The download is not safe. We can now rename the file to its
501 // tentative name using RenameInProgressDownloadFile. 530 // tentative name using RenameInProgressDownloadFile.
502 // NOTE: The |Rename| below will be a no-op for dangerous files, as we're 531 // NOTE: The |Rename| below will be a no-op for dangerous files, as we're
503 // renaming it to the same name. 532 // renaming it to the same name.
504 download_path = info->path; 533 download_path = download->full_path();
505 } else { 534 } else {
506 // The download is a safe download. We need to 535 // The download is a safe download. We need to
507 // rename it to its intermediate '.crdownload' path. The final 536 // rename it to its intermediate '.crdownload' path. The final
508 // name after user confirmation will be set from 537 // name after user confirmation will be set from
509 // DownloadItem::OnDownloadCompleting. 538 // DownloadItem::OnDownloadCompleting.
510 download_path = download_util::GetCrDownloadPath(info->path); 539 download_path =
540 download_util::GetCrDownloadPath(download->full_path());
511 } 541 }
512 542
513 BrowserThread::PostTask( 543 BrowserThread::PostTask(
514 BrowserThread::FILE, FROM_HERE, 544 BrowserThread::FILE, FROM_HERE,
515 NewRunnableMethod( 545 NewRunnableMethod(
516 file_manager_, &DownloadFileManager::RenameInProgressDownloadFile, 546 file_manager_, &DownloadFileManager::RenameInProgressDownloadFile,
517 download->id(), download_path)); 547 download->id(), download_path));
518 548
519 download->Rename(download_path); 549 download->Rename(download_path);
520 550
521 download_history_->AddEntry(*info, download, 551 download_history_->AddEntry(download,
522 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete)); 552 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete));
523 } 553 }
524 554
525 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { 555 void DownloadManager::UpdateDownload(int32 download_id, int64 size) {
526 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 556 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
527 DownloadMap::iterator it = active_downloads_.find(download_id); 557 DownloadMap::iterator it = active_downloads_.find(download_id);
528 if (it != active_downloads_.end()) { 558 if (it != active_downloads_.end()) {
529 DownloadItem* download = it->second; 559 DownloadItem* download = it->second;
530 if (download->IsInProgress()) { 560 if (download->IsInProgress()) {
531 download->Update(size); 561 download->Update(size);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 614 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
585 DVLOG(1) << "CheckDownloadHashDone, download_id: " << download_id 615 DVLOG(1) << "CheckDownloadHashDone, download_id: " << download_id
586 << " is dangerous_hash: " << is_dangerous_hash; 616 << " is dangerous_hash: " << is_dangerous_hash;
587 617
588 // If it's not in active_downloads_, that means it was cancelled or 618 // If it's not in active_downloads_, that means it was cancelled or
589 // the download already finished. 619 // the download already finished.
590 if (active_downloads_.count(download_id) == 0) 620 if (active_downloads_.count(download_id) == 0)
591 return; 621 return;
592 622
593 DVLOG(1) << "CheckDownloadHashDone, url: " 623 DVLOG(1) << "CheckDownloadHashDone, url: "
594 << active_downloads_[download_id]->url().spec(); 624 << active_downloads_[download_id]->GetURL().spec();
595 } 625 }
596 626
597 bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) { 627 bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) {
598 // If we don't have all the data, the download is not ready for 628 // If we don't have all the data, the download is not ready for
599 // completion. 629 // completion.
600 if (!download->all_data_saved()) 630 if (!download->all_data_saved())
601 return false; 631 return false;
602 632
603 // If the download is dangerous, but not yet validated, it's not ready for 633 // If the download is dangerous, but not yet validated, it's not ready for
604 // completion. 634 // completion.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 int os_error) { 755 int os_error) {
726 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 756 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
727 DownloadMap::iterator it = active_downloads_.find(download_id); 757 DownloadMap::iterator it = active_downloads_.find(download_id);
728 // A cancel at the right time could remove the download from the 758 // A cancel at the right time could remove the download from the
729 // |active_downloads_| map before we get here. 759 // |active_downloads_| map before we get here.
730 if (it == active_downloads_.end()) 760 if (it == active_downloads_.end())
731 return; 761 return;
732 762
733 DownloadItem* download = it->second; 763 DownloadItem* download = it->second;
734 764
735 VLOG(20) << "Error " << os_error << " at offset " 765 VLOG(20) << __FUNCTION__ << "()" << " Error " << os_error
736 << download->received_bytes() << " for download = " 766 << " at offset " << download->received_bytes()
737 << download->DebugString(true); 767 << " for download = " << download->DebugString(true);
768
769 download->Interrupted(size, os_error);
738 770
739 // TODO(ahendrickson) - Remove this when we add resuming of interrupted 771 // TODO(ahendrickson) - Remove this when we add resuming of interrupted
740 // downloads, as we will keep the download item around in that case. 772 // downloads, as we will keep the download item around in that case.
741 // 773 //
742 // Clean up will happen when the history system create callback runs if we 774 // Clean up will happen when the history system create callback runs if we
743 // don't have a valid db_handle yet. 775 // don't have a valid db_handle yet.
744 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { 776 if (download->db_handle() != DownloadHistory::kUninitializedHandle) {
745 in_progress_.erase(download_id); 777 in_progress_.erase(download_id);
746 active_downloads_.erase(download_id); 778 active_downloads_.erase(download_id);
747 UpdateAppIcon(); // Reflect removal from in_progress_. 779 UpdateAppIcon(); // Reflect removal from in_progress_.
748 download_history_->UpdateEntry(download); 780 download_history_->UpdateEntry(download);
749 } 781 }
750 782
751 download->Interrupted(size, os_error);
752
753 BrowserThread::PostTask( 783 BrowserThread::PostTask(
754 BrowserThread::FILE, FROM_HERE, 784 BrowserThread::FILE, FROM_HERE,
755 NewRunnableMethod( 785 NewRunnableMethod(
756 file_manager_, &DownloadFileManager::CancelDownload, download_id)); 786 file_manager_, &DownloadFileManager::CancelDownload, download_id));
757 } 787 }
758 788
759 void DownloadManager::PauseDownload(int32 download_id, bool pause) { 789 void DownloadManager::PauseDownload(int32 download_id, bool pause) {
760 DownloadMap::iterator it = in_progress_.find(download_id); 790 DownloadMap::iterator it = in_progress_.find(download_id);
761 if (it == in_progress_.end()) 791 if (it == in_progress_.end())
762 return; 792 return;
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 int64 total_bytes = 0; 989 int64 total_bytes = 0;
960 for (DownloadMap::iterator i = in_progress_.begin(); 990 for (DownloadMap::iterator i = in_progress_.begin();
961 i != in_progress_.end(); ++i) { 991 i != in_progress_.end(); ++i) {
962 total_bytes += i->second->total_bytes(); 992 total_bytes += i->second->total_bytes();
963 } 993 }
964 return total_bytes; 994 return total_bytes;
965 } 995 }
966 996
967 void DownloadManager::FileSelected(const FilePath& path, 997 void DownloadManager::FileSelected(const FilePath& path,
968 int index, void* params) { 998 int index, void* params) {
969 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); 999 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
970 if (info->prompt_user_for_save_location) 1000
1001 int32* id_ptr = reinterpret_cast<int32*>(params);
1002 DCHECK(id_ptr != NULL);
1003 int32 download_id = *id_ptr;
1004 delete id_ptr;
1005
1006 DownloadItem* download = GetActiveDownloadItem(download_id);
1007 if (!download)
1008 return;
1009 VLOG(20) << __FUNCTION__ << "()" << " path = \"" << path.value() << "\""
1010 << " download = " << download->DebugString(true);
1011
1012 if (download->save_as())
971 last_download_path_ = path.DirName(); 1013 last_download_path_ = path.DirName();
972 1014
973 info->path = path; 1015 // Make sure the initial file name is set only once.
974 AttachDownloadItem(info); 1016 ContinueDownloadWithPath(download, path);
975 } 1017 }
976 1018
977 void DownloadManager::FileSelectionCanceled(void* params) { 1019 void DownloadManager::FileSelectionCanceled(void* params) {
978 // The user didn't pick a place to save the file, so need to cancel the 1020 // 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. 1021 // download that's already in progress to the temporary location.
980 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); 1022 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
981 DownloadCancelledInternal(info->download_id, info->process_handle); 1023 int32* id_ptr = reinterpret_cast<int32*>(params);
1024 DCHECK(id_ptr != NULL);
1025 int32 download_id = *id_ptr;
1026 delete id_ptr;
1027
1028 DownloadItem* download = GetActiveDownloadItem(download_id);
1029 if (!download)
1030 return;
1031
1032 VLOG(20) << __FUNCTION__ << "()"
1033 << " download = " << download->DebugString(true);
1034
1035 DownloadCancelledInternal(download_id, download->process_handle());
1036 }
1037
1038 // TODO(phajdan.jr): This is apparently not being exercised in tests.
1039 bool DownloadManager::IsDangerous(const DownloadItem& download,
1040 const DownloadStateInfo& state) {
1041 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1042
1043 bool auto_open = ShouldOpenFileBasedOnExtension(state.suggested_path);
1044 download_util::DownloadDangerLevel danger_level =
1045 download_util::GetFileDangerLevel(state.suggested_path.BaseName());
1046
1047 if (danger_level == download_util::Dangerous)
1048 return !(auto_open && state.has_user_gesture);
1049
1050 if (danger_level == download_util::AllowOnUserGesture &&
1051 !state.has_user_gesture)
1052 return true;
1053
1054 if (state.is_extension_install) {
1055 // Extensions that are not from the gallery are considered dangerous.
1056 ExtensionService* service = profile()->GetExtensionService();
1057 if (!service || !service->IsDownloadFromGallery(download.GetURL(),
1058 download.referrer_url()))
1059 return true;
1060 }
1061 return false;
982 } 1062 }
983 1063
984 void DownloadManager::DangerousDownloadValidated(DownloadItem* download) { 1064 void DownloadManager::DangerousDownloadValidated(DownloadItem* download) {
985 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1065 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
986 DCHECK_EQ(DownloadItem::DANGEROUS, download->safety_state()); 1066 DCHECK_EQ(DownloadItem::DANGEROUS, download->safety_state());
987 download->set_safety_state(DownloadItem::DANGEROUS_BUT_VALIDATED); 1067 download->set_safety_state(DownloadItem::DANGEROUS_BUT_VALIDATED);
988 download->UpdateObservers(); 1068 download->UpdateObservers();
989 1069
990 MaybeCompleteDownload(download); 1070 MaybeCompleteDownload(download);
991 } 1071 }
992 1072
993 // Operations posted to us from the history service ---------------------------- 1073 // Operations posted to us from the history service ----------------------------
994 1074
995 // The history service has retrieved all download entries. 'entries' contains 1075 // The history service has retrieved all download entries. 'entries' contains
996 // 'DownloadCreateInfo's in sorted order (by ascending start_time). 1076 // 'DownloadHistoryInfo's in sorted order (by ascending start_time).
997 void DownloadManager::OnQueryDownloadEntriesComplete( 1077 void DownloadManager::OnQueryDownloadEntriesComplete(
998 std::vector<DownloadCreateInfo>* entries) { 1078 std::vector<DownloadHistoryInfo>* entries) {
999 for (size_t i = 0; i < entries->size(); ++i) { 1079 for (size_t i = 0; i < entries->size(); ++i) {
1000 DownloadItem* download = new DownloadItem(this, entries->at(i)); 1080 DownloadItem* download = new DownloadItem(this, entries->at(i));
1001 DCHECK(!ContainsKey(history_downloads_, download->db_handle())); 1081 DCHECK(!ContainsKey(history_downloads_, download->db_handle()));
1002 downloads_.insert(download); 1082 downloads_.insert(download);
1003 history_downloads_[download->db_handle()] = download; 1083 history_downloads_[download->db_handle()] = download;
1004 VLOG(20) << __FUNCTION__ << "()" << i << ">" 1084 VLOG(20) << __FUNCTION__ << "()" << i << ">"
1005 << " download = " << download->DebugString(true); 1085 << " download = " << download->DebugString(true);
1006 } 1086 }
1007 NotifyModelChanged(); 1087 NotifyModelChanged();
1008 } 1088 }
1009 1089
1010 // Once the new DownloadItem's creation info has been committed to the history 1090 // 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 1091 // service, we associate the DownloadItem with the db handle, update our
1012 // 'history_downloads_' map and inform observers. 1092 // 'history_downloads_' map and inform observers.
1013 void DownloadManager::OnCreateDownloadEntryComplete( 1093 void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id,
1014 DownloadCreateInfo info, 1094 int64 db_handle) {
1015 int64 db_handle) {
1016 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1095 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1017 DownloadMap::iterator it = in_progress_.find(info.download_id); 1096 DownloadItem* download = GetActiveDownloadItem(download_id);
1018 DCHECK(it != in_progress_.end()); 1097 if (!download)
1098 return;
1019 1099
1020 DownloadItem* download = it->second;
1021 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle 1100 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle
1022 << " download_id = " << info.download_id 1101 << " download_id = " << download_id
1023 << " download = " << download->DebugString(true); 1102 << " download = " << download->DebugString(true);
1024 1103
1025 // It's not immediately obvious, but HistoryBackend::CreateDownload() can 1104 // It's not immediately obvious, but HistoryBackend::CreateDownload() can
1026 // call this function with an invalid |db_handle|. For instance, this can 1105 // call this function with an invalid |db_handle|. For instance, this can
1027 // happen when the history database is offline. We cannot have multiple 1106 // 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 1107 // DownloadItems with the same invalid db_handle, so we need to assign a
1029 // unique |db_handle| here. 1108 // unique |db_handle| here.
1030 if (db_handle == DownloadHistory::kUninitializedHandle) 1109 if (db_handle == DownloadHistory::kUninitializedHandle)
1031 db_handle = download_history_->GetNextFakeDbHandle(); 1110 db_handle = download_history_->GetNextFakeDbHandle();
1032 1111
1033 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle); 1112 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle);
1034 download->set_db_handle(db_handle); 1113 download->set_db_handle(db_handle);
1035 1114
1036 DCHECK(!ContainsKey(history_downloads_, download->db_handle())); 1115 DCHECK(!ContainsKey(history_downloads_, download->db_handle()));
1037 history_downloads_[download->db_handle()] = download; 1116 history_downloads_[download->db_handle()] = download;
1038 1117
1039 // Show in the appropriate browser UI. 1118 // Show in the appropriate browser UI.
1040 // This includes buttons to save or cancel, for a dangerous download. 1119 // This includes buttons to save or cancel, for a dangerous download.
1041 ShowDownloadInBrowser(&info.process_handle, download); 1120 ShowDownloadInBrowser(download);
1042 1121
1043 // Inform interested objects about the new download. 1122 // Inform interested objects about the new download.
1044 NotifyModelChanged(); 1123 NotifyModelChanged();
1045 1124
1046 // If the download is still in progress, try to complete it. 1125 // If the download is still in progress, try to complete it.
1047 // 1126 //
1048 // Otherwise, download has been cancelled or interrupted before we've 1127 // Otherwise, download has been cancelled or interrupted before we've
1049 // received the DB handle. We post one final message to the history 1128 // 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 1129 // 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 1130 // completion status, and also inform any observers so that they get
1052 // more than just the start notification. 1131 // more than just the start notification.
1053 if (download->IsInProgress()) { 1132 if (download->IsInProgress()) {
1054 MaybeCompleteDownload(download); 1133 MaybeCompleteDownload(download);
1055 } else { 1134 } else {
1056 DCHECK(download->IsCancelled()) 1135 DCHECK(download->IsCancelled())
1057 << " download = " << download->DebugString(true); 1136 << " download = " << download->DebugString(true);
1058 in_progress_.erase(it); 1137 in_progress_.erase(download_id);
1059 active_downloads_.erase(info.download_id); 1138 active_downloads_.erase(download_id);
1060 download_history_->UpdateEntry(download); 1139 download_history_->UpdateEntry(download);
1061 download->UpdateObservers(); 1140 download->UpdateObservers();
1062 } 1141 }
1063 } 1142 }
1064 1143
1065 void DownloadManager::ShowDownloadInBrowser( 1144 void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) {
1066 DownloadProcessHandle* process_handle, DownloadItem* download) {
1067 if (!process_handle)
1068 return;
1069 1145
1070 // The 'contents' may no longer exist if the user closed the tab before we 1146 // 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 1147 // get this start completion event. If it does, tell the origin TabContents
1072 // to display its download shelf. 1148 // to display its download shelf.
1073 TabContents* contents = process_handle->GetTabContents(); 1149 DownloadProcessHandle process_handle = download->process_handle();
1150 TabContents* contents = process_handle.GetTabContents();
1074 TabContentsWrapper* wrapper = NULL; 1151 TabContentsWrapper* wrapper = NULL;
1075 if (contents) 1152 if (contents)
1076 wrapper = TabContentsWrapper::GetCurrentWrapperForContents(contents); 1153 wrapper = TabContentsWrapper::GetCurrentWrapperForContents(contents);
1077 1154
1078 // If the contents no longer exists, we start the download in the last active 1155 // 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 1156 // browser. This is not ideal but better than fully hiding the download from
1080 // the user. 1157 // the user.
1081 if (!wrapper) { 1158 if (!wrapper) {
1082 Browser* last_active = BrowserList::GetLastActive(); 1159 Browser* last_active = BrowserList::GetLastActive();
1083 if (last_active) 1160 if (last_active)
1084 wrapper = last_active->GetSelectedTabContentsWrapper(); 1161 wrapper = last_active->GetSelectedTabContentsWrapper();
1085 } 1162 }
1086 1163
1087 if (!wrapper) 1164 if (!wrapper)
1088 return; 1165 return;
1089 1166
1090 wrapper->download_tab_helper()->OnStartDownload(download); 1167 wrapper->download_tab_helper()->OnStartDownload(download);
1091 } 1168 }
1092 1169
1093 // Clears the last download path, used to initialize "save as" dialogs. 1170 // Clears the last download path, used to initialize "save as" dialogs.
1094 void DownloadManager::ClearLastDownloadPath() { 1171 void DownloadManager::ClearLastDownloadPath() {
1095 last_download_path_ = FilePath(); 1172 last_download_path_ = FilePath();
1096 } 1173 }
1097 1174
1098 void DownloadManager::NotifyModelChanged() { 1175 void DownloadManager::NotifyModelChanged() {
1099 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged()); 1176 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged());
1100 } 1177 }
1101 1178
1102 DownloadItem* DownloadManager::GetDownloadItem(int id) { 1179 DownloadItem* DownloadManager::GetDownloadItem(int download_id) {
1180 // The |history_downloads_| map is indexed by the download's db_handle,
1181 // not its id, so we have to iterate.
1103 for (DownloadMap::iterator it = history_downloads_.begin(); 1182 for (DownloadMap::iterator it = history_downloads_.begin();
1104 it != history_downloads_.end(); ++it) { 1183 it != history_downloads_.end(); ++it) {
1105 DownloadItem* item = it->second; 1184 DownloadItem* item = it->second;
1106 if (item->id() == id) 1185 if (item->id() == download_id)
1107 return item; 1186 return item;
1108 } 1187 }
1109 return NULL; 1188 return NULL;
1110 } 1189 }
1111 1190
1191 DownloadItem* DownloadManager::GetActiveDownloadItem(int download_id) {
1192 DCHECK(ContainsKey(active_downloads_, download_id));
1193 DownloadItem* download = active_downloads_[download_id];
1194 DCHECK(download != NULL);
1195 return download;
1196 }
1197
1112 // Confirm that everything in all maps is also in |downloads_|, and that 1198 // Confirm that everything in all maps is also in |downloads_|, and that
1113 // everything in |downloads_| is also in some other map. 1199 // everything in |downloads_| is also in some other map.
1114 void DownloadManager::AssertContainersConsistent() const { 1200 void DownloadManager::AssertContainersConsistent() const {
1115 #if !defined(NDEBUG) 1201 #if !defined(NDEBUG)
1116 // Turn everything into sets. 1202 // Turn everything into sets.
1117 DownloadSet active_set, history_set; 1203 DownloadSet active_set, history_set;
1118 const DownloadMap* input_maps[] = {&active_downloads_, &history_downloads_}; 1204 const DownloadMap* input_maps[] = {&active_downloads_, &history_downloads_};
1119 DownloadSet* local_sets[] = {&active_set, &history_set}; 1205 DownloadSet* local_sets[] = {&active_set, &history_set};
1120 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(local_sets)); 1206 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(local_sets));
1121 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) { 1207 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); 1261 observed_download_manager_->RemoveObserver(this);
1176 } 1262 }
1177 1263
1178 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { 1264 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() {
1179 observing_download_manager_->NotifyModelChanged(); 1265 observing_download_manager_->NotifyModelChanged();
1180 } 1266 }
1181 1267
1182 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { 1268 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() {
1183 observed_download_manager_ = NULL; 1269 observed_download_manager_ = NULL;
1184 } 1270 }
OLDNEW
« no previous file with comments | « chrome/browser/download/download_manager.h ('k') | chrome/browser/download/download_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698