Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: chrome/browser/chromeos/gdata/gdata_file_system.cc

Issue 10274002: Add gdata content search (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: style nits Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 *error = base::PLATFORM_FILE_OK; 736 *error = base::PLATFORM_FILE_OK;
737 } 737 }
738 } 738 }
739 739
740 *mime_type = kMimeTypeJson; 740 *mime_type = kMimeTypeJson;
741 *file_type = HOSTED_DOCUMENT; 741 *file_type = HOSTED_DOCUMENT;
742 if (*error != base::PLATFORM_FILE_OK) 742 if (*error != base::PLATFORM_FILE_OK)
743 temp_file_path->clear(); 743 temp_file_path->clear();
744 } 744 }
745 745
746 // Tests if we are allowed to create new directory in the provided directory.
747 bool ShouldCreateDirectory(const FilePath& directory_path) {
748 // We allow directory creation for paths that are on gdata file system
749 // (GDATA_SEARCH_PATH_INVALID) and paths that reference actual gdata file
750 // system path (GDATA_SEARCH_PATH_RESULT_CHILD).
751 util::GDataSearchPathType path_type =
752 util::GetSearchPathStatus(directory_path);
753 return path_type == util::GDATA_SEARCH_PATH_INVALID ||
754 path_type == util::GDATA_SEARCH_PATH_RESULT_CHILD;
755 }
756
746 // Relays the given FindEntryCallback to another thread via |replay_proxy|. 757 // Relays the given FindEntryCallback to another thread via |replay_proxy|.
747 void RelayFindEntryCallback(scoped_refptr<base::MessageLoopProxy> relay_proxy, 758 void RelayFindEntryCallback(scoped_refptr<base::MessageLoopProxy> relay_proxy,
748 const FindEntryCallback& callback, 759 const FindEntryCallback& callback,
749 base::PlatformFileError error, 760 base::PlatformFileError error,
750 const FilePath& directory_path, 761 const FilePath& directory_path,
751 GDataEntry* entry) { 762 GDataEntry* entry) {
752 relay_proxy->PostTask(FROM_HERE, 763 relay_proxy->PostTask(FROM_HERE,
753 base::Bind(callback, error, directory_path, entry)); 764 base::Bind(callback, error, directory_path, entry));
754 } 765 }
755 766
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 873
863 GDataFileProperties::~GDataFileProperties() { 874 GDataFileProperties::~GDataFileProperties() {
864 } 875 }
865 876
866 // GDataFileSystem::GetDocumentsParams struct implementation. 877 // GDataFileSystem::GetDocumentsParams struct implementation.
867 878
868 GDataFileSystem::GetDocumentsParams::GetDocumentsParams( 879 GDataFileSystem::GetDocumentsParams::GetDocumentsParams(
869 int start_changestamp, 880 int start_changestamp,
870 int root_feed_changestamp, 881 int root_feed_changestamp,
871 std::vector<DocumentFeed*>* feed_list, 882 std::vector<DocumentFeed*>* feed_list,
883 bool should_fetch_multiple_feeds,
872 const FilePath& search_file_path, 884 const FilePath& search_file_path,
885 const std::string& search_query,
873 const FindEntryCallback& callback) 886 const FindEntryCallback& callback)
874 : start_changestamp(start_changestamp), 887 : start_changestamp(start_changestamp),
875 root_feed_changestamp(root_feed_changestamp), 888 root_feed_changestamp(root_feed_changestamp),
876 feed_list(feed_list), 889 feed_list(feed_list),
890 should_fetch_multiple_feeds(should_fetch_multiple_feeds),
877 search_file_path(search_file_path), 891 search_file_path(search_file_path),
892 search_query(search_query),
878 callback(callback) { 893 callback(callback) {
879 } 894 }
880 895
881 GDataFileSystem::GetDocumentsParams::~GetDocumentsParams() { 896 GDataFileSystem::GetDocumentsParams::~GetDocumentsParams() {
882 STLDeleteElements(feed_list.get()); 897 STLDeleteElements(feed_list.get());
883 } 898 }
884 899
885 // GDataFileSystem::CreateDirectoryParams struct implementation. 900 // GDataFileSystem::CreateDirectoryParams struct implementation.
886 901
887 GDataFileSystem::CreateDirectoryParams::CreateDirectoryParams( 902 GDataFileSystem::CreateDirectoryParams::CreateDirectoryParams(
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 int local_changestamp, 1155 int local_changestamp,
1141 const FilePath& search_file_path, 1156 const FilePath& search_file_path,
1142 const FindEntryCallback& callback, 1157 const FindEntryCallback& callback,
1143 GDataErrorCode status, 1158 GDataErrorCode status,
1144 scoped_ptr<base::Value> feed_data) { 1159 scoped_ptr<base::Value> feed_data) {
1145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1146 1161
1147 base::PlatformFileError error = GDataToPlatformError(status); 1162 base::PlatformFileError error = GDataToPlatformError(status);
1148 if (error != base::PLATFORM_FILE_OK) { 1163 if (error != base::PLATFORM_FILE_OK) {
1149 // Get changes starting from the next changestamp from what we have locally. 1164 // Get changes starting from the next changestamp from what we have locally.
1150 LoadFeedFromServer(local_changestamp + 1, 0, search_file_path, callback); 1165 LoadFeedFromServer(local_changestamp + 1, 0,
1166 true, /* should_fetch_multiple_feeds */
1167 search_file_path,
1168 std::string() /* no search query */,
1169 callback,
1170 base::Bind(&GDataFileSystem::OnFeedFromServerLoaded,
1171 ui_weak_ptr_));
1151 return; 1172 return;
1152 } 1173 }
1153 1174
1154 scoped_ptr<AccountMetadataFeed> feed; 1175 scoped_ptr<AccountMetadataFeed> feed;
1155 if (feed_data.get()) 1176 if (feed_data.get())
1156 feed = AccountMetadataFeed::CreateFrom(*feed_data); 1177 feed = AccountMetadataFeed::CreateFrom(*feed_data);
1157 if (!feed.get()) { 1178 if (!feed.get()) {
1158 LoadFeedFromServer(local_changestamp + 1, 0, search_file_path, callback); 1179 LoadFeedFromServer(local_changestamp + 1, 0,
1180 true, /* should_fetch_multiple_feeds */
1181 search_file_path,
1182 std::string() /* no search query */,
1183 callback,
1184 base::Bind(&GDataFileSystem::OnFeedFromServerLoaded,
1185 ui_weak_ptr_));
1159 return; 1186 return;
1160 } 1187 }
1161 1188
1162 bool changes_detected = true; 1189 bool changes_detected = true;
1163 if (local_changestamp >= feed->largest_changestamp()) { 1190 if (local_changestamp >= feed->largest_changestamp()) {
1164 if (local_changestamp > feed->largest_changestamp()) { 1191 if (local_changestamp > feed->largest_changestamp()) {
1165 LOG(WARNING) << "Cached client feed is fresher than server, client = " 1192 LOG(WARNING) << "Cached client feed is fresher than server, client = "
1166 << local_changestamp 1193 << local_changestamp
1167 << ", server = " 1194 << ", server = "
1168 << feed->largest_changestamp(); 1195 << feed->largest_changestamp();
(...skipping 13 matching lines...) Expand all
1182 1209
1183 NotifyInitialLoadFinished(); 1210 NotifyInitialLoadFinished();
1184 return; 1211 return;
1185 } 1212 }
1186 1213
1187 SaveFeed(feed_data.Pass(), FilePath(kAccountMetadataFile)); 1214 SaveFeed(feed_data.Pass(), FilePath(kAccountMetadataFile));
1188 1215
1189 // Load changes from the server. 1216 // Load changes from the server.
1190 LoadFeedFromServer(local_changestamp > 0 ? local_changestamp + 1 : 0, 1217 LoadFeedFromServer(local_changestamp > 0 ? local_changestamp + 1 : 0,
1191 feed->largest_changestamp(), 1218 feed->largest_changestamp(),
1219 true, /* should_fetch_multiple_feeds */
1192 search_file_path, 1220 search_file_path,
1193 callback); 1221 std::string() /* no search query */,
1222 callback,
1223 base::Bind(&GDataFileSystem::OnFeedFromServerLoaded,
1224 ui_weak_ptr_));
1194 } 1225 }
1195 1226
1196 void GDataFileSystem::LoadFeedFromServer( 1227 void GDataFileSystem::LoadFeedFromServer(
1197 int start_changestamp, 1228 int start_changestamp,
1198 int root_feed_changestamp, 1229 int root_feed_changestamp,
1230 bool should_fetch_multiple_feeds,
1199 const FilePath& search_file_path, 1231 const FilePath& search_file_path,
1200 const FindEntryCallback& callback) { 1232 const std::string& search_query,
1233 const FindEntryCallback& entry_found_callback,
1234 const LoadDocumentFeedCallback& feed_load_callback) {
1201 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1202 1236
1203 // ...then also kick off document feed fetching from the server as well. 1237 // ...then also kick off document feed fetching from the server as well.
1204 // |feed_list| will contain the list of all collected feed updates that 1238 // |feed_list| will contain the list of all collected feed updates that
1205 // we will receive through calls of DocumentsService::GetDocuments(). 1239 // we will receive through calls of DocumentsService::GetDocuments().
1206 scoped_ptr<std::vector<DocumentFeed*> > feed_list( 1240 scoped_ptr<std::vector<DocumentFeed*> > feed_list(
1207 new std::vector<DocumentFeed*>); 1241 new std::vector<DocumentFeed*>);
1208 // Kick off document feed fetching here if we don't have complete data 1242 // Kick off document feed fetching here if we don't have complete data
1209 // to finish this call. 1243 // to finish this call.
1210 documents_service_->GetDocuments( 1244 documents_service_->GetDocuments(
1211 GURL(), // root feed start. 1245 GURL(), // root feed start.
1212 start_changestamp, 1246 start_changestamp,
1247 search_query,
1213 base::Bind(&GDataFileSystem::OnGetDocuments, 1248 base::Bind(&GDataFileSystem::OnGetDocuments,
1214 ui_weak_ptr_, 1249 ui_weak_ptr_,
1250 feed_load_callback,
1215 base::Owned(new GetDocumentsParams(start_changestamp, 1251 base::Owned(new GetDocumentsParams(start_changestamp,
1216 root_feed_changestamp, 1252 root_feed_changestamp,
1217 feed_list.release(), 1253 feed_list.release(),
1254 should_fetch_multiple_feeds,
1218 search_file_path, 1255 search_file_path,
1219 callback)))); 1256 search_query,
1257 entry_found_callback))));
1258 }
1259
1260 void GDataFileSystem::OnFeedFromServerLoaded(GetDocumentsParams* params,
1261 base::PlatformFileError error) {
1262 if (error != base::PLATFORM_FILE_OK) {
1263 params->callback.Run(error, FilePath(),
1264 reinterpret_cast<GDataEntry*>(NULL));
1265 return;
1266 }
1267
1268 error = UpdateFromFeed(*params->feed_list,
1269 FROM_SERVER,
1270 params->start_changestamp,
1271 params->root_feed_changestamp);
1272
1273 if (error != base::PLATFORM_FILE_OK) {
1274 if (!params->callback.is_null()) {
1275 params->callback.Run(error, FilePath(),
1276 reinterpret_cast<GDataEntry*>(NULL));
1277 }
1278
1279 return;
1280 }
1281
1282 // Save file system metadata to disk.
1283 SaveFileSystemAsProto();
1284
1285 // If we had someone to report this too, then this retrieval was done in a
1286 // context of search... so continue search.
1287 if (!params->callback.is_null()) {
1288 FindEntryByPathSyncOnUIThread(params->search_file_path, params->callback);
1289 }
1220 } 1290 }
1221 1291
1222 void GDataFileSystem::TransferFile(const FilePath& local_file_path, 1292 void GDataFileSystem::TransferFile(const FilePath& local_file_path,
1223 const FilePath& remote_dest_file_path, 1293 const FilePath& remote_dest_file_path,
1224 const FileOperationCallback& callback) { 1294 const FileOperationCallback& callback) {
1225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1226 1296
1227 base::AutoLock lock(lock_); 1297 base::AutoLock lock(lock_);
1228 // Make sure the destination directory exists 1298 // Make sure the destination directory exists
1229 GDataEntry* dest_dir = GetGDataEntryByPath( 1299 GDataEntry* dest_dir = GetGDataEntryByPath(
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 base::Bind(&RelayFileOperationCallback, 1440 base::Bind(&RelayFileOperationCallback,
1371 base::MessageLoopProxy::current(), 1441 base::MessageLoopProxy::current(),
1372 callback))); 1442 callback)));
1373 DCHECK(posted); 1443 DCHECK(posted);
1374 return; 1444 return;
1375 } 1445 }
1376 1446
1377 CopyOnUIThread(src_file_path, dest_file_path, callback); 1447 CopyOnUIThread(src_file_path, dest_file_path, callback);
1378 } 1448 }
1379 1449
1380 void GDataFileSystem::CopyOnUIThread(const FilePath& src_file_path, 1450 void GDataFileSystem::CopyOnUIThread(const FilePath& original_src_file_path,
1381 const FilePath& dest_file_path, 1451 const FilePath& original_dest_file_path,
1382 const FileOperationCallback& callback) { 1452 const FileOperationCallback& callback) {
1383 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1453 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1384 1454
1385 base::PlatformFileError error = base::PLATFORM_FILE_OK; 1455 base::PlatformFileError error = base::PLATFORM_FILE_OK;
1386 FilePath dest_parent_path = dest_file_path.DirName(); 1456 FilePath dest_parent_path = original_dest_file_path.DirName();
1457
1458 FilePath src_file_path;
1459 FilePath dest_file_path;
1387 1460
1388 std::string src_file_resource_id; 1461 std::string src_file_resource_id;
1389 bool src_file_is_hosted_document = false; 1462 bool src_file_is_hosted_document = false;
1390 { 1463 {
1391 base::AutoLock lock(lock_); 1464 base::AutoLock lock(lock_);
1392 GDataEntry* src_entry = GetGDataEntryByPath(src_file_path); 1465 GDataEntry* src_entry = GetGDataEntryByPath(original_src_file_path);
1393 GDataEntry* dest_parent = GetGDataEntryByPath(dest_parent_path); 1466 GDataEntry* dest_parent = GetGDataEntryByPath(dest_parent_path);
1394 if (!src_entry || !dest_parent) { 1467 if (!src_entry || !dest_parent) {
1395 error = base::PLATFORM_FILE_ERROR_NOT_FOUND; 1468 error = base::PLATFORM_FILE_ERROR_NOT_FOUND;
1396 } else if (!dest_parent->AsGDataDirectory()) { 1469 } else if (!dest_parent->AsGDataDirectory()) {
1397 error = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; 1470 error = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
1398 } else if (!src_entry->AsGDataFile()) { 1471 } else if (!src_entry->AsGDataFile() || dest_parent->is_detached()) {
1399 // TODO(benchan): Implement copy for directories. In the interim, 1472 // TODO(benchan): Implement copy for directories. In the interim,
1400 // we handle recursive directory copy in the file manager. 1473 // we handle recursive directory copy in the file manager.
1401 error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION; 1474 error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
1402 } else { 1475 } else {
1403 src_file_resource_id = src_entry->resource_id(); 1476 src_file_resource_id = src_entry->resource_id();
1404 src_file_is_hosted_document = 1477 src_file_is_hosted_document =
1405 src_entry->AsGDataFile()->is_hosted_document(); 1478 src_entry->AsGDataFile()->is_hosted_document();
1479 // |original_src_file_path| and |original_dest_file_path| don't have to
1480 // necessary be equal to |src_entry|'s or |dest_entry|'s file path (e.g.
1481 // paths used to display gdata content search results).
1482 // That's why, instead of using |original_src_file_path| and
1483 // |original_dest_file_path|, we will get file paths to use in copy
1484 // operation from the entries.
1485 src_file_path = src_entry->GetFilePath();
1486 dest_parent_path = dest_parent->GetFilePath();
1487 dest_file_path = dest_parent_path.Append(
1488 original_dest_file_path.BaseName());
1406 } 1489 }
1407 } 1490 }
1408 1491
1409 if (error != base::PLATFORM_FILE_OK) { 1492 if (error != base::PLATFORM_FILE_OK) {
1410 if (!callback.is_null()) 1493 if (!callback.is_null())
1411 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, error)); 1494 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, error));
1412 1495
1413 return; 1496 return;
1414 } 1497 }
1415 1498
1499 DCHECK(!src_file_path.empty());
1500 DCHECK(!dest_file_path.empty());
1501
1416 if (src_file_is_hosted_document) { 1502 if (src_file_is_hosted_document) {
1417 CopyDocumentToDirectory(dest_parent_path, 1503 CopyDocumentToDirectory(dest_parent_path,
1418 src_file_resource_id, 1504 src_file_resource_id,
1419 // Drop the document extension, which should not be 1505 // Drop the document extension, which should not be
1420 // in the document title. 1506 // in the document title.
1421 dest_file_path.BaseName().RemoveExtension().value(), 1507 dest_file_path.BaseName().RemoveExtension().value(),
1422 callback); 1508 callback);
1423 return; 1509 return;
1424 } 1510 }
1425 1511
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 base::Bind(&RelayFileOperationCallback, 1632 base::Bind(&RelayFileOperationCallback,
1547 base::MessageLoopProxy::current(), 1633 base::MessageLoopProxy::current(),
1548 callback))); 1634 callback)));
1549 DCHECK(posted); 1635 DCHECK(posted);
1550 return; 1636 return;
1551 } 1637 }
1552 1638
1553 MoveOnUIThread(src_file_path, dest_file_path, callback); 1639 MoveOnUIThread(src_file_path, dest_file_path, callback);
1554 } 1640 }
1555 1641
1556 void GDataFileSystem::MoveOnUIThread(const FilePath& src_file_path, 1642 void GDataFileSystem::MoveOnUIThread(const FilePath& original_src_file_path,
1557 const FilePath& dest_file_path, 1643 const FilePath& original_dest_file_path,
1558 const FileOperationCallback& callback) { 1644 const FileOperationCallback& callback) {
1559 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1645 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1560 1646
1561 base::PlatformFileError error = base::PLATFORM_FILE_OK; 1647 base::PlatformFileError error = base::PLATFORM_FILE_OK;
1562 FilePath dest_parent_path = dest_file_path.DirName(); 1648 FilePath dest_parent_path = original_dest_file_path.DirName();
1649
1650 FilePath src_file_path;
1651 FilePath dest_file_path;
1652 FilePath dest_name = original_dest_file_path.BaseName();
1563 1653
1564 { 1654 {
1565 // This scoped lock needs to be released before calling Rename() below. 1655 // This scoped lock needs to be released before calling Rename() below.
1566 base::AutoLock lock(lock_); 1656 base::AutoLock lock(lock_);
1567 GDataEntry* src_entry = GetGDataEntryByPath(src_file_path); 1657 GDataEntry* src_entry = GetGDataEntryByPath(original_src_file_path);
1568 GDataEntry* dest_parent = GetGDataEntryByPath(dest_parent_path); 1658 GDataEntry* dest_parent = GetGDataEntryByPath(dest_parent_path);
1569 if (!src_entry || !dest_parent) { 1659 if (!src_entry || !dest_parent) {
1570 error = base::PLATFORM_FILE_ERROR_NOT_FOUND; 1660 error = base::PLATFORM_FILE_ERROR_NOT_FOUND;
1571 } else { 1661 } else if (!dest_parent->AsGDataDirectory()) {
1572 if (!dest_parent->AsGDataDirectory())
1573 error = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; 1662 error = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
1663 } else if (dest_parent->is_detached()) {
1664 // We allow moving to a directory without file system root only if it's
1665 // done as part of renaming (i.e. source and destination parent paths are
1666 // the same).
1667 if (original_src_file_path.DirName() != dest_parent_path) {
1668 error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
1669 } else {
1670 // If we are indeed renaming, we have to strip resource id from the file
1671 // name.
1672 std::string resource_id;
1673 std::string file_name;
1674 util::ParseSearchFileName(dest_name.value(), &resource_id, &file_name);
1675 if (!file_name.empty())
1676 dest_name = FilePath(file_name);
1677 }
1574 } 1678 }
1575 1679
1576 if (error != base::PLATFORM_FILE_OK) { 1680 if (error != base::PLATFORM_FILE_OK) {
1577 if (!callback.is_null()) { 1681 if (!callback.is_null()) {
1578 MessageLoop::current()->PostTask(FROM_HERE, 1682 MessageLoop::current()->PostTask(FROM_HERE,
1579 base::Bind(callback, error)); 1683 base::Bind(callback, error));
1580 } 1684 }
1581 return; 1685 return;
1582 } 1686 }
1687 // |original_src_file_path| and |original_dest_file_path| don't have to
1688 // necessary be equal to |src_entry|'s or |dest_entry|'s file path (e.g.
1689 // paths used to display gdata content search results).
1690 // That's why, instead of using |original_src_file_path| and
1691 // |original_dest_file_path|, we will get file paths to use in move
1692 // operation from the entries.
1693 src_file_path = src_entry->GetFilePath();
1694 if (!dest_parent->is_detached())
1695 dest_parent_path = dest_parent->GetFilePath();
1696 dest_file_path = dest_parent_path.Append(dest_name);
1583 } 1697 }
1584 1698
1699 DCHECK(!src_file_path.empty());
1700 DCHECK(!dest_file_path.empty());
1701
1585 // If the file/directory is moved to the same directory, just rename it. 1702 // If the file/directory is moved to the same directory, just rename it.
1586 if (src_file_path.DirName() == dest_parent_path) { 1703 if (original_src_file_path.DirName() == dest_parent_path) {
1587 FilePathUpdateCallback final_file_path_update_callback = 1704 FilePathUpdateCallback final_file_path_update_callback =
1588 base::Bind(&GDataFileSystem::OnFilePathUpdated, 1705 base::Bind(&GDataFileSystem::OnFilePathUpdated,
1589 ui_weak_ptr_, 1706 ui_weak_ptr_,
1590 callback); 1707 callback);
1591 1708
1592 Rename(src_file_path, dest_file_path.BaseName().value(), 1709 Rename(original_src_file_path, dest_name.value(),
1593 final_file_path_update_callback); 1710 final_file_path_update_callback);
1594 return; 1711 return;
1595 } 1712 }
1596 1713
1597 // Otherwise, the move operation involves three steps: 1714 // Otherwise, the move operation involves three steps:
1598 // 1. Renames the file at |src_file_path| to basename(|dest_file_path|) 1715 // 1. Renames the file at |src_file_path| to basename(|dest_file_path|)
1599 // within the same directory. The rename operation is a no-op if 1716 // within the same directory. The rename operation is a no-op if
1600 // basename(|src_file_path|) equals to basename(|dest_file_path|). 1717 // basename(|src_file_path|) equals to basename(|dest_file_path|).
1601 // 2. Removes the file from its parent directory (the file is not deleted), 1718 // 2. Removes the file from its parent directory (the file is not deleted),
1602 // which effectively moves the file to the root directory. 1719 // which effectively moves the file to the root directory.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1732 base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND)); 1849 base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
1733 } 1850 }
1734 return; 1851 return;
1735 } 1852 }
1736 1853
1737 documents_service_->DeleteDocument( 1854 documents_service_->DeleteDocument(
1738 entry->edit_url(), 1855 entry->edit_url(),
1739 base::Bind(&GDataFileSystem::OnRemovedDocument, 1856 base::Bind(&GDataFileSystem::OnRemovedDocument,
1740 ui_weak_ptr_, 1857 ui_weak_ptr_,
1741 callback, 1858 callback,
1742 file_path)); 1859 entry->GetFilePath()));
1743 } 1860 }
1744 1861
1745 void GDataFileSystem::CreateDirectory( 1862 void GDataFileSystem::CreateDirectory(
1746 const FilePath& directory_path, 1863 const FilePath& directory_path,
1747 bool is_exclusive, 1864 bool is_exclusive,
1748 bool is_recursive, 1865 bool is_recursive,
1749 const FileOperationCallback& callback) { 1866 const FileOperationCallback& callback) {
1750 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 1867 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
1751 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1868 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1752 const bool posted = BrowserThread::PostTask( 1869 const bool posted = BrowserThread::PostTask(
(...skipping 15 matching lines...) Expand all
1768 directory_path, is_exclusive, is_recursive, callback); 1885 directory_path, is_exclusive, is_recursive, callback);
1769 } 1886 }
1770 1887
1771 void GDataFileSystem::CreateDirectoryOnUIThread( 1888 void GDataFileSystem::CreateDirectoryOnUIThread(
1772 const FilePath& directory_path, 1889 const FilePath& directory_path,
1773 bool is_exclusive, 1890 bool is_exclusive,
1774 bool is_recursive, 1891 bool is_recursive,
1775 const FileOperationCallback& callback) { 1892 const FileOperationCallback& callback) {
1776 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1893 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1777 1894
1895 if (!ShouldCreateDirectory(directory_path)) {
1896 if (!callback.is_null()) {
1897 MessageLoop::current()->PostTask(FROM_HERE,
1898 base::Bind(callback, base::PLATFORM_FILE_ERROR_INVALID_OPERATION));
1899 }
1900 return;
1901 }
1902
1778 FilePath last_parent_dir_path; 1903 FilePath last_parent_dir_path;
1779 FilePath first_missing_path; 1904 FilePath first_missing_path;
1780 GURL last_parent_dir_url; 1905 GURL last_parent_dir_url;
1781 FindMissingDirectoryResult result = 1906 FindMissingDirectoryResult result =
1782 FindFirstMissingParentDirectory(directory_path, 1907 FindFirstMissingParentDirectory(directory_path,
1783 &last_parent_dir_url, 1908 &last_parent_dir_url,
1784 &first_missing_path); 1909 &first_missing_path);
1785 switch (result) { 1910 switch (result) {
1786 case FOUND_INVALID: { 1911 case FOUND_INVALID: {
1787 if (!callback.is_null()) { 1912 if (!callback.is_null()) {
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after
2682 params.callback); 2807 params.callback);
2683 return; 2808 return;
2684 } 2809 }
2685 2810
2686 if (!params.callback.is_null()) { 2811 if (!params.callback.is_null()) {
2687 // Finally done with the create request. 2812 // Finally done with the create request.
2688 params.callback.Run(base::PLATFORM_FILE_OK); 2813 params.callback.Run(base::PLATFORM_FILE_OK);
2689 } 2814 }
2690 } 2815 }
2691 2816
2692 void GDataFileSystem::OnGetDocuments(GetDocumentsParams* params, 2817 void GDataFileSystem::OnSearch(const ReadDirectoryCallback& callback,
2818 GetDocumentsParams* params,
2819 base::PlatformFileError error) {
2820 // The search results will be returned using virtual directory.
2821 // The directory is not really part of the file system, so it has no parent or
2822 // root.
2823 scoped_ptr<GDataDirectory> search_dir(new GDataDirectory(NULL, NULL));
2824
2825 base::AutoLock lock(lock_);
2826
2827 int delta_feed_changestamp = 0;
2828 int num_regular_files = 0;
2829 int num_hosted_documents = 0;
2830 FileResourceIdMap file_map;
2831 if (error == base::PLATFORM_FILE_OK) {
2832 error = FeedToFileResourceMap(*params->feed_list,
2833 &file_map,
2834 &delta_feed_changestamp,
2835 &num_regular_files,
2836 &num_hosted_documents);
2837 }
2838
2839 if (error == base::PLATFORM_FILE_OK) {
2840 std::set<FilePath> ignored;
2841
2842 // Go through all entires generated by the feed and add them to the search
2843 // result directory.
2844 for (FileResourceIdMap::const_iterator it = file_map.begin();
2845 it != file_map.end(); ++it) {
2846 scoped_ptr<GDataEntry> entry(it->second);
2847 DCHECK_EQ(it->first, entry->resource_id());
2848 DCHECK(!entry->is_deleted());
2849
2850 entry->set_title(entry->resource_id() + "." + entry->title());
2851
2852 search_dir->AddEntry(entry.release());
2853 }
2854 }
2855
2856 scoped_ptr<GDataDirectoryProto> directory_proto(new GDataDirectoryProto);
2857 search_dir->ToProto(directory_proto.get());
2858
2859 if (!callback.is_null()) {
2860 callback.Run(error, directory_proto.Pass());
2861 }
2862 }
2863
2864 void GDataFileSystem::SearchAsync(const std::string& search_query,
2865 const ReadDirectoryCallback& callback) {
2866 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2867 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2868 const bool posted = BrowserThread::PostTask(
2869 BrowserThread::UI,
2870 FROM_HERE,
2871 base::Bind(&GDataFileSystem::SearchAsyncOnUIThread,
2872 ui_weak_ptr_,
2873 search_query,
2874 base::Bind(&RelayReadDirectoryCallback,
2875 base::MessageLoopProxy::current(),
2876 callback)));
2877 DCHECK(posted);
2878 return;
2879 }
2880
2881 SearchAsyncOnUIThread(search_query, callback);
2882 }
2883
2884 void GDataFileSystem::SearchAsyncOnUIThread(
2885 const std::string& search_query,
2886 const ReadDirectoryCallback& callback) {
2887 scoped_ptr<std::vector<DocumentFeed*> > feed_list(
2888 new std::vector<DocumentFeed*>);
2889
2890 LoadFeedFromServer(0, 0, // We don't use change stamps when fetching search
2891 // data; we always fetch the whole result feed.
2892 false, // Stop fetching search results after first feed
2893 // chunk to avoid displaying huge number of search
2894 // results (especially since we don't cache them).
2895 FilePath(), // Not used.
2896 search_query,
2897 FindEntryCallback(), // Not used.
2898 base::Bind(&GDataFileSystem::OnSearch,
2899 ui_weak_ptr_, callback));
2900 }
2901
2902 void GDataFileSystem::OnGetDocuments(const LoadDocumentFeedCallback& callback,
2903 GetDocumentsParams* params,
2693 GDataErrorCode status, 2904 GDataErrorCode status,
2694 scoped_ptr<base::Value> data) { 2905 scoped_ptr<base::Value> data) {
2695 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2906 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2696 2907
2697 base::PlatformFileError error = GDataToPlatformError(status); 2908 base::PlatformFileError error = GDataToPlatformError(status);
2698 if (error == base::PLATFORM_FILE_OK && 2909 if (error == base::PLATFORM_FILE_OK &&
2699 (!data.get() || data->GetType() != Value::TYPE_DICTIONARY)) { 2910 (!data.get() || data->GetType() != Value::TYPE_DICTIONARY)) {
2700 LOG(WARNING) << "No feed content!";
2701 error = base::PLATFORM_FILE_ERROR_FAILED; 2911 error = base::PLATFORM_FILE_ERROR_FAILED;
2702 } 2912 }
2703 2913
2704 if (error != base::PLATFORM_FILE_OK) { 2914 if (error != base::PLATFORM_FILE_OK) {
2705 if (!params->callback.is_null()) { 2915 if (!callback.is_null()) {
2706 params->callback.Run(error, FilePath(), 2916 callback.Run(params, error);
2707 reinterpret_cast<GDataEntry*>(NULL));
2708 } 2917 }
2709 2918
2710 return; 2919 return;
2711 } 2920 }
2712 2921
2713 // TODO(zelidrag): Find a faster way to get next url rather than parsing 2922 // TODO(zelidrag): Find a faster way to get next url rather than parsing
2714 // the entire feed. 2923 // the entire feed.
2715 GURL next_feed_url; 2924 GURL next_feed_url;
2716 scoped_ptr<DocumentFeed> current_feed(DocumentFeed::ExtractAndParse(*data)); 2925 scoped_ptr<DocumentFeed> current_feed(DocumentFeed::ExtractAndParse(*data));
2717 if (!current_feed.get()) { 2926 if (!current_feed.get()) {
2718 if (!params->callback.is_null()) { 2927 if (!callback.is_null()) {
2719 params->callback.Run(base::PLATFORM_FILE_ERROR_FAILED, FilePath(), 2928 callback.Run(params, base::PLATFORM_FILE_ERROR_FAILED);
2720 reinterpret_cast<GDataEntry*>(NULL));
2721 } 2929 }
2722 2930
2723 return; 2931 return;
2724 } 2932 }
2725 const bool has_next_feed_url = current_feed->GetNextFeedURL(&next_feed_url); 2933 const bool has_next_feed_url = current_feed->GetNextFeedURL(&next_feed_url);
2726 2934
2727 // Add the current feed to the list of collected feeds for this directory. 2935 // Add the current feed to the list of collected feeds for this directory.
2728 params->feed_list->push_back(current_feed.release()); 2936 params->feed_list->push_back(current_feed.release());
2729 2937
2730 // Check if we need to collect more data to complete the directory list. 2938 // Check if we need to collect more data to complete the directory list.
2731 if (has_next_feed_url && !next_feed_url.is_empty()) { 2939 if (params->should_fetch_multiple_feeds && has_next_feed_url &&
2940 !next_feed_url.is_empty()) {
2732 // Kick of the remaining part of the feeds. 2941 // Kick of the remaining part of the feeds.
2733 documents_service_->GetDocuments( 2942 documents_service_->GetDocuments(
2734 next_feed_url, 2943 next_feed_url,
2735 params->start_changestamp, 2944 params->start_changestamp,
2945 params->search_query,
2736 base::Bind(&GDataFileSystem::OnGetDocuments, 2946 base::Bind(&GDataFileSystem::OnGetDocuments,
2737 ui_weak_ptr_, 2947 ui_weak_ptr_,
2948 callback,
2738 base::Owned( 2949 base::Owned(
2739 new GetDocumentsParams(params->start_changestamp, 2950 new GetDocumentsParams(
2740 params->root_feed_changestamp, 2951 params->start_changestamp,
2741 params->feed_list.release(), 2952 params->root_feed_changestamp,
2742 params->search_file_path, 2953 params->feed_list.release(),
2743 params->callback)))); 2954 params->should_fetch_multiple_feeds,
2955 params->search_file_path,
2956 params->search_query,
2957 params->callback))));
2744 return; 2958 return;
2745 } 2959 }
2746 2960
2747 error = UpdateFromFeed(*params->feed_list, 2961 if (!callback.is_null())
2748 FROM_SERVER, 2962 callback.Run(params, error);
2749 params->start_changestamp,
2750 params->root_feed_changestamp);
2751
2752 if (error != base::PLATFORM_FILE_OK) {
2753 if (!params->callback.is_null()) {
2754 params->callback.Run(error, FilePath(),
2755 reinterpret_cast<GDataEntry*>(NULL));
2756 }
2757
2758 return;
2759 }
2760
2761 // Save file system metadata to disk.
2762 SaveFileSystemAsProto();
2763
2764 // If we had someone to report this too, then this retrieval was done in a
2765 // context of search... so continue search.
2766 if (!params->callback.is_null()) {
2767 FindEntryByPathSyncOnUIThread(params->search_file_path, params->callback);
2768 }
2769 } 2963 }
2770 2964
2771 void GDataFileSystem::LoadRootFeedFromCache( 2965 void GDataFileSystem::LoadRootFeedFromCache(
2772 bool should_load_from_server, 2966 bool should_load_from_server,
2773 const FilePath& search_file_path, 2967 const FilePath& search_file_path,
2774 const FindEntryCallback& callback) { 2968 const FindEntryCallback& callback) {
2775 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2969 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2776 2970
2777 const FilePath path = 2971 const FilePath path =
2778 GetCacheDirectoryPath(GDataRootDirectory::CACHE_TYPE_META).Append( 2972 GetCacheDirectoryPath(GDataRootDirectory::CACHE_TYPE_META).Append(
(...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after
3522 return base::PLATFORM_FILE_ERROR_FAILED; 3716 return base::PLATFORM_FILE_ERROR_FAILED;
3523 3717
3524 GDataEntry* new_entry = GDataEntry::FromDocumentEntry(parent_dir, 3718 GDataEntry* new_entry = GDataEntry::FromDocumentEntry(parent_dir,
3525 doc_entry.get(), 3719 doc_entry.get(),
3526 root_.get()); 3720 root_.get());
3527 if (!new_entry) 3721 if (!new_entry)
3528 return base::PLATFORM_FILE_ERROR_FAILED; 3722 return base::PLATFORM_FILE_ERROR_FAILED;
3529 3723
3530 parent_dir->AddEntry(new_entry); 3724 parent_dir->AddEntry(new_entry);
3531 3725
3532 NotifyDirectoryChanged(directory_path); 3726 // |directory_path| is not necessary same as |entry->GetFilePath()|. It may be
3727 // virtual path that references the entry (e.g. path under which content
3728 // search result is shown).
3729 // We want to dispatch directory changed with the actual entry's path.
3730 NotifyDirectoryChanged(entry->GetFilePath());
3533 return base::PLATFORM_FILE_OK; 3731 return base::PLATFORM_FILE_OK;
3534 } 3732 }
3535 3733
3536 GDataFileSystem::FindMissingDirectoryResult 3734 GDataFileSystem::FindMissingDirectoryResult
3537 GDataFileSystem::FindFirstMissingParentDirectory( 3735 GDataFileSystem::FindFirstMissingParentDirectory(
3538 const FilePath& directory_path, 3736 const FilePath& directory_path,
3539 GURL* last_dir_content_url, 3737 GURL* last_dir_content_url,
3540 FilePath* first_missing_parent_path) { 3738 FilePath* first_missing_parent_path) {
3541 // Let's find which how deep is the existing directory structure and 3739 // Let's find which how deep is the existing directory structure and
3542 // get the first element that's missing. 3740 // get the first element that's missing.
(...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after
4790 pref_registrar_->Init(profile_->GetPrefs()); 4988 pref_registrar_->Init(profile_->GetPrefs());
4791 pref_registrar_->Add(prefs::kDisableGDataHostedFiles, this); 4989 pref_registrar_->Add(prefs::kDisableGDataHostedFiles, this);
4792 } 4990 }
4793 4991
4794 void SetFreeDiskSpaceGetterForTesting(FreeDiskSpaceGetterInterface* getter) { 4992 void SetFreeDiskSpaceGetterForTesting(FreeDiskSpaceGetterInterface* getter) {
4795 delete global_free_disk_getter_for_testing; // Safe to delete NULL; 4993 delete global_free_disk_getter_for_testing; // Safe to delete NULL;
4796 global_free_disk_getter_for_testing = getter; 4994 global_free_disk_getter_for_testing = getter;
4797 } 4995 }
4798 4996
4799 } // namespace gdata 4997 } // namespace gdata
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/gdata/gdata_file_system.h ('k') | chrome/browser/chromeos/gdata/gdata_file_system_proxy.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698