| 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 |