1 // Copyright 2013 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.
5 #include "chrome/browser/media_galleries/fileapi/safe_iapps_library_parser.h"
7 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
8 #include "chrome/common/chrome_utility_messages.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "content/public/browser/child_process_data.h"
11 #include "ipc/ipc_platform_file.h"
13 using content::BrowserThread
;
14 using content::UtilityProcessHost
;
18 SafeIAppsLibraryParser::SafeIAppsLibraryParser()
19 : parser_state_(INITIAL_STATE
) {}
21 void SafeIAppsLibraryParser::ParseIPhotoLibrary(
22 const base::FilePath
& library_file
,
23 const IPhotoParserCallback
& callback
) {
24 library_file_
= library_file
;
25 iphoto_callback_
= callback
;
29 void SafeIAppsLibraryParser::ParseITunesLibrary(
30 const base::FilePath
& library_file
,
31 const ITunesParserCallback
& callback
) {
32 library_file_
= library_file
;
33 itunes_callback_
= callback
;
37 void SafeIAppsLibraryParser::Start() {
38 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
40 // |library_platform_file_| will be closed on the IO thread once it
41 // has been handed off to the child process.
42 library_platform_file_
= base::CreatePlatformFile(
44 base::PLATFORM_FILE_OPEN
| base::PLATFORM_FILE_READ
,
47 if (library_platform_file_
== base::kInvalidPlatformFileValue
) {
48 VLOG(1) << "Could not open iApps library XML file: "
49 << library_file_
.value();
50 BrowserThread::PostTask(
51 BrowserThread::IO
, FROM_HERE
,
52 base::Bind(&SafeIAppsLibraryParser::OnOpenLibraryFileFailed
, this));
56 BrowserThread::PostTask(
57 BrowserThread::IO
, FROM_HERE
,
58 base::Bind(&SafeIAppsLibraryParser::StartProcessOnIOThread
, this));
61 SafeIAppsLibraryParser::~SafeIAppsLibraryParser() {}
63 void SafeIAppsLibraryParser::StartProcessOnIOThread() {
64 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
65 DCHECK_EQ(INITIAL_STATE
, parser_state_
);
67 scoped_refptr
<base::MessageLoopProxy
> message_loop_proxy
=
68 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
);
69 utility_process_host_
=
70 UtilityProcessHost::Create(this, message_loop_proxy
.get())->AsWeakPtr();
71 // Wait for the startup notification before sending the main IPC to the
72 // utility process, so that we can dup the file handle.
73 utility_process_host_
->Send(new ChromeUtilityMsg_StartupPing
);
74 parser_state_
= PINGED_UTILITY_PROCESS_STATE
;
77 void SafeIAppsLibraryParser::OnUtilityProcessStarted() {
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
79 if (parser_state_
!= PINGED_UTILITY_PROCESS_STATE
)
82 if (utility_process_host_
->GetData().handle
== base::kNullProcessHandle
) {
83 DLOG(ERROR
) << "Child process handle is null";
88 if (!itunes_callback_
.is_null()) {
89 utility_process_host_
->Send(
90 new ChromeUtilityMsg_ParseITunesLibraryXmlFile(
91 IPC::GetFileHandleForProcess(
92 library_platform_file_
,
93 utility_process_host_
->GetData().handle
,
94 true /* close_source_handle */)));
95 } else if (!iphoto_callback_
.is_null()) {
96 #if defined(OS_MACOSX)
97 utility_process_host_
->Send(
98 new ChromeUtilityMsg_ParseIPhotoLibraryXmlFile(
99 IPC::GetFileHandleForProcess(
100 library_platform_file_
,
101 utility_process_host_
->GetData().handle
,
102 true /* close_source_handle */)));
106 parser_state_
= STARTED_PARSING_STATE
;
109 #if defined(OS_MACOSX)
110 void SafeIAppsLibraryParser::OnGotIPhotoLibrary(
111 bool result
, const iphoto::parser::Library
& library
) {
112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
113 DCHECK(!iphoto_callback_
.is_null());
115 if (parser_state_
!= STARTED_PARSING_STATE
)
118 MediaFileSystemBackend::MediaTaskRunner()->PostTask(
120 base::Bind(iphoto_callback_
, result
, library
));
121 parser_state_
= FINISHED_PARSING_STATE
;
125 void SafeIAppsLibraryParser::OnGotITunesLibrary(
126 bool result
, const itunes::parser::Library
& library
) {
127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
128 DCHECK(!itunes_callback_
.is_null());
130 if (parser_state_
!= STARTED_PARSING_STATE
)
133 MediaFileSystemBackend::MediaTaskRunner()->PostTask(
135 base::Bind(itunes_callback_
, result
, library
));
136 parser_state_
= FINISHED_PARSING_STATE
;
139 void SafeIAppsLibraryParser::OnOpenLibraryFileFailed() {
140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
144 void SafeIAppsLibraryParser::OnProcessCrashed(int exit_code
) {
148 void SafeIAppsLibraryParser::OnError() {
149 parser_state_
= FINISHED_PARSING_STATE
;
150 if (!itunes_callback_
.is_null())
151 OnGotITunesLibrary(false /* failed */, itunes::parser::Library());
153 #if defined(OS_MACOSX)
154 if (!iphoto_callback_
.is_null())
155 OnGotIPhotoLibrary(false /* failed */, iphoto::parser::Library());
159 bool SafeIAppsLibraryParser::OnMessageReceived(
160 const IPC::Message
& message
) {
162 IPC_BEGIN_MESSAGE_MAP(SafeIAppsLibraryParser
, message
)
163 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted
,
164 OnUtilityProcessStarted
)
165 #if defined(OS_MACOSX)
166 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_GotIPhotoLibrary
,
169 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_GotITunesLibrary
,
171 IPC_MESSAGE_UNHANDLED(handled
= false)
172 IPC_END_MESSAGE_MAP()