| Index: chrome/browser/media_galleries/fileapi/safe_picasa_albums_indexer.cc
|
| diff --git a/chrome/browser/media_galleries/fileapi/safe_picasa_albums_indexer.cc b/chrome/browser/media_galleries/fileapi/safe_picasa_albums_indexer.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..57ea926b534a50ad185d4017f5595fa1b1df24a7
|
| --- /dev/null
|
| +++ b/chrome/browser/media_galleries/fileapi/safe_picasa_albums_indexer.cc
|
| @@ -0,0 +1,141 @@
|
| +// Copyright 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/media_galleries/fileapi/safe_picasa_albums_indexer.h"
|
| +
|
| +#include "base/file_util.h"
|
| +#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
|
| +#include "chrome/common/chrome_utility_messages.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/child_process_data.h"
|
| +#include "content/public/browser/utility_process_host.h"
|
| +
|
| +using chrome::MediaFileSystemBackend;
|
| +using content::BrowserThread;
|
| +using content::UtilityProcessHost;
|
| +
|
| +namespace picasa {
|
| +
|
| +namespace {
|
| +
|
| +// Picasa INI files are named "picasa.ini" on Picasa for Windows before version
|
| +// 71.18. Later versions and Picasa for Mac uses ".picasa.ini".
|
| +// See: https://support.google.com/picasa/answer/11257?hl=en
|
| +const char kPicasaINIFilename[] = ".picasa.ini";
|
| +const char kPicasaINIFilenameLegacy[] = "picasa.ini";
|
| +
|
| +// Arbitrarily chosen to be a decent size but not block thread too much.
|
| +const int kPicasaINIReadBatchSize = 10;
|
| +
|
| +} // namespace
|
| +
|
| +SafePicasaAlbumsIndexer::SafePicasaAlbumsIndexer(
|
| + const AlbumMap& albums,
|
| + const AlbumMap& folders,
|
| + const DoneCallback& callback)
|
| + : callback_(callback),
|
| + parser_state_(INITIAL_STATE) {
|
| + DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
|
| + DCHECK(!callback_.is_null());
|
| +
|
| + folders_inis_.reserve(folders.size());
|
| +
|
| + for (AlbumMap::const_iterator it = albums.begin(); it != albums.end(); ++it)
|
| + album_uids_.insert(it->second.uid);
|
| +
|
| + for (AlbumMap::const_iterator it = folders.begin(); it != folders.end(); ++it)
|
| + folders_queue_.push(it->second.path);
|
| +}
|
| +
|
| +void SafePicasaAlbumsIndexer::Start() {
|
| + DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
|
| +
|
| + ProcessFoldersBatch();
|
| +}
|
| +
|
| +SafePicasaAlbumsIndexer::~SafePicasaAlbumsIndexer() {
|
| +}
|
| +
|
| +void SafePicasaAlbumsIndexer::ProcessFoldersBatch() {
|
| + DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
|
| +
|
| + for (int i = 0; i < kPicasaINIReadBatchSize && !folders_queue_.empty(); ++i) {
|
| + base::FilePath folder_path = folders_queue_.front();
|
| + folders_queue_.pop();
|
| +
|
| + folders_inis_.push_back(FolderINIContents());
|
| +
|
| + bool ini_read =
|
| + file_util::ReadFileToString(
|
| + folder_path.AppendASCII(kPicasaINIFilename),
|
| + &folders_inis_.back().ini_contents) ||
|
| + file_util::ReadFileToString(
|
| + folder_path.AppendASCII(kPicasaINIFilenameLegacy),
|
| + &folders_inis_.back().ini_contents);
|
| +
|
| + // See kPicasaINIFilename declaration for details.
|
| + if (ini_read)
|
| + folders_inis_.back().folder_path = folder_path;
|
| + else
|
| + folders_inis_.pop_back();
|
| + }
|
| +
|
| + // If queue of folders to process not empty, post self onto task runner again.
|
| + if (!folders_queue_.empty()) {
|
| + MediaFileSystemBackend::MediaTaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&SafePicasaAlbumsIndexer::ProcessFoldersBatch, this));
|
| + } else {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO,
|
| + FROM_HERE,
|
| + base::Bind(&SafePicasaAlbumsIndexer::StartWorkOnIOThread, this));
|
| + }
|
| +}
|
| +
|
| +void SafePicasaAlbumsIndexer::StartWorkOnIOThread() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + DCHECK_EQ(INITIAL_STATE, parser_state_);
|
| +
|
| + UtilityProcessHost* host =
|
| + UtilityProcessHost::Create(this, base::MessageLoopProxy::current());
|
| + host->EnableZygote();
|
| + host->Send(new ChromeUtilityMsg_IndexPicasaAlbumsContents(album_uids_,
|
| + folders_inis_));
|
| + parser_state_ = STARTED_PARSING_STATE;
|
| +}
|
| +
|
| +void SafePicasaAlbumsIndexer::OnIndexPicasaAlbumsContentsFinished(
|
| + const AlbumImagesMap& albums_images) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + if (parser_state_ != STARTED_PARSING_STATE)
|
| + return;
|
| +
|
| + MediaFileSystemBackend::MediaTaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(callback_, true, albums_images));
|
| + parser_state_ = FINISHED_PARSING_STATE;
|
| +}
|
| +
|
| +void SafePicasaAlbumsIndexer::OnProcessCrashed(int exit_code) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + MediaFileSystemBackend::MediaTaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(callback_, false, AlbumImagesMap()));
|
| +}
|
| +
|
| +bool SafePicasaAlbumsIndexer::OnMessageReceived(
|
| + const IPC::Message& message) {
|
| + bool handled = true;
|
| + IPC_BEGIN_MESSAGE_MAP(SafePicasaAlbumsIndexer, message)
|
| + IPC_MESSAGE_HANDLER(
|
| + ChromeUtilityHostMsg_IndexPicasaAlbumsContents_Finished,
|
| + OnIndexPicasaAlbumsContentsFinished)
|
| + IPC_MESSAGE_UNHANDLED(handled = false)
|
| + IPC_END_MESSAGE_MAP()
|
| + return handled;
|
| +}
|
| +
|
| +} // namespace picasa
|
|
|