OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h" | 5 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/callback.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
12 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h" | 12 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h" |
13 #include "chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader. h" | 13 #include "chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader. h" |
14 #include "chrome/browser/media_galleries/fileapi/safe_picasa_albums_indexer.h" | |
14 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h" | 15 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h" |
15 #include "webkit/browser/fileapi/file_system_operation_context.h" | 16 #include "webkit/browser/fileapi/file_system_operation_context.h" |
16 #include "webkit/browser/fileapi/file_system_url.h" | 17 #include "webkit/browser/fileapi/file_system_url.h" |
17 | 18 |
18 using chrome::MediaFileSystemBackend; | 19 using chrome::MediaFileSystemBackend; |
19 | 20 |
20 namespace picasa { | 21 namespace picasa { |
21 | 22 |
23 namespace { | |
24 | |
25 void RunAllCallbacks( | |
26 std::queue<PicasaDataProvider::ReadyCallback>* ready_callbacks_queue, | |
27 bool success) { | |
28 while (!ready_callbacks_queue->empty()) { | |
29 ready_callbacks_queue->front().Run(success); | |
30 ready_callbacks_queue->pop(); | |
31 } | |
32 } | |
33 | |
34 } // namespace | |
35 | |
22 PicasaDataProvider::PicasaDataProvider(const base::FilePath& database_path) | 36 PicasaDataProvider::PicasaDataProvider(const base::FilePath& database_path) |
23 : database_path_(database_path), | 37 : database_path_(database_path), |
24 needs_refresh_(true), | 38 state_(STALE_DATA_STATE), |
25 weak_factory_(this) { | 39 weak_factory_(this) { |
40 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); | |
26 } | 41 } |
27 | 42 |
28 PicasaDataProvider::~PicasaDataProvider() {} | 43 PicasaDataProvider::~PicasaDataProvider() {} |
29 | 44 |
30 void PicasaDataProvider::RefreshData(const base::Closure& ready_callback) { | 45 void PicasaDataProvider::RefreshData(DataType needed_data, |
46 const ReadyCallback& ready_callback) { | |
31 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); | 47 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); |
32 // TODO(tommycli): Need to watch the database_path_ folder and handle | 48 // TODO(tommycli): Need to watch the database_path_ folder and handle |
33 // rereading the data when it changes. | 49 // rereading the data when it changes. |
34 if (!needs_refresh_) { | 50 |
35 ready_callback.Run(); | 51 if (state_ == INVALID_DATA_STATE) { |
52 ready_callback.Run(false /* success */); | |
36 return; | 53 return; |
37 } | 54 } |
38 | 55 |
39 needs_refresh_ = false; | 56 if (needed_data == LIST_OF_ALBUMS_AND_FOLDERS_DATA) { |
40 album_table_reader_ = new SafePicasaAlbumTableReader( | 57 if (state_ != STALE_DATA_STATE) { |
vandebo (ex-Chrome)
2013/08/22 17:48:02
This is correct, but in terms of making it more fu
tommycli
2013/08/22 22:32:51
Done.
| |
41 AlbumTableFiles(database_path_), | 58 ready_callback.Run(true /* success */); |
42 base::Bind(&PicasaDataProvider::OnDataRefreshed, | 59 return; |
43 weak_factory_.GetWeakPtr(), | 60 } |
44 ready_callback)); | 61 album_list_ready_callbacks_.push(ready_callback); |
45 album_table_reader_->Start(); | 62 } else { |
63 if (state_ == ALBUMS_IMAGES_FRESH_STATE) { | |
64 ready_callback.Run(true /* success */); | |
65 return; | |
66 } | |
67 albums_index_ready_callbacks_.push(ready_callback); | |
68 } | |
69 DoRefreshIfNecessary(); | |
46 } | 70 } |
47 | 71 |
48 scoped_ptr<AlbumMap> PicasaDataProvider::GetFolders() { | 72 scoped_ptr<AlbumMap> PicasaDataProvider::GetFolders() { |
49 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); | 73 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); |
74 DCHECK(state_ == LIST_OF_ALBUMS_AND_FOLDERS_FRESH_STATE || | |
75 state_ == ALBUMS_IMAGES_FRESH_STATE); | |
50 return make_scoped_ptr(new AlbumMap(folder_map_)); | 76 return make_scoped_ptr(new AlbumMap(folder_map_)); |
51 } | 77 } |
52 | 78 |
53 scoped_ptr<AlbumMap> PicasaDataProvider::GetAlbums() { | 79 scoped_ptr<AlbumMap> PicasaDataProvider::GetAlbums() { |
54 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); | 80 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); |
81 DCHECK(state_ == LIST_OF_ALBUMS_AND_FOLDERS_FRESH_STATE || | |
82 state_ == ALBUMS_IMAGES_FRESH_STATE); | |
55 return make_scoped_ptr(new AlbumMap(album_map_)); | 83 return make_scoped_ptr(new AlbumMap(album_map_)); |
56 } | 84 } |
57 | 85 |
58 void PicasaDataProvider::OnDataRefreshed( | 86 scoped_ptr<AlbumImages> PicasaDataProvider::FindAlbumImages( |
59 const base::Closure& ready_callback, | 87 const std::string& key, |
88 base::PlatformFileError* error) { | |
89 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); | |
90 DCHECK(state_ == ALBUMS_IMAGES_FRESH_STATE); | |
91 DCHECK(error); | |
92 | |
93 AlbumImagesMap::const_iterator it = albums_images_.find(key); | |
94 | |
95 if (it == albums_images_.end()) { | |
96 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
97 return scoped_ptr<AlbumImages>(); | |
98 } | |
99 | |
100 *error = base::PLATFORM_FILE_OK; | |
101 return make_scoped_ptr(new AlbumImages(it->second)); | |
102 } | |
103 | |
104 void PicasaDataProvider::InvalidateData() { | |
105 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); | |
106 DCHECK(!(album_table_reader_ && albums_indexer_)); | |
vandebo (ex-Chrome)
2013/08/22 17:48:02
Why this invariant should be true, this method doe
tommycli
2013/08/22 22:32:51
Done.
| |
107 | |
108 // Set data state to stale and ignore responses from any in-flight processes. | |
109 // TODO(tommycli): Implement and call Cancel function for these | |
110 // UtilityProcessHostClients to actually kill the in-flight processes. | |
111 state_ = STALE_DATA_STATE; | |
112 album_table_reader_ = NULL; | |
113 albums_indexer_ = NULL; | |
114 | |
115 DoRefreshIfNecessary(); | |
116 } | |
117 | |
118 void PicasaDataProvider::DoRefreshIfNecessary() { | |
119 DCHECK(state_ != INVALID_DATA_STATE); | |
120 DCHECK(state_ != ALBUMS_IMAGES_FRESH_STATE); | |
121 DCHECK(!(album_table_reader_ && albums_indexer_)); | |
122 | |
123 if (album_list_ready_callbacks_.empty() && | |
124 albums_index_ready_callbacks_.empty()) { | |
125 return; | |
126 } | |
127 | |
128 if (state_ == STALE_DATA_STATE) { | |
129 if (album_table_reader_) | |
130 return; | |
131 album_table_reader_ = new SafePicasaAlbumTableReader( | |
132 AlbumTableFiles(database_path_), | |
133 base::Bind(&PicasaDataProvider::OnAlbumTableReaderDone, | |
134 weak_factory_.GetWeakPtr())); | |
135 album_table_reader_->Start(); | |
136 } else { | |
137 DCHECK(state_ == LIST_OF_ALBUMS_AND_FOLDERS_FRESH_STATE); | |
138 if (albums_indexer_) | |
139 return; | |
140 albums_indexer_ = new SafePicasaAlbumsIndexer( | |
141 album_map_, | |
142 folder_map_, | |
143 base::Bind(&PicasaDataProvider::OnAlbumsIndexerDone, | |
144 weak_factory_.GetWeakPtr())); | |
145 albums_indexer_->Start(); | |
146 } | |
147 } | |
148 | |
149 void PicasaDataProvider::OnAlbumTableReaderDone( | |
150 scoped_refptr<SafePicasaAlbumTableReader> reader, | |
60 bool parse_success, | 151 bool parse_success, |
61 const std::vector<AlbumInfo>& albums, | 152 const std::vector<AlbumInfo>& albums, |
62 const std::vector<AlbumInfo>& folders) { | 153 const std::vector<AlbumInfo>& folders) { |
63 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); | 154 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); |
64 if (parse_success) { | 155 // If the reader has already been deemed stale, ignore the result. |
65 UniquifyNames(albums, &album_map_); | 156 if (reader != album_table_reader_) |
66 UniquifyNames(folders, &folder_map_); | 157 return; |
158 album_table_reader_ = NULL; | |
159 | |
160 DCHECK(state_ == STALE_DATA_STATE); | |
161 | |
162 if (!parse_success) { | |
163 // If we didn't get the list successfully, fail all those waiting for | |
164 // the albums indexer also. | |
165 state_ = INVALID_DATA_STATE; | |
166 RunAllCallbacks(&album_list_ready_callbacks_, false /* success */); | |
167 RunAllCallbacks(&albums_index_ready_callbacks_, false /* success */); | |
168 return; | |
67 } | 169 } |
68 ready_callback.Run(); | 170 |
171 album_map_.clear(); | |
172 folder_map_.clear(); | |
173 UniquifyNames(albums, &album_map_); | |
174 UniquifyNames(folders, &folder_map_); | |
175 | |
176 state_ = LIST_OF_ALBUMS_AND_FOLDERS_FRESH_STATE; | |
177 RunAllCallbacks(&album_list_ready_callbacks_, parse_success); | |
178 | |
179 // Chain from this process onto refreshing the albums images if necessary. | |
180 DoRefreshIfNecessary(); | |
181 } | |
182 | |
183 void PicasaDataProvider::OnAlbumsIndexerDone( | |
184 scoped_refptr<SafePicasaAlbumsIndexer> indexer, | |
185 bool success, | |
186 const picasa::AlbumImagesMap& albums_images) { | |
187 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); | |
188 // If the indexer has already been deemed stale, ignore the result. | |
189 if (indexer != albums_indexer_) | |
190 return; | |
191 albums_indexer_ = NULL; | |
192 | |
193 DCHECK(state_ == LIST_OF_ALBUMS_AND_FOLDERS_FRESH_STATE); | |
194 | |
195 if (success) { | |
196 state_ = ALBUMS_IMAGES_FRESH_STATE; | |
197 | |
198 albums_images_ = albums_images; | |
199 } | |
200 | |
201 RunAllCallbacks(&albums_index_ready_callbacks_, success); | |
69 } | 202 } |
70 | 203 |
71 // static | 204 // static |
72 std::string PicasaDataProvider::DateToPathString(const base::Time& time) { | 205 std::string PicasaDataProvider::DateToPathString(const base::Time& time) { |
73 base::Time::Exploded exploded_time; | 206 base::Time::Exploded exploded_time; |
74 time.LocalExplode(&exploded_time); | 207 time.LocalExplode(&exploded_time); |
75 | 208 |
76 // TODO(tommycli): Investigate better localization and persisting which locale | 209 // TODO(tommycli): Investigate better localization and persisting which locale |
77 // we use to generate these unique names. | 210 // we use to generate these unique names. |
78 return base::StringPrintf("%04d-%02d-%02d", exploded_time.year, | 211 return base::StringPrintf("%04d-%02d-%02d", exploded_time.year, |
(...skipping 23 matching lines...) Expand all Loading... | |
102 if (total_counts[name] != 1) { | 235 if (total_counts[name] != 1) { |
103 name = base::StringPrintf("%s (%d)", name.c_str(), | 236 name = base::StringPrintf("%s (%d)", name.c_str(), |
104 ++current_counts[name]); | 237 ++current_counts[name]); |
105 } | 238 } |
106 | 239 |
107 result_map->insert(std::pair<std::string, AlbumInfo>(name, info_list[i])); | 240 result_map->insert(std::pair<std::string, AlbumInfo>(name, info_list[i])); |
108 } | 241 } |
109 } | 242 } |
110 | 243 |
111 } // namespace picasa | 244 } // namespace picasa |
OLD | NEW |