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

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

Issue 2890853002: Downloads: replace BrowserThread::FILE with task scheduler. (Closed)
Patch Set: Address Avi's comments. Created 3 years, 5 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/download/mhtml_generation_manager.h" 5 #include "content/browser/download/mhtml_generation_manager.h"
6 6
7 #include <map> 7 #include <map>
8 #include <queue> 8 #include <queue>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/files/file.h" 12 #include "base/files/file.h"
13 #include "base/guid.h" 13 #include "base/guid.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/metrics/histogram_macros.h" 16 #include "base/metrics/histogram_macros.h"
17 #include "base/scoped_observer.h" 17 #include "base/scoped_observer.h"
18 #include "base/stl_util.h" 18 #include "base/stl_util.h"
19 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
20 #include "base/strings/stringprintf.h" 20 #include "base/strings/stringprintf.h"
21 #include "base/task_runner_util.h"
21 #include "base/time/time.h" 22 #include "base/time/time.h"
22 #include "base/trace_event/trace_event.h" 23 #include "base/trace_event/trace_event.h"
23 #include "content/browser/bad_message.h" 24 #include "content/browser/bad_message.h"
25 #include "content/browser/download/download_task_runner.h"
24 #include "content/browser/download/mhtml_extra_parts_impl.h" 26 #include "content/browser/download/mhtml_extra_parts_impl.h"
25 #include "content/browser/frame_host/frame_tree_node.h" 27 #include "content/browser/frame_host/frame_tree_node.h"
26 #include "content/browser/frame_host/render_frame_host_impl.h" 28 #include "content/browser/frame_host/render_frame_host_impl.h"
27 #include "content/common/frame_messages.h" 29 #include "content/common/frame_messages.h"
28 #include "content/public/browser/browser_thread.h" 30 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/mhtml_extra_parts.h" 31 #include "content/public/browser/mhtml_extra_parts.h"
30 #include "content/public/browser/render_frame_host.h" 32 #include "content/public/browser/render_frame_host.h"
31 #include "content/public/browser/render_process_host.h" 33 #include "content/public/browser/render_process_host.h"
32 #include "content/public/browser/render_process_host_observer.h" 34 #include "content/public/browser/render_process_host_observer.h"
33 #include "content/public/browser/web_contents.h" 35 #include "content/public/browser/web_contents.h"
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 375
374 if (!browser_file_.IsValid()) { 376 if (!browser_file_.IsValid()) {
375 // Only update the status if that won't hide an earlier error. 377 // Only update the status if that won't hide an earlier error.
376 if (save_status == MhtmlSaveStatus::SUCCESS) 378 if (save_status == MhtmlSaveStatus::SUCCESS)
377 save_status = MhtmlSaveStatus::FILE_WRITTING_ERROR; 379 save_status = MhtmlSaveStatus::FILE_WRITTING_ERROR;
378 callback.Run(std::make_tuple(save_status, -1)); 380 callback.Run(std::make_tuple(save_status, -1));
379 return; 381 return;
380 } 382 }
381 383
382 // If no previous error occurred the boundary should be sent. 384 // If no previous error occurred the boundary should be sent.
383 BrowserThread::PostTaskAndReplyWithResult( 385 base::PostTaskAndReplyWithResult(
384 BrowserThread::FILE, FROM_HERE, 386 GetDownloadTaskRunner().get(), FROM_HERE,
385 base::Bind( 387 base::Bind(
386 &MHTMLGenerationManager::Job::FinalizeAndCloseFileOnFileThread, 388 &MHTMLGenerationManager::Job::FinalizeAndCloseFileOnFileThread,
387 save_status, 389 save_status,
388 (save_status == MhtmlSaveStatus::SUCCESS ? mhtml_boundary_marker_ 390 (save_status == MhtmlSaveStatus::SUCCESS ? mhtml_boundary_marker_
389 : std::string()), 391 : std::string()),
390 base::Passed(&browser_file_), extra_parts_), 392 base::Passed(&browser_file_), extra_parts_),
391 callback); 393 callback);
392 } 394 }
393 395
394 bool MHTMLGenerationManager::Job::IsMessageFromFrameExpected( 396 bool MHTMLGenerationManager::Job::IsMessageFromFrameExpected(
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 return SendToNextRenderFrame(); 433 return SendToNextRenderFrame();
432 } 434 }
433 435
434 // static 436 // static
435 std::tuple<MhtmlSaveStatus, int64_t> 437 std::tuple<MhtmlSaveStatus, int64_t>
436 MHTMLGenerationManager::Job::FinalizeAndCloseFileOnFileThread( 438 MHTMLGenerationManager::Job::FinalizeAndCloseFileOnFileThread(
437 MhtmlSaveStatus save_status, 439 MhtmlSaveStatus save_status,
438 const std::string& boundary, 440 const std::string& boundary,
439 base::File file, 441 base::File file,
440 const MHTMLExtraPartsImpl* extra_parts) { 442 const MHTMLExtraPartsImpl* extra_parts) {
441 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 443 DCHECK(GetDownloadTaskRunner()->RunsTasksInCurrentSequence());
442 444
443 // If no previous error occurred the boundary should have been provided. 445 // If no previous error occurred the boundary should have been provided.
444 if (save_status == MhtmlSaveStatus::SUCCESS) { 446 if (save_status == MhtmlSaveStatus::SUCCESS) {
445 TRACE_EVENT0("page-serialization", 447 TRACE_EVENT0("page-serialization",
446 "MHTMLGenerationManager::Job MHTML footer writing"); 448 "MHTMLGenerationManager::Job MHTML footer writing");
447 DCHECK(!boundary.empty()); 449 DCHECK(!boundary.empty());
448 450
449 // Write the extra data into a part of its own, if we have any. 451 // Write the extra data into a part of its own, if we have any.
450 if (!WriteExtraDataParts(boundary, file, extra_parts)) { 452 if (!WriteExtraDataParts(boundary, file, extra_parts)) {
451 save_status = MhtmlSaveStatus::FILE_WRITTING_ERROR; 453 save_status = MhtmlSaveStatus::FILE_WRITTING_ERROR;
(...skipping 15 matching lines...) Expand all
467 } 469 }
468 470
469 return std::make_tuple(save_status, file_size); 471 return std::make_tuple(save_status, file_size);
470 } 472 }
471 473
472 // static 474 // static
473 bool MHTMLGenerationManager::Job::WriteExtraDataParts( 475 bool MHTMLGenerationManager::Job::WriteExtraDataParts(
474 const std::string& boundary, 476 const std::string& boundary,
475 base::File& file, 477 base::File& file,
476 const MHTMLExtraPartsImpl* extra_parts) { 478 const MHTMLExtraPartsImpl* extra_parts) {
477 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 479 DCHECK(GetDownloadTaskRunner()->RunsTasksInCurrentSequence());
478 // Don't write an extra data part if there is none. 480 // Don't write an extra data part if there is none.
479 if (extra_parts == nullptr) 481 if (extra_parts == nullptr)
480 return true; 482 return true;
481 483
482 const std::vector<MHTMLExtraDataPart>& extra_data_parts(extra_parts->parts()); 484 const std::vector<MHTMLExtraDataPart>& extra_data_parts(extra_parts->parts());
483 if (extra_data_parts.empty()) 485 if (extra_data_parts.empty())
484 return true; 486 return true;
485 487
486 std::string serialized_extra_data_parts; 488 std::string serialized_extra_data_parts;
487 489
(...skipping 14 matching lines...) Expand all
502 } 504 }
503 505
504 // Write the string into the file. Returns false if we failed the write. 506 // Write the string into the file. Returns false if we failed the write.
505 return (file.WriteAtCurrentPos(serialized_extra_data_parts.data(), 507 return (file.WriteAtCurrentPos(serialized_extra_data_parts.data(),
506 serialized_extra_data_parts.size()) >= 0); 508 serialized_extra_data_parts.size()) >= 0);
507 } 509 }
508 510
509 // static 511 // static
510 bool MHTMLGenerationManager::Job::WriteFooter(const std::string& boundary, 512 bool MHTMLGenerationManager::Job::WriteFooter(const std::string& boundary,
511 base::File& file) { 513 base::File& file) {
512 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 514 DCHECK(GetDownloadTaskRunner()->RunsTasksInCurrentSequence());
513 std::string footer = base::StringPrintf("--%s--\r\n", boundary.c_str()); 515 std::string footer = base::StringPrintf("--%s--\r\n", boundary.c_str());
514 DCHECK(base::IsStringASCII(footer)); 516 DCHECK(base::IsStringASCII(footer));
515 return (file.WriteAtCurrentPos(footer.data(), footer.size()) >= 0); 517 return (file.WriteAtCurrentPos(footer.data(), footer.size()) >= 0);
516 } 518 }
517 519
518 // static 520 // static
519 bool MHTMLGenerationManager::Job::CloseFileIfValid(base::File& file, 521 bool MHTMLGenerationManager::Job::CloseFileIfValid(base::File& file,
520 int64_t* file_size) { 522 int64_t* file_size) {
521 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 523 DCHECK(GetDownloadTaskRunner()->RunsTasksInCurrentSequence());
522 DCHECK(file_size); 524 DCHECK(file_size);
523 if (file.IsValid()) { 525 if (file.IsValid()) {
524 *file_size = file.GetLength(); 526 *file_size = file.GetLength();
525 file.Close(); 527 file.Close();
526 return true; 528 return true;
527 } 529 }
528 530
529 return false; 531 return false;
530 } 532 }
531 533
(...skipping 10 matching lines...) Expand all
542 const MHTMLGenerationParams& params, 544 const MHTMLGenerationParams& params,
543 const GenerateMHTMLCallback& callback) { 545 const GenerateMHTMLCallback& callback) {
544 DCHECK_CURRENTLY_ON(BrowserThread::UI); 546 DCHECK_CURRENTLY_ON(BrowserThread::UI);
545 547
546 Job* job = NewJob(web_contents, params, callback); 548 Job* job = NewJob(web_contents, params, callback);
547 TRACE_EVENT_NESTABLE_ASYNC_BEGIN2( 549 TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
548 "page-serialization", "SavingMhtmlJob", job, "url", 550 "page-serialization", "SavingMhtmlJob", job, "url",
549 web_contents->GetLastCommittedURL().possibly_invalid_spec(), 551 web_contents->GetLastCommittedURL().possibly_invalid_spec(),
550 "file", params.file_path.AsUTF8Unsafe()); 552 "file", params.file_path.AsUTF8Unsafe());
551 553
552 BrowserThread::PostTaskAndReplyWithResult( 554 base::PostTaskAndReplyWithResult(
553 BrowserThread::FILE, FROM_HERE, 555 GetDownloadTaskRunner().get(), FROM_HERE,
554 base::Bind(&MHTMLGenerationManager::CreateFile, params.file_path), 556 base::Bind(&MHTMLGenerationManager::CreateFile, params.file_path),
555 base::Bind(&MHTMLGenerationManager::OnFileAvailable, 557 base::Bind(&MHTMLGenerationManager::OnFileAvailable,
556 base::Unretained(this), // Safe b/c |this| is a singleton. 558 base::Unretained(this), // Safe b/c |this| is a singleton.
557 job->id())); 559 job->id()));
558 } 560 }
559 561
560 void MHTMLGenerationManager::OnSerializeAsMHTMLResponse( 562 void MHTMLGenerationManager::OnSerializeAsMHTMLResponse(
561 RenderFrameHostImpl* sender, 563 RenderFrameHostImpl* sender,
562 int job_id, 564 int job_id,
563 MhtmlSaveStatus save_status, 565 MhtmlSaveStatus save_status,
(...skipping 26 matching lines...) Expand all
590 return; 592 return;
591 } 593 }
592 594
593 // Otherwise report completion if the job is done. 595 // Otherwise report completion if the job is done.
594 if (job->IsDone()) 596 if (job->IsDone())
595 JobFinished(job, MhtmlSaveStatus::SUCCESS); 597 JobFinished(job, MhtmlSaveStatus::SUCCESS);
596 } 598 }
597 599
598 // static 600 // static
599 base::File MHTMLGenerationManager::CreateFile(const base::FilePath& file_path) { 601 base::File MHTMLGenerationManager::CreateFile(const base::FilePath& file_path) {
600 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 602 DCHECK(GetDownloadTaskRunner()->RunsTasksInCurrentSequence());
601 603
602 // SECURITY NOTE: A file descriptor to the file created below will be passed 604 // SECURITY NOTE: A file descriptor to the file created below will be passed
603 // to multiple renderer processes which (in out-of-process iframes mode) can 605 // to multiple renderer processes which (in out-of-process iframes mode) can
604 // act on behalf of separate web principals. Therefore it is important to 606 // act on behalf of separate web principals. Therefore it is important to
605 // only allow writing to the file and forbid reading from the file (as this 607 // only allow writing to the file and forbid reading from the file (as this
606 // would allow reading content generated by other renderers / other web 608 // would allow reading content generated by other renderers / other web
607 // principals). 609 // principals).
608 uint32_t file_flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE; 610 uint32_t file_flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE;
609 611
610 base::File browser_file(file_path, file_flags); 612 base::File browser_file(file_path, file_flags);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 return iter->second.get(); 693 return iter->second.get();
692 } 694 }
693 695
694 void MHTMLGenerationManager::RenderProcessExited(Job* job) { 696 void MHTMLGenerationManager::RenderProcessExited(Job* job) {
695 DCHECK_CURRENTLY_ON(BrowserThread::UI); 697 DCHECK_CURRENTLY_ON(BrowserThread::UI);
696 DCHECK(job); 698 DCHECK(job);
697 JobFinished(job, MhtmlSaveStatus::RENDER_PROCESS_EXITED); 699 JobFinished(job, MhtmlSaveStatus::RENDER_PROCESS_EXITED);
698 } 700 }
699 701
700 } // namespace content 702 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/download/mhtml_generation_browsertest.cc ('k') | content/browser/download/mock_download_file.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698