- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / media_galleries / fileapi / safe_iapps_library_parser.cc
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.
4
5 #include "chrome/browser/media_galleries/fileapi/safe_iapps_library_parser.h"
6
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"
12
13 using content::BrowserThread;
14 using content::UtilityProcessHost;
15
16 namespace iapps {
17
18 SafeIAppsLibraryParser::SafeIAppsLibraryParser()
19     : parser_state_(INITIAL_STATE) {}
20
21 void SafeIAppsLibraryParser::ParseIPhotoLibrary(
22     const base::FilePath& library_file,
23     const IPhotoParserCallback& callback) {
24   library_file_ = library_file;
25   iphoto_callback_ = callback;
26   Start();
27 }
28
29 void SafeIAppsLibraryParser::ParseITunesLibrary(
30     const base::FilePath& library_file,
31     const ITunesParserCallback& callback) {
32   library_file_ = library_file;
33   itunes_callback_ = callback;
34   Start();
35 }
36
37 void SafeIAppsLibraryParser::Start() {
38   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
39
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(
43       library_file_,
44       base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
45       NULL,   // created
46       NULL);  // error_code
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));
53     return;
54   }
55
56   BrowserThread::PostTask(
57       BrowserThread::IO, FROM_HERE,
58       base::Bind(&SafeIAppsLibraryParser::StartProcessOnIOThread, this));
59 }
60
61 SafeIAppsLibraryParser::~SafeIAppsLibraryParser() {}
62
63 void SafeIAppsLibraryParser::StartProcessOnIOThread() {
64   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
65   DCHECK_EQ(INITIAL_STATE, parser_state_);
66
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;
75 }
76
77 void SafeIAppsLibraryParser::OnUtilityProcessStarted() {
78   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
79   if (parser_state_ != PINGED_UTILITY_PROCESS_STATE)
80     return;
81
82   if (utility_process_host_->GetData().handle == base::kNullProcessHandle) {
83     DLOG(ERROR) << "Child process handle is null";
84     OnError();
85     return;
86   }
87
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 */)));
103 #endif
104   }
105
106   parser_state_ = STARTED_PARSING_STATE;
107 }
108
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());
114
115   if (parser_state_ != STARTED_PARSING_STATE)
116     return;
117
118   MediaFileSystemBackend::MediaTaskRunner()->PostTask(
119       FROM_HERE,
120       base::Bind(iphoto_callback_, result, library));
121   parser_state_ = FINISHED_PARSING_STATE;
122 }
123 #endif
124
125 void SafeIAppsLibraryParser::OnGotITunesLibrary(
126     bool result, const itunes::parser::Library& library) {
127   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
128   DCHECK(!itunes_callback_.is_null());
129
130   if (parser_state_ != STARTED_PARSING_STATE)
131     return;
132
133   MediaFileSystemBackend::MediaTaskRunner()->PostTask(
134       FROM_HERE,
135       base::Bind(itunes_callback_, result, library));
136   parser_state_ = FINISHED_PARSING_STATE;
137 }
138
139 void SafeIAppsLibraryParser::OnOpenLibraryFileFailed() {
140   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
141   OnError();
142 }
143
144 void SafeIAppsLibraryParser::OnProcessCrashed(int exit_code) {
145   OnError();
146 }
147
148 void SafeIAppsLibraryParser::OnError() {
149   parser_state_ = FINISHED_PARSING_STATE;
150   if (!itunes_callback_.is_null())
151     OnGotITunesLibrary(false /* failed */, itunes::parser::Library());
152
153 #if defined(OS_MACOSX)
154   if (!iphoto_callback_.is_null())
155     OnGotIPhotoLibrary(false /* failed */, iphoto::parser::Library());
156 #endif
157 }
158
159 bool SafeIAppsLibraryParser::OnMessageReceived(
160     const IPC::Message& message) {
161   bool handled = true;
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,
167                         OnGotIPhotoLibrary)
168 #endif
169     IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_GotITunesLibrary,
170                         OnGotITunesLibrary)
171     IPC_MESSAGE_UNHANDLED(handled = false)
172   IPC_END_MESSAGE_MAP()
173   return handled;
174 }
175
176 }  // namespace iapps