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/font_cache_handler_win.h" | 41 #include "chrome/utility/font_cache_handler_win.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 | 97 |
104 mojo::StrongBinding<ResourceUsageReporter> binding_; | 98 mojo::StrongBinding<ResourceUsageReporter> binding_; |
105 }; | 99 }; |
106 | 100 |
107 void CreateResourceUsageReporter( | 101 void CreateResourceUsageReporter( |
108 mojo::InterfaceRequest<ResourceUsageReporter> request) { | 102 mojo::InterfaceRequest<ResourceUsageReporter> request) { |
109 new ResourceUsageReporterImpl(std::move(request)); | 103 new ResourceUsageReporterImpl(std::move(request)); |
110 } | 104 } |
111 #endif // OS_ANDROID | 105 #endif // OS_ANDROID |
112 | 106 |
| 107 void CreateImageDecoder(mojo::InterfaceRequest<mojom::ImageDecoder> request) { |
| 108 content::UtilityThread::Get()->EnsureBlinkInitialized(); |
| 109 new ImageDecoderImpl(std::move(request)); |
| 110 } |
| 111 |
113 } // namespace | 112 } // namespace |
114 | 113 |
115 int64_t ChromeContentUtilityClient::max_ipc_message_size_ = | |
116 IPC::Channel::kMaximumMessageSize; | |
117 | |
118 ChromeContentUtilityClient::ChromeContentUtilityClient() | 114 ChromeContentUtilityClient::ChromeContentUtilityClient() |
119 : filter_messages_(false) { | 115 : filter_messages_(false) { |
120 #if !defined(OS_ANDROID) | 116 #if !defined(OS_ANDROID) |
121 handlers_.push_back(new ProfileImportHandler()); | 117 handlers_.push_back(new ProfileImportHandler()); |
122 #endif | 118 #endif |
123 | 119 |
124 #if defined(ENABLE_EXTENSIONS) | 120 #if defined(ENABLE_EXTENSIONS) |
125 handlers_.push_back(new extensions::ExtensionsHandler(this)); | 121 handlers_.push_back(new extensions::ExtensionsHandler(this)); |
126 handlers_.push_back(new image_writer::ImageWriterHandler()); | 122 handlers_.push_back(new image_writer::ImageWriterHandler()); |
127 #endif | 123 #endif |
(...skipping 28 matching lines...) Expand all Loading... |
156 } | 152 } |
157 } | 153 } |
158 | 154 |
159 bool ChromeContentUtilityClient::OnMessageReceived( | 155 bool ChromeContentUtilityClient::OnMessageReceived( |
160 const IPC::Message& message) { | 156 const IPC::Message& message) { |
161 if (filter_messages_ && !ContainsKey(message_id_whitelist_, message.type())) | 157 if (filter_messages_ && !ContainsKey(message_id_whitelist_, message.type())) |
162 return false; | 158 return false; |
163 | 159 |
164 bool handled = true; | 160 bool handled = true; |
165 IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message) | 161 IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message) |
166 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_DecodeImage, OnDecodeImage) | |
167 #if defined(OS_CHROMEOS) | |
168 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RobustJPEGDecodeImage, | |
169 OnRobustJPEGDecodeImage) | |
170 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RobustPNGDecodeImage, | |
171 OnRobustPNGDecodeImage) | |
172 #endif // defined(OS_CHROMEOS) | |
173 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileBsdiff, | 162 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileBsdiff, |
174 OnPatchFileBsdiff) | 163 OnPatchFileBsdiff) |
175 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileCourgette, | 164 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileCourgette, |
176 OnPatchFileCourgette) | 165 OnPatchFileCourgette) |
177 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_StartupPing, OnStartupPing) | 166 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_StartupPing, OnStartupPing) |
178 #if defined(FULL_SAFE_BROWSING) | 167 #if defined(FULL_SAFE_BROWSING) |
179 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_AnalyzeZipFileForDownloadProtection, | 168 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_AnalyzeZipFileForDownloadProtection, |
180 OnAnalyzeZipFileForDownloadProtection) | 169 OnAnalyzeZipFileForDownloadProtection) |
181 #if defined(OS_MACOSX) | 170 #if defined(OS_MACOSX) |
182 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_AnalyzeDmgFileForDownloadProtection, | 171 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_AnalyzeDmgFileForDownloadProtection, |
(...skipping 15 matching lines...) Expand all Loading... |
198 } | 187 } |
199 | 188 |
200 void ChromeContentUtilityClient::RegisterMojoServices( | 189 void ChromeContentUtilityClient::RegisterMojoServices( |
201 content::ServiceRegistry* registry) { | 190 content::ServiceRegistry* registry) { |
202 #if !defined(OS_ANDROID) | 191 #if !defined(OS_ANDROID) |
203 registry->AddService<net::interfaces::ProxyResolverFactory>( | 192 registry->AddService<net::interfaces::ProxyResolverFactory>( |
204 base::Bind(CreateProxyResolverFactory)); | 193 base::Bind(CreateProxyResolverFactory)); |
205 registry->AddService<ResourceUsageReporter>( | 194 registry->AddService<ResourceUsageReporter>( |
206 base::Bind(CreateResourceUsageReporter)); | 195 base::Bind(CreateResourceUsageReporter)); |
207 #endif | 196 #endif |
| 197 registry->AddService(base::Bind(&CreateImageDecoder)); |
208 } | 198 } |
209 | 199 |
210 void ChromeContentUtilityClient::AddHandler( | 200 void ChromeContentUtilityClient::AddHandler( |
211 scoped_ptr<UtilityMessageHandler> handler) { | 201 scoped_ptr<UtilityMessageHandler> handler) { |
212 handlers_.push_back(std::move(handler)); | 202 handlers_.push_back(std::move(handler)); |
213 } | 203 } |
214 | 204 |
215 // static | 205 // static |
216 void ChromeContentUtilityClient::PreSandboxStartup() { | 206 void ChromeContentUtilityClient::PreSandboxStartup() { |
217 #if defined(ENABLE_EXTENSIONS) | 207 #if defined(ENABLE_EXTENSIONS) |
218 extensions::ExtensionsHandler::PreSandboxStartup(); | 208 extensions::ExtensionsHandler::PreSandboxStartup(); |
219 #endif | 209 #endif |
220 } | 210 } |
221 | 211 |
222 // static | |
223 SkBitmap ChromeContentUtilityClient::DecodeImage( | |
224 const std::vector<unsigned char>& encoded_data, bool shrink_to_fit) { | |
225 SkBitmap decoded_image; | |
226 if (encoded_data.empty()) | |
227 return decoded_image; | |
228 | |
229 decoded_image = content::DecodeImage(&encoded_data[0], | |
230 gfx::Size(), | |
231 encoded_data.size()); | |
232 | |
233 int64_t struct_size = sizeof(ChromeUtilityHostMsg_DecodeImage_Succeeded); | |
234 int64_t image_size = decoded_image.computeSize64(); | |
235 int halves = 0; | |
236 while (struct_size + (image_size >> 2*halves) > max_ipc_message_size_) | |
237 halves++; | |
238 if (halves) { | |
239 if (shrink_to_fit) { | |
240 // If decoded image is too large for IPC message, shrink it by halves. | |
241 // This prevents quality loss, and should never overshrink on displays | |
242 // smaller than 3600x2400. | |
243 // TODO (Issue 416916): Instead of shrinking, return via shared memory | |
244 decoded_image = skia::ImageOperations::Resize( | |
245 decoded_image, skia::ImageOperations::RESIZE_LANCZOS3, | |
246 decoded_image.width() >> halves, decoded_image.height() >> halves); | |
247 } else { | |
248 // Image too big for IPC message, but caller didn't request resize; | |
249 // pre-delete image so DecodeImageAndSend() will send an error. | |
250 decoded_image.reset(); | |
251 LOG(ERROR) << "Decoded image too large for IPC message"; | |
252 } | |
253 } | |
254 | |
255 return decoded_image; | |
256 } | |
257 | |
258 // static | |
259 void ChromeContentUtilityClient::DecodeImageAndSend( | |
260 const std::vector<unsigned char>& encoded_data, | |
261 bool shrink_to_fit, | |
262 int request_id) { | |
263 SkBitmap decoded_image = DecodeImage(encoded_data, shrink_to_fit); | |
264 | |
265 if (decoded_image.empty()) { | |
266 Send(new ChromeUtilityHostMsg_DecodeImage_Failed(request_id)); | |
267 } else { | |
268 Send(new ChromeUtilityHostMsg_DecodeImage_Succeeded(decoded_image, | |
269 request_id)); | |
270 } | |
271 ReleaseProcessIfNeeded(); | |
272 } | |
273 | |
274 void ChromeContentUtilityClient::OnDecodeImage( | |
275 const std::vector<unsigned char>& encoded_data, | |
276 bool shrink_to_fit, | |
277 int request_id) { | |
278 content::UtilityThread::Get()->EnsureBlinkInitialized(); | |
279 DecodeImageAndSend(encoded_data, shrink_to_fit, request_id); | |
280 } | |
281 | |
282 #if defined(OS_CHROMEOS) | 212 #if defined(OS_CHROMEOS) |
283 void ChromeContentUtilityClient::OnCreateZipFile( | 213 void ChromeContentUtilityClient::OnCreateZipFile( |
284 const base::FilePath& src_dir, | 214 const base::FilePath& src_dir, |
285 const std::vector<base::FilePath>& src_relative_paths, | 215 const std::vector<base::FilePath>& src_relative_paths, |
286 const base::FileDescriptor& dest_fd) { | 216 const base::FileDescriptor& dest_fd) { |
287 // dest_fd should be closed in the function. See ipc/ipc_message_util.h for | 217 // dest_fd should be closed in the function. See ipc/ipc_message_util.h for |
288 // details. | 218 // details. |
289 base::ScopedFD fd_closer(dest_fd.fd); | 219 base::ScopedFD fd_closer(dest_fd.fd); |
290 bool succeeded = true; | 220 bool succeeded = true; |
291 | 221 |
(...skipping 12 matching lines...) Expand all Loading... |
304 succeeded = zip::ZipFiles(src_dir, src_relative_paths, dest_fd.fd); | 234 succeeded = zip::ZipFiles(src_dir, src_relative_paths, dest_fd.fd); |
305 | 235 |
306 if (succeeded) | 236 if (succeeded) |
307 Send(new ChromeUtilityHostMsg_CreateZipFile_Succeeded()); | 237 Send(new ChromeUtilityHostMsg_CreateZipFile_Succeeded()); |
308 else | 238 else |
309 Send(new ChromeUtilityHostMsg_CreateZipFile_Failed()); | 239 Send(new ChromeUtilityHostMsg_CreateZipFile_Failed()); |
310 ReleaseProcessIfNeeded(); | 240 ReleaseProcessIfNeeded(); |
311 } | 241 } |
312 #endif // defined(OS_CHROMEOS) | 242 #endif // defined(OS_CHROMEOS) |
313 | 243 |
314 #if defined(OS_CHROMEOS) | |
315 void ChromeContentUtilityClient::OnRobustJPEGDecodeImage( | |
316 const std::vector<unsigned char>& encoded_data, | |
317 int request_id) { | |
318 // Our robust jpeg decoding is using IJG libjpeg. | |
319 if (!encoded_data.empty()) { | |
320 scoped_ptr<SkBitmap> decoded_image(gfx::JPEGCodecRobustSlow::Decode( | |
321 &encoded_data[0], encoded_data.size())); | |
322 if (!decoded_image.get() || decoded_image->empty()) { | |
323 Send(new ChromeUtilityHostMsg_DecodeImage_Failed(request_id)); | |
324 } else { | |
325 Send(new ChromeUtilityHostMsg_DecodeImage_Succeeded(*decoded_image, | |
326 request_id)); | |
327 } | |
328 } else { | |
329 Send(new ChromeUtilityHostMsg_DecodeImage_Failed(request_id)); | |
330 } | |
331 ReleaseProcessIfNeeded(); | |
332 } | |
333 | |
334 void ChromeContentUtilityClient::OnRobustPNGDecodeImage( | |
335 const std::vector<unsigned char>& encoded_data, | |
336 int request_id) { | |
337 // Our robust PNG decoding is using libpng. | |
338 if (!encoded_data.empty()) { | |
339 SkBitmap decoded_image; | |
340 if (gfx::PNGCodec::Decode(encoded_data.data(), | |
341 encoded_data.size(), | |
342 &decoded_image)) { | |
343 Send(new ChromeUtilityHostMsg_DecodeImage_Succeeded(decoded_image, | |
344 request_id)); | |
345 } else { | |
346 Send(new ChromeUtilityHostMsg_DecodeImage_Failed(request_id)); | |
347 } | |
348 } else { | |
349 Send(new ChromeUtilityHostMsg_DecodeImage_Failed(request_id)); | |
350 } | |
351 ReleaseProcessIfNeeded(); | |
352 } | |
353 #endif // defined(OS_CHROMEOS) | |
354 | |
355 void ChromeContentUtilityClient::OnPatchFileBsdiff( | 244 void ChromeContentUtilityClient::OnPatchFileBsdiff( |
356 const base::FilePath& input_file, | 245 const base::FilePath& input_file, |
357 const base::FilePath& patch_file, | 246 const base::FilePath& patch_file, |
358 const base::FilePath& output_file) { | 247 const base::FilePath& output_file) { |
359 if (input_file.empty() || patch_file.empty() || output_file.empty()) { | 248 if (input_file.empty() || patch_file.empty() || output_file.empty()) { |
360 Send(new ChromeUtilityHostMsg_PatchFile_Finished(-1)); | 249 Send(new ChromeUtilityHostMsg_PatchFile_Finished(-1)); |
361 } else { | 250 } else { |
362 const int patch_status = courgette::ApplyBinaryPatch(input_file, | 251 const int patch_status = courgette::ApplyBinaryPatch(input_file, |
363 patch_file, | 252 patch_file, |
364 output_file); | 253 output_file); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 safe_browsing::zip_analyzer::Results results; | 296 safe_browsing::zip_analyzer::Results results; |
408 safe_browsing::dmg::AnalyzeDMGFile( | 297 safe_browsing::dmg::AnalyzeDMGFile( |
409 IPC::PlatformFileForTransitToFile(dmg_file), &results); | 298 IPC::PlatformFileForTransitToFile(dmg_file), &results); |
410 Send(new ChromeUtilityHostMsg_AnalyzeDmgFileForDownloadProtection_Finished( | 299 Send(new ChromeUtilityHostMsg_AnalyzeDmgFileForDownloadProtection_Finished( |
411 results)); | 300 results)); |
412 ReleaseProcessIfNeeded(); | 301 ReleaseProcessIfNeeded(); |
413 } | 302 } |
414 #endif // defined(OS_MACOSX) | 303 #endif // defined(OS_MACOSX) |
415 | 304 |
416 #endif // defined(FULL_SAFE_BROWSING) | 305 #endif // defined(FULL_SAFE_BROWSING) |
OLD | NEW |