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

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

Powered by Google App Engine
This is Rietveld 408576698