Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 // Close the file on the file thread and respond back on the UI thread with | 68 // Close the file on the file thread and respond back on the UI thread with |
| 69 // file size. | 69 // file size. |
| 70 void CloseFile(base::Callback<void(int64_t file_size)> callback); | 70 void CloseFile(base::Callback<void(int64_t file_size)> callback); |
| 71 | 71 |
| 72 // RenderProcessHostObserver: | 72 // RenderProcessHostObserver: |
| 73 void RenderProcessExited(RenderProcessHost* host, | 73 void RenderProcessExited(RenderProcessHost* host, |
| 74 base::TerminationStatus status, | 74 base::TerminationStatus status, |
| 75 int exit_code) override; | 75 int exit_code) override; |
| 76 void RenderProcessHostDestroyed(RenderProcessHost* host) override; | 76 void RenderProcessHostDestroyed(RenderProcessHost* host) override; |
| 77 | 77 |
| 78 bool is_finished() const { return is_finished_; } | |
| 79 void MarkAsFinished() { is_finished_ = true; } | |
| 80 | |
| 78 private: | 81 private: |
| 79 static int64_t CloseFileOnFileThread(base::File file); | 82 static int64_t CloseFileOnFileThread(base::File file); |
| 80 void AddFrame(RenderFrameHost* render_frame_host); | 83 void AddFrame(RenderFrameHost* render_frame_host); |
| 81 | 84 |
| 82 // Creates a new map with values (content ids) the same as in | 85 // Creates a new map with values (content ids) the same as in |
| 83 // |frame_tree_node_to_content_id_| map, but with the keys translated from | 86 // |frame_tree_node_to_content_id_| map, but with the keys translated from |
| 84 // frame_tree_node_id into a |site_instance|-specific routing_id. | 87 // frame_tree_node_id into a |site_instance|-specific routing_id. |
| 85 std::map<int, std::string> CreateFrameRoutingIdToContentId( | 88 std::map<int, std::string> CreateFrameRoutingIdToContentId( |
| 86 SiteInstance* site_instance); | 89 SiteInstance* site_instance); |
| 87 | 90 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 112 // MIME multipart boundary to use in the MHTML doc. | 115 // MIME multipart boundary to use in the MHTML doc. |
| 113 std::string mhtml_boundary_marker_; | 116 std::string mhtml_boundary_marker_; |
| 114 | 117 |
| 115 // Digests of URIs of already generated MHTML parts. | 118 // Digests of URIs of already generated MHTML parts. |
| 116 std::set<std::string> digests_of_already_serialized_uris_; | 119 std::set<std::string> digests_of_already_serialized_uris_; |
| 117 std::string salt_; | 120 std::string salt_; |
| 118 | 121 |
| 119 // The callback to call once generation is complete. | 122 // The callback to call once generation is complete. |
| 120 const GenerateMHTMLCallback callback_; | 123 const GenerateMHTMLCallback callback_; |
| 121 | 124 |
| 125 // Whether the job is finished (set to true only for the short duration of | |
| 126 // time between MHTMLGenerationManager::JobFinished is called and the job is | |
| 127 // destroyed by MHTMLGenerationManager::OnFileClosed). | |
| 128 bool is_finished_; | |
| 129 | |
| 122 // RAII helper for registering this Job as a RenderProcessHost observer. | 130 // RAII helper for registering this Job as a RenderProcessHost observer. |
| 123 ScopedObserver<RenderProcessHost, MHTMLGenerationManager::Job> | 131 ScopedObserver<RenderProcessHost, MHTMLGenerationManager::Job> |
| 124 observed_renderer_process_host_; | 132 observed_renderer_process_host_; |
| 125 | 133 |
| 126 DISALLOW_COPY_AND_ASSIGN(Job); | 134 DISALLOW_COPY_AND_ASSIGN(Job); |
| 127 }; | 135 }; |
| 128 | 136 |
| 129 MHTMLGenerationManager::Job::Job(int job_id, | 137 MHTMLGenerationManager::Job::Job(int job_id, |
| 130 WebContents* web_contents, | 138 WebContents* web_contents, |
| 131 const MHTMLGenerationParams& params, | 139 const MHTMLGenerationParams& params, |
| 132 const GenerateMHTMLCallback& callback) | 140 const GenerateMHTMLCallback& callback) |
| 133 : job_id_(job_id), | 141 : job_id_(job_id), |
| 134 params_(params), | 142 params_(params), |
| 135 frame_tree_node_id_of_busy_frame_(FrameTreeNode::kFrameTreeNodeInvalidId), | 143 frame_tree_node_id_of_busy_frame_(FrameTreeNode::kFrameTreeNodeInvalidId), |
| 136 mhtml_boundary_marker_(net::GenerateMimeMultipartBoundary()), | 144 mhtml_boundary_marker_(net::GenerateMimeMultipartBoundary()), |
| 137 salt_(base::GenerateGUID()), | 145 salt_(base::GenerateGUID()), |
| 138 callback_(callback), | 146 callback_(callback), |
| 147 is_finished_(false), | |
| 139 observed_renderer_process_host_(this) { | 148 observed_renderer_process_host_(this) { |
| 140 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 149 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 141 web_contents->ForEachFrame(base::Bind( | 150 web_contents->ForEachFrame(base::Bind( |
| 142 &MHTMLGenerationManager::Job::AddFrame, | 151 &MHTMLGenerationManager::Job::AddFrame, |
| 143 base::Unretained(this))); // Safe because ForEachFrame is synchronous. | 152 base::Unretained(this))); // Safe because ForEachFrame is synchronous. |
| 144 | 153 |
| 145 // Main frame needs to be processed first. | 154 // Main frame needs to be processed first. |
| 146 DCHECK(!pending_frame_tree_node_ids_.empty()); | 155 DCHECK(!pending_frame_tree_node_ids_.empty()); |
| 147 DCHECK(FrameTreeNode::GloballyFindByID(pending_frame_tree_node_ids_.front()) | 156 DCHECK(FrameTreeNode::GloballyFindByID(pending_frame_tree_node_ids_.front()) |
| 148 ->parent() == nullptr); | 157 ->parent() == nullptr); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 381 | 390 |
| 382 if (!job->SendToNextRenderFrame()) { | 391 if (!job->SendToNextRenderFrame()) { |
| 383 JobFinished(job, JobStatus::FAILURE); | 392 JobFinished(job, JobStatus::FAILURE); |
| 384 } | 393 } |
| 385 } | 394 } |
| 386 | 395 |
| 387 void MHTMLGenerationManager::JobFinished(Job* job, JobStatus job_status) { | 396 void MHTMLGenerationManager::JobFinished(Job* job, JobStatus job_status) { |
| 388 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 397 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 389 DCHECK(job); | 398 DCHECK(job); |
| 390 | 399 |
| 391 job->CloseFile( | 400 // Make sure we gracefully handle the case when JobFinished is called twice |
| 392 base::Bind(&MHTMLGenerationManager::OnFileClosed, | 401 // (i.e. once from OnSerializeAsMHTMLResponse and while the file is being |
| 393 base::Unretained(this), // Safe b/c |this| is a singleton. | 402 // closed also called a second time from RenderProcessExited). |
| 394 job->id(), job_status)); | 403 if (!job->is_finished()) { // Is this the first time JobFinished is called? |
| 404 job->MarkAsFinished(); | |
|
dewittj
2016/07/20 16:37:48
May want to clear |job|'s |observed_renderer_proce
Randy Smith (Not in Mondays)
2016/07/20 16:46:58
This is a good point, but wouldn't this solve this
Łukasz Anforowicz
2016/07/20 21:10:07
Done. Good point.
Randy Smith (Not in Mondays)
2016/07/20 22:47:49
Sure, that sounds good. Thanks for thinking the i
| |
| 405 job->CloseFile( | |
| 406 base::Bind(&MHTMLGenerationManager::OnFileClosed, | |
| 407 base::Unretained(this), // Safe b/c |this| is a singleton. | |
| 408 job->id(), job_status)); | |
| 409 } | |
| 395 } | 410 } |
| 396 | 411 |
| 397 void MHTMLGenerationManager::OnFileClosed(int job_id, | 412 void MHTMLGenerationManager::OnFileClosed(int job_id, |
| 398 JobStatus job_status, | 413 JobStatus job_status, |
| 399 int64_t file_size) { | 414 int64_t file_size) { |
| 400 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 415 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 401 | 416 |
| 402 Job* job = FindJob(job_id); | 417 Job* job = FindJob(job_id); |
| 403 job->callback().Run(job_status == JobStatus::SUCCESS ? file_size : -1); | 418 job->callback().Run(job_status == JobStatus::SUCCESS ? file_size : -1); |
| 404 id_to_job_.erase(job_id); | 419 id_to_job_.erase(job_id); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 426 return iter->second; | 441 return iter->second; |
| 427 } | 442 } |
| 428 | 443 |
| 429 void MHTMLGenerationManager::RenderProcessExited(Job* job) { | 444 void MHTMLGenerationManager::RenderProcessExited(Job* job) { |
| 430 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 445 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 431 DCHECK(job); | 446 DCHECK(job); |
| 432 JobFinished(job, JobStatus::FAILURE); | 447 JobFinished(job, JobStatus::FAILURE); |
| 433 } | 448 } |
| 434 | 449 |
| 435 } // namespace content | 450 } // namespace content |
| OLD | NEW |