| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/drive/file_system/create_directory_operation.h
" | 5 #include "chrome/browser/chromeos/drive/file_system/create_directory_operation.h
" |
| 6 | 6 |
| 7 #include "chrome/browser/chromeos/drive/drive.pb.h" | 7 #include "chrome/browser/chromeos/drive/drive.pb.h" |
| 8 #include "chrome/browser/chromeos/drive/file_change.h" |
| 8 #include "chrome/browser/chromeos/drive/file_system/operation_observer.h" | 9 #include "chrome/browser/chromeos/drive/file_system/operation_observer.h" |
| 9 #include "chrome/browser/chromeos/drive/file_system_util.h" | 10 #include "chrome/browser/chromeos/drive/file_system_util.h" |
| 10 #include "chrome/browser/chromeos/drive/resource_metadata.h" | 11 #include "chrome/browser/chromeos/drive/resource_metadata.h" |
| 11 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
| 12 | 13 |
| 13 using content::BrowserThread; | 14 using content::BrowserThread; |
| 14 | 15 |
| 15 namespace drive { | 16 namespace drive { |
| 16 namespace file_system { | 17 namespace file_system { |
| 17 | 18 |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| 20 FileError CreateDirectoryRecursively( | 21 FileError CreateDirectoryRecursively(internal::ResourceMetadata* metadata, |
| 21 internal::ResourceMetadata* metadata, | 22 const std::string& parent_local_id, |
| 22 const std::string& parent_local_id, | 23 const base::FilePath& relative_file_path, |
| 23 const base::FilePath& relative_file_path, | 24 std::set<std::string>* updated_local_ids, |
| 24 std::set<std::string>* updated_local_ids, | 25 FileChange* changed_files) { |
| 25 std::set<base::FilePath>* changed_directories) { | |
| 26 // Split the first component and remaining ones of |relative_file_path|. | 26 // Split the first component and remaining ones of |relative_file_path|. |
| 27 std::vector<base::FilePath::StringType> components; | 27 std::vector<base::FilePath::StringType> components; |
| 28 relative_file_path.GetComponents(&components); | 28 relative_file_path.GetComponents(&components); |
| 29 DCHECK(!components.empty()); | 29 DCHECK(!components.empty()); |
| 30 base::FilePath title(components[0]); | 30 base::FilePath title(components[0]); |
| 31 base::FilePath remaining_path; | 31 base::FilePath remaining_path; |
| 32 title.AppendRelativePath(relative_file_path, &remaining_path); | 32 title.AppendRelativePath(relative_file_path, &remaining_path); |
| 33 | 33 |
| 34 ResourceEntry entry; | 34 ResourceEntry entry; |
| 35 const base::Time now = base::Time::Now(); | 35 const base::Time now = base::Time::Now(); |
| 36 entry.set_title(title.AsUTF8Unsafe()); | 36 entry.set_title(title.AsUTF8Unsafe()); |
| 37 entry.mutable_file_info()->set_is_directory(true); | 37 entry.mutable_file_info()->set_is_directory(true); |
| 38 entry.mutable_file_info()->set_last_modified(now.ToInternalValue()); | 38 entry.mutable_file_info()->set_last_modified(now.ToInternalValue()); |
| 39 entry.mutable_file_info()->set_last_accessed(now.ToInternalValue()); | 39 entry.mutable_file_info()->set_last_accessed(now.ToInternalValue()); |
| 40 entry.set_parent_local_id(parent_local_id); | 40 entry.set_parent_local_id(parent_local_id); |
| 41 entry.set_metadata_edit_state(ResourceEntry::DIRTY); | 41 entry.set_metadata_edit_state(ResourceEntry::DIRTY); |
| 42 entry.set_modification_date(base::Time::Now().ToInternalValue()); | 42 entry.set_modification_date(base::Time::Now().ToInternalValue()); |
| 43 | 43 |
| 44 std::string local_id; | 44 std::string local_id; |
| 45 FileError error = metadata->AddEntry(entry, &local_id); | 45 FileError error = metadata->AddEntry(entry, &local_id); |
| 46 if (error != FILE_ERROR_OK) | 46 if (error != FILE_ERROR_OK) |
| 47 return error; | 47 return error; |
| 48 | 48 |
| 49 base::FilePath path; | 49 base::FilePath path; |
| 50 error = metadata->GetFilePath(local_id, &path); | 50 error = metadata->GetFilePath(local_id, &path); |
| 51 if (error != FILE_ERROR_OK) | 51 if (error != FILE_ERROR_OK) |
| 52 return error; | 52 return error; |
| 53 | 53 |
| 54 updated_local_ids->insert(local_id); | 54 updated_local_ids->insert(local_id); |
| 55 changed_directories->insert(path.DirName()); | 55 DCHECK(changed_files); |
| 56 changed_files->Update(path, |
| 57 FileChange::FILE_TYPE_DIRECTORY, |
| 58 FileChange::ADD_OR_UPDATE); |
| 56 | 59 |
| 57 if (remaining_path.empty()) // All directories are created successfully. | 60 if (remaining_path.empty()) // All directories are created successfully. |
| 58 return FILE_ERROR_OK; | 61 return FILE_ERROR_OK; |
| 59 | 62 |
| 60 // Create descendant directories. | 63 // Create descendant directories. |
| 61 return CreateDirectoryRecursively(metadata, local_id, remaining_path, | 64 return CreateDirectoryRecursively( |
| 62 updated_local_ids, changed_directories); | 65 metadata, local_id, remaining_path, updated_local_ids, changed_files); |
| 63 } | 66 } |
| 64 | 67 |
| 65 FileError UpdateLocalState(internal::ResourceMetadata* metadata, | 68 FileError UpdateLocalState(internal::ResourceMetadata* metadata, |
| 66 const base::FilePath& directory_path, | 69 const base::FilePath& directory_path, |
| 67 bool is_exclusive, | 70 bool is_exclusive, |
| 68 bool is_recursive, | 71 bool is_recursive, |
| 69 std::set<std::string>* updated_local_ids, | 72 std::set<std::string>* updated_local_ids, |
| 70 std::set<base::FilePath>* changed_directories) { | 73 FileChange* changed_files) { |
| 71 // Get the existing deepest entry. | 74 // Get the existing deepest entry. |
| 72 std::vector<base::FilePath::StringType> components; | 75 std::vector<base::FilePath::StringType> components; |
| 73 directory_path.GetComponents(&components); | 76 directory_path.GetComponents(&components); |
| 74 | 77 |
| 75 if (components.empty() || components[0] != util::kDriveGrandRootDirName) | 78 if (components.empty() || components[0] != util::kDriveGrandRootDirName) |
| 76 return FILE_ERROR_NOT_FOUND; | 79 return FILE_ERROR_NOT_FOUND; |
| 77 | 80 |
| 78 base::FilePath existing_deepest_path(components[0]); | 81 base::FilePath existing_deepest_path(components[0]); |
| 79 std::string local_id = util::kDriveGrandRootLocalId; | 82 std::string local_id = util::kDriveGrandRootLocalId; |
| 80 for (size_t i = 1; i < components.size(); ++i) { | 83 for (size_t i = 1; i < components.size(); ++i) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 101 return is_exclusive ? FILE_ERROR_EXISTS : FILE_ERROR_OK; | 104 return is_exclusive ? FILE_ERROR_EXISTS : FILE_ERROR_OK; |
| 102 | 105 |
| 103 // If it is not recursive creation, the found directory must be the direct | 106 // If it is not recursive creation, the found directory must be the direct |
| 104 // parent of |directory_path| to ensure creating exact one directory. | 107 // parent of |directory_path| to ensure creating exact one directory. |
| 105 if (!is_recursive && existing_deepest_path != directory_path.DirName()) | 108 if (!is_recursive && existing_deepest_path != directory_path.DirName()) |
| 106 return FILE_ERROR_NOT_FOUND; | 109 return FILE_ERROR_NOT_FOUND; |
| 107 | 110 |
| 108 // Create directories under the found directory. | 111 // Create directories under the found directory. |
| 109 base::FilePath remaining_path; | 112 base::FilePath remaining_path; |
| 110 existing_deepest_path.AppendRelativePath(directory_path, &remaining_path); | 113 existing_deepest_path.AppendRelativePath(directory_path, &remaining_path); |
| 111 return CreateDirectoryRecursively(metadata, entry.local_id(), remaining_path, | 114 return CreateDirectoryRecursively(metadata, |
| 112 updated_local_ids, changed_directories); | 115 entry.local_id(), |
| 116 remaining_path, |
| 117 updated_local_ids, |
| 118 changed_files); |
| 113 } | 119 } |
| 114 | 120 |
| 115 } // namespace | 121 } // namespace |
| 116 | 122 |
| 117 CreateDirectoryOperation::CreateDirectoryOperation( | 123 CreateDirectoryOperation::CreateDirectoryOperation( |
| 118 base::SequencedTaskRunner* blocking_task_runner, | 124 base::SequencedTaskRunner* blocking_task_runner, |
| 119 OperationObserver* observer, | 125 OperationObserver* observer, |
| 120 internal::ResourceMetadata* metadata) | 126 internal::ResourceMetadata* metadata) |
| 121 : blocking_task_runner_(blocking_task_runner), | 127 : blocking_task_runner_(blocking_task_runner), |
| 122 observer_(observer), | 128 observer_(observer), |
| 123 metadata_(metadata), | 129 metadata_(metadata), |
| 124 weak_ptr_factory_(this) { | 130 weak_ptr_factory_(this) { |
| 125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 126 } | 132 } |
| 127 | 133 |
| 128 CreateDirectoryOperation::~CreateDirectoryOperation() { | 134 CreateDirectoryOperation::~CreateDirectoryOperation() { |
| 129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 130 } | 136 } |
| 131 | 137 |
| 132 void CreateDirectoryOperation::CreateDirectory( | 138 void CreateDirectoryOperation::CreateDirectory( |
| 133 const base::FilePath& directory_path, | 139 const base::FilePath& directory_path, |
| 134 bool is_exclusive, | 140 bool is_exclusive, |
| 135 bool is_recursive, | 141 bool is_recursive, |
| 136 const FileOperationCallback& callback) { | 142 const FileOperationCallback& callback) { |
| 137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 138 DCHECK(!callback.is_null()); | 144 DCHECK(!callback.is_null()); |
| 139 | 145 |
| 140 std::set<std::string>* updated_local_ids = new std::set<std::string>; | 146 std::set<std::string>* updated_local_ids = new std::set<std::string>; |
| 141 std::set<base::FilePath>* changed_directories = new std::set<base::FilePath>; | 147 FileChange* changed_files(new FileChange); |
| 142 base::PostTaskAndReplyWithResult( | 148 base::PostTaskAndReplyWithResult( |
| 143 blocking_task_runner_.get(), | 149 blocking_task_runner_.get(), |
| 144 FROM_HERE, | 150 FROM_HERE, |
| 145 base::Bind(&UpdateLocalState, | 151 base::Bind(&UpdateLocalState, |
| 146 metadata_, directory_path, is_exclusive, is_recursive, | 152 metadata_, |
| 147 updated_local_ids, changed_directories), | 153 directory_path, |
| 148 base::Bind(&CreateDirectoryOperation:: | 154 is_exclusive, |
| 149 CreateDirectoryAfterUpdateLocalState, | 155 is_recursive, |
| 150 weak_ptr_factory_.GetWeakPtr(), | 156 updated_local_ids, |
| 151 callback, | 157 changed_files), |
| 152 base::Owned(updated_local_ids), | 158 base::Bind( |
| 153 base::Owned(changed_directories))); | 159 &CreateDirectoryOperation::CreateDirectoryAfterUpdateLocalState, |
| 160 weak_ptr_factory_.GetWeakPtr(), |
| 161 callback, |
| 162 base::Owned(updated_local_ids), |
| 163 base::Owned(changed_files))); |
| 154 } | 164 } |
| 155 | 165 |
| 156 void CreateDirectoryOperation::CreateDirectoryAfterUpdateLocalState( | 166 void CreateDirectoryOperation::CreateDirectoryAfterUpdateLocalState( |
| 157 const FileOperationCallback& callback, | 167 const FileOperationCallback& callback, |
| 158 const std::set<std::string>* updated_local_ids, | 168 const std::set<std::string>* updated_local_ids, |
| 159 const std::set<base::FilePath>* changed_directories, | 169 const FileChange* changed_files, |
| 160 FileError error) { | 170 FileError error) { |
| 161 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 162 DCHECK(!callback.is_null()); | 172 DCHECK(!callback.is_null()); |
| 163 | 173 |
| 164 for (std::set<std::string>::const_iterator it = updated_local_ids->begin(); | 174 for (std::set<std::string>::const_iterator it = updated_local_ids->begin(); |
| 165 it != updated_local_ids->end(); ++it) | 175 it != updated_local_ids->end(); ++it) |
| 166 observer_->OnEntryUpdatedByOperation(*it); | 176 observer_->OnEntryUpdatedByOperation(*it); |
| 167 | 177 |
| 168 for (std::set<base::FilePath>::const_iterator it = | 178 observer_->OnDirectoryChangedByOperation(*changed_files); |
| 169 changed_directories->begin(); it != changed_directories->end(); ++it) | |
| 170 observer_->OnDirectoryChangedByOperation(*it); | |
| 171 | 179 |
| 172 callback.Run(error); | 180 callback.Run(error); |
| 173 } | 181 } |
| 174 | 182 |
| 175 } // namespace file_system | 183 } // namespace file_system |
| 176 } // namespace drive | 184 } // namespace drive |
| OLD | NEW |