17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// found in the LICENSE file.
47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.h"
67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/bind.h"
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/logging.h"
97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/common/chrome_utility_messages.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/extensions/chrome_utility_extensions_messages.h"
127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/browser/browser_thread.h"
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/browser/child_process_data.h"
147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing content::BrowserThread;
167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace picasa {
187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSafePicasaAlbumTableReader::SafePicasaAlbumTableReader(
20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    AlbumTableFiles album_table_files)
21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    : album_table_files_(album_table_files.Pass()),
22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      parser_state_(INITIAL_STATE) {
237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // TODO(tommycli): Add DCHECK to make sure |album_table_files| are all
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // opened read-only once security adds ability to check PlatformFiles.
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void SafePicasaAlbumTableReader::Start(const ParserCallback& callback) {
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!callback.is_null());
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  callback_ = callback;
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Don't bother spawning process if any of the files are invalid.
35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!album_table_files_.indicator_file.IsValid() ||
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      !album_table_files_.category_file.IsValid() ||
37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      !album_table_files_.date_file.IsValid() ||
38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      !album_table_files_.filename_file.IsValid() ||
39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      !album_table_files_.name_file.IsValid() ||
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      !album_table_files_.token_file.IsValid() ||
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      !album_table_files_.uid_file.IsValid()) {
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    MediaFileSystemBackend::MediaTaskRunner()->PostTask(
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        FROM_HERE,
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        base::Bind(callback_,
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   false /* parse_success */,
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   std::vector<AlbumInfo>(),
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   std::vector<AlbumInfo>()));
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  BrowserThread::PostTask(
527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      BrowserThread::IO,
537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      FROM_HERE,
547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&SafePicasaAlbumTableReader::StartWorkOnIOThread, this));
557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
577dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSafePicasaAlbumTableReader::~SafePicasaAlbumTableReader() {
587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SafePicasaAlbumTableReader::StartWorkOnIOThread() {
61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK_EQ(INITIAL_STATE, parser_state_);
637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  utility_process_host_ = content::UtilityProcessHost::Create(
657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      this,
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get())
677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      ->AsWeakPtr();
687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Wait for the startup notification before sending the main IPC to the
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // utility process, so that we can dup the file handle.
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  utility_process_host_->Send(new ChromeUtilityMsg_StartupPing);
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  parser_state_ = PINGED_UTILITY_PROCESS_STATE;
727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SafePicasaAlbumTableReader::OnProcessStarted() {
75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (parser_state_ != PINGED_UTILITY_PROCESS_STATE)
777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (utility_process_host_->GetData().handle == base::kNullProcessHandle) {
807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DLOG(ERROR) << "Child process handle is null";
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  AlbumTableFilesForTransit files_for_transit;
83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  files_for_transit.indicator_file = IPC::TakeFileHandleForProcess(
84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      album_table_files_.indicator_file.Pass(),
85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      utility_process_host_->GetData().handle);
86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  files_for_transit.category_file = IPC::TakeFileHandleForProcess(
87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      album_table_files_.category_file.Pass(),
88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      utility_process_host_->GetData().handle);
89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  files_for_transit.date_file = IPC::TakeFileHandleForProcess(
90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      album_table_files_.date_file.Pass(),
91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      utility_process_host_->GetData().handle);
92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  files_for_transit.filename_file = IPC::TakeFileHandleForProcess(
93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      album_table_files_.filename_file.Pass(),
94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      utility_process_host_->GetData().handle);
95c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  files_for_transit.name_file = IPC::TakeFileHandleForProcess(
96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      album_table_files_.name_file.Pass(),
97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      utility_process_host_->GetData().handle);
98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  files_for_transit.token_file = IPC::TakeFileHandleForProcess(
99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      album_table_files_.token_file.Pass(),
100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      utility_process_host_->GetData().handle);
101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  files_for_transit.uid_file = IPC::TakeFileHandleForProcess(
102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      album_table_files_.uid_file.Pass(),
103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      utility_process_host_->GetData().handle);
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  utility_process_host_->Send(new ChromeUtilityMsg_ParsePicasaPMPDatabase(
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      files_for_transit));
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  parser_state_ = STARTED_PARSING_STATE;
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SafePicasaAlbumTableReader::OnParsePicasaPMPDatabaseFinished(
1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bool parse_success,
1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::vector<AlbumInfo>& albums,
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::vector<AlbumInfo>& folders) {
113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!callback_.is_null());
1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (parser_state_ != STARTED_PARSING_STATE)
1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  MediaFileSystemBackend::MediaTaskRunner()->PostTask(
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      FROM_HERE, base::Bind(callback_, parse_success, albums, folders));
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  parser_state_ = FINISHED_PARSING_STATE;
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SafePicasaAlbumTableReader::OnProcessCrashed(int exit_code) {
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DLOG(ERROR) << "SafePicasaAlbumTableReader::OnProcessCrashed()";
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OnParsePicasaPMPDatabaseFinished(
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      false, std::vector<AlbumInfo>(), std::vector<AlbumInfo>());
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool SafePicasaAlbumTableReader::OnMessageReceived(
1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const IPC::Message& message) {
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool handled = true;
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  IPC_BEGIN_MESSAGE_MAP(SafePicasaAlbumTableReader, message)
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted,
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                        OnProcessStarted)
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParsePicasaPMPDatabase_Finished,
1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                        OnParsePicasaPMPDatabaseFinished)
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    IPC_MESSAGE_UNHANDLED(handled = false)
1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  IPC_END_MESSAGE_MAP()
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return handled;
1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace picasa
143