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