1ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org// Copyright 2013 The Chromium Authors. All rights reserved.
265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// Use of this source code is governed by a BSD-style license that can be
365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// found in the LICENSE file.
465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "chrome/browser/media_galleries/fileapi/picasa_data_provider.h"
665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include <utility>
865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "base/basictypes.h"
1065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "base/bind_helpers.h"
1165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "base/callback.h"
1265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "base/files/file_util.h"
1365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "base/strings/stringprintf.h"
1465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "chrome/browser/media_galleries/fileapi/file_path_watcher_util.h"
1565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
1665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.h"
1765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "chrome/browser/media_galleries/fileapi/safe_picasa_albums_indexer.h"
1865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
1965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "storage/browser/fileapi/file_system_operation_context.h"
2065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "storage/browser/fileapi/file_system_url.h"
2165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
2265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgnamespace picasa {
2365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
2465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgnamespace {
2565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
2665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgvoid RunAllCallbacks(
2765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    std::vector<PicasaDataProvider::ReadyCallback>* ready_callbacks,
2865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    bool success) {
2965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  for (std::vector<PicasaDataProvider::ReadyCallback>::const_iterator it =
3065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org           ready_callbacks->begin();
3165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org       it != ready_callbacks->end();
3265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org       ++it) {
3365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    it->Run(success);
3465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  }
3565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  ready_callbacks->clear();
3665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}
3765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
3865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}  // namespace
3965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
4065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgPicasaDataProvider::PicasaDataProvider(const base::FilePath& database_path)
418f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    : database_path_(database_path),
428f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      state_(STALE_DATA_STATE),
438f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      weak_factory_(this) {
448f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
458f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
468f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  StartFilePathWatchOnMediaTaskRunner(
478f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      database_path_.DirName().AppendASCII(kPicasaTempDirName),
488f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      base::Bind(&PicasaDataProvider::OnTempDirWatchStarted,
4965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org                 weak_factory_.GetWeakPtr()),
5065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      base::Bind(&PicasaDataProvider::OnTempDirChanged,
5165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org                 weak_factory_.GetWeakPtr()));
528f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org}
538f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
548f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.orgPicasaDataProvider::~PicasaDataProvider() {}
5565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
568f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.orgvoid PicasaDataProvider::RefreshData(DataType needed_data,
5765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org                                     const ReadyCallback& ready_callback) {
5865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
5965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  // TODO(tommycli): Need to watch the database_path_ folder and handle
6065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  // rereading the data when it changes.
61c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
62c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (state_ == INVALID_DATA_STATE) {
63c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ready_callback.Run(false /* success */);
64c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return;
65c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
66c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
67c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (needed_data == LIST_OF_ALBUMS_AND_FOLDERS_DATA) {
68c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (state_ == LIST_OF_ALBUMS_AND_FOLDERS_FRESH_STATE ||
69c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        state_ == ALBUMS_IMAGES_FRESH_STATE) {
70c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ready_callback.Run(true /* success */);
71c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      return;
72c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
73c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    album_list_ready_callbacks_.push_back(ready_callback);
74c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
75c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (state_ == ALBUMS_IMAGES_FRESH_STATE) {
76c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ready_callback.Run(true /* success */);
77c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      return;
78c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
79c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    albums_index_ready_callbacks_.push_back(ready_callback);
8040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  }
818e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DoRefreshIfNecessary();
824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgscoped_ptr<AlbumMap> PicasaDataProvider::GetFolders() {
858e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
868e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DCHECK(state_ == LIST_OF_ALBUMS_AND_FOLDERS_FRESH_STATE ||
87030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org         state_ == ALBUMS_IMAGES_FRESH_STATE);
888e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  return make_scoped_ptr(new AlbumMap(folder_map_));
898e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org}
908e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
918e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgscoped_ptr<AlbumMap> PicasaDataProvider::GetAlbums() {
928e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
938e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DCHECK(state_ == LIST_OF_ALBUMS_AND_FOLDERS_FRESH_STATE ||
948e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org         state_ == ALBUMS_IMAGES_FRESH_STATE);
9540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  return make_scoped_ptr(new AlbumMap(album_map_));
968e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org}
97030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org
988e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgscoped_ptr<AlbumImages> PicasaDataProvider::FindAlbumImages(
998e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    const std::string& key,
1008e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    base::File::Error* error) {
10140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
1028e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DCHECK(state_ == ALBUMS_IMAGES_FRESH_STATE);
10340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  DCHECK(error);
1048e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1058e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  AlbumImagesMap::const_iterator it = albums_images_.find(key);
1068e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1078e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  if (it == albums_images_.end()) {
1088e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    *error = base::File::FILE_ERROR_NOT_FOUND;
1098e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    return scoped_ptr<AlbumImages>();
1108e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
1118e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1128e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  *error = base::File::FILE_OK;
1138e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  return make_scoped_ptr(new AlbumImages(it->second));
1148e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org}
1158e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1168e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid PicasaDataProvider::InvalidateData() {
1178e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
1188e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1198e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // Set data state to stale and ignore responses from any in-flight processes.
1208e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // TODO(tommycli): Implement and call Cancel function for these
1218e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // UtilityProcessHostClients to actually kill the in-flight processes.
1228e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  state_ = STALE_DATA_STATE;
1238e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  album_table_reader_ = NULL;
1248e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  albums_indexer_ = NULL;
1258e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1268e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DoRefreshIfNecessary();
1278e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org}
1288e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1298e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid PicasaDataProvider::OnTempDirWatchStarted(
1308e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    scoped_ptr<base::FilePathWatcher> temp_dir_watcher) {
1318e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
1328e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  temp_dir_watcher_.reset(temp_dir_watcher.release());
13340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org}
1348e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1358e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid PicasaDataProvider::OnTempDirChanged(const base::FilePath& temp_dir_path,
13640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                          bool error) {
1378e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
1388e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  if (base::IsDirectoryEmpty(temp_dir_path))
1398e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    InvalidateData();
14040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org}
1418e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1428e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid PicasaDataProvider::DoRefreshIfNecessary() {
1438e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DCHECK(state_ != INVALID_DATA_STATE);
1448e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  DCHECK(state_ != ALBUMS_IMAGES_FRESH_STATE);
14540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  DCHECK(!(album_table_reader_.get() && albums_indexer_.get()));
146378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
14740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  if (album_list_ready_callbacks_.empty() &&
148378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      albums_index_ready_callbacks_.empty()) {
149378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return;
15040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  }
151030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org
152c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (state_ == STALE_DATA_STATE) {
153378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    if (album_table_reader_.get())
154378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      return;
155378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    album_table_reader_ =
15640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org        new SafePicasaAlbumTableReader(AlbumTableFiles(database_path_));
157378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    album_table_reader_->Start(
15840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org        base::Bind(&PicasaDataProvider::OnAlbumTableReaderDone,
15940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                   weak_factory_.GetWeakPtr(),
160378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                   album_table_reader_));
161378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  } else {
162378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    DCHECK(state_ == LIST_OF_ALBUMS_AND_FOLDERS_FRESH_STATE);
163378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    if (albums_indexer_.get())
164030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org      return;
165378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    albums_indexer_ = new SafePicasaAlbumsIndexer(album_map_, folder_map_);
166378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    albums_indexer_->Start(base::Bind(&PicasaDataProvider::OnAlbumsIndexerDone,
167378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                                      weak_factory_.GetWeakPtr(),
168378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                                      albums_indexer_));
169378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
170378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org}
171378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
172378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgvoid PicasaDataProvider::OnAlbumTableReaderDone(
173378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    scoped_refptr<SafePicasaAlbumTableReader> reader,
174378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    bool parse_success,
175378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    const std::vector<AlbumInfo>& albums,
176378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    const std::vector<AlbumInfo>& folders) {
17740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
17840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // If the reader has already been deemed stale, ignore the result.
179378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  if (reader.get() != album_table_reader_.get())
180030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org    return;
181378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  album_table_reader_ = NULL;
182378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
183378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  DCHECK(state_ == STALE_DATA_STATE);
184378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
185378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  if (!parse_success) {
18640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    // If we didn't get the list successfully, fail all those waiting for
18740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    // the albums indexer also.
188378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    state_ = INVALID_DATA_STATE;
18940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    RunAllCallbacks(&album_list_ready_callbacks_, false /* success */);
190378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    RunAllCallbacks(&albums_index_ready_callbacks_, false /* success */);
191378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return;
192378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
193378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
194378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  album_map_.clear();
195378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  folder_map_.clear();
196378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  UniquifyNames(albums, &album_map_);
197378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  UniquifyNames(folders, &folder_map_);
198378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
199378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  state_ = LIST_OF_ALBUMS_AND_FOLDERS_FRESH_STATE;
200378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  RunAllCallbacks(&album_list_ready_callbacks_, parse_success);
20131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
20231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  // Chain from this process onto refreshing the albums images if necessary.
20331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  DoRefreshIfNecessary();
20431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org}
205378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
206160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgvoid PicasaDataProvider::OnAlbumsIndexerDone(
207378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    scoped_refptr<SafePicasaAlbumsIndexer> indexer,
208378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    bool success,
209378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    const picasa::AlbumImagesMap& albums_images) {
210378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
211378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // If the indexer has already been deemed stale, ignore the result.
212378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  if (indexer.get() != albums_indexer_.get())
213378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return;
214378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  albums_indexer_ = NULL;
2157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
216378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  DCHECK(state_ == LIST_OF_ALBUMS_AND_FOLDERS_FRESH_STATE);
217160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org
218378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  if (success) {
219378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    state_ = ALBUMS_IMAGES_FRESH_STATE;
220378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
221378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    albums_images_ = albums_images;
222378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
223378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
224378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  RunAllCallbacks(&albums_index_ready_callbacks_, success);
225378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org}
226378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
227378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// static
228378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgstd::string PicasaDataProvider::DateToPathString(const base::Time& time) {
229378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  base::Time::Exploded exploded_time;
230378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  time.LocalExplode(&exploded_time);
231378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
23240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // TODO(tommycli): Investigate better localization and persisting which locale
233378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // we use to generate these unique names.
234378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  return base::StringPrintf("%04d-%02d-%02d", exploded_time.year,
23540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                            exploded_time.month, exploded_time.day_of_month);
236378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org}
237378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
238378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// static
23940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgvoid PicasaDataProvider::UniquifyNames(const std::vector<AlbumInfo>& info_list,
24040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                       AlbumMap* result_map) {
241378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // TODO(tommycli): We should persist the uniquified names.
242378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  std::vector<std::string> desired_names;
243378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
244378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  std::map<std::string, int> total_counts;
245378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  std::map<std::string, int> current_counts;
246378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
2472c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  for (std::vector<AlbumInfo>::const_iterator it = info_list.begin();
2482c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org       it != info_list.end(); ++it) {
2492c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    std::string desired_name =
2502c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org        it->name + " " + DateToPathString(it->timestamp);
2512c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    desired_names.push_back(desired_name);
2522c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    ++total_counts[desired_name];
2532c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  }
2542c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
2552c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  for (unsigned int i = 0; i < info_list.size(); i++) {
2562c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    std::string name = desired_names[i];
2572c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
2582c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    if (total_counts[name] != 1) {
2592c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org      name = base::StringPrintf("%s (%d)", name.c_str(),
2602c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                ++current_counts[name]);
2612c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    }
2622c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
2632c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    result_map->insert(std::pair<std::string, AlbumInfo>(name, info_list[i]));
2642c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  }
2652c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org}
2662c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
2672c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org}  // namespace picasa
2682c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org