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"
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;
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());
27 void SafePicasaAlbumTableReader::Start(const ParserCallback& callback) {
28 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
29 DCHECK(!callback.is_null());
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(
44 false /* parse_success */,
45 std::vector<AlbumInfo>(),
46 std::vector<AlbumInfo>()));
50 BrowserThread::PostTask(
53 base::Bind(&SafePicasaAlbumTableReader::StartWorkOnIOThread, this));
56 SafePicasaAlbumTableReader::~SafePicasaAlbumTableReader() {
59 void SafePicasaAlbumTableReader::StartWorkOnIOThread() {
60 DCHECK_CURRENTLY_ON(BrowserThread::IO);
61 DCHECK_EQ(INITIAL_STATE, parser_state_);
63 utility_process_host_ = content::UtilityProcessHost::Create(
65 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get())
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;
73 void SafePicasaAlbumTableReader::OnProcessStarted() {
74 DCHECK_CURRENTLY_ON(BrowserThread::IO);
75 if (parser_state_ != PINGED_UTILITY_PROCESS_STATE)
78 if (utility_process_host_->GetData().handle == base::kNullProcessHandle) {
79 DLOG(ERROR) << "Child process handle is null";
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(
105 parser_state_ = STARTED_PARSING_STATE;
108 void SafePicasaAlbumTableReader::OnParsePicasaPMPDatabaseFinished(
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)
117 MediaFileSystemBackend::MediaTaskRunner()->PostTask(
118 FROM_HERE, base::Bind(callback_, parse_success, albums, folders));
119 parser_state_ = FINISHED_PARSING_STATE;
122 void SafePicasaAlbumTableReader::OnProcessCrashed(int exit_code) {
123 DLOG(ERROR) << "SafePicasaAlbumTableReader::OnProcessCrashed()";
124 OnParsePicasaPMPDatabaseFinished(
125 false, std::vector<AlbumInfo>(), std::vector<AlbumInfo>());
128 bool SafePicasaAlbumTableReader::OnMessageReceived(
129 const IPC::Message& message) {
131 IPC_BEGIN_MESSAGE_MAP(SafePicasaAlbumTableReader, message)
132 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted,
134 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParsePicasaPMPDatabase_Finished,
135 OnParsePicasaPMPDatabaseFinished)
136 IPC_MESSAGE_UNHANDLED(handled = false)
137 IPC_END_MESSAGE_MAP()
141 } // namespace picasa