NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / media_galleries / fileapi / safe_picasa_album_table_reader.cc
blob1660765f50afca294b1f19b2e3c390fe9e1f4555
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_picasa_album_table_reader.h"
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"
14 using content::BrowserThread;
16 namespace picasa {
18 SafePicasaAlbumTableReader::SafePicasaAlbumTableReader(
19 const AlbumTableFiles& album_table_files)
20 : album_table_files_(album_table_files), parser_state_(INITIAL_STATE) {
21 // TODO(tommycli): Add DCHECK to make sure |album_table_files| are all
22 // opened read-only once security adds ability to check PlatformFiles.
23 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
26 void SafePicasaAlbumTableReader::Start(const ParserCallback& callback) {
27 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
28 DCHECK(!callback.is_null());
30 callback_ = callback;
32 // Don't bother spawning process if any of the files are invalid.
33 if (album_table_files_.indicator_file == base::kInvalidPlatformFileValue ||
34 album_table_files_.category_file == base::kInvalidPlatformFileValue ||
35 album_table_files_.date_file == base::kInvalidPlatformFileValue ||
36 album_table_files_.filename_file == base::kInvalidPlatformFileValue ||
37 album_table_files_.name_file == base::kInvalidPlatformFileValue ||
38 album_table_files_.token_file == base::kInvalidPlatformFileValue ||
39 album_table_files_.uid_file == base::kInvalidPlatformFileValue) {
40 MediaFileSystemBackend::MediaTaskRunner()->PostTask(
41 FROM_HERE,
42 base::Bind(callback_,
43 false /* parse_success */,
44 std::vector<AlbumInfo>(),
45 std::vector<AlbumInfo>()));
46 return;
49 BrowserThread::PostTask(
50 BrowserThread::IO,
51 FROM_HERE,
52 base::Bind(&SafePicasaAlbumTableReader::StartWorkOnIOThread, this));
55 SafePicasaAlbumTableReader::~SafePicasaAlbumTableReader() {
58 void SafePicasaAlbumTableReader::StartWorkOnIOThread() {
59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
60 DCHECK_EQ(INITIAL_STATE, parser_state_);
62 utility_process_host_ = content::UtilityProcessHost::Create(
63 this,
64 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get())
65 ->AsWeakPtr();
66 // Wait for the startup notification before sending the main IPC to the
67 // utility process, so that we can dup the file handle.
68 utility_process_host_->Send(new ChromeUtilityMsg_StartupPing);
69 parser_state_ = PINGED_UTILITY_PROCESS_STATE;
72 void SafePicasaAlbumTableReader::OnProcessStarted() {
73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
74 if (parser_state_ != PINGED_UTILITY_PROCESS_STATE)
75 return;
77 if (utility_process_host_->GetData().handle == base::kNullProcessHandle) {
78 DLOG(ERROR) << "Child process handle is null";
80 AlbumTableFilesForTransit files_for_transit;
81 files_for_transit.indicator_file = IPC::GetFileHandleForProcess(
82 album_table_files_.indicator_file,
83 utility_process_host_->GetData().handle,
84 true /* close_source_handle */);
85 files_for_transit.category_file = IPC::GetFileHandleForProcess(
86 album_table_files_.category_file,
87 utility_process_host_->GetData().handle,
88 true /* close_source_handle */);
89 files_for_transit.date_file = IPC::GetFileHandleForProcess(
90 album_table_files_.date_file,
91 utility_process_host_->GetData().handle,
92 true /* close_source_handle */);
93 files_for_transit.filename_file = IPC::GetFileHandleForProcess(
94 album_table_files_.filename_file,
95 utility_process_host_->GetData().handle,
96 true /* close_source_handle */);
97 files_for_transit.name_file = IPC::GetFileHandleForProcess(
98 album_table_files_.name_file,
99 utility_process_host_->GetData().handle,
100 true /* close_source_handle */);
101 files_for_transit.token_file = IPC::GetFileHandleForProcess(
102 album_table_files_.token_file,
103 utility_process_host_->GetData().handle,
104 true /* close_source_handle */);
105 files_for_transit.uid_file = IPC::GetFileHandleForProcess(
106 album_table_files_.uid_file,
107 utility_process_host_->GetData().handle,
108 true /* close_source_handle */);
109 utility_process_host_->Send(new ChromeUtilityMsg_ParsePicasaPMPDatabase(
110 files_for_transit));
111 parser_state_ = STARTED_PARSING_STATE;
114 void SafePicasaAlbumTableReader::OnParsePicasaPMPDatabaseFinished(
115 bool parse_success,
116 const std::vector<AlbumInfo>& albums,
117 const std::vector<AlbumInfo>& folders) {
118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
119 DCHECK(!callback_.is_null());
120 if (parser_state_ != STARTED_PARSING_STATE)
121 return;
123 MediaFileSystemBackend::MediaTaskRunner()->PostTask(
124 FROM_HERE, base::Bind(callback_, parse_success, albums, folders));
125 parser_state_ = FINISHED_PARSING_STATE;
128 void SafePicasaAlbumTableReader::OnProcessCrashed(int exit_code) {
129 DLOG(ERROR) << "SafePicasaAlbumTableReader::OnProcessCrashed()";
130 OnParsePicasaPMPDatabaseFinished(
131 false, std::vector<AlbumInfo>(), std::vector<AlbumInfo>());
134 bool SafePicasaAlbumTableReader::OnMessageReceived(
135 const IPC::Message& message) {
136 bool handled = true;
137 IPC_BEGIN_MESSAGE_MAP(SafePicasaAlbumTableReader, message)
138 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted,
139 OnProcessStarted)
140 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParsePicasaPMPDatabase_Finished,
141 OnParsePicasaPMPDatabaseFinished)
142 IPC_MESSAGE_UNHANDLED(handled = false)
143 IPC_END_MESSAGE_MAP()
144 return handled;
147 } // namespace picasa