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