Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <errno.h> | 5 #include <errno.h> |
| 6 #include <string> | 6 #include <string> |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 264 | 264 |
| 265 void FindAndTestFilePath(const FilePath& file_path) { | 265 void FindAndTestFilePath(const FilePath& file_path) { |
| 266 GDataEntry* entry = FindEntry(file_path); | 266 GDataEntry* entry = FindEntry(file_path); |
| 267 ASSERT_TRUE(entry) << "Entry can't be found " << file_path.value(); | 267 ASSERT_TRUE(entry) << "Entry can't be found " << file_path.value(); |
| 268 EXPECT_EQ(entry->GetFilePath(), file_path); | 268 EXPECT_EQ(entry->GetFilePath(), file_path); |
| 269 } | 269 } |
| 270 | 270 |
| 271 GDataEntry* FindEntryByResourceId(const std::string& resource_id) { | 271 GDataEntry* FindEntryByResourceId(const std::string& resource_id) { |
| 272 ReadOnlyFindEntryDelegate search_delegate; | 272 ReadOnlyFindEntryDelegate search_delegate; |
| 273 file_system_->FindEntryByResourceIdSync(resource_id, | 273 file_system_->FindEntryByResourceIdSync(resource_id, |
| 274 &search_delegate); | 274 &search_delegate); |
| 275 return search_delegate.entry(); | 275 return search_delegate.entry(); |
| 276 } | 276 } |
| 277 | 277 |
| 278 // Gets the file info for |file_path| and compare the contents against | |
|
Ben Chan
2012/04/30 18:00:42
nit: compare -> compares
satorux1
2012/04/30 19:47:25
Done.
| |
| 279 // |entry|. Returns true if the file info matches |entry|. | |
| 280 bool GetFileInfoAndCompare(const FilePath& file_path, | |
| 281 GDataEntry* entry) { | |
| 282 file_system_->GetFileInfoByPathAsync( | |
| 283 file_path, | |
| 284 base::Bind(&CallbackHelper::GetFileInfoCallback, | |
| 285 callback_helper_.get())); | |
| 286 message_loop_.RunAllPending(); | |
| 287 | |
| 288 if (entry == NULL) { | |
| 289 // File info is expected not to be found. | |
| 290 return callback_helper_->file_info_ == NULL; | |
| 291 } | |
| 292 | |
| 293 scoped_ptr<GDataFileProto> file_info = | |
| 294 callback_helper_->file_info_.Pass(); | |
| 295 return (entry->resource_id() == file_info->gdata_entry().resource_id()); | |
| 296 } | |
| 297 | |
| 278 FilePath GetCacheFilePath( | 298 FilePath GetCacheFilePath( |
| 279 const std::string& resource_id, | 299 const std::string& resource_id, |
| 280 const std::string& md5, | 300 const std::string& md5, |
| 281 GDataRootDirectory::CacheSubDirectoryType sub_dir_type, | 301 GDataRootDirectory::CacheSubDirectoryType sub_dir_type, |
| 282 GDataFileSystem::CachedFileOrigin file_origin) { | 302 GDataFileSystem::CachedFileOrigin file_origin) { |
| 283 return file_system_->GetCacheFilePath(resource_id, md5, sub_dir_type, | 303 return file_system_->GetCacheFilePath(resource_id, md5, sub_dir_type, |
| 284 file_origin); | 304 file_origin); |
| 285 } | 305 } |
| 286 | 306 |
| 287 // Returns true if the cache entry exists for the given resource ID and MD5. | 307 // Returns true if the cache entry exists for the given resource ID and MD5. |
| (...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 943 | 963 |
| 944 // This is used as a helper for registering callbacks that need to be | 964 // This is used as a helper for registering callbacks that need to be |
| 945 // RefCountedThreadSafe, and a place where we can fetch results from various | 965 // RefCountedThreadSafe, and a place where we can fetch results from various |
| 946 // operations. | 966 // operations. |
| 947 class CallbackHelper | 967 class CallbackHelper |
| 948 : public base::RefCountedThreadSafe<CallbackHelper> { | 968 : public base::RefCountedThreadSafe<CallbackHelper> { |
| 949 public: | 969 public: |
| 950 CallbackHelper() | 970 CallbackHelper() |
| 951 : last_error_(base::PLATFORM_FILE_OK), | 971 : last_error_(base::PLATFORM_FILE_OK), |
| 952 quota_bytes_total_(0), | 972 quota_bytes_total_(0), |
| 953 quota_bytes_used_(0) {} | 973 quota_bytes_used_(0), |
| 974 file_info_(NULL) {} | |
| 954 virtual ~CallbackHelper() {} | 975 virtual ~CallbackHelper() {} |
| 955 virtual void GetFileCallback(base::PlatformFileError error, | 976 virtual void GetFileCallback(base::PlatformFileError error, |
| 956 const FilePath& file_path, | 977 const FilePath& file_path, |
| 957 const std::string& mime_type, | 978 const std::string& mime_type, |
| 958 GDataFileType file_type) { | 979 GDataFileType file_type) { |
| 959 last_error_ = error; | 980 last_error_ = error; |
| 960 download_path_ = file_path; | 981 download_path_ = file_path; |
| 961 mime_type_ = mime_type; | 982 mime_type_ = mime_type; |
| 962 file_type_ = file_type; | 983 file_type_ = file_type; |
| 963 } | 984 } |
| 964 virtual void FileOperationCallback(base::PlatformFileError error) { | 985 virtual void FileOperationCallback(base::PlatformFileError error) { |
| 965 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 986 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 966 | 987 |
| 967 last_error_ = error; | 988 last_error_ = error; |
| 968 } | 989 } |
| 969 virtual void GetAvailableSpaceCallback(base::PlatformFileError error, | 990 virtual void GetAvailableSpaceCallback(base::PlatformFileError error, |
| 970 int64 bytes_total, | 991 int64 bytes_total, |
| 971 int64 bytes_used) { | 992 int64 bytes_used) { |
| 972 last_error_ = error; | 993 last_error_ = error; |
| 973 quota_bytes_total_ = bytes_total; | 994 quota_bytes_total_ = bytes_total; |
| 974 quota_bytes_used_ = bytes_used; | 995 quota_bytes_used_ = bytes_used; |
| 975 } | 996 } |
| 997 virtual void GetFileInfoCallback( | |
| 998 base::PlatformFileError error, | |
| 999 scoped_ptr<GDataFileProto> file_info) { | |
| 1000 last_error_ = error; | |
| 1001 file_info_ = file_info.Pass(); | |
| 1002 } | |
| 976 | 1003 |
| 977 base::PlatformFileError last_error_; | 1004 base::PlatformFileError last_error_; |
| 978 FilePath download_path_; | 1005 FilePath download_path_; |
| 979 std::string mime_type_; | 1006 std::string mime_type_; |
| 980 GDataFileType file_type_; | 1007 GDataFileType file_type_; |
| 981 int64 quota_bytes_total_; | 1008 int64 quota_bytes_total_; |
| 982 int64 quota_bytes_used_; | 1009 int64 quota_bytes_used_; |
| 1010 scoped_ptr<GDataFileProto> file_info_; | |
| 983 }; | 1011 }; |
| 984 | 1012 |
| 985 MessageLoopForUI message_loop_; | 1013 MessageLoopForUI message_loop_; |
| 986 // The order of the test threads is important, do not change the order. | 1014 // The order of the test threads is important, do not change the order. |
| 987 // See also content/browser/browser_thread_imple.cc. | 1015 // See also content/browser/browser_thread_imple.cc. |
| 988 content::TestBrowserThread ui_thread_; | 1016 content::TestBrowserThread ui_thread_; |
| 989 content::TestBrowserThread io_thread_; | 1017 content::TestBrowserThread io_thread_; |
| 990 scoped_ptr<TestingProfile> profile_; | 1018 scoped_ptr<TestingProfile> profile_; |
| 991 scoped_refptr<CallbackHelper> callback_helper_; | 1019 scoped_refptr<CallbackHelper> callback_helper_; |
| 992 GDataFileSystem* file_system_; | 1020 GDataFileSystem* file_system_; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1035 | 1063 |
| 1036 file_system_->FindEntryByPathAsync( | 1064 file_system_->FindEntryByPathAsync( |
| 1037 FilePath(FILE_PATH_LITERAL("gdata")), callback); | 1065 FilePath(FILE_PATH_LITERAL("gdata")), callback); |
| 1038 file_system_->FindEntryByPathAsync( | 1066 file_system_->FindEntryByPathAsync( |
| 1039 FilePath(FILE_PATH_LITERAL("gdata")), callback); | 1067 FilePath(FILE_PATH_LITERAL("gdata")), callback); |
| 1040 message_loop_.Run(); // Wait to get our result | 1068 message_loop_.Run(); // Wait to get our result |
| 1041 EXPECT_EQ(2, counter); | 1069 EXPECT_EQ(2, counter); |
| 1042 } | 1070 } |
| 1043 | 1071 |
| 1044 TEST_F(GDataFileSystemTest, SearchRootDirectory) { | 1072 TEST_F(GDataFileSystemTest, SearchRootDirectory) { |
| 1045 EXPECT_TRUE(FindEntry(FilePath(FILE_PATH_LITERAL("gdata")))); | 1073 const FilePath kFilePath = FilePath(FILE_PATH_LITERAL("gdata")); |
| 1074 GDataEntry* entry = FindEntry(FilePath(FILE_PATH_LITERAL(kFilePath))); | |
| 1075 ASSERT_TRUE(entry); | |
| 1076 EXPECT_EQ(kFilePath, entry->GetFilePath()); | |
| 1046 } | 1077 } |
| 1047 | 1078 |
| 1048 TEST_F(GDataFileSystemTest, SearchExistingFile) { | 1079 TEST_F(GDataFileSystemTest, SearchExistingFile) { |
| 1049 LoadRootFeedDocument("root_feed.json"); | 1080 LoadRootFeedDocument("root_feed.json"); |
| 1050 EXPECT_TRUE(FindEntry(FilePath(FILE_PATH_LITERAL("gdata/File 1.txt")))); | 1081 |
| 1082 const FilePath kFilePath = FilePath( | |
| 1083 FILE_PATH_LITERAL("gdata/File 1.txt")); | |
| 1084 GDataEntry* entry = FindEntry(kFilePath); | |
| 1085 ASSERT_TRUE(entry); | |
| 1086 EXPECT_EQ(kFilePath, entry->GetFilePath()); | |
| 1087 EXPECT_TRUE(GetFileInfoAndCompare(kFilePath, entry)); | |
| 1051 } | 1088 } |
| 1052 | 1089 |
| 1053 TEST_F(GDataFileSystemTest, SearchExistingDocument) { | 1090 TEST_F(GDataFileSystemTest, SearchExistingDocument) { |
| 1054 LoadRootFeedDocument("root_feed.json"); | 1091 LoadRootFeedDocument("root_feed.json"); |
| 1055 EXPECT_TRUE(FindEntry(FilePath(FILE_PATH_LITERAL("gdata/Document 1.gdoc")))); | 1092 |
| 1093 const FilePath kFilePath = FilePath( | |
| 1094 FILE_PATH_LITERAL("gdata/Document 1.gdoc")); | |
| 1095 GDataEntry* entry = FindEntry(kFilePath); | |
| 1096 ASSERT_TRUE(entry); | |
| 1097 EXPECT_EQ(kFilePath, entry->GetFilePath()); | |
| 1098 EXPECT_TRUE(GetFileInfoAndCompare(kFilePath, entry)); | |
| 1056 } | 1099 } |
| 1057 | 1100 |
| 1058 TEST_F(GDataFileSystemTest, SearchNonExistingFile) { | 1101 TEST_F(GDataFileSystemTest, SearchNonExistingFile) { |
| 1059 LoadRootFeedDocument("root_feed.json"); | 1102 LoadRootFeedDocument("root_feed.json"); |
| 1060 EXPECT_FALSE( | 1103 |
| 1061 FindEntry(FilePath(FILE_PATH_LITERAL("gdata/nonexisting.file")))); | 1104 const FilePath kFilePath = FilePath( |
| 1105 FILE_PATH_LITERAL("gdata/nonexisting.file")); | |
| 1106 GDataEntry* entry = FindEntry(kFilePath); | |
| 1107 ASSERT_FALSE(entry); | |
| 1108 EXPECT_TRUE(GetFileInfoAndCompare(kFilePath, NULL)); | |
| 1062 } | 1109 } |
| 1063 | 1110 |
| 1064 TEST_F(GDataFileSystemTest, SearchEncodedFileNames) { | 1111 TEST_F(GDataFileSystemTest, SearchEncodedFileNames) { |
| 1065 LoadRootFeedDocument("root_feed.json"); | 1112 LoadRootFeedDocument("root_feed.json"); |
| 1066 | 1113 |
| 1067 EXPECT_FALSE(FindEntry(FilePath(FILE_PATH_LITERAL( | 1114 const FilePath kFilePath1 = FilePath( |
| 1068 "gdata/Slash / in file 1.txt")))); | 1115 FILE_PATH_LITERAL("gdata/Slash / in file 1.txt")); |
| 1116 GDataEntry* entry = FindEntry(kFilePath1); | |
| 1117 ASSERT_FALSE(entry); | |
| 1069 | 1118 |
| 1070 EXPECT_TRUE(FindEntry(FilePath::FromUTF8Unsafe( | 1119 const FilePath kFilePath2 = FilePath::FromUTF8Unsafe( |
| 1071 "gdata/Slash \xE2\x88\x95 in file 1.txt"))); | 1120 "gdata/Slash \xE2\x88\x95 in file 1.txt"); |
| 1121 entry = FindEntry(kFilePath2); | |
| 1122 ASSERT_TRUE(entry); | |
| 1123 EXPECT_EQ(kFilePath2, entry->GetFilePath()); | |
| 1124 EXPECT_TRUE(GetFileInfoAndCompare(kFilePath2, entry)); | |
| 1072 | 1125 |
| 1073 EXPECT_TRUE(FindEntry(FilePath::FromUTF8Unsafe( | 1126 const FilePath kFilePath3 = FilePath::FromUTF8Unsafe( |
| 1074 "gdata/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt"))); | 1127 "gdata/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt"); |
| 1128 entry = FindEntry(kFilePath3); | |
| 1129 ASSERT_TRUE(entry); | |
| 1130 EXPECT_EQ(kFilePath3, entry->GetFilePath()); | |
| 1131 EXPECT_TRUE(GetFileInfoAndCompare(kFilePath3, entry)); | |
| 1075 } | 1132 } |
| 1076 | 1133 |
| 1077 TEST_F(GDataFileSystemTest, SearchEncodedFileNamesLoadingRoot) { | 1134 TEST_F(GDataFileSystemTest, SearchEncodedFileNamesLoadingRoot) { |
| 1078 LoadRootFeedDocument("root_feed.json"); | 1135 LoadRootFeedDocument("root_feed.json"); |
| 1079 | 1136 |
| 1080 EXPECT_FALSE(FindEntry(FilePath(FILE_PATH_LITERAL( | 1137 const FilePath kFilePath1 = FilePath( |
| 1081 "gdata/Slash / in file 1.txt")))); | 1138 FILE_PATH_LITERAL("gdata/Slash / in file 1.txt")); |
| 1139 GDataEntry* entry = FindEntry(kFilePath1); | |
| 1140 ASSERT_FALSE(entry); | |
| 1082 | 1141 |
| 1083 EXPECT_TRUE(FindEntry(FilePath::FromUTF8Unsafe( | 1142 const FilePath kFilePath2 = FilePath::FromUTF8Unsafe( |
| 1084 "gdata/Slash \xE2\x88\x95 in file 1.txt"))); | 1143 "gdata/Slash \xE2\x88\x95 in file 1.txt"); |
| 1144 entry = FindEntry(kFilePath2); | |
| 1145 ASSERT_TRUE(entry); | |
| 1146 EXPECT_EQ(kFilePath2, entry->GetFilePath()); | |
| 1147 EXPECT_TRUE(GetFileInfoAndCompare(kFilePath2, entry)); | |
| 1085 | 1148 |
| 1086 EXPECT_TRUE(FindEntry(FilePath::FromUTF8Unsafe( | 1149 const FilePath kFilePath3 = FilePath::FromUTF8Unsafe( |
| 1087 "gdata/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt"))); | 1150 "gdata/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt"); |
| 1151 entry = FindEntry(kFilePath3); | |
| 1152 ASSERT_TRUE(entry); | |
| 1153 EXPECT_EQ(kFilePath3, entry->GetFilePath()); | |
| 1154 EXPECT_TRUE(GetFileInfoAndCompare(kFilePath3, entry)); | |
| 1088 } | 1155 } |
| 1089 | 1156 |
| 1090 TEST_F(GDataFileSystemTest, SearchDuplicateNames) { | 1157 TEST_F(GDataFileSystemTest, SearchDuplicateNames) { |
| 1091 LoadRootFeedDocument("root_feed.json"); | 1158 LoadRootFeedDocument("root_feed.json"); |
| 1092 EXPECT_TRUE(FindEntry(FilePath( | 1159 |
| 1093 FILE_PATH_LITERAL("gdata/Duplicate Name.txt")))); | 1160 const FilePath kFilePath1 = FilePath( |
| 1094 EXPECT_TRUE(FindEntry(FilePath( | 1161 FILE_PATH_LITERAL("gdata/Duplicate Name.txt")); |
| 1095 FILE_PATH_LITERAL("gdata/Duplicate Name (2).txt")))); | 1162 GDataEntry* entry = FindEntry(kFilePath1); |
| 1163 ASSERT_TRUE(entry); | |
| 1164 EXPECT_EQ(kFilePath1, entry->GetFilePath()); | |
| 1165 EXPECT_TRUE(GetFileInfoAndCompare(kFilePath1, entry)); | |
| 1166 | |
| 1167 const FilePath kFilePath2 = FilePath( | |
| 1168 FILE_PATH_LITERAL("gdata/Duplicate Name (2).txt")); | |
| 1169 entry = FindEntry(kFilePath2); | |
| 1170 ASSERT_TRUE(entry); | |
| 1171 EXPECT_EQ(kFilePath2, entry->GetFilePath()); | |
| 1172 EXPECT_TRUE(GetFileInfoAndCompare(kFilePath2, entry)); | |
| 1096 } | 1173 } |
| 1097 | 1174 |
| 1098 TEST_F(GDataFileSystemTest, SearchExistingDirectory) { | 1175 TEST_F(GDataFileSystemTest, SearchExistingDirectory) { |
| 1099 LoadRootFeedDocument("root_feed.json"); | 1176 LoadRootFeedDocument("root_feed.json"); |
| 1100 EXPECT_TRUE(FindEntry(FilePath( | 1177 |
| 1101 FILE_PATH_LITERAL("gdata/Directory 1")))); | 1178 const FilePath kFilePath = FilePath( |
| 1179 FILE_PATH_LITERAL("gdata/Directory 1")); | |
| 1180 GDataEntry* entry = FindEntry(kFilePath); | |
| 1181 ASSERT_TRUE(entry); | |
| 1182 EXPECT_EQ(kFilePath, entry->GetFilePath()); | |
| 1102 } | 1183 } |
| 1103 | 1184 |
| 1104 TEST_F(GDataFileSystemTest, SearchInSubdir) { | 1185 TEST_F(GDataFileSystemTest, SearchInSubdir) { |
| 1105 LoadRootFeedDocument("root_feed.json"); | 1186 LoadRootFeedDocument("root_feed.json"); |
| 1106 EXPECT_TRUE(FindEntry(FilePath( | 1187 |
| 1107 FILE_PATH_LITERAL("gdata/Directory 1/SubDirectory File 1.txt")))); | 1188 const FilePath kFilePath = FilePath( |
| 1189 FILE_PATH_LITERAL("gdata/Directory 1/SubDirectory File 1.txt")); | |
| 1190 GDataEntry* entry = FindEntry(kFilePath); | |
| 1191 ASSERT_TRUE(entry); | |
| 1192 EXPECT_EQ(kFilePath, entry->GetFilePath()); | |
| 1193 EXPECT_TRUE(GetFileInfoAndCompare(kFilePath, entry)); | |
| 1108 } | 1194 } |
| 1109 | 1195 |
| 1110 // Check the reconstruction of the directory structure from only the root feed. | 1196 // Check the reconstruction of the directory structure from only the root feed. |
| 1111 TEST_F(GDataFileSystemTest, SearchInSubSubdir) { | 1197 TEST_F(GDataFileSystemTest, SearchInSubSubdir) { |
| 1112 LoadRootFeedDocument("root_feed.json"); | 1198 LoadRootFeedDocument("root_feed.json"); |
| 1113 EXPECT_TRUE(FindEntry(FilePath( | 1199 |
| 1200 const FilePath kFilePath = FilePath( | |
| 1114 FILE_PATH_LITERAL("gdata/Directory 1/Sub Directory Folder/" | 1201 FILE_PATH_LITERAL("gdata/Directory 1/Sub Directory Folder/" |
| 1115 "Sub Sub Directory Folder")))); | 1202 "Sub Sub Directory Folder")); |
| 1203 GDataEntry* entry = FindEntry(kFilePath); | |
| 1204 ASSERT_TRUE(entry); | |
| 1205 EXPECT_EQ(kFilePath, entry->GetFilePath()); | |
| 1116 } | 1206 } |
| 1117 | 1207 |
| 1118 TEST_F(GDataFileSystemTest, FilePathTests) { | 1208 TEST_F(GDataFileSystemTest, FilePathTests) { |
| 1119 LoadRootFeedDocument("root_feed.json"); | 1209 LoadRootFeedDocument("root_feed.json"); |
| 1120 | 1210 |
| 1121 FindAndTestFilePath(FilePath(FILE_PATH_LITERAL("gdata/File 1.txt"))); | 1211 FindAndTestFilePath(FilePath(FILE_PATH_LITERAL("gdata/File 1.txt"))); |
| 1122 FindAndTestFilePath(FilePath(FILE_PATH_LITERAL("gdata/Directory 1"))); | 1212 FindAndTestFilePath(FilePath(FILE_PATH_LITERAL("gdata/Directory 1"))); |
| 1123 FindAndTestFilePath( | 1213 FindAndTestFilePath( |
| 1124 FilePath(FILE_PATH_LITERAL("gdata/Directory 1/SubDirectory File 1.txt"))); | 1214 FilePath(FILE_PATH_LITERAL("gdata/Directory 1/SubDirectory File 1.txt"))); |
| 1125 } | 1215 } |
| (...skipping 1825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2951 EXPECT_EQ(1, num_callback_invocations_); | 3041 EXPECT_EQ(1, num_callback_invocations_); |
| 2952 EXPECT_TRUE(CacheEntryExists(resource_id, md5)); | 3042 EXPECT_TRUE(CacheEntryExists(resource_id, md5)); |
| 2953 | 3043 |
| 2954 // Try to remove the file. | 3044 // Try to remove the file. |
| 2955 num_callback_invocations_ = 0; | 3045 num_callback_invocations_ = 0; |
| 2956 TestRemoveFromCache(resource_id, base::PLATFORM_FILE_OK); | 3046 TestRemoveFromCache(resource_id, base::PLATFORM_FILE_OK); |
| 2957 EXPECT_EQ(1, num_callback_invocations_); | 3047 EXPECT_EQ(1, num_callback_invocations_); |
| 2958 } | 3048 } |
| 2959 | 3049 |
| 2960 } // namespace gdata | 3050 } // namespace gdata |
| OLD | NEW |