| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/platform_file.h" | 8 #include "base/platform_file.h" |
| 9 #include "content/browser/renderer_host/render_process_host_impl.h" | 9 #include "content/browser/renderer_host/render_process_host_impl.h" |
| 10 #include "content/browser/renderer_host/render_view_host_impl.h" | 10 #include "content/browser/renderer_host/render_view_host_impl.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 MHTMLGenerationManager* MHTMLGenerationManager::GetInstance() { | 29 MHTMLGenerationManager* MHTMLGenerationManager::GetInstance() { |
| 30 return Singleton<MHTMLGenerationManager>::get(); | 30 return Singleton<MHTMLGenerationManager>::get(); |
| 31 } | 31 } |
| 32 | 32 |
| 33 MHTMLGenerationManager::MHTMLGenerationManager() { | 33 MHTMLGenerationManager::MHTMLGenerationManager() { |
| 34 } | 34 } |
| 35 | 35 |
| 36 MHTMLGenerationManager::~MHTMLGenerationManager() { | 36 MHTMLGenerationManager::~MHTMLGenerationManager() { |
| 37 } | 37 } |
| 38 | 38 |
| 39 void MHTMLGenerationManager::GenerateMHTML( | 39 void MHTMLGenerationManager::SaveMHTML(WebContents* web_contents, |
| 40 WebContents* web_contents, | 40 const base::FilePath& file, |
| 41 const base::FilePath& file, | 41 const GenerateMHTMLCallback& callback) { |
| 42 const GenerateMHTMLCallback& callback) { | |
| 43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 44 static int id_counter = 0; | |
| 45 | 43 |
| 46 int job_id = id_counter++; | 44 int job_id = NewJob(web_contents, callback); |
| 47 Job job; | |
| 48 job.file_path = file; | |
| 49 job.process_id = web_contents->GetRenderProcessHost()->GetID(); | |
| 50 job.routing_id = web_contents->GetRenderViewHost()->GetRoutingID(); | |
| 51 job.callback = callback; | |
| 52 id_to_job_[job_id] = job; | |
| 53 if (!registrar_.IsRegistered( | |
| 54 this, | |
| 55 NOTIFICATION_RENDERER_PROCESS_TERMINATED, | |
| 56 Source<RenderProcessHost>(web_contents->GetRenderProcessHost()))) { | |
| 57 registrar_.Add( | |
| 58 this, | |
| 59 NOTIFICATION_RENDERER_PROCESS_TERMINATED, | |
| 60 Source<RenderProcessHost>(web_contents->GetRenderProcessHost())); | |
| 61 } | |
| 62 | 45 |
| 63 base::ProcessHandle renderer_process = | 46 base::ProcessHandle renderer_process = |
| 64 web_contents->GetRenderProcessHost()->GetHandle(); | 47 web_contents->GetRenderProcessHost()->GetHandle(); |
| 65 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 48 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 66 base::Bind(&MHTMLGenerationManager::CreateFile, base::Unretained(this), | 49 base::Bind(&MHTMLGenerationManager::CreateFile, base::Unretained(this), |
| 67 job_id, file, renderer_process)); | 50 job_id, file, renderer_process)); |
| 68 } | 51 } |
| 69 | 52 |
| 53 void MHTMLGenerationManager::StreamMHTML( |
| 54 WebContents* web_contents, |
| 55 const base::PlatformFile browser_file, |
| 56 const GenerateMHTMLCallback& callback) { |
| 57 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 58 |
| 59 int job_id = NewJob(web_contents, callback); |
| 60 |
| 61 base::ProcessHandle renderer_process = |
| 62 web_contents->GetRenderProcessHost()->GetHandle(); |
| 63 IPC::PlatformFileForTransit renderer_file = |
| 64 IPC::GetFileHandleForProcess(browser_file, renderer_process, false); |
| 65 |
| 66 FileHandleAvailable(job_id, browser_file, renderer_file); |
| 67 } |
| 68 |
| 69 |
| 70 void MHTMLGenerationManager::MHTMLGenerated(int job_id, int64 mhtml_data_size) { | 70 void MHTMLGenerationManager::MHTMLGenerated(int job_id, int64 mhtml_data_size) { |
| 71 JobFinished(job_id, mhtml_data_size); | 71 JobFinished(job_id, mhtml_data_size); |
| 72 } | 72 } |
| 73 | 73 |
| 74 void MHTMLGenerationManager::CreateFile( | 74 void MHTMLGenerationManager::CreateFile( |
| 75 int job_id, const base::FilePath& file_path, | 75 int job_id, const base::FilePath& file_path, |
| 76 base::ProcessHandle renderer_process) { | 76 base::ProcessHandle renderer_process) { |
| 77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 78 base::PlatformFile browser_file = base::CreatePlatformFile(file_path, | 78 base::PlatformFile browser_file = base::CreatePlatformFile(file_path, |
| 79 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE, | 79 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE, |
| 80 NULL, NULL); | 80 NULL, NULL); |
| 81 if (browser_file == base::kInvalidPlatformFileValue) { | 81 if (browser_file == base::kInvalidPlatformFileValue) { |
| 82 LOG(ERROR) << "Failed to create file to save MHTML at: " << | 82 LOG(ERROR) << "Failed to create file to save MHTML at: " << |
| 83 file_path.value(); | 83 file_path.value(); |
| 84 } | 84 } |
| 85 | 85 |
| 86 IPC::PlatformFileForTransit renderer_file = | 86 IPC::PlatformFileForTransit renderer_file = |
| 87 IPC::GetFileHandleForProcess(browser_file, renderer_process, false); | 87 IPC::GetFileHandleForProcess(browser_file, renderer_process, false); |
| 88 | 88 |
| 89 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 89 BrowserThread::PostTask( |
| 90 base::Bind(&MHTMLGenerationManager::FileCreated, base::Unretained(this), | 90 BrowserThread::UI, |
| 91 job_id, browser_file, renderer_file)); | 91 FROM_HERE, |
| 92 base::Bind(&MHTMLGenerationManager::FileHandleAvailable, |
| 93 base::Unretained(this), |
| 94 job_id, |
| 95 browser_file, |
| 96 renderer_file)); |
| 92 } | 97 } |
| 93 | 98 |
| 94 void MHTMLGenerationManager::FileCreated(int job_id, | 99 void MHTMLGenerationManager::FileHandleAvailable(int job_id, |
| 95 base::PlatformFile browser_file, | 100 base::PlatformFile browser_file, |
| 96 IPC::PlatformFileForTransit renderer_file) { | 101 IPC::PlatformFileForTransit renderer_file) { |
| 97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 98 if (browser_file == base::kInvalidPlatformFileValue) { | 103 if (browser_file == base::kInvalidPlatformFileValue) { |
| 99 LOG(ERROR) << "Failed to create file"; | 104 LOG(ERROR) << "Failed to create file"; |
| 100 JobFinished(job_id, -1); | 105 JobFinished(job_id, -1); |
| 101 return; | 106 return; |
| 102 } | 107 } |
| 103 | 108 |
| 104 IDToJobMap::iterator iter = id_to_job_.find(job_id); | 109 IDToJobMap::iterator iter = id_to_job_.find(job_id); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 124 } | 129 } |
| 125 | 130 |
| 126 void MHTMLGenerationManager::JobFinished(int job_id, int64 file_size) { | 131 void MHTMLGenerationManager::JobFinished(int job_id, int64 file_size) { |
| 127 IDToJobMap::iterator iter = id_to_job_.find(job_id); | 132 IDToJobMap::iterator iter = id_to_job_.find(job_id); |
| 128 if (iter == id_to_job_.end()) { | 133 if (iter == id_to_job_.end()) { |
| 129 NOTREACHED(); | 134 NOTREACHED(); |
| 130 return; | 135 return; |
| 131 } | 136 } |
| 132 | 137 |
| 133 Job& job = iter->second; | 138 Job& job = iter->second; |
| 134 job.callback.Run(job.file_path, file_size); | 139 job.callback.Run(file_size); |
| 135 | 140 |
| 136 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 141 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 137 base::Bind(&MHTMLGenerationManager::CloseFile, base::Unretained(this), | 142 base::Bind(&MHTMLGenerationManager::CloseFile, base::Unretained(this), |
| 138 job.browser_file)); | 143 job.browser_file)); |
| 139 | 144 |
| 140 id_to_job_.erase(job_id); | 145 id_to_job_.erase(job_id); |
| 141 } | 146 } |
| 142 | 147 |
| 143 void MHTMLGenerationManager::CloseFile(base::PlatformFile file) { | 148 void MHTMLGenerationManager::CloseFile(base::PlatformFile file) { |
| 144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 149 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 145 base::ClosePlatformFile(file); | 150 base::ClosePlatformFile(file); |
| 146 } | 151 } |
| 147 | 152 |
| 153 int MHTMLGenerationManager::NewJob(WebContents* web_contents, |
| 154 const GenerateMHTMLCallback& callback) { |
| 155 static int id_counter = 0; |
| 156 int job_id = id_counter++; |
| 157 Job& job = id_to_job_[job_id]; |
| 158 job.process_id = web_contents->GetRenderProcessHost()->GetID(); |
| 159 job.routing_id = web_contents->GetRenderViewHost()->GetRoutingID(); |
| 160 job.callback = callback; |
| 161 if (!registrar_.IsRegistered( |
| 162 this, |
| 163 NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| 164 Source<RenderProcessHost>(web_contents->GetRenderProcessHost()))) { |
| 165 registrar_.Add( |
| 166 this, |
| 167 NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| 168 Source<RenderProcessHost>(web_contents->GetRenderProcessHost())); |
| 169 } |
| 170 return job_id; |
| 171 } |
| 172 |
| 148 void MHTMLGenerationManager::Observe(int type, | 173 void MHTMLGenerationManager::Observe(int type, |
| 149 const NotificationSource& source, | 174 const NotificationSource& source, |
| 150 const NotificationDetails& details) { | 175 const NotificationDetails& details) { |
| 151 DCHECK(type == NOTIFICATION_RENDERER_PROCESS_TERMINATED); | 176 DCHECK(type == NOTIFICATION_RENDERER_PROCESS_TERMINATED); |
| 152 RenderProcessHost* host = Source<RenderProcessHost>(source).ptr(); | 177 RenderProcessHost* host = Source<RenderProcessHost>(source).ptr(); |
| 153 registrar_.Remove( | 178 registrar_.Remove( |
| 154 this, | 179 this, |
| 155 NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 180 NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| 156 source); | 181 source); |
| 157 std::set<int> job_to_delete; | 182 std::set<int> job_to_delete; |
| 158 for (IDToJobMap::iterator it = id_to_job_.begin(); it != id_to_job_.end(); | 183 for (IDToJobMap::iterator it = id_to_job_.begin(); it != id_to_job_.end(); |
| 159 ++it) { | 184 ++it) { |
| 160 if (it->second.process_id == host->GetID()) | 185 if (it->second.process_id == host->GetID()) |
| 161 job_to_delete.insert(it->first); | 186 job_to_delete.insert(it->first); |
| 162 } | 187 } |
| 163 for (std::set<int>::iterator it = job_to_delete.begin(); | 188 for (std::set<int>::iterator it = job_to_delete.begin(); |
| 164 it != job_to_delete.end(); | 189 it != job_to_delete.end(); |
| 165 ++it) { | 190 ++it) { |
| 166 JobFinished(*it, -1); | 191 JobFinished(*it, -1); |
| 167 } | 192 } |
| 168 } | 193 } |
| 169 | 194 |
| 170 } // namespace content | 195 } // namespace content |
| OLD | NEW |