| 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_file_util.h" | 5 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_file_util.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
| 10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 12 #include "chrome/browser/media_galleries/fileapi/filtering_file_enumerator.h" | |
| 13 #include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_p
rovider.h" | 12 #include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_p
rovider.h" |
| 14 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_album_table_reade
r.h" | 13 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_album_table_reade
r.h" |
| 15 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h" | 14 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h" |
| 16 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h" | 15 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h" |
| 17 #include "webkit/browser/fileapi/file_system_operation_context.h" | 16 #include "webkit/browser/fileapi/file_system_operation_context.h" |
| 18 #include "webkit/browser/fileapi/file_system_url.h" | 17 #include "webkit/browser/fileapi/file_system_url.h" |
| 19 #include "webkit/common/fileapi/file_system_util.h" | 18 #include "webkit/common/fileapi/file_system_util.h" |
| 20 | 19 |
| 21 using base::FilePath; | 20 using base::FilePath; |
| 22 using fileapi::FileSystemOperationContext; | 21 using fileapi::FileSystemOperationContext; |
| 23 using fileapi::FileSystemURL; | 22 using fileapi::FileSystemURL; |
| 24 | 23 |
| 25 namespace picasa { | 24 namespace picasa { |
| 26 | 25 |
| 27 namespace { | 26 namespace { |
| 28 | 27 |
| 29 class DirectorySkippingFileEnumerator | 28 fileapi::DirectoryEntry MakeDirectoryEntry( |
| 30 : public fileapi::FileSystemFileUtil::AbstractFileEnumerator { | 29 const base::FilePath& path, |
| 31 public: | 30 int64 size, |
| 32 DirectorySkippingFileEnumerator( | 31 const base::Time& last_modified_time, |
| 33 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> | 32 bool is_directory) { |
| 34 base_enumerator) | 33 fileapi::DirectoryEntry entry; |
| 35 : base_enumerator_(base_enumerator.Pass()) { | 34 entry.name = path.BaseName().value(); |
| 36 } | 35 entry.is_directory = is_directory; |
| 37 virtual ~DirectorySkippingFileEnumerator() {} | 36 entry.size = size; |
| 38 | 37 entry.last_modified_time = last_modified_time; |
| 39 virtual base::FilePath Next() OVERRIDE { | 38 return entry; |
| 40 while (true) { | 39 } |
| 41 base::FilePath next = base_enumerator_->Next(); | |
| 42 if (next.empty() || !base_enumerator_->IsDirectory()) | |
| 43 return next; | |
| 44 } | |
| 45 } | |
| 46 | |
| 47 virtual int64 Size() OVERRIDE { | |
| 48 return base_enumerator_->Size(); | |
| 49 } | |
| 50 | |
| 51 virtual base::Time LastModifiedTime() OVERRIDE { | |
| 52 return base_enumerator_->LastModifiedTime(); | |
| 53 } | |
| 54 | |
| 55 virtual bool IsDirectory() OVERRIDE { | |
| 56 DCHECK(!base_enumerator_->IsDirectory()); | |
| 57 return base_enumerator_->IsDirectory(); | |
| 58 } | |
| 59 | |
| 60 private: | |
| 61 // The file enumerator to be wrapped. | |
| 62 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> | |
| 63 base_enumerator_; | |
| 64 }; | |
| 65 | |
| 66 struct VirtualFile { | |
| 67 VirtualFile(const base::FilePath& path, int64 size, | |
| 68 const base::Time& last_modified_time, bool is_directory) | |
| 69 : path(path), | |
| 70 size(size), | |
| 71 last_modified_time(last_modified_time), | |
| 72 is_directory(is_directory) {} | |
| 73 | |
| 74 base::FilePath path; | |
| 75 int64 size; | |
| 76 base::Time last_modified_time; | |
| 77 bool is_directory; | |
| 78 }; | |
| 79 | |
| 80 class VirtualFileEnumerator | |
| 81 : public fileapi::FileSystemFileUtil::AbstractFileEnumerator { | |
| 82 public: | |
| 83 explicit VirtualFileEnumerator(const std::vector<VirtualFile>& files) | |
| 84 : files_(files), next_called_(false), index_(0) {} | |
| 85 | |
| 86 virtual base::FilePath Next() OVERRIDE { | |
| 87 if (next_called_ && index_ < files_.size()) | |
| 88 ++index_; | |
| 89 | |
| 90 next_called_ = true; | |
| 91 | |
| 92 if (index_ >= files_.size()) | |
| 93 return FilePath(); | |
| 94 return files_[index_].path; | |
| 95 } | |
| 96 | |
| 97 virtual int64 Size() OVERRIDE { | |
| 98 if (index_ >= files_.size()) | |
| 99 return 0; | |
| 100 return files_[index_].size; | |
| 101 } | |
| 102 | |
| 103 virtual base::Time LastModifiedTime() OVERRIDE { | |
| 104 if (index_ >= files_.size()) | |
| 105 return base::Time(); | |
| 106 return files_[index_].last_modified_time; | |
| 107 } | |
| 108 | |
| 109 virtual bool IsDirectory() OVERRIDE { | |
| 110 if (index_ >= files_.size()) | |
| 111 return false; | |
| 112 return files_[index_].is_directory; | |
| 113 } | |
| 114 | |
| 115 private: | |
| 116 std::vector<VirtualFile> files_; | |
| 117 bool next_called_; | |
| 118 size_t index_; | |
| 119 }; | |
| 120 | 40 |
| 121 // |error| is only set when the method fails and the return is NULL. | 41 // |error| is only set when the method fails and the return is NULL. |
| 122 base::PlatformFileError FindAlbumInfo(const std::string& key, | 42 base::PlatformFileError FindAlbumInfo(const std::string& key, |
| 123 const AlbumMap* map, | 43 const AlbumMap* map, |
| 124 AlbumInfo* album_info) { | 44 AlbumInfo* album_info) { |
| 125 if (!map) | 45 if (!map) |
| 126 return base::PLATFORM_FILE_ERROR_FAILED; | 46 return base::PLATFORM_FILE_ERROR_FAILED; |
| 127 | 47 |
| 128 AlbumMap::const_iterator it = map->find(key); | 48 AlbumMap::const_iterator it = map->find(key); |
| 129 | 49 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 | 86 |
| 167 } // namespace | 87 } // namespace |
| 168 | 88 |
| 169 const char kPicasaDirAlbums[] = "albums"; | 89 const char kPicasaDirAlbums[] = "albums"; |
| 170 const char kPicasaDirFolders[] = "folders"; | 90 const char kPicasaDirFolders[] = "folders"; |
| 171 | 91 |
| 172 PicasaFileUtil::PicasaFileUtil() {} | 92 PicasaFileUtil::PicasaFileUtil() {} |
| 173 | 93 |
| 174 PicasaFileUtil::~PicasaFileUtil() {} | 94 PicasaFileUtil::~PicasaFileUtil() {} |
| 175 | 95 |
| 176 base::PlatformFileError PicasaFileUtil::GetFileInfo( | 96 base::PlatformFileError PicasaFileUtil::GetFileInfoSync( |
| 177 FileSystemOperationContext* context, const FileSystemURL& url, | 97 FileSystemOperationContext* context, const FileSystemURL& url, |
| 178 base::PlatformFileInfo* file_info, base::FilePath* platform_path) { | 98 base::PlatformFileInfo* file_info, base::FilePath* platform_path) { |
| 179 DCHECK(context); | 99 DCHECK(context); |
| 180 DCHECK(file_info); | 100 DCHECK(file_info); |
| 181 DCHECK(platform_path); | 101 DCHECK(platform_path); |
| 182 | 102 |
| 183 *platform_path = base::FilePath(); | 103 *platform_path = base::FilePath(); |
| 184 | 104 |
| 185 std::vector<std::string> path_components = GetComponents(url); | 105 std::vector<std::string> path_components = GetComponents(url); |
| 186 | 106 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 203 base::PlatformFileError error = | 123 base::PlatformFileError error = |
| 204 FindAlbumInfo(path_components[1], album_map.get(), NULL); | 124 FindAlbumInfo(path_components[1], album_map.get(), NULL); |
| 205 if (error != base::PLATFORM_FILE_OK) | 125 if (error != base::PLATFORM_FILE_OK) |
| 206 return error; | 126 return error; |
| 207 | 127 |
| 208 file_info->is_directory = true; | 128 file_info->is_directory = true; |
| 209 return base::PLATFORM_FILE_OK; | 129 return base::PLATFORM_FILE_OK; |
| 210 } | 130 } |
| 211 | 131 |
| 212 if (path_components[0] == kPicasaDirFolders) { | 132 if (path_components[0] == kPicasaDirFolders) { |
| 213 return NativeMediaFileUtil::GetFileInfo(context, url, file_info, | 133 return NativeMediaFileUtil::GetFileInfoSync(context, url, file_info, |
| 214 platform_path); | 134 platform_path); |
| 215 } | 135 } |
| 216 break; | 136 break; |
| 217 case 3: | 137 case 3: |
| 218 // NativeMediaFileUtil::GetInfo calls into virtual function | 138 // NativeMediaFileUtil::GetInfo calls into virtual function |
| 219 // PicasaFileUtil::GetLocalFilePath, and that will handle both | 139 // PicasaFileUtil::GetLocalFilePath, and that will handle both |
| 220 // album contents and folder contents. | 140 // album contents and folder contents. |
| 221 base::PlatformFileError result = NativeMediaFileUtil::GetFileInfo( | 141 base::PlatformFileError result = NativeMediaFileUtil::GetFileInfoSync( |
| 222 context, url, file_info, platform_path); | 142 context, url, file_info, platform_path); |
| 223 | 143 |
| 224 DCHECK(path_components[0] == kPicasaDirAlbums || | 144 DCHECK(path_components[0] == kPicasaDirAlbums || |
| 225 path_components[0] == kPicasaDirFolders || | 145 path_components[0] == kPicasaDirFolders || |
| 226 result == base::PLATFORM_FILE_ERROR_NOT_FOUND); | 146 result == base::PLATFORM_FILE_ERROR_NOT_FOUND); |
| 227 | 147 |
| 228 return result; | 148 return result; |
| 229 } | 149 } |
| 230 | 150 |
| 231 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 151 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 232 } | 152 } |
| 233 | 153 |
| 234 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> | 154 base::PlatformFileError PicasaFileUtil::ReadDirectorySync( |
| 235 PicasaFileUtil::CreateFileEnumerator(FileSystemOperationContext* context, | 155 fileapi::FileSystemOperationContext* context, |
| 236 const FileSystemURL& url) { | 156 const fileapi::FileSystemURL& url, |
| 157 EntryList* file_list) { |
| 237 DCHECK(context); | 158 DCHECK(context); |
| 159 DCHECK(file_list); |
| 160 DCHECK(file_list->empty()); |
| 161 |
| 162 base::PlatformFileInfo file_info; |
| 163 base::FilePath platform_directory_path; |
| 164 base::PlatformFileError error = GetFileInfoSync( |
| 165 context, url, &file_info, &platform_directory_path); |
| 166 |
| 167 if (error == base::PLATFORM_FILE_OK && !file_info.is_directory) |
| 168 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
| 169 |
| 170 if (error != base::PLATFORM_FILE_OK) |
| 171 return error; |
| 172 |
| 238 std::vector<std::string> path_components = GetComponents(url); | 173 std::vector<std::string> path_components = GetComponents(url); |
| 239 | 174 |
| 240 std::vector<VirtualFile> files; | |
| 241 FilePath folders_path = base::FilePath().AppendASCII(kPicasaDirFolders); | 175 FilePath folders_path = base::FilePath().AppendASCII(kPicasaDirFolders); |
| 242 | 176 |
| 243 switch (path_components.size()) { | 177 switch (path_components.size()) { |
| 244 case 0: { | 178 case 0: { |
| 245 // Root directory. | 179 // Root directory. |
| 246 FilePath albums_path = base::FilePath().AppendASCII(kPicasaDirAlbums); | 180 FilePath albums_path = base::FilePath().AppendASCII(kPicasaDirAlbums); |
| 247 files.push_back(VirtualFile(albums_path, 0, base::Time(), true)); | 181 file_list->push_back( |
| 248 files.push_back(VirtualFile(folders_path, 0, base::Time(), true)); | 182 MakeDirectoryEntry(albums_path, 0, base::Time(), true)); |
| 183 file_list->push_back( |
| 184 MakeDirectoryEntry(folders_path, 0, base::Time(), true)); |
| 249 break; | 185 break; |
| 250 } | 186 } |
| 251 case 1: | 187 case 1: |
| 252 if (path_components[0] == kPicasaDirAlbums) { | 188 if (path_components[0] == kPicasaDirAlbums) { |
| 253 scoped_ptr<AlbumMap> albums = DataProvider()->GetAlbums(); | 189 scoped_ptr<AlbumMap> albums = DataProvider()->GetAlbums(); |
| 254 if (!albums) | 190 if (!albums) |
| 255 return scoped_ptr<AbstractFileEnumerator>(new EmptyFileEnumerator()); | 191 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 256 | 192 |
| 257 // TODO(tommycli): Use AlbumMap enumerator to avoid copies. | |
| 258 for (AlbumMap::const_iterator it = albums->begin(); | 193 for (AlbumMap::const_iterator it = albums->begin(); |
| 259 it != albums->end(); ++it) { | 194 it != albums->end(); ++it) { |
| 260 files.push_back(VirtualFile( | 195 file_list->push_back(MakeDirectoryEntry( |
| 261 folders_path.Append(FilePath::FromUTF8Unsafe(it->first)), | 196 folders_path.Append(FilePath::FromUTF8Unsafe(it->first)), |
| 262 0, | 197 0, |
| 263 it->second.timestamp, | 198 it->second.timestamp, |
| 264 true)); | 199 true)); |
| 265 } | 200 } |
| 266 } else if (path_components[0] == kPicasaDirFolders) { | 201 } else if (path_components[0] == kPicasaDirFolders) { |
| 267 scoped_ptr<AlbumMap> folders = DataProvider()->GetFolders(); | 202 scoped_ptr<AlbumMap> folders = DataProvider()->GetFolders(); |
| 268 if (!folders) | 203 if (!folders) |
| 269 return scoped_ptr<AbstractFileEnumerator>(new EmptyFileEnumerator()); | 204 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 270 | 205 |
| 271 // TODO(tommycli): Use AlbumMap enumerator to avoid copies. | |
| 272 for (AlbumMap::const_iterator it = folders->begin(); | 206 for (AlbumMap::const_iterator it = folders->begin(); |
| 273 it != folders->end(); ++it) { | 207 it != folders->end(); ++it) { |
| 274 files.push_back(VirtualFile( | 208 file_list->push_back(MakeDirectoryEntry( |
| 275 folders_path.Append(FilePath::FromUTF8Unsafe(it->first)), | 209 folders_path.Append(FilePath::FromUTF8Unsafe(it->first)), |
| 276 0, | 210 0, |
| 277 it->second.timestamp, | 211 it->second.timestamp, |
| 278 true)); | 212 true)); |
| 279 } | 213 } |
| 280 } | 214 } |
| 281 break; | 215 break; |
| 282 case 2: | 216 case 2: |
| 283 if (path_components[0] == kPicasaDirAlbums) { | 217 if (path_components[0] == kPicasaDirAlbums) { |
| 284 // TODO(tommycli): Implement album contents. | 218 // TODO(tommycli): Implement album contents. |
| 285 } | 219 } |
| 286 | 220 |
| 287 if (path_components[0] == kPicasaDirFolders) | 221 if (path_components[0] == kPicasaDirFolders) { |
| 288 return scoped_ptr<AbstractFileEnumerator>( | 222 EntryList super_list; |
| 289 new DirectorySkippingFileEnumerator( | 223 base::PlatformFileError error = |
| 290 NativeMediaFileUtil::CreateFileEnumerator(context, url))); | 224 NativeMediaFileUtil::ReadDirectorySync(context, url, &super_list); |
| 225 if (error != base::PLATFORM_FILE_OK) |
| 226 return error; |
| 227 |
| 228 for (EntryList::const_iterator it = super_list.begin(); |
| 229 it != super_list.end(); ++it) { |
| 230 if (!it->is_directory) |
| 231 file_list->push_back(*it); |
| 232 } |
| 233 } |
| 234 |
| 291 break; | 235 break; |
| 292 } | 236 } |
| 293 | 237 |
| 294 return scoped_ptr<AbstractFileEnumerator>(new VirtualFileEnumerator(files)); | 238 return base::PLATFORM_FILE_OK; |
| 295 } | 239 } |
| 296 | 240 |
| 297 base::PlatformFileError PicasaFileUtil::GetLocalFilePath( | 241 base::PlatformFileError PicasaFileUtil::GetLocalFilePath( |
| 298 FileSystemOperationContext* context, const FileSystemURL& url, | 242 FileSystemOperationContext* context, const FileSystemURL& url, |
| 299 base::FilePath* local_file_path) { | 243 base::FilePath* local_file_path) { |
| 300 DCHECK(local_file_path); | 244 DCHECK(local_file_path); |
| 301 DCHECK(url.is_valid()); | 245 DCHECK(url.is_valid()); |
| 302 std::vector<std::string> path_components = GetComponents(url); | 246 std::vector<std::string> path_components = GetComponents(url); |
| 303 | 247 |
| 304 switch (path_components.size()) { | 248 switch (path_components.size()) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 // intercepted by GetFileInfo()/CreateFileEnumerator(). Invalid cases | 292 // intercepted by GetFileInfo()/CreateFileEnumerator(). Invalid cases |
| 349 // return a NOT_FOUND error. | 293 // return a NOT_FOUND error. |
| 350 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 294 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 351 } | 295 } |
| 352 | 296 |
| 353 PicasaDataProvider* PicasaFileUtil::DataProvider() { | 297 PicasaDataProvider* PicasaFileUtil::DataProvider() { |
| 354 return chrome::ImportedMediaGalleryRegistry::picasa_data_provider(); | 298 return chrome::ImportedMediaGalleryRegistry::picasa_data_provider(); |
| 355 } | 299 } |
| 356 | 300 |
| 357 } // namespace picasa | 301 } // namespace picasa |
| OLD | NEW |