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 "chrome/common/extensions/chrome_utility_extensions_messages.h"
12 #include "chrome/grit/generated_resources.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/child_process_data.h"
15 #include "ui/base/l10n/l10n_util.h"
17 using content::BrowserThread
;
21 SafePicasaAlbumTableReader::SafePicasaAlbumTableReader(
22 AlbumTableFiles album_table_files
)
23 : album_table_files_(album_table_files
.Pass()),
24 parser_state_(INITIAL_STATE
) {
25 // TODO(tommycli): Add DCHECK to make sure |album_table_files| are all
26 // opened read-only once security adds ability to check PlatformFiles.
27 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
30 void SafePicasaAlbumTableReader::Start(const ParserCallback
& callback
) {
31 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
32 DCHECK(!callback
.is_null());
36 // Don't bother spawning process if any of the files are invalid.
37 if (!album_table_files_
.indicator_file
.IsValid() ||
38 !album_table_files_
.category_file
.IsValid() ||
39 !album_table_files_
.date_file
.IsValid() ||
40 !album_table_files_
.filename_file
.IsValid() ||
41 !album_table_files_
.name_file
.IsValid() ||
42 !album_table_files_
.token_file
.IsValid() ||
43 !album_table_files_
.uid_file
.IsValid()) {
44 MediaFileSystemBackend::MediaTaskRunner()->PostTask(
47 false /* parse_success */,
48 std::vector
<AlbumInfo
>(),
49 std::vector
<AlbumInfo
>()));
53 BrowserThread::PostTask(
56 base::Bind(&SafePicasaAlbumTableReader::StartWorkOnIOThread
, this));
59 SafePicasaAlbumTableReader::~SafePicasaAlbumTableReader() {
62 void SafePicasaAlbumTableReader::StartWorkOnIOThread() {
63 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
64 DCHECK_EQ(INITIAL_STATE
, parser_state_
);
66 utility_process_host_
= content::UtilityProcessHost::Create(
68 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
).get())
70 utility_process_host_
->SetName(l10n_util::GetStringUTF16(
71 IDS_UTILITY_PROCESS_MEDIA_LIBRARY_FILE_CHECKER_NAME
));
72 // Wait for the startup notification before sending the main IPC to the
73 // utility process, so that we can dup the file handle.
74 utility_process_host_
->Send(new ChromeUtilityMsg_StartupPing
);
75 parser_state_
= PINGED_UTILITY_PROCESS_STATE
;
78 void SafePicasaAlbumTableReader::OnProcessStarted() {
79 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
80 if (parser_state_
!= PINGED_UTILITY_PROCESS_STATE
)
83 if (utility_process_host_
->GetData().handle
== base::kNullProcessHandle
) {
84 DLOG(ERROR
) << "Child process handle is null";
86 AlbumTableFilesForTransit files_for_transit
;
87 files_for_transit
.indicator_file
= IPC::TakeFileHandleForProcess(
88 album_table_files_
.indicator_file
.Pass(),
89 utility_process_host_
->GetData().handle
);
90 files_for_transit
.category_file
= IPC::TakeFileHandleForProcess(
91 album_table_files_
.category_file
.Pass(),
92 utility_process_host_
->GetData().handle
);
93 files_for_transit
.date_file
= IPC::TakeFileHandleForProcess(
94 album_table_files_
.date_file
.Pass(),
95 utility_process_host_
->GetData().handle
);
96 files_for_transit
.filename_file
= IPC::TakeFileHandleForProcess(
97 album_table_files_
.filename_file
.Pass(),
98 utility_process_host_
->GetData().handle
);
99 files_for_transit
.name_file
= IPC::TakeFileHandleForProcess(
100 album_table_files_
.name_file
.Pass(),
101 utility_process_host_
->GetData().handle
);
102 files_for_transit
.token_file
= IPC::TakeFileHandleForProcess(
103 album_table_files_
.token_file
.Pass(),
104 utility_process_host_
->GetData().handle
);
105 files_for_transit
.uid_file
= IPC::TakeFileHandleForProcess(
106 album_table_files_
.uid_file
.Pass(),
107 utility_process_host_
->GetData().handle
);
108 utility_process_host_
->Send(new ChromeUtilityMsg_ParsePicasaPMPDatabase(
110 parser_state_
= STARTED_PARSING_STATE
;
113 void SafePicasaAlbumTableReader::OnParsePicasaPMPDatabaseFinished(
115 const std::vector
<AlbumInfo
>& albums
,
116 const std::vector
<AlbumInfo
>& folders
) {
117 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
118 DCHECK(!callback_
.is_null());
119 if (parser_state_
!= STARTED_PARSING_STATE
)
122 MediaFileSystemBackend::MediaTaskRunner()->PostTask(
123 FROM_HERE
, base::Bind(callback_
, parse_success
, albums
, folders
));
124 parser_state_
= FINISHED_PARSING_STATE
;
127 void SafePicasaAlbumTableReader::OnProcessCrashed(int exit_code
) {
128 DLOG(ERROR
) << "SafePicasaAlbumTableReader::OnProcessCrashed()";
129 OnParsePicasaPMPDatabaseFinished(
130 false, std::vector
<AlbumInfo
>(), std::vector
<AlbumInfo
>());
133 bool SafePicasaAlbumTableReader::OnMessageReceived(
134 const IPC::Message
& message
) {
136 IPC_BEGIN_MESSAGE_MAP(SafePicasaAlbumTableReader
, message
)
137 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted
,
139 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParsePicasaPMPDatabase_Finished
,
140 OnParsePicasaPMPDatabaseFinished
)
141 IPC_MESSAGE_UNHANDLED(handled
= false)
142 IPC_END_MESSAGE_MAP()
146 } // namespace picasa