18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file. 48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/safe_iapps_library_parser.h" 68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h" 88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/common/chrome_utility_messages.h" 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/extensions/chrome_utility_extensions_messages.h" 108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/child_process_data.h" 128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ipc/ipc_platform_file.h" 138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)using content::BrowserThread; 158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)using content::UtilityProcessHost; 168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace iapps { 188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SafeIAppsLibraryParser::SafeIAppsLibraryParser() 208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : parser_state_(INITIAL_STATE) {} 218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SafeIAppsLibraryParser::ParseIPhotoLibrary( 238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const base::FilePath& library_file, 248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const IPhotoParserCallback& callback) { 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch library_file_path_ = library_file; 268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) iphoto_callback_ = callback; 278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Start(); 288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SafeIAppsLibraryParser::ParseITunesLibrary( 318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const base::FilePath& library_file, 328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const ITunesParserCallback& callback) { 33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch library_file_path_ = library_file; 348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) itunes_callback_ = callback; 358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Start(); 368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SafeIAppsLibraryParser::Start() { 398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); 408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // |library_file_| will be closed on the IO thread once it has been handed 42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // off to the child process. 43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch library_file_.Initialize(library_file_path_, 44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::File::FLAG_OPEN | base::File::FLAG_READ); 45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!library_file_.IsValid()) { 468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) VLOG(1) << "Could not open iApps library XML file: " 47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << library_file_path_.value(); 488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) BrowserThread::PostTask( 498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) BrowserThread::IO, FROM_HERE, 508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Bind(&SafeIAppsLibraryParser::OnOpenLibraryFileFailed, this)); 518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) BrowserThread::PostTask( 558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) BrowserThread::IO, FROM_HERE, 568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Bind(&SafeIAppsLibraryParser::StartProcessOnIOThread, this)); 578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SafeIAppsLibraryParser::~SafeIAppsLibraryParser() {} 608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SafeIAppsLibraryParser::StartProcessOnIOThread() { 62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK_EQ(INITIAL_STATE, parser_state_); 648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> message_loop_proxy = 668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); 678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) utility_process_host_ = 688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UtilityProcessHost::Create(this, message_loop_proxy.get())->AsWeakPtr(); 698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Wait for the startup notification before sending the main IPC to the 708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // utility process, so that we can dup the file handle. 718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) utility_process_host_->Send(new ChromeUtilityMsg_StartupPing); 728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) parser_state_ = PINGED_UTILITY_PROCESS_STATE; 738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SafeIAppsLibraryParser::OnUtilityProcessStarted() { 76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (parser_state_ != PINGED_UTILITY_PROCESS_STATE) 788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (utility_process_host_->GetData().handle == base::kNullProcessHandle) { 818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DLOG(ERROR) << "Child process handle is null"; 828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnError(); 838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!itunes_callback_.is_null()) { 878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) utility_process_host_->Send( 888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) new ChromeUtilityMsg_ParseITunesLibraryXmlFile( 89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IPC::TakeFileHandleForProcess( 90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch library_file_.Pass(), 91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch utility_process_host_->GetData().handle))); 928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else if (!iphoto_callback_.is_null()) { 938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_MACOSX) 948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) utility_process_host_->Send( 958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) new ChromeUtilityMsg_ParseIPhotoLibraryXmlFile( 96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IPC::TakeFileHandleForProcess( 97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch library_file_.Pass(), 98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch utility_process_host_->GetData().handle))); 998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) parser_state_ = STARTED_PARSING_STATE; 1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_MACOSX) 1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SafeIAppsLibraryParser::OnGotIPhotoLibrary( 1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool result, const iphoto::parser::Library& library) { 108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 1098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(!iphoto_callback_.is_null()); 1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (parser_state_ != STARTED_PARSING_STATE) 1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MediaFileSystemBackend::MediaTaskRunner()->PostTask( 1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) FROM_HERE, 1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Bind(iphoto_callback_, result, library)); 1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) parser_state_ = FINISHED_PARSING_STATE; 1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SafeIAppsLibraryParser::OnGotITunesLibrary( 1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool result, const itunes::parser::Library& library) { 123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(!itunes_callback_.is_null()); 1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (parser_state_ != STARTED_PARSING_STATE) 1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MediaFileSystemBackend::MediaTaskRunner()->PostTask( 1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) FROM_HERE, 1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Bind(itunes_callback_, result, library)); 1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) parser_state_ = FINISHED_PARSING_STATE; 1338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SafeIAppsLibraryParser::OnOpenLibraryFileFailed() { 136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnError(); 1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SafeIAppsLibraryParser::OnProcessCrashed(int exit_code) { 1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnError(); 1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SafeIAppsLibraryParser::OnError() { 1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) parser_state_ = FINISHED_PARSING_STATE; 1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!itunes_callback_.is_null()) 1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnGotITunesLibrary(false /* failed */, itunes::parser::Library()); 1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_MACOSX) 1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!iphoto_callback_.is_null()) 1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnGotIPhotoLibrary(false /* failed */, iphoto::parser::Library()); 1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SafeIAppsLibraryParser::OnMessageReceived( 1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const IPC::Message& message) { 1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool handled = true; 1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(SafeIAppsLibraryParser, message) 1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted, 1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnUtilityProcessStarted) 1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_MACOSX) 1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_GotIPhotoLibrary, 1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnGotIPhotoLibrary) 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_GotITunesLibrary, 1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnGotITunesLibrary) 1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 1688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) IPC_END_MESSAGE_MAP() 1698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return handled; 1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} // namespace iapps 173