Implement MoveFileLocal (with creating a snapshot).
[chromium-blink-merge.git] / chrome / browser / media_galleries / fileapi / safe_picasa_albums_indexer.cc
blob3e5e9aa9b960469e06ed8d412c9edd9f3cff8deb
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_albums_indexer.h"
7 #include "base/files/file_util.h"
8 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
9 #include "chrome/common/extensions/chrome_utility_extensions_messages.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/child_process_data.h"
12 #include "content/public/browser/utility_process_host.h"
14 using content::BrowserThread;
15 using content::UtilityProcessHost;
17 namespace picasa {
19 namespace {
21 // Arbitrarily chosen to be a decent size but not block thread too much.
22 const int kPicasaINIReadBatchSize = 10;
24 } // namespace
26 // Picasa INI files are named "picasa.ini" on Picasa for Windows before version
27 // 71.18. Later versions and Picasa for Mac uses ".picasa.ini".
28 // See: https://support.google.com/picasa/answer/11257?hl=en
29 const char kPicasaINIFilenameLegacy[] = "picasa.ini";
31 SafePicasaAlbumsIndexer::SafePicasaAlbumsIndexer(const AlbumMap& albums,
32 const AlbumMap& folders)
33 : parser_state_(INITIAL_STATE) {
34 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
36 folders_inis_.reserve(folders.size());
38 for (AlbumMap::const_iterator it = albums.begin(); it != albums.end(); ++it)
39 album_uids_.insert(it->second.uid);
41 for (AlbumMap::const_iterator it = folders.begin(); it != folders.end(); ++it)
42 folders_queue_.push(it->second.path);
45 void SafePicasaAlbumsIndexer::Start(const DoneCallback& callback) {
46 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
47 DCHECK(!callback.is_null());
49 callback_ = callback;
50 ProcessFoldersBatch();
53 SafePicasaAlbumsIndexer::~SafePicasaAlbumsIndexer() {
56 void SafePicasaAlbumsIndexer::ProcessFoldersBatch() {
57 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
59 for (int i = 0; i < kPicasaINIReadBatchSize && !folders_queue_.empty(); ++i) {
60 base::FilePath folder_path = folders_queue_.front();
61 folders_queue_.pop();
63 folders_inis_.push_back(FolderINIContents());
65 bool ini_read =
66 base::ReadFileToString(
67 folder_path.AppendASCII(kPicasaINIFilename),
68 &folders_inis_.back().ini_contents) ||
69 base::ReadFileToString(
70 folder_path.AppendASCII(kPicasaINIFilenameLegacy),
71 &folders_inis_.back().ini_contents);
73 // See kPicasaINIFilename declaration for details.
74 if (ini_read)
75 folders_inis_.back().folder_path = folder_path;
76 else
77 folders_inis_.pop_back();
80 // If queue of folders to process not empty, post self onto task runner again.
81 if (!folders_queue_.empty()) {
82 MediaFileSystemBackend::MediaTaskRunner()->PostTask(
83 FROM_HERE,
84 base::Bind(&SafePicasaAlbumsIndexer::ProcessFoldersBatch, this));
85 } else {
86 BrowserThread::PostTask(
87 BrowserThread::IO,
88 FROM_HERE,
89 base::Bind(&SafePicasaAlbumsIndexer::StartWorkOnIOThread, this));
93 void SafePicasaAlbumsIndexer::StartWorkOnIOThread() {
94 DCHECK_CURRENTLY_ON(BrowserThread::IO);
95 DCHECK_EQ(INITIAL_STATE, parser_state_);
97 UtilityProcessHost* host =
98 UtilityProcessHost::Create(this, base::MessageLoopProxy::current());
99 host->Send(new ChromeUtilityMsg_IndexPicasaAlbumsContents(album_uids_,
100 folders_inis_));
101 parser_state_ = STARTED_PARSING_STATE;
104 void SafePicasaAlbumsIndexer::OnIndexPicasaAlbumsContentsFinished(
105 const AlbumImagesMap& albums_images) {
106 DCHECK_CURRENTLY_ON(BrowserThread::IO);
107 DCHECK(!callback_.is_null());
108 if (parser_state_ != STARTED_PARSING_STATE)
109 return;
111 MediaFileSystemBackend::MediaTaskRunner()->PostTask(
112 FROM_HERE,
113 base::Bind(callback_, true, albums_images));
114 parser_state_ = FINISHED_PARSING_STATE;
117 void SafePicasaAlbumsIndexer::OnProcessCrashed(int exit_code) {
118 DCHECK_CURRENTLY_ON(BrowserThread::IO);
119 DCHECK(!callback_.is_null());
121 MediaFileSystemBackend::MediaTaskRunner()->PostTask(
122 FROM_HERE,
123 base::Bind(callback_, false, AlbumImagesMap()));
126 bool SafePicasaAlbumsIndexer::OnMessageReceived(
127 const IPC::Message& message) {
128 bool handled = true;
129 IPC_BEGIN_MESSAGE_MAP(SafePicasaAlbumsIndexer, message)
130 IPC_MESSAGE_HANDLER(
131 ChromeUtilityHostMsg_IndexPicasaAlbumsContents_Finished,
132 OnIndexPicasaAlbumsContentsFinished)
133 IPC_MESSAGE_UNHANDLED(handled = false)
134 IPC_END_MESSAGE_MAP()
135 return handled;
138 } // namespace picasa