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 "chrome/utility/chrome_content_utility_client.h" | 5 #include "chrome/utility/chrome_content_utility_client.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
14 #include "build/build_config.h" | 14 #include "build/build_config.h" |
15 #include "chrome/common/chrome_utility_messages.h" | 15 #include "chrome/common/chrome_utility_messages.h" |
16 #include "chrome/common/safe_browsing/zip_analyzer.h" | 16 #include "chrome/common/safe_browsing/zip_analyzer.h" |
17 #include "chrome/common/safe_browsing/zip_analyzer_results.h" | 17 #include "chrome/common/safe_browsing/zip_analyzer_results.h" |
18 #include "chrome/utility/chrome_content_utility_ipc_whitelist.h" | 18 #include "chrome/utility/chrome_content_utility_ipc_whitelist.h" |
| 19 #include "chrome/utility/image_decoder_impl.h" |
19 #include "chrome/utility/safe_json_parser_handler.h" | 20 #include "chrome/utility/safe_json_parser_handler.h" |
20 #include "chrome/utility/utility_message_handler.h" | 21 #include "chrome/utility/utility_message_handler.h" |
21 #include "content/public/child/image_decoder_utils.h" | 22 #include "content/public/child/image_decoder_utils.h" |
22 #include "content/public/common/content_switches.h" | 23 #include "content/public/common/content_switches.h" |
23 #include "content/public/common/service_registry.h" | 24 #include "content/public/common/service_registry.h" |
24 #include "content/public/utility/utility_thread.h" | 25 #include "content/public/utility/utility_thread.h" |
25 #include "courgette/courgette.h" | 26 #include "courgette/courgette.h" |
26 #include "courgette/third_party/bsdiff.h" | 27 #include "courgette/third_party/bsdiff.h" |
27 #include "ipc/ipc_channel.h" | 28 #include "ipc/ipc_channel.h" |
28 #include "skia/ext/image_operations.h" | |
29 #include "third_party/skia/include/core/SkBitmap.h" | |
30 #include "third_party/zlib/google/zip.h" | 29 #include "third_party/zlib/google/zip.h" |
31 #include "ui/gfx/geometry/size.h" | 30 #include "ui/gfx/geometry/size.h" |
32 | 31 |
33 #if defined(OS_CHROMEOS) | |
34 #include "ui/gfx/chromeos/codec/jpeg_codec_robust_slow.h" | |
35 #include "ui/gfx/codec/png_codec.h" | |
36 #endif | |
37 | |
38 #if !defined(OS_ANDROID) | 32 #if !defined(OS_ANDROID) |
39 #include "chrome/common/resource_usage_reporter.mojom.h" | 33 #include "chrome/common/resource_usage_reporter.mojom.h" |
40 #include "chrome/utility/profile_import_handler.h" | 34 #include "chrome/utility/profile_import_handler.h" |
41 #include "mojo/public/cpp/bindings/strong_binding.h" | 35 #include "mojo/public/cpp/bindings/strong_binding.h" |
42 #include "net/proxy/mojo_proxy_resolver_factory_impl.h" | 36 #include "net/proxy/mojo_proxy_resolver_factory_impl.h" |
43 #include "net/proxy/proxy_resolver_v8.h" | 37 #include "net/proxy/proxy_resolver_v8.h" |
44 #endif | 38 #endif |
45 | 39 |
46 #if defined(OS_WIN) | 40 #if defined(OS_WIN) |
47 #include "chrome/utility/shell_handler_win.h" | 41 #include "chrome/utility/shell_handler_win.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 | 96 |
103 mojo::StrongBinding<ResourceUsageReporter> binding_; | 97 mojo::StrongBinding<ResourceUsageReporter> binding_; |
104 }; | 98 }; |
105 | 99 |
106 void CreateResourceUsageReporter( | 100 void CreateResourceUsageReporter( |
107 mojo::InterfaceRequest<ResourceUsageReporter> request) { | 101 mojo::InterfaceRequest<ResourceUsageReporter> request) { |
108 new ResourceUsageReporterImpl(std::move(request)); | 102 new ResourceUsageReporterImpl(std::move(request)); |
109 } | 103 } |
110 #endif // OS_ANDROID | 104 #endif // OS_ANDROID |
111 | 105 |
| 106 void CreateImageDecoder(mojo::InterfaceRequest<mojom::ImageDecoder> request) { |
| 107 content::UtilityThread::Get()->EnsureBlinkInitialized(); |
| 108 new ImageDecoderImpl(std::move(request)); |
| 109 } |
| 110 |
112 } // namespace | 111 } // namespace |
113 | 112 |
114 int64_t ChromeContentUtilityClient::max_ipc_message_size_ = | |
115 IPC::Channel::kMaximumMessageSize; | |
116 | |
117 ChromeContentUtilityClient::ChromeContentUtilityClient() | 113 ChromeContentUtilityClient::ChromeContentUtilityClient() |
118 : filter_messages_(false) { | 114 : filter_messages_(false) { |
119 #if !defined(OS_ANDROID) | 115 #if !defined(OS_ANDROID) |
120 handlers_.push_back(new ProfileImportHandler()); | 116 handlers_.push_back(new ProfileImportHandler()); |
121 #endif | 117 #endif |
122 | 118 |
123 #if defined(ENABLE_EXTENSIONS) | 119 #if defined(ENABLE_EXTENSIONS) |
124 handlers_.push_back(new extensions::ExtensionsHandler(this)); | 120 handlers_.push_back(new extensions::ExtensionsHandler(this)); |
125 handlers_.push_back(new image_writer::ImageWriterHandler()); | 121 handlers_.push_back(new image_writer::ImageWriterHandler()); |
126 #endif | 122 #endif |
(...skipping 27 matching lines...) Expand all Loading... |
154 } | 150 } |
155 } | 151 } |
156 | 152 |
157 bool ChromeContentUtilityClient::OnMessageReceived( | 153 bool ChromeContentUtilityClient::OnMessageReceived( |
158 const IPC::Message& message) { | 154 const IPC::Message& message) { |
159 if (filter_messages_ && !ContainsKey(message_id_whitelist_, message.type())) | 155 if (filter_messages_ && !ContainsKey(message_id_whitelist_, message.type())) |
160 return false; | 156 return false; |
161 | 157 |
162 bool handled = true; | 158 bool handled = true; |
163 IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message) | 159 IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message) |
164 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_DecodeImage, OnDecodeImage) | |
165 #if defined(OS_CHROMEOS) | |
166 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RobustJPEGDecodeImage, | |
167 OnRobustJPEGDecodeImage) | |
168 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RobustPNGDecodeImage, | |
169 OnRobustPNGDecodeImage) | |
170 #endif // defined(OS_CHROMEOS) | |
171 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileBsdiff, | 160 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileBsdiff, |
172 OnPatchFileBsdiff) | 161 OnPatchFileBsdiff) |
173 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileCourgette, | 162 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileCourgette, |
174 OnPatchFileCourgette) | 163 OnPatchFileCourgette) |
175 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_StartupPing, OnStartupPing) | 164 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_StartupPing, OnStartupPing) |
176 #if defined(FULL_SAFE_BROWSING) | 165 #if defined(FULL_SAFE_BROWSING) |
177 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_AnalyzeZipFileForDownloadProtection, | 166 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_AnalyzeZipFileForDownloadProtection, |
178 OnAnalyzeZipFileForDownloadProtection) | 167 OnAnalyzeZipFileForDownloadProtection) |
179 #if defined(OS_MACOSX) | 168 #if defined(OS_MACOSX) |
180 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_AnalyzeDmgFileForDownloadProtection, | 169 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_AnalyzeDmgFileForDownloadProtection, |
(...skipping 24 matching lines...) Expand all Loading... |
205 // converted to Mojo. | 194 // converted to Mojo. |
206 if (filter_messages_) | 195 if (filter_messages_) |
207 return; | 196 return; |
208 | 197 |
209 #if !defined(OS_ANDROID) | 198 #if !defined(OS_ANDROID) |
210 registry->AddService<net::interfaces::ProxyResolverFactory>( | 199 registry->AddService<net::interfaces::ProxyResolverFactory>( |
211 base::Bind(CreateProxyResolverFactory)); | 200 base::Bind(CreateProxyResolverFactory)); |
212 registry->AddService<ResourceUsageReporter>( | 201 registry->AddService<ResourceUsageReporter>( |
213 base::Bind(CreateResourceUsageReporter)); | 202 base::Bind(CreateResourceUsageReporter)); |
214 #endif | 203 #endif |
| 204 registry->AddService(base::Bind(&CreateImageDecoder)); |
215 } | 205 } |
216 | 206 |
217 void ChromeContentUtilityClient::AddHandler( | 207 void ChromeContentUtilityClient::AddHandler( |
218 scoped_ptr<UtilityMessageHandler> handler) { | 208 scoped_ptr<UtilityMessageHandler> handler) { |
219 handlers_.push_back(std::move(handler)); | 209 handlers_.push_back(std::move(handler)); |
220 } | 210 } |
221 | 211 |
222 // static | 212 // static |
223 void ChromeContentUtilityClient::PreSandboxStartup() { | 213 void ChromeContentUtilityClient::PreSandboxStartup() { |
224 #if defined(ENABLE_EXTENSIONS) | 214 #if defined(ENABLE_EXTENSIONS) |
225 extensions::ExtensionsHandler::PreSandboxStartup(); | 215 extensions::ExtensionsHandler::PreSandboxStartup(); |
226 #endif | 216 #endif |
227 } | 217 } |
228 | 218 |
229 // static | |
230 SkBitmap ChromeContentUtilityClient::DecodeImage( | |
231 const std::vector<unsigned char>& encoded_data, bool shrink_to_fit) { | |
232 SkBitmap decoded_image; | |
233 if (encoded_data.empty()) | |
234 return decoded_image; | |
235 | |
236 decoded_image = content::DecodeImage(&encoded_data[0], | |
237 gfx::Size(), | |
238 encoded_data.size()); | |
239 | |
240 int64_t struct_size = sizeof(ChromeUtilityHostMsg_DecodeImage_Succeeded); | |
241 int64_t image_size = decoded_image.computeSize64(); | |
242 int halves = 0; | |
243 while (struct_size + (image_size >> 2*halves) > max_ipc_message_size_) | |
244 halves++; | |
245 if (halves) { | |
246 if (shrink_to_fit) { | |
247 // If decoded image is too large for IPC message, shrink it by halves. | |
248 // This prevents quality loss, and should never overshrink on displays | |
249 // smaller than 3600x2400. | |
250 // TODO (Issue 416916): Instead of shrinking, return via shared memory | |
251 decoded_image = skia::ImageOperations::Resize( | |
252 decoded_image, skia::ImageOperations::RESIZE_LANCZOS3, | |
253 decoded_image.width() >> halves, decoded_image.height() >> halves); | |
254 } else { | |
255 // Image too big for IPC message, but caller didn't request resize; | |
256 // pre-delete image so DecodeImageAndSend() will send an error. | |
257 decoded_image.reset(); | |
258 LOG(ERROR) << "Decoded image too large for IPC message"; | |
259 } | |
260 } | |
261 | |
262 return decoded_image; | |
263 } | |
264 | |
265 // static | |
266 void ChromeContentUtilityClient::DecodeImageAndSend( | |
267 const std::vector<unsigned char>& encoded_data, | |
268 bool shrink_to_fit, | |
269 int request_id) { | |
270 SkBitmap decoded_image = DecodeImage(encoded_data, shrink_to_fit); | |
271 | |
272 if (decoded_image.empty()) { | |
273 Send(new ChromeUtilityHostMsg_DecodeImage_Failed(request_id)); | |
274 } else { | |
275 Send(new ChromeUtilityHostMsg_DecodeImage_Succeeded(decoded_image, | |
276 request_id)); | |
277 } | |
278 ReleaseProcessIfNeeded(); | |
279 } | |
280 | |
281 void ChromeContentUtilityClient::OnDecodeImage( | |
282 const std::vector<unsigned char>& encoded_data, | |
283 bool shrink_to_fit, | |
284 int request_id) { | |
285 content::UtilityThread::Get()->EnsureBlinkInitialized(); | |
286 DecodeImageAndSend(encoded_data, shrink_to_fit, request_id); | |
287 } | |
288 | |
289 #if defined(OS_CHROMEOS) | 219 #if defined(OS_CHROMEOS) |
290 void ChromeContentUtilityClient::OnCreateZipFile( | 220 void ChromeContentUtilityClient::OnCreateZipFile( |
291 const base::FilePath& src_dir, | 221 const base::FilePath& src_dir, |
292 const std::vector<base::FilePath>& src_relative_paths, | 222 const std::vector<base::FilePath>& src_relative_paths, |
293 const base::FileDescriptor& dest_fd) { | 223 const base::FileDescriptor& dest_fd) { |
294 // dest_fd should be closed in the function. See ipc/ipc_message_util.h for | 224 // dest_fd should be closed in the function. See ipc/ipc_message_util.h for |
295 // details. | 225 // details. |
296 base::ScopedFD fd_closer(dest_fd.fd); | 226 base::ScopedFD fd_closer(dest_fd.fd); |
297 bool succeeded = true; | 227 bool succeeded = true; |
298 | 228 |
(...skipping 12 matching lines...) Expand all Loading... |
311 succeeded = zip::ZipFiles(src_dir, src_relative_paths, dest_fd.fd); | 241 succeeded = zip::ZipFiles(src_dir, src_relative_paths, dest_fd.fd); |
312 | 242 |
313 if (succeeded) | 243 if (succeeded) |
314 Send(new ChromeUtilityHostMsg_CreateZipFile_Succeeded()); | 244 Send(new ChromeUtilityHostMsg_CreateZipFile_Succeeded()); |
315 else | 245 else |
316 Send(new ChromeUtilityHostMsg_CreateZipFile_Failed()); | 246 Send(new ChromeUtilityHostMsg_CreateZipFile_Failed()); |
317 ReleaseProcessIfNeeded(); | 247 ReleaseProcessIfNeeded(); |
318 } | 248 } |
319 #endif // defined(OS_CHROMEOS) | 249 #endif // defined(OS_CHROMEOS) |
320 | 250 |
321 #if defined(OS_CHROMEOS) | |
322 void ChromeContentUtilityClient::OnRobustJPEGDecodeImage( | |
323 const std::vector<unsigned char>& encoded_data, | |
324 int request_id) { | |
325 // Our robust jpeg decoding is using IJG libjpeg. | |
326 if (!encoded_data.empty()) { | |
327 scoped_ptr<SkBitmap> decoded_image(gfx::JPEGCodecRobustSlow::Decode( | |
328 &encoded_data[0], encoded_data.size())); | |
329 if (!decoded_image.get() || decoded_image->empty()) { | |
330 Send(new ChromeUtilityHostMsg_DecodeImage_Failed(request_id)); | |
331 } else { | |
332 Send(new ChromeUtilityHostMsg_DecodeImage_Succeeded(*decoded_image, | |
333 request_id)); | |
334 } | |
335 } else { | |
336 Send(new ChromeUtilityHostMsg_DecodeImage_Failed(request_id)); | |
337 } | |
338 ReleaseProcessIfNeeded(); | |
339 } | |
340 | |
341 void ChromeContentUtilityClient::OnRobustPNGDecodeImage( | |
342 const std::vector<unsigned char>& encoded_data, | |
343 int request_id) { | |
344 // Our robust PNG decoding is using libpng. | |
345 if (!encoded_data.empty()) { | |
346 SkBitmap decoded_image; | |
347 if (gfx::PNGCodec::Decode(encoded_data.data(), | |
348 encoded_data.size(), | |
349 &decoded_image)) { | |
350 Send(new ChromeUtilityHostMsg_DecodeImage_Succeeded(decoded_image, | |
351 request_id)); | |
352 } else { | |
353 Send(new ChromeUtilityHostMsg_DecodeImage_Failed(request_id)); | |
354 } | |
355 } else { | |
356 Send(new ChromeUtilityHostMsg_DecodeImage_Failed(request_id)); | |
357 } | |
358 ReleaseProcessIfNeeded(); | |
359 } | |
360 #endif // defined(OS_CHROMEOS) | |
361 | |
362 void ChromeContentUtilityClient::OnPatchFileBsdiff( | 251 void ChromeContentUtilityClient::OnPatchFileBsdiff( |
363 const base::FilePath& input_file, | 252 const base::FilePath& input_file, |
364 const base::FilePath& patch_file, | 253 const base::FilePath& patch_file, |
365 const base::FilePath& output_file) { | 254 const base::FilePath& output_file) { |
366 if (input_file.empty() || patch_file.empty() || output_file.empty()) { | 255 if (input_file.empty() || patch_file.empty() || output_file.empty()) { |
367 Send(new ChromeUtilityHostMsg_PatchFile_Finished(-1)); | 256 Send(new ChromeUtilityHostMsg_PatchFile_Finished(-1)); |
368 } else { | 257 } else { |
369 const int patch_status = courgette::ApplyBinaryPatch(input_file, | 258 const int patch_status = courgette::ApplyBinaryPatch(input_file, |
370 patch_file, | 259 patch_file, |
371 output_file); | 260 output_file); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 safe_browsing::zip_analyzer::Results results; | 303 safe_browsing::zip_analyzer::Results results; |
415 safe_browsing::dmg::AnalyzeDMGFile( | 304 safe_browsing::dmg::AnalyzeDMGFile( |
416 IPC::PlatformFileForTransitToFile(dmg_file), &results); | 305 IPC::PlatformFileForTransitToFile(dmg_file), &results); |
417 Send(new ChromeUtilityHostMsg_AnalyzeDmgFileForDownloadProtection_Finished( | 306 Send(new ChromeUtilityHostMsg_AnalyzeDmgFileForDownloadProtection_Finished( |
418 results)); | 307 results)); |
419 ReleaseProcessIfNeeded(); | 308 ReleaseProcessIfNeeded(); |
420 } | 309 } |
421 #endif // defined(OS_MACOSX) | 310 #endif // defined(OS_MACOSX) |
422 | 311 |
423 #endif // defined(FULL_SAFE_BROWSING) | 312 #endif // defined(FULL_SAFE_BROWSING) |
OLD | NEW |