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