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
;
21 // Arbitrarily chosen to be a decent size but not block thread too much.
22 const int kPicasaINIReadBatchSize
= 10;
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());
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();
63 folders_inis_
.push_back(FolderINIContents());
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.
75 folders_inis_
.back().folder_path
= folder_path
;
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(
84 base::Bind(&SafePicasaAlbumsIndexer::ProcessFoldersBatch
, this));
86 BrowserThread::PostTask(
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_
,
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
)
111 MediaFileSystemBackend::MediaTaskRunner()->PostTask(
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(
123 base::Bind(callback_
, false, AlbumImagesMap()));
126 bool SafePicasaAlbumsIndexer::OnMessageReceived(
127 const IPC::Message
& message
) {
129 IPC_BEGIN_MESSAGE_MAP(SafePicasaAlbumsIndexer
, message
)
131 ChromeUtilityHostMsg_IndexPicasaAlbumsContents_Finished
,
132 OnIndexPicasaAlbumsContentsFinished
)
133 IPC_MESSAGE_UNHANDLED(handled
= false)
134 IPC_END_MESSAGE_MAP()
138 } // namespace picasa