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 3 // found in the LICENSE file. 4 5 #include "chrome/utility/chrome_content_utility_client.h" 6 7 #include "base/base64.h" 8 #include "base/bind.h" 9 #include "base/command_line.h" 10 #include "base/files/file_path.h" 11 #include "base/json/json_reader.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/path_service.h" 15 #include "base/time/time.h" 16 #include "chrome/common/chrome_utility_messages.h" 17 #include "chrome/common/extensions/chrome_extensions_client.h" 18 #include "chrome/common/extensions/extension.h" 19 #include "chrome/common/extensions/extension_l10n_util.h" 20 #include "chrome/common/extensions/manifest.h" 21 #include "chrome/common/extensions/update_manifest.h" 22 #include "chrome/common/safe_browsing/zip_analyzer.h" 23 #include "chrome/utility/extensions/unpacker.h" 24 #include "chrome/utility/profile_import_handler.h" 25 #include "chrome/utility/web_resource_unpacker.h" 26 #include "content/public/child/image_decoder_utils.h" 27 #include "content/public/common/content_paths.h" 28 #include "content/public/utility/utility_thread.h" 29 #include "media/base/media.h" 30 #include "media/base/media_file_checker.h" 31 #include "printing/page_range.h" 32 #include "third_party/skia/include/core/SkBitmap.h" 33 #include "third_party/zlib/google/zip.h" 34 #include "ui/base/ui_base_switches.h" 35 #include "ui/gfx/codec/jpeg_codec.h" 36 #include "ui/gfx/rect.h" 37 #include "ui/gfx/size.h" 38 39 #if defined(OS_WIN) 40 #include "base/file_util.h" 41 #include "base/path_service.h" 42 #include "base/win/iat_patch_function.h" 43 #include "base/win/scoped_handle.h" 44 #include "chrome/common/chrome_paths.h" 45 #include "chrome/utility/media_galleries/itunes_pref_parser_win.h" 46 #include "printing/emf_win.h" 47 #include "ui/gfx/gdi_util.h" 48 #endif // defined(OS_WIN) 49 50 #if defined(OS_WIN) || defined(OS_MACOSX) 51 #include "chrome/utility/media_galleries/itunes_library_parser.h" 52 #include "chrome/utility/media_galleries/picasa_album_table_reader.h" 53 #include "chrome/utility/media_galleries/picasa_albums_indexer.h" 54 #endif // defined(OS_WIN) || defined(OS_MACOSX) 55 56 #if defined(ENABLE_FULL_PRINTING) 57 #include "chrome/common/child_process_logging.h" 58 #include "printing/backend/print_backend.h" 59 #endif 60 61 #if defined(ENABLE_MDNS) 62 #include "chrome/utility/local_discovery/service_discovery_message_handler.h" 63 #endif // ENABLE_MDNS 64 65 namespace chrome { 66 67 namespace { 68 69 bool Send(IPC::Message* message) { 70 return content::UtilityThread::Get()->Send(message); 71 } 72 73 void ReleaseProcessIfNeeded() { 74 content::UtilityThread::Get()->ReleaseProcessIfNeeded(); 75 } 76 77 } // namespace 78 79 ChromeContentUtilityClient::ChromeContentUtilityClient() { 80 #if !defined(OS_ANDROID) 81 handlers_.push_back(new ProfileImportHandler()); 82 #endif // OS_ANDROID 83 84 #if defined(ENABLE_MDNS) 85 handlers_.push_back(new local_discovery::ServiceDiscoveryMessageHandler()); 86 #endif // ENABLE_MDNS 87 } 88 89 ChromeContentUtilityClient::~ChromeContentUtilityClient() { 90 } 91 92 void ChromeContentUtilityClient::UtilityThreadStarted() { 93 #if defined(OS_WIN) 94 // Load the pdf plugin before the sandbox is turned on. This is for Windows 95 // only because we need this DLL only on Windows. 96 base::FilePath pdf; 97 if (PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf) && 98 base::PathExists(pdf)) { 99 bool rv = !!LoadLibrary(pdf.value().c_str()); 100 DCHECK(rv) << "Couldn't load PDF plugin"; 101 } 102 #endif 103 104 CommandLine* command_line = CommandLine::ForCurrentProcess(); 105 std::string lang = command_line->GetSwitchValueASCII(switches::kLang); 106 if (!lang.empty()) 107 extension_l10n_util::SetProcessLocale(lang); 108 } 109 110 bool ChromeContentUtilityClient::OnMessageReceived( 111 const IPC::Message& message) { 112 bool handled = true; 113 IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message) 114 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_UnpackExtension, OnUnpackExtension) 115 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_UnpackWebResource, 116 OnUnpackWebResource) 117 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseUpdateManifest, 118 OnParseUpdateManifest) 119 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_DecodeImage, OnDecodeImage) 120 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_DecodeImageBase64, OnDecodeImageBase64) 121 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafile, 122 OnRenderPDFPagesToMetafile) 123 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RobustJPEGDecodeImage, 124 OnRobustJPEGDecodeImage) 125 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseJSON, OnParseJSON) 126 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_GetPrinterCapsAndDefaults, 127 OnGetPrinterCapsAndDefaults) 128 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_StartupPing, OnStartupPing) 129 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_AnalyzeZipFileForDownloadProtection, 130 OnAnalyzeZipFileForDownloadProtection) 131 132 #if !defined(OS_ANDROID) && !defined(OS_IOS) 133 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_CheckMediaFile, OnCheckMediaFile) 134 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) 135 136 #if defined(OS_CHROMEOS) 137 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_CreateZipFile, OnCreateZipFile) 138 #endif // defined(OS_CHROMEOS) 139 140 #if defined(OS_WIN) 141 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseITunesPrefXml, 142 OnParseITunesPrefXml) 143 #endif // defined(OS_WIN) 144 145 #if defined(OS_WIN) || defined(OS_MACOSX) 146 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseITunesLibraryXmlFile, 147 OnParseITunesLibraryXmlFile) 148 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParsePicasaPMPDatabase, 149 OnParsePicasaPMPDatabase) 150 #endif // defined(OS_WIN) || defined(OS_MACOSX) 151 152 IPC_MESSAGE_UNHANDLED(handled = false) 153 IPC_END_MESSAGE_MAP() 154 155 for (Handlers::iterator it = handlers_.begin(); 156 !handled && it != handlers_.end(); ++it) { 157 handled = (*it)->OnMessageReceived(message); 158 } 159 160 return handled; 161 } 162 163 // static 164 void ChromeContentUtilityClient::PreSandboxStartup() { 165 #if defined(ENABLE_MDNS) 166 local_discovery::ServiceDiscoveryMessageHandler::PreSandboxStartup(); 167 #endif // ENABLE_MDNS 168 169 // Load media libraries for media file validation. 170 base::FilePath media_path; 171 PathService::Get(content::DIR_MEDIA_LIBS, &media_path); 172 if (!media_path.empty()) 173 media::InitializeMediaLibrary(media_path); 174 } 175 176 void ChromeContentUtilityClient::OnUnpackExtension( 177 const base::FilePath& extension_path, 178 const std::string& extension_id, 179 int location, 180 int creation_flags) { 181 CHECK_GT(location, extensions::Manifest::INVALID_LOCATION); 182 CHECK_LT(location, extensions::Manifest::NUM_LOCATIONS); 183 extensions::ExtensionsClient::Set( 184 extensions::ChromeExtensionsClient::GetInstance()); 185 extensions::Unpacker unpacker( 186 extension_path, 187 extension_id, 188 static_cast<extensions::Manifest::Location>(location), 189 creation_flags); 190 if (unpacker.Run() && unpacker.DumpImagesToFile() && 191 unpacker.DumpMessageCatalogsToFile()) { 192 Send(new ChromeUtilityHostMsg_UnpackExtension_Succeeded( 193 *unpacker.parsed_manifest())); 194 } else { 195 Send(new ChromeUtilityHostMsg_UnpackExtension_Failed( 196 unpacker.error_message())); 197 } 198 199 ReleaseProcessIfNeeded(); 200 } 201 202 void ChromeContentUtilityClient::OnUnpackWebResource( 203 const std::string& resource_data) { 204 // Parse json data. 205 // TODO(mrc): Add the possibility of a template that controls parsing, and 206 // the ability to download and verify images. 207 WebResourceUnpacker unpacker(resource_data); 208 if (unpacker.Run()) { 209 Send(new ChromeUtilityHostMsg_UnpackWebResource_Succeeded( 210 *unpacker.parsed_json())); 211 } else { 212 Send(new ChromeUtilityHostMsg_UnpackWebResource_Failed( 213 unpacker.error_message())); 214 } 215 216 ReleaseProcessIfNeeded(); 217 } 218 219 void ChromeContentUtilityClient::OnParseUpdateManifest(const std::string& xml) { 220 UpdateManifest manifest; 221 if (!manifest.Parse(xml)) { 222 Send(new ChromeUtilityHostMsg_ParseUpdateManifest_Failed( 223 manifest.errors())); 224 } else { 225 Send(new ChromeUtilityHostMsg_ParseUpdateManifest_Succeeded( 226 manifest.results())); 227 } 228 ReleaseProcessIfNeeded(); 229 } 230 231 void ChromeContentUtilityClient::OnDecodeImage( 232 const std::vector<unsigned char>& encoded_data) { 233 const SkBitmap& decoded_image = content::DecodeImage(&encoded_data[0], 234 gfx::Size(), 235 encoded_data.size()); 236 if (decoded_image.empty()) { 237 Send(new ChromeUtilityHostMsg_DecodeImage_Failed()); 238 } else { 239 Send(new ChromeUtilityHostMsg_DecodeImage_Succeeded(decoded_image)); 240 } 241 ReleaseProcessIfNeeded(); 242 } 243 244 void ChromeContentUtilityClient::OnDecodeImageBase64( 245 const std::string& encoded_string) { 246 std::string decoded_string; 247 248 if (!base::Base64Decode(encoded_string, &decoded_string)) { 249 Send(new ChromeUtilityHostMsg_DecodeImage_Failed()); 250 return; 251 } 252 253 std::vector<unsigned char> decoded_vector(decoded_string.size()); 254 for (size_t i = 0; i < decoded_string.size(); ++i) { 255 decoded_vector[i] = static_cast<unsigned char>(decoded_string[i]); 256 } 257 258 OnDecodeImage(decoded_vector); 259 } 260 261 #if defined(OS_CHROMEOS) 262 void ChromeContentUtilityClient::OnCreateZipFile( 263 const base::FilePath& src_dir, 264 const std::vector<base::FilePath>& src_relative_paths, 265 const base::FileDescriptor& dest_fd) { 266 bool succeeded = true; 267 268 // Check sanity of source relative paths. Reject if path is absolute or 269 // contains any attempt to reference a parent directory ("../" tricks). 270 for (std::vector<base::FilePath>::const_iterator iter = 271 src_relative_paths.begin(); iter != src_relative_paths.end(); 272 ++iter) { 273 if (iter->IsAbsolute() || iter->ReferencesParent()) { 274 succeeded = false; 275 break; 276 } 277 } 278 279 if (succeeded) 280 succeeded = zip::ZipFiles(src_dir, src_relative_paths, dest_fd.fd); 281 282 if (succeeded) 283 Send(new ChromeUtilityHostMsg_CreateZipFile_Succeeded()); 284 else 285 Send(new ChromeUtilityHostMsg_CreateZipFile_Failed()); 286 ReleaseProcessIfNeeded(); 287 } 288 #endif // defined(OS_CHROMEOS) 289 290 void ChromeContentUtilityClient::OnRenderPDFPagesToMetafile( 291 base::PlatformFile pdf_file, 292 const base::FilePath& metafile_path, 293 const printing::PdfRenderSettings& pdf_render_settings, 294 const std::vector<printing::PageRange>& page_ranges) { 295 bool succeeded = false; 296 #if defined(OS_WIN) 297 int highest_rendered_page_number = 0; 298 double scale_factor = 1.0; 299 succeeded = RenderPDFToWinMetafile(pdf_file, 300 metafile_path, 301 pdf_render_settings.area(), 302 pdf_render_settings.dpi(), 303 pdf_render_settings.autorotate(), 304 page_ranges, 305 &highest_rendered_page_number, 306 &scale_factor); 307 if (succeeded) { 308 Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafile_Succeeded( 309 highest_rendered_page_number, scale_factor)); 310 } 311 #endif // defined(OS_WIN) 312 if (!succeeded) { 313 Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafile_Failed()); 314 } 315 ReleaseProcessIfNeeded(); 316 } 317 318 #if defined(OS_WIN) 319 // Exported by pdf.dll 320 typedef bool (*RenderPDFPageToDCProc)( 321 const unsigned char* pdf_buffer, int buffer_size, int page_number, HDC dc, 322 int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y, 323 int bounds_width, int bounds_height, bool fit_to_bounds, 324 bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds, 325 bool autorotate); 326 327 typedef bool (*GetPDFDocInfoProc)(const unsigned char* pdf_buffer, 328 int buffer_size, int* page_count, 329 double* max_page_width); 330 331 // The 2 below IAT patch functions are almost identical to the code in 332 // render_process_impl.cc. This is needed to work around specific Windows APIs 333 // used by the Chrome PDF plugin that will fail in the sandbox. 334 static base::win::IATPatchFunction g_iat_patch_createdca; 335 HDC WINAPI UtilityProcess_CreateDCAPatch(LPCSTR driver_name, 336 LPCSTR device_name, 337 LPCSTR output, 338 const DEVMODEA* init_data) { 339 if (driver_name && 340 (std::string("DISPLAY") == std::string(driver_name))) 341 // CreateDC fails behind the sandbox, but not CreateCompatibleDC. 342 return CreateCompatibleDC(NULL); 343 344 NOTREACHED(); 345 return CreateDCA(driver_name, device_name, output, init_data); 346 } 347 348 static base::win::IATPatchFunction g_iat_patch_get_font_data; 349 DWORD WINAPI UtilityProcess_GetFontDataPatch( 350 HDC hdc, DWORD table, DWORD offset, LPVOID buffer, DWORD length) { 351 int rv = GetFontData(hdc, table, offset, buffer, length); 352 if (rv == GDI_ERROR && hdc) { 353 HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT)); 354 355 LOGFONT logfont; 356 if (GetObject(font, sizeof(LOGFONT), &logfont)) { 357 std::vector<char> font_data; 358 content::UtilityThread::Get()->PreCacheFont(logfont); 359 rv = GetFontData(hdc, table, offset, buffer, length); 360 content::UtilityThread::Get()->ReleaseCachedFonts(); 361 } 362 } 363 return rv; 364 } 365 366 bool ChromeContentUtilityClient::RenderPDFToWinMetafile( 367 base::PlatformFile pdf_file, 368 const base::FilePath& metafile_path, 369 const gfx::Rect& render_area, 370 int render_dpi, 371 bool autorotate, 372 const std::vector<printing::PageRange>& page_ranges, 373 int* highest_rendered_page_number, 374 double* scale_factor) { 375 *highest_rendered_page_number = -1; 376 *scale_factor = 1.0; 377 base::win::ScopedHandle file(pdf_file); 378 base::FilePath pdf_module_path; 379 PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_module_path); 380 HMODULE pdf_module = GetModuleHandle(pdf_module_path.value().c_str()); 381 if (!pdf_module) 382 return false; 383 384 RenderPDFPageToDCProc render_proc = 385 reinterpret_cast<RenderPDFPageToDCProc>( 386 GetProcAddress(pdf_module, "RenderPDFPageToDC")); 387 if (!render_proc) 388 return false; 389 390 GetPDFDocInfoProc get_info_proc = reinterpret_cast<GetPDFDocInfoProc>( 391 GetProcAddress(pdf_module, "GetPDFDocInfo")); 392 if (!get_info_proc) 393 return false; 394 395 // Patch the IAT for handling specific APIs known to fail in the sandbox. 396 if (!g_iat_patch_createdca.is_patched()) 397 g_iat_patch_createdca.Patch(pdf_module_path.value().c_str(), 398 "gdi32.dll", "CreateDCA", 399 UtilityProcess_CreateDCAPatch); 400 401 if (!g_iat_patch_get_font_data.is_patched()) 402 g_iat_patch_get_font_data.Patch(pdf_module_path.value().c_str(), 403 "gdi32.dll", "GetFontData", 404 UtilityProcess_GetFontDataPatch); 405 406 // TODO(sanjeevr): Add a method to the PDF DLL that takes in a file handle 407 // and a page range array. That way we don't need to read the entire PDF into 408 // memory. 409 DWORD length = ::GetFileSize(file, NULL); 410 if (length == INVALID_FILE_SIZE) 411 return false; 412 413 std::vector<uint8> buffer; 414 buffer.resize(length); 415 DWORD bytes_read = 0; 416 if (!ReadFile(pdf_file, &buffer.front(), length, &bytes_read, NULL) || 417 (bytes_read != length)) 418 return false; 419 420 int total_page_count = 0; 421 if (!get_info_proc(&buffer.front(), buffer.size(), &total_page_count, NULL)) 422 return false; 423 424 printing::Emf metafile; 425 metafile.InitToFile(metafile_path); 426 // We need to scale down DC to fit an entire page into DC available area. 427 // Current metafile is based on screen DC and have current screen size. 428 // Writing outside of those boundaries will result in the cut-off output. 429 // On metafiles (this is the case here), scaling down will still record 430 // original coordinates and we'll be able to print in full resolution. 431 // Before playback we'll need to counter the scaling up that will happen 432 // in the service (print_system_win.cc). 433 *scale_factor = gfx::CalculatePageScale(metafile.context(), 434 render_area.right(), 435 render_area.bottom()); 436 gfx::ScaleDC(metafile.context(), *scale_factor); 437 438 bool ret = false; 439 std::vector<printing::PageRange>::const_iterator iter; 440 for (iter = page_ranges.begin(); iter != page_ranges.end(); ++iter) { 441 for (int page_number = iter->from; page_number <= iter->to; ++page_number) { 442 if (page_number >= total_page_count) 443 break; 444 // The underlying metafile is of type Emf and ignores the arguments passed 445 // to StartPage. 446 metafile.StartPage(gfx::Size(), gfx::Rect(), 1); 447 if (render_proc(&buffer.front(), buffer.size(), page_number, 448 metafile.context(), render_dpi, render_dpi, 449 render_area.x(), render_area.y(), render_area.width(), 450 render_area.height(), true, false, true, true, 451 autorotate)) 452 if (*highest_rendered_page_number < page_number) 453 *highest_rendered_page_number = page_number; 454 ret = true; 455 metafile.FinishPage(); 456 } 457 } 458 metafile.FinishDocument(); 459 return ret; 460 } 461 #endif // defined(OS_WIN) 462 463 void ChromeContentUtilityClient::OnRobustJPEGDecodeImage( 464 const std::vector<unsigned char>& encoded_data) { 465 // Our robust jpeg decoding is using IJG libjpeg. 466 if (gfx::JPEGCodec::JpegLibraryVariant() == gfx::JPEGCodec::IJG_LIBJPEG) { 467 scoped_ptr<SkBitmap> decoded_image(gfx::JPEGCodec::Decode( 468 &encoded_data[0], encoded_data.size())); 469 if (!decoded_image.get() || decoded_image->empty()) { 470 Send(new ChromeUtilityHostMsg_DecodeImage_Failed()); 471 } else { 472 Send(new ChromeUtilityHostMsg_DecodeImage_Succeeded(*decoded_image)); 473 } 474 } else { 475 Send(new ChromeUtilityHostMsg_DecodeImage_Failed()); 476 } 477 ReleaseProcessIfNeeded(); 478 } 479 480 void ChromeContentUtilityClient::OnParseJSON(const std::string& json) { 481 int error_code; 482 std::string error; 483 base::Value* value = base::JSONReader::ReadAndReturnError( 484 json, base::JSON_PARSE_RFC, &error_code, &error); 485 if (value) { 486 base::ListValue wrapper; 487 wrapper.Append(value); 488 Send(new ChromeUtilityHostMsg_ParseJSON_Succeeded(wrapper)); 489 } else { 490 Send(new ChromeUtilityHostMsg_ParseJSON_Failed(error)); 491 } 492 ReleaseProcessIfNeeded(); 493 } 494 495 void ChromeContentUtilityClient::OnGetPrinterCapsAndDefaults( 496 const std::string& printer_name) { 497 #if defined(ENABLE_FULL_PRINTING) 498 scoped_refptr<printing::PrintBackend> print_backend = 499 printing::PrintBackend::CreateInstance(NULL); 500 printing::PrinterCapsAndDefaults printer_info; 501 502 child_process_logging::ScopedPrinterInfoSetter prn_info( 503 print_backend->GetPrinterDriverInfo(printer_name)); 504 505 if (print_backend->GetPrinterCapsAndDefaults(printer_name, &printer_info)) { 506 Send(new ChromeUtilityHostMsg_GetPrinterCapsAndDefaults_Succeeded( 507 printer_name, printer_info)); 508 } else // NOLINT 509 #endif 510 { 511 Send(new ChromeUtilityHostMsg_GetPrinterCapsAndDefaults_Failed( 512 printer_name)); 513 } 514 ReleaseProcessIfNeeded(); 515 } 516 517 void ChromeContentUtilityClient::OnStartupPing() { 518 Send(new ChromeUtilityHostMsg_ProcessStarted); 519 // Don't release the process, we assume further messages are on the way. 520 } 521 522 void ChromeContentUtilityClient::OnAnalyzeZipFileForDownloadProtection( 523 const IPC::PlatformFileForTransit& zip_file) { 524 safe_browsing::zip_analyzer::Results results; 525 safe_browsing::zip_analyzer::AnalyzeZipFile( 526 IPC::PlatformFileForTransitToPlatformFile(zip_file), &results); 527 Send(new ChromeUtilityHostMsg_AnalyzeZipFileForDownloadProtection_Finished( 528 results)); 529 ReleaseProcessIfNeeded(); 530 } 531 532 #if !defined(OS_ANDROID) && !defined(OS_IOS) 533 void ChromeContentUtilityClient::OnCheckMediaFile( 534 int64 milliseconds_of_decoding, 535 const IPC::PlatformFileForTransit& media_file) { 536 media::MediaFileChecker 537 checker(IPC::PlatformFileForTransitToPlatformFile(media_file)); 538 const bool check_success = checker.Start( 539 base::TimeDelta::FromMilliseconds(milliseconds_of_decoding)); 540 Send(new ChromeUtilityHostMsg_CheckMediaFile_Finished(check_success)); 541 ReleaseProcessIfNeeded(); 542 } 543 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) 544 545 #if defined(OS_WIN) 546 void ChromeContentUtilityClient::OnParseITunesPrefXml( 547 const std::string& itunes_xml_data) { 548 base::FilePath library_path( 549 itunes::FindLibraryLocationInPrefXml(itunes_xml_data)); 550 Send(new ChromeUtilityHostMsg_GotITunesDirectory(library_path)); 551 ReleaseProcessIfNeeded(); 552 } 553 #endif // defined(OS_WIN) 554 555 #if defined(OS_WIN) || defined(OS_MACOSX) 556 void ChromeContentUtilityClient::OnParseITunesLibraryXmlFile( 557 const IPC::PlatformFileForTransit& itunes_library_file) { 558 itunes::ITunesLibraryParser parser; 559 base::PlatformFile file = 560 IPC::PlatformFileForTransitToPlatformFile(itunes_library_file); 561 bool result = parser.Parse( 562 itunes::ITunesLibraryParser::ReadITunesLibraryXmlFile(file)); 563 Send(new ChromeUtilityHostMsg_GotITunesLibrary(result, parser.library())); 564 ReleaseProcessIfNeeded(); 565 } 566 567 void ChromeContentUtilityClient::OnParsePicasaPMPDatabase( 568 const picasa::AlbumTableFilesForTransit& album_table_files) { 569 picasa::AlbumTableFiles files; 570 files.indicator_file = IPC::PlatformFileForTransitToPlatformFile( 571 album_table_files.indicator_file); 572 files.category_file = IPC::PlatformFileForTransitToPlatformFile( 573 album_table_files.category_file); 574 files.date_file = IPC::PlatformFileForTransitToPlatformFile( 575 album_table_files.date_file); 576 files.filename_file = IPC::PlatformFileForTransitToPlatformFile( 577 album_table_files.filename_file); 578 files.name_file = IPC::PlatformFileForTransitToPlatformFile( 579 album_table_files.name_file); 580 files.token_file = IPC::PlatformFileForTransitToPlatformFile( 581 album_table_files.token_file); 582 files.uid_file = IPC::PlatformFileForTransitToPlatformFile( 583 album_table_files.uid_file); 584 585 picasa::PicasaAlbumTableReader reader(files); 586 bool parse_success = reader.Init(); 587 Send(new ChromeUtilityHostMsg_ParsePicasaPMPDatabase_Finished( 588 parse_success, 589 reader.albums(), 590 reader.folders())); 591 ReleaseProcessIfNeeded(); 592 } 593 594 void OnIndexPicasaAlbumsContents( 595 const picasa::AlbumUIDSet& album_uids, 596 const std::vector<picasa::FolderINIContents>& folders_inis) { 597 picasa::PicasaAlbumsIndexer indexer(album_uids); 598 for (std::vector<picasa::FolderINIContents>::const_iterator it = 599 folders_inis.begin(); 600 it != folders_inis.end(); ++it) { 601 indexer.ParseFolderINI(it->folder_path, it->ini_contents); 602 } 603 604 Send(new ChromeUtilityHostMsg_IndexPicasaAlbumsContents_Finished( 605 indexer.albums_images())); 606 ReleaseProcessIfNeeded(); 607 } 608 #endif // defined(OS_WIN) || defined(OS_MACOSX) 609 610 } // namespace chrome 611