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 "chrome/browser/chromeos/gdata/gdata_file_system.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_file_system.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <sys/stat.h> | 8 #include <sys/stat.h> |
| 9 | 9 |
| 10 #include <set> | 10 #include <set> |
| (...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 855 | 855 |
| 856 GDataFileProperties::~GDataFileProperties() { | 856 GDataFileProperties::~GDataFileProperties() { |
| 857 } | 857 } |
| 858 | 858 |
| 859 // GDataFileSystem::GetDocumentsParams struct implementation. | 859 // GDataFileSystem::GetDocumentsParams struct implementation. |
| 860 | 860 |
| 861 GDataFileSystem::GetDocumentsParams::GetDocumentsParams( | 861 GDataFileSystem::GetDocumentsParams::GetDocumentsParams( |
| 862 int start_changestamp, | 862 int start_changestamp, |
| 863 int root_feed_changestamp, | 863 int root_feed_changestamp, |
| 864 std::vector<DocumentFeed*>* feed_list, | 864 std::vector<DocumentFeed*>* feed_list, |
| 865 bool allow_multiple_feeds, | |
| 865 const FilePath& search_file_path, | 866 const FilePath& search_file_path, |
| 867 const std::string& search_query, | |
| 866 const FindEntryCallback& callback) | 868 const FindEntryCallback& callback) |
| 867 : start_changestamp(start_changestamp), | 869 : start_changestamp(start_changestamp), |
| 868 root_feed_changestamp(root_feed_changestamp), | 870 root_feed_changestamp(root_feed_changestamp), |
| 869 feed_list(feed_list), | 871 feed_list(feed_list), |
| 872 allow_multiple_feeds(allow_multiple_feeds), | |
| 870 search_file_path(search_file_path), | 873 search_file_path(search_file_path), |
| 874 search_query(search_query), | |
| 871 callback(callback) { | 875 callback(callback) { |
| 872 } | 876 } |
| 873 | 877 |
| 874 GDataFileSystem::GetDocumentsParams::~GetDocumentsParams() { | 878 GDataFileSystem::GetDocumentsParams::~GetDocumentsParams() { |
| 875 STLDeleteElements(feed_list.get()); | 879 STLDeleteElements(feed_list.get()); |
| 876 } | 880 } |
| 877 | 881 |
| 878 // GDataFileSystem::CreateDirectoryParams struct implementation. | 882 // GDataFileSystem::CreateDirectoryParams struct implementation. |
| 879 | 883 |
| 880 GDataFileSystem::CreateDirectoryParams::CreateDirectoryParams( | 884 GDataFileSystem::CreateDirectoryParams::CreateDirectoryParams( |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1121 int local_changestamp, | 1125 int local_changestamp, |
| 1122 const FilePath& search_file_path, | 1126 const FilePath& search_file_path, |
| 1123 const FindEntryCallback& callback, | 1127 const FindEntryCallback& callback, |
| 1124 GDataErrorCode status, | 1128 GDataErrorCode status, |
| 1125 scoped_ptr<base::Value> feed_data) { | 1129 scoped_ptr<base::Value> feed_data) { |
| 1126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1127 | 1131 |
| 1128 base::PlatformFileError error = GDataToPlatformError(status); | 1132 base::PlatformFileError error = GDataToPlatformError(status); |
| 1129 if (error != base::PLATFORM_FILE_OK) { | 1133 if (error != base::PLATFORM_FILE_OK) { |
| 1130 // Get changes starting from the next changestamp from what we have locally. | 1134 // Get changes starting from the next changestamp from what we have locally. |
| 1131 LoadFeedFromServer(local_changestamp + 1, 0, search_file_path, callback); | 1135 LoadFeedFromServer(local_changestamp + 1, 0, |
| 1136 true, | |
| 1137 search_file_path, | |
| 1138 std::string() /* no search query*/, | |
| 1139 callback, | |
| 1140 base::Bind(&GDataFileSystem::OnFeedFromServerLoaded, | |
| 1141 ui_weak_ptr_)); | |
| 1132 return; | 1142 return; |
| 1133 } | 1143 } |
| 1134 | 1144 |
| 1135 scoped_ptr<AccountMetadataFeed> feed; | 1145 scoped_ptr<AccountMetadataFeed> feed; |
| 1136 if (feed_data.get()) | 1146 if (feed_data.get()) |
| 1137 feed = AccountMetadataFeed::CreateFrom(*feed_data); | 1147 feed = AccountMetadataFeed::CreateFrom(*feed_data); |
| 1138 if (!feed.get()) { | 1148 if (!feed.get()) { |
| 1139 LoadFeedFromServer(local_changestamp + 1, 0, search_file_path, callback); | 1149 LoadFeedFromServer(local_changestamp + 1, 0, |
| 1150 true, | |
| 1151 search_file_path, | |
| 1152 std::string() /* no search query*/, | |
| 1153 callback, | |
| 1154 base::Bind(&GDataFileSystem::OnFeedFromServerLoaded, | |
| 1155 ui_weak_ptr_)); | |
| 1140 return; | 1156 return; |
| 1141 } | 1157 } |
| 1142 | 1158 |
| 1143 bool changes_detected = true; | 1159 bool changes_detected = true; |
| 1144 if (local_changestamp >= feed->largest_changestamp()) { | 1160 if (local_changestamp >= feed->largest_changestamp()) { |
| 1145 if (local_changestamp > feed->largest_changestamp()) { | 1161 if (local_changestamp > feed->largest_changestamp()) { |
| 1146 LOG(WARNING) << "Cached client feed is fresher than server, client = " | 1162 LOG(WARNING) << "Cached client feed is fresher than server, client = " |
| 1147 << local_changestamp | 1163 << local_changestamp |
| 1148 << ", server = " | 1164 << ", server = " |
| 1149 << feed->largest_changestamp(); | 1165 << feed->largest_changestamp(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1163 | 1179 |
| 1164 NotifyInitialLoadFinished(); | 1180 NotifyInitialLoadFinished(); |
| 1165 return; | 1181 return; |
| 1166 } | 1182 } |
| 1167 | 1183 |
| 1168 SaveFeed(feed_data.Pass(), FilePath(kAccountMetadataFile)); | 1184 SaveFeed(feed_data.Pass(), FilePath(kAccountMetadataFile)); |
| 1169 | 1185 |
| 1170 // Load changes from the server. | 1186 // Load changes from the server. |
| 1171 LoadFeedFromServer(local_changestamp > 0 ? local_changestamp + 1 : 0, | 1187 LoadFeedFromServer(local_changestamp > 0 ? local_changestamp + 1 : 0, |
| 1172 feed->largest_changestamp(), | 1188 feed->largest_changestamp(), |
| 1189 true, | |
| 1173 search_file_path, | 1190 search_file_path, |
| 1174 callback); | 1191 std::string() /* no search query*/, |
| 1192 callback, | |
| 1193 base::Bind(&GDataFileSystem::OnFeedFromServerLoaded, | |
| 1194 ui_weak_ptr_)); | |
| 1175 } | 1195 } |
| 1176 | 1196 |
| 1177 void GDataFileSystem::LoadFeedFromServer( | 1197 void GDataFileSystem::LoadFeedFromServer( |
| 1178 int start_changestamp, | 1198 int start_changestamp, |
| 1179 int root_feed_changestamp, | 1199 int root_feed_changestamp, |
| 1200 bool allow_multiple_feeds, | |
| 1180 const FilePath& search_file_path, | 1201 const FilePath& search_file_path, |
| 1181 const FindEntryCallback& callback) { | 1202 const std::string& search_query, |
| 1203 const FindEntryCallback& entry_found_callback, | |
| 1204 const LoadDocumentFeedCallback& feed_load_callback) { | |
| 1182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1183 | 1206 |
| 1184 // ...then also kick off document feed fetching from the server as well. | 1207 // ...then also kick off document feed fetching from the server as well. |
| 1185 // |feed_list| will contain the list of all collected feed updates that | 1208 // |feed_list| will contain the list of all collected feed updates that |
| 1186 // we will receive through calls of DocumentsService::GetDocuments(). | 1209 // we will receive through calls of DocumentsService::GetDocuments(). |
| 1187 scoped_ptr<std::vector<DocumentFeed*> > feed_list( | 1210 scoped_ptr<std::vector<DocumentFeed*> > feed_list( |
| 1188 new std::vector<DocumentFeed*>); | 1211 new std::vector<DocumentFeed*>); |
| 1189 // Kick off document feed fetching here if we don't have complete data | 1212 // Kick off document feed fetching here if we don't have complete data |
| 1190 // to finish this call. | 1213 // to finish this call. |
| 1191 documents_service_->GetDocuments( | 1214 documents_service_->GetDocuments( |
| 1192 GURL(), // root feed start. | 1215 GURL(), // root feed start. |
| 1193 start_changestamp, | 1216 start_changestamp, |
| 1217 search_query, | |
| 1194 base::Bind(&GDataFileSystem::OnGetDocuments, | 1218 base::Bind(&GDataFileSystem::OnGetDocuments, |
| 1195 ui_weak_ptr_, | 1219 ui_weak_ptr_, |
| 1220 feed_load_callback, | |
| 1196 base::Owned(new GetDocumentsParams(start_changestamp, | 1221 base::Owned(new GetDocumentsParams(start_changestamp, |
| 1197 root_feed_changestamp, | 1222 root_feed_changestamp, |
| 1198 feed_list.release(), | 1223 feed_list.release(), |
| 1224 allow_multiple_feeds, | |
| 1199 search_file_path, | 1225 search_file_path, |
| 1200 callback)))); | 1226 search_query, |
| 1227 entry_found_callback)))); | |
| 1228 } | |
| 1229 | |
| 1230 void GDataFileSystem::OnFeedFromServerLoaded(GetDocumentsParams* params, | |
| 1231 base::PlatformFileError error) { | |
| 1232 if (error != base::PLATFORM_FILE_OK) { | |
| 1233 params->callback.Run(error, FilePath(), | |
| 1234 reinterpret_cast<GDataEntry*>(NULL)); | |
|
satorux1
2012/05/03 17:58:34
indentation is off?
tbarzic
2012/05/03 23:56:17
Done.
| |
| 1235 return; | |
| 1236 } | |
| 1237 | |
| 1238 error = UpdateFromFeed(*params->feed_list, | |
| 1239 FROM_SERVER, | |
| 1240 params->start_changestamp, | |
| 1241 params->root_feed_changestamp); | |
| 1242 | |
| 1243 if (error != base::PLATFORM_FILE_OK) { | |
| 1244 if (!params->callback.is_null()) { | |
| 1245 params->callback.Run(error, FilePath(), | |
| 1246 reinterpret_cast<GDataEntry*>(NULL)); | |
|
satorux1
2012/05/03 17:58:34
indentation is off?
tbarzic
2012/05/03 23:56:17
Done.
| |
| 1247 } | |
| 1248 | |
| 1249 return; | |
| 1250 } | |
| 1251 | |
| 1252 // Save file system metadata to disk. | |
| 1253 SaveFileSystemAsProto(); | |
| 1254 | |
| 1255 // If we had someone to report this too, then this retrieval was done in a | |
| 1256 // context of search... so continue search. | |
| 1257 if (!params->callback.is_null()) { | |
| 1258 FindEntryByPathSyncOnUIThread(params->search_file_path, params->callback); | |
| 1259 } | |
| 1201 } | 1260 } |
| 1202 | 1261 |
| 1203 void GDataFileSystem::TransferFile(const FilePath& local_file_path, | 1262 void GDataFileSystem::TransferFile(const FilePath& local_file_path, |
| 1204 const FilePath& remote_dest_file_path, | 1263 const FilePath& remote_dest_file_path, |
| 1205 const FileOperationCallback& callback) { | 1264 const FileOperationCallback& callback) { |
| 1206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1265 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1207 | 1266 |
| 1208 base::AutoLock lock(lock_); | 1267 base::AutoLock lock(lock_); |
| 1209 // Make sure the destination directory exists | 1268 // Make sure the destination directory exists |
| 1210 GDataEntry* dest_dir = GetGDataEntryByPath( | 1269 GDataEntry* dest_dir = GetGDataEntryByPath( |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1351 base::Bind(&RelayFileOperationCallback, | 1410 base::Bind(&RelayFileOperationCallback, |
| 1352 base::MessageLoopProxy::current(), | 1411 base::MessageLoopProxy::current(), |
| 1353 callback))); | 1412 callback))); |
| 1354 DCHECK(posted); | 1413 DCHECK(posted); |
| 1355 return; | 1414 return; |
| 1356 } | 1415 } |
| 1357 | 1416 |
| 1358 CopyOnUIThread(src_file_path, dest_file_path, callback); | 1417 CopyOnUIThread(src_file_path, dest_file_path, callback); |
| 1359 } | 1418 } |
| 1360 | 1419 |
| 1361 void GDataFileSystem::CopyOnUIThread(const FilePath& src_file_path, | 1420 void GDataFileSystem::CopyOnUIThread(const FilePath& original_src_file_path, |
| 1362 const FilePath& dest_file_path, | 1421 const FilePath& original_dest_file_path, |
| 1363 const FileOperationCallback& callback) { | 1422 const FileOperationCallback& callback) { |
| 1364 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1365 | 1424 |
| 1366 base::PlatformFileError error = base::PLATFORM_FILE_OK; | 1425 base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| 1367 FilePath dest_parent_path = dest_file_path.DirName(); | 1426 FilePath dest_parent_path = original_dest_file_path.DirName(); |
| 1427 | |
| 1428 FilePath src_file_path = original_src_file_path; | |
| 1429 FilePath dest_file_path = original_dest_file_path; | |
|
satorux1
2012/05/03 17:58:34
If I understand right, you don't have to initializ
tbarzic
2012/05/03 23:56:17
Done.
| |
| 1368 | 1430 |
| 1369 std::string src_file_resource_id; | 1431 std::string src_file_resource_id; |
| 1370 bool src_file_is_hosted_document = false; | 1432 bool src_file_is_hosted_document = false; |
| 1371 { | 1433 { |
| 1372 base::AutoLock lock(lock_); | 1434 base::AutoLock lock(lock_); |
| 1373 GDataEntry* src_entry = GetGDataEntryByPath(src_file_path); | 1435 GDataEntry* src_entry = GetGDataEntryByPath(src_file_path); |
| 1374 GDataEntry* dest_parent = GetGDataEntryByPath(dest_parent_path); | 1436 GDataEntry* dest_parent = GetGDataEntryByPath(dest_parent_path); |
| 1375 if (!src_entry || !dest_parent) { | 1437 if (!src_entry || !dest_parent) { |
| 1376 error = base::PLATFORM_FILE_ERROR_NOT_FOUND; | 1438 error = base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 1377 } else if (!dest_parent->AsGDataDirectory()) { | 1439 } else if (!dest_parent->AsGDataDirectory()) { |
| 1378 error = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; | 1440 error = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
| 1379 } else if (!src_entry->AsGDataFile()) { | 1441 } else if (!src_entry->AsGDataFile() || dest_parent->is_detached()) { |
| 1380 // TODO(benchan): Implement copy for directories. In the interim, | 1442 // TODO(benchan): Implement copy for directories. In the interim, |
| 1381 // we handle recursive directory copy in the file manager. | 1443 // we handle recursive directory copy in the file manager. |
| 1382 error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION; | 1444 error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION; |
| 1383 } else { | 1445 } else { |
| 1384 src_file_resource_id = src_entry->resource_id(); | 1446 src_file_resource_id = src_entry->resource_id(); |
| 1385 src_file_is_hosted_document = | 1447 src_file_is_hosted_document = |
| 1386 src_entry->AsGDataFile()->is_hosted_document(); | 1448 src_entry->AsGDataFile()->is_hosted_document(); |
| 1449 // If original source or destinatino paths are virtual (e.g. paths used to | |
| 1450 // show content search results), we don't want to use them to perform copy | |
| 1451 // operation. Instead we use file paths of the files they point to. | |
| 1452 src_file_path = src_entry->GetFilePath(); | |
| 1453 dest_parent_path = dest_parent->GetFilePath(); | |
|
satorux1
2012/05/03 17:58:34
This code path is used for regular paths (not sear
tbarzic
2012/05/03 23:56:17
Done.
| |
| 1454 dest_file_path = dest_parent_path.Append(dest_file_path.BaseName()); | |
| 1387 } | 1455 } |
| 1388 } | 1456 } |
|
satorux1
2012/05/03 17:58:34
might want to add:
DCHECK(!src_file_path.empty())
tbarzic
2012/05/03 23:56:17
Done.
| |
| 1389 | 1457 |
| 1390 if (error != base::PLATFORM_FILE_OK) { | 1458 if (error != base::PLATFORM_FILE_OK) { |
| 1391 if (!callback.is_null()) | 1459 if (!callback.is_null()) |
| 1392 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, error)); | 1460 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, error)); |
| 1393 | 1461 |
| 1394 return; | 1462 return; |
| 1395 } | 1463 } |
| 1396 | 1464 |
| 1397 if (src_file_is_hosted_document) { | 1465 if (src_file_is_hosted_document) { |
| 1398 CopyDocumentToDirectory(dest_parent_path, | 1466 CopyDocumentToDirectory(dest_parent_path, |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1527 base::Bind(&RelayFileOperationCallback, | 1595 base::Bind(&RelayFileOperationCallback, |
| 1528 base::MessageLoopProxy::current(), | 1596 base::MessageLoopProxy::current(), |
| 1529 callback))); | 1597 callback))); |
| 1530 DCHECK(posted); | 1598 DCHECK(posted); |
| 1531 return; | 1599 return; |
| 1532 } | 1600 } |
| 1533 | 1601 |
| 1534 MoveOnUIThread(src_file_path, dest_file_path, callback); | 1602 MoveOnUIThread(src_file_path, dest_file_path, callback); |
| 1535 } | 1603 } |
| 1536 | 1604 |
| 1537 void GDataFileSystem::MoveOnUIThread(const FilePath& src_file_path, | 1605 void GDataFileSystem::MoveOnUIThread(const FilePath& original_src_file_path, |
| 1538 const FilePath& dest_file_path, | 1606 const FilePath& original_dest_file_path, |
| 1539 const FileOperationCallback& callback) { | 1607 const FileOperationCallback& callback) { |
| 1540 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1608 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1541 | 1609 |
| 1542 base::PlatformFileError error = base::PLATFORM_FILE_OK; | 1610 base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| 1543 FilePath dest_parent_path = dest_file_path.DirName(); | 1611 FilePath dest_parent_path = original_dest_file_path.DirName(); |
| 1612 | |
| 1613 FilePath src_file_path = original_src_file_path; | |
| 1614 FilePath dest_file_path = original_dest_file_path; | |
| 1615 FilePath dest_name = dest_file_path.BaseName(); | |
| 1544 | 1616 |
| 1545 { | 1617 { |
| 1546 // This scoped lock needs to be released before calling Rename() below. | 1618 // This scoped lock needs to be released before calling Rename() below. |
| 1547 base::AutoLock lock(lock_); | 1619 base::AutoLock lock(lock_); |
| 1548 GDataEntry* src_entry = GetGDataEntryByPath(src_file_path); | 1620 GDataEntry* src_entry = GetGDataEntryByPath(src_file_path); |
| 1549 GDataEntry* dest_parent = GetGDataEntryByPath(dest_parent_path); | 1621 GDataEntry* dest_parent = GetGDataEntryByPath(dest_parent_path); |
| 1550 if (!src_entry || !dest_parent) { | 1622 if (!src_entry || !dest_parent) { |
| 1551 error = base::PLATFORM_FILE_ERROR_NOT_FOUND; | 1623 error = base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 1552 } else { | 1624 } else if (!dest_parent->AsGDataDirectory()) { |
| 1553 if (!dest_parent->AsGDataDirectory()) | |
| 1554 error = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; | 1625 error = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
| 1626 } else if (dest_parent->is_detached()){ | |
| 1627 // We allow moving to a directory without file system root only if it's | |
| 1628 // done as part of renaming (i.e. source and destination parent paths are | |
| 1629 // the same). | |
| 1630 if (src_file_path.DirName() != dest_parent_path) { | |
| 1631 error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION; | |
| 1632 } else { | |
| 1633 // If we are indeed renaming, we have to strip resource id from the file | |
| 1634 // name. | |
| 1635 std::string resource_id; | |
| 1636 std::string file_name; | |
| 1637 util::CrackSearchFileName(dest_name.value(), &resource_id, &file_name); | |
| 1638 if (!file_name.empty()) | |
| 1639 dest_name = FilePath(file_name); | |
| 1640 } | |
| 1555 } | 1641 } |
| 1556 | 1642 |
| 1557 if (error != base::PLATFORM_FILE_OK) { | 1643 if (error != base::PLATFORM_FILE_OK) { |
| 1558 if (!callback.is_null()) { | 1644 if (!callback.is_null()) { |
| 1559 MessageLoop::current()->PostTask(FROM_HERE, | 1645 MessageLoop::current()->PostTask(FROM_HERE, |
| 1560 base::Bind(callback, error)); | 1646 base::Bind(callback, error)); |
| 1561 } | 1647 } |
| 1562 return; | 1648 return; |
| 1563 } | 1649 } |
| 1650 src_file_path = src_entry->GetFilePath(); | |
| 1651 if (!dest_parent->is_detached()) | |
| 1652 dest_parent_path = dest_parent->GetFilePath(); | |
| 1653 dest_file_path = dest_parent_path.Append(dest_name); | |
| 1564 } | 1654 } |
| 1565 | 1655 |
| 1566 // If the file/directory is moved to the same directory, just rename it. | 1656 // If the file/directory is moved to the same directory, just rename it. |
| 1567 if (src_file_path.DirName() == dest_parent_path) { | 1657 if (original_src_file_path.DirName() == dest_parent_path) { |
| 1568 FilePathUpdateCallback final_file_path_update_callback = | 1658 FilePathUpdateCallback final_file_path_update_callback = |
| 1569 base::Bind(&GDataFileSystem::OnFilePathUpdated, | 1659 base::Bind(&GDataFileSystem::OnFilePathUpdated, |
| 1570 ui_weak_ptr_, | 1660 ui_weak_ptr_, |
| 1571 callback); | 1661 callback); |
| 1572 | 1662 |
| 1573 Rename(src_file_path, dest_file_path.BaseName().value(), | 1663 Rename(original_src_file_path, dest_name.value(), |
| 1574 final_file_path_update_callback); | 1664 final_file_path_update_callback); |
| 1575 return; | 1665 return; |
| 1576 } | 1666 } |
| 1577 | 1667 |
| 1578 // Otherwise, the move operation involves three steps: | 1668 // Otherwise, the move operation involves three steps: |
| 1579 // 1. Renames the file at |src_file_path| to basename(|dest_file_path|) | 1669 // 1. Renames the file at |src_file_path| to basename(|dest_file_path|) |
| 1580 // within the same directory. The rename operation is a no-op if | 1670 // within the same directory. The rename operation is a no-op if |
| 1581 // basename(|src_file_path|) equals to basename(|dest_file_path|). | 1671 // basename(|src_file_path|) equals to basename(|dest_file_path|). |
| 1582 // 2. Removes the file from its parent directory (the file is not deleted), | 1672 // 2. Removes the file from its parent directory (the file is not deleted), |
| 1583 // which effectively moves the file to the root directory. | 1673 // which effectively moves the file to the root directory. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1703 bool is_recursive, | 1793 bool is_recursive, |
| 1704 const FileOperationCallback& callback) { | 1794 const FileOperationCallback& callback) { |
| 1705 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1795 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1706 | 1796 |
| 1707 base::AutoLock lock(lock_); | 1797 base::AutoLock lock(lock_); |
| 1708 GDataEntry* entry = GetGDataEntryByPath(file_path); | 1798 GDataEntry* entry = GetGDataEntryByPath(file_path); |
| 1709 if (!entry) { | 1799 if (!entry) { |
| 1710 if (!callback.is_null()) { | 1800 if (!callback.is_null()) { |
| 1711 MessageLoop::current()->PostTask( | 1801 MessageLoop::current()->PostTask( |
| 1712 FROM_HERE, | 1802 FROM_HERE, |
| 1713 base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND)); | 1803 base::Bind(callback, base::PLATFORM_FILE_OK)); |
|
satorux1
2012/05/03 17:58:34
Why is it OK? The entry wasn't found, right? pleas
tbarzic
2012/05/03 23:56:17
Done.
| |
| 1714 } | 1804 } |
| 1715 return; | 1805 return; |
| 1716 } | 1806 } |
| 1717 | 1807 |
| 1718 documents_service_->DeleteDocument( | 1808 documents_service_->DeleteDocument( |
| 1719 entry->edit_url(), | 1809 entry->edit_url(), |
| 1720 base::Bind(&GDataFileSystem::OnRemovedDocument, | 1810 base::Bind(&GDataFileSystem::OnRemovedDocument, |
| 1721 ui_weak_ptr_, | 1811 ui_weak_ptr_, |
| 1722 callback, | 1812 callback, |
| 1723 file_path)); | 1813 entry->GetFilePath())); |
|
satorux1
2012/05/03 17:58:34
why is this changed? file_path == entry->GetFilePa
tbarzic
2012/05/03 23:56:17
not necessary.
if file_path is in gdata search res
satorux1
2012/05/04 01:48:40
I see then, could you add it as a comment?
| |
| 1724 } | 1814 } |
| 1725 | 1815 |
| 1726 void GDataFileSystem::CreateDirectory( | 1816 void GDataFileSystem::CreateDirectory( |
| 1727 const FilePath& directory_path, | 1817 const FilePath& directory_path, |
| 1728 bool is_exclusive, | 1818 bool is_exclusive, |
| 1729 bool is_recursive, | 1819 bool is_recursive, |
| 1730 const FileOperationCallback& callback) { | 1820 const FileOperationCallback& callback) { |
| 1731 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 1821 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 1732 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 1822 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 1733 const bool posted = BrowserThread::PostTask( | 1823 const bool posted = BrowserThread::PostTask( |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1749 directory_path, is_exclusive, is_recursive, callback); | 1839 directory_path, is_exclusive, is_recursive, callback); |
| 1750 } | 1840 } |
| 1751 | 1841 |
| 1752 void GDataFileSystem::CreateDirectoryOnUIThread( | 1842 void GDataFileSystem::CreateDirectoryOnUIThread( |
| 1753 const FilePath& directory_path, | 1843 const FilePath& directory_path, |
| 1754 bool is_exclusive, | 1844 bool is_exclusive, |
| 1755 bool is_recursive, | 1845 bool is_recursive, |
| 1756 const FileOperationCallback& callback) { | 1846 const FileOperationCallback& callback) { |
| 1757 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1847 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1758 | 1848 |
| 1849 // We don't want ot allow creating new directories in virtual search | |
| 1850 // directories. Also directory "gdata/.search" should be reserved. | |
| 1851 util::GDataSearchPathType path_type = | |
| 1852 util::GetSearchPathStatus(directory_path); | |
| 1853 if (path_type == util::GDATA_SEARCH_PATH_ROOT || | |
| 1854 path_type == util::GDATA_SEARCH_PATH_QUERY || | |
| 1855 path_type == util::GDATA_SEARCH_PATH_RESULT) { | |
|
satorux1
2012/05/03 17:58:34
maybe:
if (util::IsSearchDirectoryPath(directory
tbarzic
2012/05/03 23:56:17
Done.
| |
| 1856 if (!callback.is_null()) { | |
| 1857 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1858 base::Bind(callback, base::PLATFORM_FILE_ERROR_INVALID_OPERATION)); | |
| 1859 } | |
| 1860 return; | |
| 1861 } | |
| 1862 | |
| 1759 FilePath last_parent_dir_path; | 1863 FilePath last_parent_dir_path; |
| 1760 FilePath first_missing_path; | 1864 FilePath first_missing_path; |
| 1761 GURL last_parent_dir_url; | 1865 GURL last_parent_dir_url; |
| 1762 FindMissingDirectoryResult result = | 1866 FindMissingDirectoryResult result = |
| 1763 FindFirstMissingParentDirectory(directory_path, | 1867 FindFirstMissingParentDirectory(directory_path, |
| 1764 &last_parent_dir_url, | 1868 &last_parent_dir_url, |
| 1765 &first_missing_path); | 1869 &first_missing_path); |
| 1766 switch (result) { | 1870 switch (result) { |
| 1767 case FOUND_INVALID: { | 1871 case FOUND_INVALID: { |
| 1768 if (!callback.is_null()) { | 1872 if (!callback.is_null()) { |
| (...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2663 params.callback); | 2767 params.callback); |
| 2664 return; | 2768 return; |
| 2665 } | 2769 } |
| 2666 | 2770 |
| 2667 if (!params.callback.is_null()) { | 2771 if (!params.callback.is_null()) { |
| 2668 // Finally done with the create request. | 2772 // Finally done with the create request. |
| 2669 params.callback.Run(base::PLATFORM_FILE_OK); | 2773 params.callback.Run(base::PLATFORM_FILE_OK); |
| 2670 } | 2774 } |
| 2671 } | 2775 } |
| 2672 | 2776 |
| 2673 void GDataFileSystem::OnGetDocuments(GetDocumentsParams* params, | 2777 void GDataFileSystem::OnSearchContent(const ReadDirectoryCallback& callback, |
| 2778 GetDocumentsParams* params, | |
| 2779 base::PlatformFileError error) { | |
| 2780 // The search results will be returned using virtual directory. | |
| 2781 // The directory is not really part of the file system, so it has no parent or | |
| 2782 // root. | |
| 2783 scoped_ptr<GDataDirectory> search_dir(new GDataDirectory(NULL, NULL)); | |
| 2784 | |
| 2785 base::AutoLock lock(lock_); | |
| 2786 | |
| 2787 int delta_feed_changestamp = 0; | |
| 2788 int num_regular_files = 0; | |
| 2789 int num_hosted_documents = 0; | |
| 2790 FileResourceIdMap file_map; | |
| 2791 if (error == base::PLATFORM_FILE_OK) { | |
| 2792 error = FeedToFileResourceMap(*params->feed_list, | |
| 2793 &file_map, | |
| 2794 &delta_feed_changestamp, | |
| 2795 &num_regular_files, | |
| 2796 &num_hosted_documents); | |
| 2797 } | |
| 2798 | |
| 2799 if (error == base::PLATFORM_FILE_OK) { | |
| 2800 std::set<FilePath> ignored; | |
| 2801 | |
| 2802 // Go through all entires generated by the feed and add them to the search | |
| 2803 // result directory. | |
| 2804 for (FileResourceIdMap::const_iterator it = file_map.begin(); | |
| 2805 it != file_map.end(); ++it) { | |
| 2806 scoped_ptr<GDataEntry> entry(it->second); | |
| 2807 DCHECK_EQ(it->first, entry->resource_id()); | |
| 2808 DCHECK(!entry->is_deleted()); | |
| 2809 | |
| 2810 entry->set_title(entry->resource_id() + "." + entry->title()); | |
| 2811 | |
| 2812 search_dir->AddEntry(entry.release()); | |
| 2813 } | |
| 2814 } | |
| 2815 | |
| 2816 scoped_ptr<GDataDirectoryProto> directory_proto(new GDataDirectoryProto); | |
| 2817 search_dir->ToProto(directory_proto.get()); | |
| 2818 | |
| 2819 if (!callback.is_null()) { | |
| 2820 callback.Run(error, directory_proto.Pass()); | |
| 2821 } | |
| 2822 } | |
| 2823 | |
| 2824 void GDataFileSystem::SearchContent(const std::string& search_query, | |
| 2825 const ReadDirectoryCallback& callback) { | |
| 2826 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
| 2827 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 2828 const bool posted = BrowserThread::PostTask( | |
| 2829 BrowserThread::UI, | |
| 2830 FROM_HERE, | |
| 2831 base::Bind(&GDataFileSystem::SearchContentOnUIThread, | |
| 2832 ui_weak_ptr_, | |
| 2833 search_query, | |
| 2834 base::Bind(&RelayReadDirectoryCallback, | |
| 2835 base::MessageLoopProxy::current(), | |
| 2836 callback))); | |
| 2837 DCHECK(posted); | |
| 2838 return; | |
| 2839 } | |
| 2840 | |
| 2841 SearchContentOnUIThread(search_query, callback); | |
| 2842 } | |
| 2843 | |
| 2844 void GDataFileSystem::SearchContentOnUIThread( | |
| 2845 const std::string& search_query, | |
| 2846 const ReadDirectoryCallback& callback) { | |
| 2847 scoped_ptr<std::vector<DocumentFeed*> > feed_list( | |
| 2848 new std::vector<DocumentFeed*>); | |
| 2849 | |
| 2850 LoadFeedFromServer(0, 0, | |
| 2851 false, | |
|
satorux1
2012/05/03 17:58:34
could you add comments to 0,0,false? they look cry
tbarzic
2012/05/03 23:56:17
yeah, I came to the same conclusion looking at the
| |
| 2852 FilePath(), | |
| 2853 search_query, | |
| 2854 FindEntryCallback(), | |
| 2855 base::Bind(&GDataFileSystem::OnSearchContent, | |
| 2856 ui_weak_ptr_, callback)); | |
| 2857 } | |
| 2858 | |
| 2859 void GDataFileSystem::OnGetDocuments(const LoadDocumentFeedCallback& callback, | |
| 2860 GetDocumentsParams* params, | |
| 2674 GDataErrorCode status, | 2861 GDataErrorCode status, |
| 2675 scoped_ptr<base::Value> data) { | 2862 scoped_ptr<base::Value> data) { |
| 2676 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2863 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 2677 | 2864 |
| 2678 base::PlatformFileError error = GDataToPlatformError(status); | 2865 base::PlatformFileError error = GDataToPlatformError(status); |
| 2679 if (error == base::PLATFORM_FILE_OK && | 2866 if (error == base::PLATFORM_FILE_OK && |
| 2680 (!data.get() || data->GetType() != Value::TYPE_DICTIONARY)) { | 2867 (!data.get() || data->GetType() != Value::TYPE_DICTIONARY)) { |
| 2681 LOG(WARNING) << "No feed content!"; | |
| 2682 error = base::PLATFORM_FILE_ERROR_FAILED; | 2868 error = base::PLATFORM_FILE_ERROR_FAILED; |
| 2683 } | 2869 } |
| 2684 | 2870 |
| 2685 if (error != base::PLATFORM_FILE_OK) { | 2871 if (error != base::PLATFORM_FILE_OK) { |
| 2686 if (!params->callback.is_null()) { | 2872 if (!callback.is_null()) { |
| 2687 params->callback.Run(error, FilePath(), | 2873 callback.Run(params, error); |
| 2688 reinterpret_cast<GDataEntry*>(NULL)); | |
| 2689 } | 2874 } |
| 2690 | 2875 |
| 2691 return; | 2876 return; |
| 2692 } | 2877 } |
| 2693 | 2878 |
| 2694 // TODO(zelidrag): Find a faster way to get next url rather than parsing | 2879 // TODO(zelidrag): Find a faster way to get next url rather than parsing |
| 2695 // the entire feed. | 2880 // the entire feed. |
| 2696 GURL next_feed_url; | 2881 GURL next_feed_url; |
| 2697 scoped_ptr<DocumentFeed> current_feed(DocumentFeed::ExtractAndParse(*data)); | 2882 scoped_ptr<DocumentFeed> current_feed(DocumentFeed::ExtractAndParse(*data)); |
| 2698 if (!current_feed.get()) { | 2883 if (!current_feed.get()) { |
| 2699 if (!params->callback.is_null()) { | 2884 if (!callback.is_null()) { |
| 2700 params->callback.Run(base::PLATFORM_FILE_ERROR_FAILED, FilePath(), | 2885 callback.Run(params, base::PLATFORM_FILE_ERROR_FAILED); |
| 2701 reinterpret_cast<GDataEntry*>(NULL)); | |
| 2702 } | 2886 } |
| 2703 | 2887 |
| 2704 return; | 2888 return; |
| 2705 } | 2889 } |
| 2706 const bool has_next_feed_url = current_feed->GetNextFeedURL(&next_feed_url); | 2890 const bool has_next_feed_url = current_feed->GetNextFeedURL(&next_feed_url); |
| 2707 | 2891 |
| 2708 // Add the current feed to the list of collected feeds for this directory. | 2892 // Add the current feed to the list of collected feeds for this directory. |
| 2709 params->feed_list->push_back(current_feed.release()); | 2893 params->feed_list->push_back(current_feed.release()); |
| 2710 | 2894 |
| 2711 // Check if we need to collect more data to complete the directory list. | 2895 // Check if we need to collect more data to complete the directory list. |
| 2712 if (has_next_feed_url && !next_feed_url.is_empty()) { | 2896 if (params->allow_multiple_feeds && has_next_feed_url && |
| 2897 !next_feed_url.is_empty()) { | |
| 2713 // Kick of the remaining part of the feeds. | 2898 // Kick of the remaining part of the feeds. |
| 2714 documents_service_->GetDocuments( | 2899 documents_service_->GetDocuments( |
| 2715 next_feed_url, | 2900 next_feed_url, |
| 2716 params->start_changestamp, | 2901 params->start_changestamp, |
| 2902 params->search_query, | |
| 2717 base::Bind(&GDataFileSystem::OnGetDocuments, | 2903 base::Bind(&GDataFileSystem::OnGetDocuments, |
| 2718 ui_weak_ptr_, | 2904 ui_weak_ptr_, |
| 2905 callback, | |
| 2719 base::Owned( | 2906 base::Owned( |
| 2720 new GetDocumentsParams(params->start_changestamp, | 2907 new GetDocumentsParams(params->start_changestamp, |
| 2721 params->root_feed_changestamp, | 2908 params->root_feed_changestamp, |
| 2722 params->feed_list.release(), | 2909 params->feed_list.release(), |
| 2910 params->allow_multiple_feeds, | |
| 2723 params->search_file_path, | 2911 params->search_file_path, |
| 2912 params->search_query, | |
| 2724 params->callback)))); | 2913 params->callback)))); |
| 2725 return; | 2914 return; |
| 2726 } | 2915 } |
| 2727 | 2916 |
| 2728 error = UpdateFromFeed(*params->feed_list, | 2917 if (!callback.is_null()) |
| 2729 FROM_SERVER, | 2918 callback.Run(params, error); |
| 2730 params->start_changestamp, | |
| 2731 params->root_feed_changestamp); | |
| 2732 | |
| 2733 if (error != base::PLATFORM_FILE_OK) { | |
| 2734 if (!params->callback.is_null()) { | |
| 2735 params->callback.Run(error, FilePath(), | |
| 2736 reinterpret_cast<GDataEntry*>(NULL)); | |
| 2737 } | |
| 2738 | |
| 2739 return; | |
| 2740 } | |
| 2741 | |
| 2742 // Save file system metadata to disk. | |
| 2743 SaveFileSystemAsProto(); | |
| 2744 | |
| 2745 // If we had someone to report this too, then this retrieval was done in a | |
| 2746 // context of search... so continue search. | |
| 2747 if (!params->callback.is_null()) { | |
| 2748 FindEntryByPathSyncOnUIThread(params->search_file_path, params->callback); | |
| 2749 } | |
| 2750 } | 2919 } |
| 2751 | 2920 |
| 2752 void GDataFileSystem::LoadRootFeedFromCache( | 2921 void GDataFileSystem::LoadRootFeedFromCache( |
| 2753 bool should_load_from_server, | 2922 bool should_load_from_server, |
| 2754 const FilePath& search_file_path, | 2923 const FilePath& search_file_path, |
| 2755 const FindEntryCallback& callback) { | 2924 const FindEntryCallback& callback) { |
| 2756 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2925 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 2757 | 2926 |
| 2758 const FilePath path = | 2927 const FilePath path = |
| 2759 GetCacheDirectoryPath(GDataRootDirectory::CACHE_TYPE_META).Append( | 2928 GetCacheDirectoryPath(GDataRootDirectory::CACHE_TYPE_META).Append( |
| (...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3503 return base::PLATFORM_FILE_ERROR_FAILED; | 3672 return base::PLATFORM_FILE_ERROR_FAILED; |
| 3504 | 3673 |
| 3505 GDataEntry* new_entry = GDataEntry::FromDocumentEntry(parent_dir, | 3674 GDataEntry* new_entry = GDataEntry::FromDocumentEntry(parent_dir, |
| 3506 doc_entry.get(), | 3675 doc_entry.get(), |
| 3507 root_.get()); | 3676 root_.get()); |
| 3508 if (!new_entry) | 3677 if (!new_entry) |
| 3509 return base::PLATFORM_FILE_ERROR_FAILED; | 3678 return base::PLATFORM_FILE_ERROR_FAILED; |
| 3510 | 3679 |
| 3511 parent_dir->AddEntry(new_entry); | 3680 parent_dir->AddEntry(new_entry); |
| 3512 | 3681 |
| 3513 NotifyDirectoryChanged(directory_path); | 3682 NotifyDirectoryChanged(entry->GetFilePath()); |
| 3514 return base::PLATFORM_FILE_OK; | 3683 return base::PLATFORM_FILE_OK; |
| 3515 } | 3684 } |
| 3516 | 3685 |
| 3517 GDataFileSystem::FindMissingDirectoryResult | 3686 GDataFileSystem::FindMissingDirectoryResult |
| 3518 GDataFileSystem::FindFirstMissingParentDirectory( | 3687 GDataFileSystem::FindFirstMissingParentDirectory( |
| 3519 const FilePath& directory_path, | 3688 const FilePath& directory_path, |
| 3520 GURL* last_dir_content_url, | 3689 GURL* last_dir_content_url, |
| 3521 FilePath* first_missing_parent_path) { | 3690 FilePath* first_missing_parent_path) { |
| 3522 // Let's find which how deep is the existing directory structure and | 3691 // Let's find which how deep is the existing directory structure and |
| 3523 // get the first element that's missing. | 3692 // get the first element that's missing. |
| (...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4771 pref_registrar_->Init(profile_->GetPrefs()); | 4940 pref_registrar_->Init(profile_->GetPrefs()); |
| 4772 pref_registrar_->Add(prefs::kDisableGDataHostedFiles, this); | 4941 pref_registrar_->Add(prefs::kDisableGDataHostedFiles, this); |
| 4773 } | 4942 } |
| 4774 | 4943 |
| 4775 void SetFreeDiskSpaceGetterForTesting(FreeDiskSpaceGetterInterface* getter) { | 4944 void SetFreeDiskSpaceGetterForTesting(FreeDiskSpaceGetterInterface* getter) { |
| 4776 delete global_free_disk_getter_for_testing; // Safe to delete NULL; | 4945 delete global_free_disk_getter_for_testing; // Safe to delete NULL; |
| 4777 global_free_disk_getter_for_testing = getter; | 4946 global_free_disk_getter_for_testing = getter; |
| 4778 } | 4947 } |
| 4779 | 4948 |
| 4780 } // namespace gdata | 4949 } // namespace gdata |
| OLD | NEW |