| Index: chrome/browser/chromeos/drive/drive_resource_metadata.cc
|
| ===================================================================
|
| --- chrome/browser/chromeos/drive/drive_resource_metadata.cc (revision 168559)
|
| +++ chrome/browser/chromeos/drive/drive_resource_metadata.cc (working copy)
|
| @@ -246,13 +246,6 @@
|
| return;
|
| }
|
|
|
| - scoped_ptr<DriveEntry> new_entry = CreateDriveEntryFromProto(
|
| - ConvertDocumentEntryToDriveEntryProto(*doc_entry));
|
| - if (!new_entry.get()) {
|
| - PostFileMoveCallbackError(callback, DRIVE_FILE_ERROR_FAILED);
|
| - return;
|
| - }
|
| -
|
| DriveEntry* dir_entry = FindEntryByPathSync(directory_path);
|
| if (!dir_entry) {
|
| PostFileMoveCallbackError(callback, DRIVE_FILE_ERROR_NOT_FOUND);
|
| @@ -265,11 +258,10 @@
|
| return;
|
| }
|
|
|
| - DriveEntry* added_entry = new_entry.release();
|
| - directory->AddEntry(added_entry); // Transfers ownership.
|
| - DVLOG(1) << "AddEntryToDirectory " << added_entry->GetFilePath().value();
|
| - base::MessageLoopProxy::current()->PostTask(FROM_HERE,
|
| - base::Bind(callback, DRIVE_FILE_OK, added_entry->GetFilePath()));
|
| + AddEntryToDirectoryInternal(
|
| + directory,
|
| + ConvertDocumentEntryToDriveEntryProto(*doc_entry),
|
| + callback);
|
| }
|
|
|
| void DriveResourceMetadata::MoveEntryToDirectory(
|
| @@ -518,48 +510,53 @@
|
| return;
|
| }
|
|
|
| - scoped_ptr<DriveEntry> drive_entry = CreateDriveEntryFromProto(
|
| - ConvertDocumentEntryToDriveEntryProto(*doc_entry));
|
| + RefreshEntryProto(ConvertDocumentEntryToDriveEntryProto(
|
| + *doc_entry), callback);
|
| +}
|
| +
|
| +void DriveResourceMetadata::RefreshEntryProto(
|
| + const DriveEntryProto& entry_proto,
|
| + const GetEntryInfoWithFilePathCallback& callback) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK(!callback.is_null());
|
| +
|
| + scoped_ptr<DriveEntry> drive_entry = CreateDriveEntryFromProto(entry_proto);
|
| if (!drive_entry.get()) {
|
| PostGetEntryInfoWithFilePathCallbackError(
|
| callback, DRIVE_FILE_ERROR_FAILED);
|
| return;
|
| }
|
|
|
| - if (!drive_entry->AsDriveFile()) {
|
| - // This is a directory, return the directory info instead.
|
| - GetEntryInfoByResourceId(drive_entry->resource_id(), callback);
|
| + DriveEntry* old_entry = GetEntryByResourceId(drive_entry->resource_id());
|
| + DriveDirectory* old_parent = old_entry ? old_entry->parent() : NULL;
|
| + DriveDirectory* new_parent = GetParent(entry_proto.parent_resource_id());
|
| + if (!old_parent || !new_parent) {
|
| + PostGetEntryInfoWithFilePathCallbackError(callback,
|
| + DRIVE_FILE_ERROR_NOT_FOUND);
|
| return;
|
| }
|
| - scoped_ptr<DriveFile> fresh_file(drive_entry.release()->AsDriveFile());
|
|
|
| - // Need to get a reference here because Passed() could get evaluated first.
|
| - const std::string& resource_id = fresh_file->resource_id();
|
| - DVLOG(1) << "RefreshFile " << resource_id;
|
| - DriveEntry* old_entry = GetEntryByResourceId(resource_id);
|
| - DriveDirectory* entry_parent = old_entry ? old_entry->parent() : NULL;
|
| -
|
| - if (!entry_parent) {
|
| - PostGetEntryInfoWithFilePathCallbackError(
|
| - callback, DRIVE_FILE_ERROR_NOT_FOUND);
|
| - return;
|
| + // Move children over to the new directory from the existing directory.
|
| + if (drive_entry->AsDriveDirectory() && old_entry->AsDriveDirectory()) {
|
| + drive_entry->AsDriveDirectory()->TakeOverEntries(
|
| + old_entry->AsDriveDirectory());
|
| }
|
|
|
| - DCHECK_EQ(fresh_file->resource_id(), old_entry->resource_id());
|
| - DCHECK(old_entry->AsDriveFile());
|
| + // Remove from the old parent and add to the new parent.
|
| + old_parent->RemoveEntry(old_entry);
|
| + DriveEntry* new_entry = drive_entry.release();
|
| + new_parent->AddEntry(new_entry); // Transfers ownership.
|
|
|
| - entry_parent->RemoveEntry(old_entry);
|
| - DriveEntry* new_entry = fresh_file.release();
|
| - entry_parent->AddEntry(new_entry);
|
| -
|
| - scoped_ptr<DriveEntryProto> entry_proto(new DriveEntryProto);
|
| - new_entry->ToProtoFull(entry_proto.get());
|
| + DVLOG(1) << "RefreshEntryProto " << new_entry->GetFilePath().value();
|
| + // Note that base_name is not the same for new_entry and entry_proto.
|
| + scoped_ptr<DriveEntryProto> new_entry_proto(new DriveEntryProto);
|
| + new_entry->ToProtoFull(new_entry_proto.get());
|
| base::MessageLoopProxy::current()->PostTask(
|
| FROM_HERE,
|
| base::Bind(callback,
|
| DRIVE_FILE_OK,
|
| new_entry->GetFilePath(),
|
| - base::Passed(&entry_proto)));
|
| + base::Passed(&new_entry_proto)));
|
| }
|
|
|
| void DriveResourceMetadata::RefreshDirectory(
|
| @@ -597,6 +594,65 @@
|
| base::Bind(callback, DRIVE_FILE_OK, directory->GetFilePath()));
|
| }
|
|
|
| +void DriveResourceMetadata::AddEntryToParent(
|
| + const DriveEntryProto& entry_proto,
|
| + const FileMoveCallback& callback) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK(!callback.is_null());
|
| +
|
| + DriveDirectory* parent = GetParent(entry_proto.parent_resource_id());
|
| + if (!parent) {
|
| + PostFileMoveCallbackError(callback, DRIVE_FILE_ERROR_NOT_FOUND);
|
| + return;
|
| + }
|
| + AddEntryToDirectoryInternal(parent, entry_proto, callback);
|
| +}
|
| +
|
| +void DriveResourceMetadata::AddEntryToDirectoryInternal(
|
| + DriveDirectory* directory,
|
| + const DriveEntryProto& entry_proto,
|
| + const FileMoveCallback& callback) {
|
| + scoped_ptr<DriveEntry> new_entry = CreateDriveEntryFromProto(entry_proto);
|
| + if (!new_entry.get()) {
|
| + PostFileMoveCallbackError(callback, DRIVE_FILE_ERROR_FAILED);
|
| + return;
|
| + }
|
| +
|
| + DriveEntry* added_entry = new_entry.release();
|
| + directory->AddEntry(added_entry); // Transfers ownership.
|
| + DVLOG(1) << "AddEntryToDirectoryInternal"
|
| + << added_entry->GetFilePath().value();
|
| + base::MessageLoopProxy::current()->PostTask(FROM_HERE,
|
| + base::Bind(callback, DRIVE_FILE_OK, added_entry->GetFilePath()));
|
| +}
|
| +
|
| +DriveDirectory* DriveResourceMetadata::GetParent(
|
| + const std::string& parent_resource_id) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + if (parent_resource_id.empty())
|
| + return root();
|
| +
|
| + DriveEntry* entry = GetEntryByResourceId(parent_resource_id);
|
| + return entry ? entry->AsDriveDirectory() : NULL;
|
| +}
|
| +
|
| +void DriveResourceMetadata::GetChildDirectories(
|
| + const std::string& resource_id,
|
| + const GetChildDirectoriesCallback& changed_dirs_callback) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK(!changed_dirs_callback.is_null());
|
| +
|
| + std::set<FilePath> changed_directories;
|
| + DriveEntry* entry = GetEntryByResourceId(resource_id);
|
| + if (entry && entry->AsDriveDirectory())
|
| + entry->AsDriveDirectory()->GetChildDirectoryPaths(&changed_directories);
|
| +
|
| + base::MessageLoopProxy::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(changed_dirs_callback, changed_directories));
|
| +}
|
| +
|
| void DriveResourceMetadata::TakeOverEntries(
|
| const std::string& source_resource_id,
|
| const std::string& destination_resource_id,
|
| @@ -834,6 +890,8 @@
|
| scoped_ptr<DriveEntry> DriveResourceMetadata::CreateDriveEntryFromProto(
|
| const DriveEntryProto& entry_proto) {
|
| scoped_ptr<DriveEntry> entry;
|
| + // TODO(achuith): This method never fails. Add basic sanity checks for
|
| + // resource_id, etc.
|
| if (entry_proto.file_info().is_directory()) {
|
| entry = CreateDriveDirectory().Pass();
|
| // Call DriveEntry::FromProto instead of DriveDirectory::FromProto because
|
|
|