Index: chrome/browser/chromeos/gdata/gdata_file_system.cc |
diff --git a/chrome/browser/chromeos/gdata/gdata_file_system.cc b/chrome/browser/chromeos/gdata/gdata_file_system.cc |
index bd79a7fada83c8cb2e48f257cbe1f9bfb8cc4cde..ec9e1f0341f122f0135512c82fb0517511347323 100644 |
--- a/chrome/browser/chromeos/gdata/gdata_file_system.cc |
+++ b/chrome/browser/chromeos/gdata/gdata_file_system.cc |
@@ -862,12 +862,16 @@ GDataFileSystem::GetDocumentsParams::GetDocumentsParams( |
int start_changestamp, |
int root_feed_changestamp, |
std::vector<DocumentFeed*>* feed_list, |
+ bool allow_multiple_feeds, |
const FilePath& search_file_path, |
+ const std::string& search_query, |
const FindEntryCallback& callback) |
: start_changestamp(start_changestamp), |
root_feed_changestamp(root_feed_changestamp), |
feed_list(feed_list), |
+ allow_multiple_feeds(allow_multiple_feeds), |
search_file_path(search_file_path), |
+ search_query(search_query), |
callback(callback) { |
} |
@@ -1128,7 +1132,13 @@ void GDataFileSystem::OnGetAccountMetadata( |
base::PlatformFileError error = GDataToPlatformError(status); |
if (error != base::PLATFORM_FILE_OK) { |
// Get changes starting from the next changestamp from what we have locally. |
- LoadFeedFromServer(local_changestamp + 1, 0, search_file_path, callback); |
+ LoadFeedFromServer(local_changestamp + 1, 0, |
+ true, |
+ search_file_path, |
+ std::string() /* no search query*/, |
+ callback, |
+ base::Bind(&GDataFileSystem::OnFeedFromServerLoaded, |
+ ui_weak_ptr_)); |
return; |
} |
@@ -1136,7 +1146,13 @@ void GDataFileSystem::OnGetAccountMetadata( |
if (feed_data.get()) |
feed = AccountMetadataFeed::CreateFrom(*feed_data); |
if (!feed.get()) { |
- LoadFeedFromServer(local_changestamp + 1, 0, search_file_path, callback); |
+ LoadFeedFromServer(local_changestamp + 1, 0, |
+ true, |
+ search_file_path, |
+ std::string() /* no search query*/, |
+ callback, |
+ base::Bind(&GDataFileSystem::OnFeedFromServerLoaded, |
+ ui_weak_ptr_)); |
return; |
} |
@@ -1170,15 +1186,22 @@ void GDataFileSystem::OnGetAccountMetadata( |
// Load changes from the server. |
LoadFeedFromServer(local_changestamp > 0 ? local_changestamp + 1 : 0, |
feed->largest_changestamp(), |
+ true, |
search_file_path, |
- callback); |
+ std::string() /* no search query*/, |
+ callback, |
+ base::Bind(&GDataFileSystem::OnFeedFromServerLoaded, |
+ ui_weak_ptr_)); |
} |
void GDataFileSystem::LoadFeedFromServer( |
int start_changestamp, |
int root_feed_changestamp, |
+ bool allow_multiple_feeds, |
const FilePath& search_file_path, |
- const FindEntryCallback& callback) { |
+ const std::string& search_query, |
+ const FindEntryCallback& entry_found_callback, |
+ const LoadDocumentFeedCallback& feed_load_callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
// ...then also kick off document feed fetching from the server as well. |
@@ -1191,13 +1214,49 @@ void GDataFileSystem::LoadFeedFromServer( |
documents_service_->GetDocuments( |
GURL(), // root feed start. |
start_changestamp, |
+ search_query, |
base::Bind(&GDataFileSystem::OnGetDocuments, |
ui_weak_ptr_, |
+ feed_load_callback, |
base::Owned(new GetDocumentsParams(start_changestamp, |
root_feed_changestamp, |
feed_list.release(), |
+ allow_multiple_feeds, |
search_file_path, |
- callback)))); |
+ search_query, |
+ entry_found_callback)))); |
+} |
+ |
+void GDataFileSystem::OnFeedFromServerLoaded(GetDocumentsParams* params, |
+ base::PlatformFileError error) { |
+ if (error != base::PLATFORM_FILE_OK) { |
+ params->callback.Run(error, FilePath(), |
+ reinterpret_cast<GDataEntry*>(NULL)); |
satorux1
2012/05/03 17:58:34
indentation is off?
tbarzic
2012/05/03 23:56:17
Done.
|
+ return; |
+ } |
+ |
+ error = UpdateFromFeed(*params->feed_list, |
+ FROM_SERVER, |
+ params->start_changestamp, |
+ params->root_feed_changestamp); |
+ |
+ if (error != base::PLATFORM_FILE_OK) { |
+ if (!params->callback.is_null()) { |
+ params->callback.Run(error, FilePath(), |
+ reinterpret_cast<GDataEntry*>(NULL)); |
satorux1
2012/05/03 17:58:34
indentation is off?
tbarzic
2012/05/03 23:56:17
Done.
|
+ } |
+ |
+ return; |
+ } |
+ |
+ // Save file system metadata to disk. |
+ SaveFileSystemAsProto(); |
+ |
+ // If we had someone to report this too, then this retrieval was done in a |
+ // context of search... so continue search. |
+ if (!params->callback.is_null()) { |
+ FindEntryByPathSyncOnUIThread(params->search_file_path, params->callback); |
+ } |
} |
void GDataFileSystem::TransferFile(const FilePath& local_file_path, |
@@ -1358,13 +1417,16 @@ void GDataFileSystem::Copy(const FilePath& src_file_path, |
CopyOnUIThread(src_file_path, dest_file_path, callback); |
} |
-void GDataFileSystem::CopyOnUIThread(const FilePath& src_file_path, |
- const FilePath& dest_file_path, |
+void GDataFileSystem::CopyOnUIThread(const FilePath& original_src_file_path, |
+ const FilePath& original_dest_file_path, |
const FileOperationCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
- FilePath dest_parent_path = dest_file_path.DirName(); |
+ FilePath dest_parent_path = original_dest_file_path.DirName(); |
+ |
+ FilePath src_file_path = original_src_file_path; |
+ 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.
|
std::string src_file_resource_id; |
bool src_file_is_hosted_document = false; |
@@ -1376,7 +1438,7 @@ void GDataFileSystem::CopyOnUIThread(const FilePath& src_file_path, |
error = base::PLATFORM_FILE_ERROR_NOT_FOUND; |
} else if (!dest_parent->AsGDataDirectory()) { |
error = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
- } else if (!src_entry->AsGDataFile()) { |
+ } else if (!src_entry->AsGDataFile() || dest_parent->is_detached()) { |
// TODO(benchan): Implement copy for directories. In the interim, |
// we handle recursive directory copy in the file manager. |
error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION; |
@@ -1384,6 +1446,12 @@ void GDataFileSystem::CopyOnUIThread(const FilePath& src_file_path, |
src_file_resource_id = src_entry->resource_id(); |
src_file_is_hosted_document = |
src_entry->AsGDataFile()->is_hosted_document(); |
+ // If original source or destinatino paths are virtual (e.g. paths used to |
+ // show content search results), we don't want to use them to perform copy |
+ // operation. Instead we use file paths of the files they point to. |
+ src_file_path = src_entry->GetFilePath(); |
+ 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.
|
+ dest_file_path = dest_parent_path.Append(dest_file_path.BaseName()); |
} |
} |
satorux1
2012/05/03 17:58:34
might want to add:
DCHECK(!src_file_path.empty())
tbarzic
2012/05/03 23:56:17
Done.
|
@@ -1534,13 +1602,17 @@ void GDataFileSystem::Move(const FilePath& src_file_path, |
MoveOnUIThread(src_file_path, dest_file_path, callback); |
} |
-void GDataFileSystem::MoveOnUIThread(const FilePath& src_file_path, |
- const FilePath& dest_file_path, |
+void GDataFileSystem::MoveOnUIThread(const FilePath& original_src_file_path, |
+ const FilePath& original_dest_file_path, |
const FileOperationCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
- FilePath dest_parent_path = dest_file_path.DirName(); |
+ FilePath dest_parent_path = original_dest_file_path.DirName(); |
+ |
+ FilePath src_file_path = original_src_file_path; |
+ FilePath dest_file_path = original_dest_file_path; |
+ FilePath dest_name = dest_file_path.BaseName(); |
{ |
// This scoped lock needs to be released before calling Rename() below. |
@@ -1549,9 +1621,23 @@ void GDataFileSystem::MoveOnUIThread(const FilePath& src_file_path, |
GDataEntry* dest_parent = GetGDataEntryByPath(dest_parent_path); |
if (!src_entry || !dest_parent) { |
error = base::PLATFORM_FILE_ERROR_NOT_FOUND; |
- } else { |
- if (!dest_parent->AsGDataDirectory()) |
+ } else if (!dest_parent->AsGDataDirectory()) { |
error = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
+ } else if (dest_parent->is_detached()){ |
+ // We allow moving to a directory without file system root only if it's |
+ // done as part of renaming (i.e. source and destination parent paths are |
+ // the same). |
+ if (src_file_path.DirName() != dest_parent_path) { |
+ error = base::PLATFORM_FILE_ERROR_INVALID_OPERATION; |
+ } else { |
+ // If we are indeed renaming, we have to strip resource id from the file |
+ // name. |
+ std::string resource_id; |
+ std::string file_name; |
+ util::CrackSearchFileName(dest_name.value(), &resource_id, &file_name); |
+ if (!file_name.empty()) |
+ dest_name = FilePath(file_name); |
+ } |
} |
if (error != base::PLATFORM_FILE_OK) { |
@@ -1561,16 +1647,20 @@ void GDataFileSystem::MoveOnUIThread(const FilePath& src_file_path, |
} |
return; |
} |
+ src_file_path = src_entry->GetFilePath(); |
+ if (!dest_parent->is_detached()) |
+ dest_parent_path = dest_parent->GetFilePath(); |
+ dest_file_path = dest_parent_path.Append(dest_name); |
} |
// If the file/directory is moved to the same directory, just rename it. |
- if (src_file_path.DirName() == dest_parent_path) { |
+ if (original_src_file_path.DirName() == dest_parent_path) { |
FilePathUpdateCallback final_file_path_update_callback = |
base::Bind(&GDataFileSystem::OnFilePathUpdated, |
ui_weak_ptr_, |
callback); |
- Rename(src_file_path, dest_file_path.BaseName().value(), |
+ Rename(original_src_file_path, dest_name.value(), |
final_file_path_update_callback); |
return; |
} |
@@ -1710,7 +1800,7 @@ void GDataFileSystem::RemoveOnUIThread( |
if (!callback.is_null()) { |
MessageLoop::current()->PostTask( |
FROM_HERE, |
- base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND)); |
+ 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.
|
} |
return; |
} |
@@ -1720,7 +1810,7 @@ void GDataFileSystem::RemoveOnUIThread( |
base::Bind(&GDataFileSystem::OnRemovedDocument, |
ui_weak_ptr_, |
callback, |
- file_path)); |
+ 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?
|
} |
void GDataFileSystem::CreateDirectory( |
@@ -1756,6 +1846,20 @@ void GDataFileSystem::CreateDirectoryOnUIThread( |
const FileOperationCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ // We don't want ot allow creating new directories in virtual search |
+ // directories. Also directory "gdata/.search" should be reserved. |
+ util::GDataSearchPathType path_type = |
+ util::GetSearchPathStatus(directory_path); |
+ if (path_type == util::GDATA_SEARCH_PATH_ROOT || |
+ path_type == util::GDATA_SEARCH_PATH_QUERY || |
+ 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.
|
+ if (!callback.is_null()) { |
+ MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(callback, base::PLATFORM_FILE_ERROR_INVALID_OPERATION)); |
+ } |
+ return; |
+ } |
+ |
FilePath last_parent_dir_path; |
FilePath first_missing_path; |
GURL last_parent_dir_url; |
@@ -2670,7 +2774,90 @@ void GDataFileSystem::OnCreateDirectoryCompleted( |
} |
} |
-void GDataFileSystem::OnGetDocuments(GetDocumentsParams* params, |
+void GDataFileSystem::OnSearchContent(const ReadDirectoryCallback& callback, |
+ GetDocumentsParams* params, |
+ base::PlatformFileError error) { |
+ // The search results will be returned using virtual directory. |
+ // The directory is not really part of the file system, so it has no parent or |
+ // root. |
+ scoped_ptr<GDataDirectory> search_dir(new GDataDirectory(NULL, NULL)); |
+ |
+ base::AutoLock lock(lock_); |
+ |
+ int delta_feed_changestamp = 0; |
+ int num_regular_files = 0; |
+ int num_hosted_documents = 0; |
+ FileResourceIdMap file_map; |
+ if (error == base::PLATFORM_FILE_OK) { |
+ error = FeedToFileResourceMap(*params->feed_list, |
+ &file_map, |
+ &delta_feed_changestamp, |
+ &num_regular_files, |
+ &num_hosted_documents); |
+ } |
+ |
+ if (error == base::PLATFORM_FILE_OK) { |
+ std::set<FilePath> ignored; |
+ |
+ // Go through all entires generated by the feed and add them to the search |
+ // result directory. |
+ for (FileResourceIdMap::const_iterator it = file_map.begin(); |
+ it != file_map.end(); ++it) { |
+ scoped_ptr<GDataEntry> entry(it->second); |
+ DCHECK_EQ(it->first, entry->resource_id()); |
+ DCHECK(!entry->is_deleted()); |
+ |
+ entry->set_title(entry->resource_id() + "." + entry->title()); |
+ |
+ search_dir->AddEntry(entry.release()); |
+ } |
+ } |
+ |
+ scoped_ptr<GDataDirectoryProto> directory_proto(new GDataDirectoryProto); |
+ search_dir->ToProto(directory_proto.get()); |
+ |
+ if (!callback.is_null()) { |
+ callback.Run(error, directory_proto.Pass()); |
+ } |
+} |
+ |
+void GDataFileSystem::SearchContent(const std::string& search_query, |
+ const ReadDirectoryCallback& callback) { |
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ const bool posted = BrowserThread::PostTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&GDataFileSystem::SearchContentOnUIThread, |
+ ui_weak_ptr_, |
+ search_query, |
+ base::Bind(&RelayReadDirectoryCallback, |
+ base::MessageLoopProxy::current(), |
+ callback))); |
+ DCHECK(posted); |
+ return; |
+ } |
+ |
+ SearchContentOnUIThread(search_query, callback); |
+} |
+ |
+void GDataFileSystem::SearchContentOnUIThread( |
+ const std::string& search_query, |
+ const ReadDirectoryCallback& callback) { |
+ scoped_ptr<std::vector<DocumentFeed*> > feed_list( |
+ new std::vector<DocumentFeed*>); |
+ |
+ LoadFeedFromServer(0, 0, |
+ 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
|
+ FilePath(), |
+ search_query, |
+ FindEntryCallback(), |
+ base::Bind(&GDataFileSystem::OnSearchContent, |
+ ui_weak_ptr_, callback)); |
+} |
+ |
+void GDataFileSystem::OnGetDocuments(const LoadDocumentFeedCallback& callback, |
+ GetDocumentsParams* params, |
GDataErrorCode status, |
scoped_ptr<base::Value> data) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
@@ -2678,14 +2865,12 @@ void GDataFileSystem::OnGetDocuments(GetDocumentsParams* params, |
base::PlatformFileError error = GDataToPlatformError(status); |
if (error == base::PLATFORM_FILE_OK && |
(!data.get() || data->GetType() != Value::TYPE_DICTIONARY)) { |
- LOG(WARNING) << "No feed content!"; |
error = base::PLATFORM_FILE_ERROR_FAILED; |
} |
if (error != base::PLATFORM_FILE_OK) { |
- if (!params->callback.is_null()) { |
- params->callback.Run(error, FilePath(), |
- reinterpret_cast<GDataEntry*>(NULL)); |
+ if (!callback.is_null()) { |
+ callback.Run(params, error); |
} |
return; |
@@ -2696,9 +2881,8 @@ void GDataFileSystem::OnGetDocuments(GetDocumentsParams* params, |
GURL next_feed_url; |
scoped_ptr<DocumentFeed> current_feed(DocumentFeed::ExtractAndParse(*data)); |
if (!current_feed.get()) { |
- if (!params->callback.is_null()) { |
- params->callback.Run(base::PLATFORM_FILE_ERROR_FAILED, FilePath(), |
- reinterpret_cast<GDataEntry*>(NULL)); |
+ if (!callback.is_null()) { |
+ callback.Run(params, base::PLATFORM_FILE_ERROR_FAILED); |
} |
return; |
@@ -2709,44 +2893,29 @@ void GDataFileSystem::OnGetDocuments(GetDocumentsParams* params, |
params->feed_list->push_back(current_feed.release()); |
// Check if we need to collect more data to complete the directory list. |
- if (has_next_feed_url && !next_feed_url.is_empty()) { |
+ if (params->allow_multiple_feeds && has_next_feed_url && |
+ !next_feed_url.is_empty()) { |
// Kick of the remaining part of the feeds. |
documents_service_->GetDocuments( |
next_feed_url, |
params->start_changestamp, |
+ params->search_query, |
base::Bind(&GDataFileSystem::OnGetDocuments, |
ui_weak_ptr_, |
+ callback, |
base::Owned( |
new GetDocumentsParams(params->start_changestamp, |
params->root_feed_changestamp, |
params->feed_list.release(), |
+ params->allow_multiple_feeds, |
params->search_file_path, |
+ params->search_query, |
params->callback)))); |
return; |
} |
- error = UpdateFromFeed(*params->feed_list, |
- FROM_SERVER, |
- params->start_changestamp, |
- params->root_feed_changestamp); |
- |
- if (error != base::PLATFORM_FILE_OK) { |
- if (!params->callback.is_null()) { |
- params->callback.Run(error, FilePath(), |
- reinterpret_cast<GDataEntry*>(NULL)); |
- } |
- |
- return; |
- } |
- |
- // Save file system metadata to disk. |
- SaveFileSystemAsProto(); |
- |
- // If we had someone to report this too, then this retrieval was done in a |
- // context of search... so continue search. |
- if (!params->callback.is_null()) { |
- FindEntryByPathSyncOnUIThread(params->search_file_path, params->callback); |
- } |
+ if (!callback.is_null()) |
+ callback.Run(params, error); |
} |
void GDataFileSystem::LoadRootFeedFromCache( |
@@ -3510,7 +3679,7 @@ base::PlatformFileError GDataFileSystem::AddNewDirectory( |
parent_dir->AddEntry(new_entry); |
- NotifyDirectoryChanged(directory_path); |
+ NotifyDirectoryChanged(entry->GetFilePath()); |
return base::PLATFORM_FILE_OK; |
} |