09bd4daed297c7054da31bfd27100df22281c8fb
[platform/framework/web/crosswalk.git] / src / chrome / browser / media_galleries / fileapi / safe_picasa_album_table_reader.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_picasa_album_table_reader.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
10 #include "chrome/common/chrome_utility_messages.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/child_process_data.h"
13
14 using content::BrowserThread;
15
16 namespace picasa {
17
18 SafePicasaAlbumTableReader::SafePicasaAlbumTableReader(
19     AlbumTableFiles album_table_files)
20     : album_table_files_(album_table_files.Pass()),
21       parser_state_(INITIAL_STATE) {
22   // TODO(tommycli): Add DCHECK to make sure |album_table_files| are all
23   // opened read-only once security adds ability to check PlatformFiles.
24   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
25 }
26
27 void SafePicasaAlbumTableReader::Start(const ParserCallback& callback) {
28   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
29   DCHECK(!callback.is_null());
30
31   callback_ = callback;
32
33   // Don't bother spawning process if any of the files are invalid.
34   if (!album_table_files_.indicator_file.IsValid() ||
35       !album_table_files_.category_file.IsValid() ||
36       !album_table_files_.date_file.IsValid() ||
37       !album_table_files_.filename_file.IsValid() ||
38       !album_table_files_.name_file.IsValid() ||
39       !album_table_files_.token_file.IsValid() ||
40       !album_table_files_.uid_file.IsValid()) {
41     MediaFileSystemBackend::MediaTaskRunner()->PostTask(
42         FROM_HERE,
43         base::Bind(callback_,
44                    false /* parse_success */,
45                    std::vector<AlbumInfo>(),
46                    std::vector<AlbumInfo>()));
47     return;
48   }
49
50   BrowserThread::PostTask(
51       BrowserThread::IO,
52       FROM_HERE,
53       base::Bind(&SafePicasaAlbumTableReader::StartWorkOnIOThread, this));
54 }
55
56 SafePicasaAlbumTableReader::~SafePicasaAlbumTableReader() {
57 }
58
59 void SafePicasaAlbumTableReader::StartWorkOnIOThread() {
60   DCHECK_CURRENTLY_ON(BrowserThread::IO);
61   DCHECK_EQ(INITIAL_STATE, parser_state_);
62
63   utility_process_host_ = content::UtilityProcessHost::Create(
64       this,
65       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get())
66       ->AsWeakPtr();
67   // Wait for the startup notification before sending the main IPC to the
68   // utility process, so that we can dup the file handle.
69   utility_process_host_->Send(new ChromeUtilityMsg_StartupPing);
70   parser_state_ = PINGED_UTILITY_PROCESS_STATE;
71 }
72
73 void SafePicasaAlbumTableReader::OnProcessStarted() {
74   DCHECK_CURRENTLY_ON(BrowserThread::IO);
75   if (parser_state_ != PINGED_UTILITY_PROCESS_STATE)
76     return;
77
78   if (utility_process_host_->GetData().handle == base::kNullProcessHandle) {
79     DLOG(ERROR) << "Child process handle is null";
80   }
81   AlbumTableFilesForTransit files_for_transit;
82   files_for_transit.indicator_file = IPC::TakeFileHandleForProcess(
83       album_table_files_.indicator_file.Pass(),
84       utility_process_host_->GetData().handle);
85   files_for_transit.category_file = IPC::TakeFileHandleForProcess(
86       album_table_files_.category_file.Pass(),
87       utility_process_host_->GetData().handle);
88   files_for_transit.date_file = IPC::TakeFileHandleForProcess(
89       album_table_files_.date_file.Pass(),
90       utility_process_host_->GetData().handle);
91   files_for_transit.filename_file = IPC::TakeFileHandleForProcess(
92       album_table_files_.filename_file.Pass(),
93       utility_process_host_->GetData().handle);
94   files_for_transit.name_file = IPC::TakeFileHandleForProcess(
95       album_table_files_.name_file.Pass(),
96       utility_process_host_->GetData().handle);
97   files_for_transit.token_file = IPC::TakeFileHandleForProcess(
98       album_table_files_.token_file.Pass(),
99       utility_process_host_->GetData().handle);
100   files_for_transit.uid_file = IPC::TakeFileHandleForProcess(
101       album_table_files_.uid_file.Pass(),
102       utility_process_host_->GetData().handle);
103   utility_process_host_->Send(new ChromeUtilityMsg_ParsePicasaPMPDatabase(
104       files_for_transit));
105   parser_state_ = STARTED_PARSING_STATE;
106 }
107
108 void SafePicasaAlbumTableReader::OnParsePicasaPMPDatabaseFinished(
109     bool parse_success,
110     const std::vector<AlbumInfo>& albums,
111     const std::vector<AlbumInfo>& folders) {
112   DCHECK_CURRENTLY_ON(BrowserThread::IO);
113   DCHECK(!callback_.is_null());
114   if (parser_state_ != STARTED_PARSING_STATE)
115     return;
116
117   MediaFileSystemBackend::MediaTaskRunner()->PostTask(
118       FROM_HERE, base::Bind(callback_, parse_success, albums, folders));
119   parser_state_ = FINISHED_PARSING_STATE;
120 }
121
122 void SafePicasaAlbumTableReader::OnProcessCrashed(int exit_code) {
123   DLOG(ERROR) << "SafePicasaAlbumTableReader::OnProcessCrashed()";
124   OnParsePicasaPMPDatabaseFinished(
125       false, std::vector<AlbumInfo>(), std::vector<AlbumInfo>());
126 }
127
128 bool SafePicasaAlbumTableReader::OnMessageReceived(
129     const IPC::Message& message) {
130   bool handled = true;
131   IPC_BEGIN_MESSAGE_MAP(SafePicasaAlbumTableReader, message)
132     IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted,
133                         OnProcessStarted)
134     IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParsePicasaPMPDatabase_Finished,
135                         OnParsePicasaPMPDatabaseFinished)
136     IPC_MESSAGE_UNHANDLED(handled = false)
137   IPC_END_MESSAGE_MAP()
138   return handled;
139 }
140
141 }  // namespace picasa