Chromium Code Reviews| Index: chrome/browser/chromeos/drive/drive_resource_metadata.cc |
| =================================================================== |
| --- chrome/browser/chromeos/drive/drive_resource_metadata.cc (revision 167238) |
| +++ 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,75 @@ |
| 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) << "AddEntryToParent" << added_entry->GetFilePath().value(); |
|
hashimoto
2012/11/14 10:15:56
s/AddEntryToParent/AddEntryToDirectoryInternal/
achuithb
2012/11/14 11:11:29
Done.
|
| + base::MessageLoopProxy::current()->PostTask(FROM_HERE, |
| + base::Bind(callback, DRIVE_FILE_OK, added_entry->GetFilePath())); |
| +} |
| + |
| +void DriveResourceMetadata::GetChangedDirectories( |
| + const std::string& resource_id, |
| + const ChangedDirectoriesCallback& 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) { |
| + const FilePath file_path = entry->GetFilePath(); |
| + // Parent. |
| + changed_directories.insert(file_path.DirName()); |
| + |
| + if (entry->AsDriveDirectory()) { |
| + // Children. |
| + entry->AsDriveDirectory()->GetChildDirectoryPaths(&changed_directories); |
| + // Self. |
| + changed_directories.insert(file_path); |
| + } |
| + } |
| + |
| + base::MessageLoopProxy::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(changed_dirs_callback, changed_directories)); |
| +} |
| + |
| +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; |
| +} |
| + |
|
hashimoto
2012/11/14 10:15:56
nit: No need to have two blank lines.
achuithb
2012/11/14 11:11:29
Done.
|
| + |
| void DriveResourceMetadata::TakeOverEntries( |
| const std::string& source_resource_id, |
| const std::string& destination_resource_id, |
| @@ -834,6 +900,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 |