| 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( |
| 57 path, FileChange::FILE_TYPE_DIRECTORY, FileChange::ADD_OR_UPDATE); |
| 56 | 58 |
| 57 if (remaining_path.empty()) // All directories are created successfully. | 59 if (remaining_path.empty()) // All directories are created successfully. |
| 58 return FILE_ERROR_OK; | 60 return FILE_ERROR_OK; |
| 59 | 61 |
| 60 // Create descendant directories. | 62 // Create descendant directories. |
| 61 return CreateDirectoryRecursively(metadata, local_id, remaining_path, | 63 return CreateDirectoryRecursively( |
| 62 updated_local_ids, changed_directories); | 64 metadata, local_id, remaining_path, updated_local_ids, changed_files); |
| 63 } | 65 } |
| 64 | 66 |
| 65 FileError UpdateLocalState(internal::ResourceMetadata* metadata, | 67 FileError UpdateLocalState(internal::ResourceMetadata* metadata, |
| 66 const base::FilePath& directory_path, | 68 const base::FilePath& directory_path, |
| 67 bool is_exclusive, | 69 bool is_exclusive, |
| 68 bool is_recursive, | 70 bool is_recursive, |
| 69 std::set<std::string>* updated_local_ids, | 71 std::set<std::string>* updated_local_ids, |
| 70 std::set<base::FilePath>* changed_directories) { | 72 FileChange* changed_files) { |
| 71 // Get the existing deepest entry. | 73 // Get the existing deepest entry. |
| 72 std::vector<base::FilePath::StringType> components; | 74 std::vector<base::FilePath::StringType> components; |
| 73 directory_path.GetComponents(&components); | 75 directory_path.GetComponents(&components); |
| 74 | 76 |
| 75 if (components.empty() || components[0] != util::kDriveGrandRootDirName) | 77 if (components.empty() || components[0] != util::kDriveGrandRootDirName) |
| 76 return FILE_ERROR_NOT_FOUND; | 78 return FILE_ERROR_NOT_FOUND; |
| 77 | 79 |
| 78 base::FilePath existing_deepest_path(components[0]); | 80 base::FilePath existing_deepest_path(components[0]); |
| 79 std::string local_id = util::kDriveGrandRootLocalId; | 81 std::string local_id = util::kDriveGrandRootLocalId; |
| 80 for (size_t i = 1; i < components.size(); ++i) { | 82 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; | 103 return is_exclusive ? FILE_ERROR_EXISTS : FILE_ERROR_OK; |
| 102 | 104 |
| 103 // If it is not recursive creation, the found directory must be the direct | 105 // If it is not recursive creation, the found directory must be the direct |
| 104 // parent of |directory_path| to ensure creating exact one directory. | 106 // parent of |directory_path| to ensure creating exact one directory. |
| 105 if (!is_recursive && existing_deepest_path != directory_path.DirName()) | 107 if (!is_recursive && existing_deepest_path != directory_path.DirName()) |
| 106 return FILE_ERROR_NOT_FOUND; | 108 return FILE_ERROR_NOT_FOUND; |
| 107 | 109 |
| 108 // Create directories under the found directory. | 110 // Create directories under the found directory. |
| 109 base::FilePath remaining_path; | 111 base::FilePath remaining_path; |
| 110 existing_deepest_path.AppendRelativePath(directory_path, &remaining_path); | 112 existing_deepest_path.AppendRelativePath(directory_path, &remaining_path); |
| 111 return CreateDirectoryRecursively(metadata, entry.local_id(), remaining_path, | 113 return CreateDirectoryRecursively(metadata, |
| 112 updated_local_ids, changed_directories); | 114 entry.local_id(), |
| 115 remaining_path, |
| 116 updated_local_ids, |
| 117 changed_files); |
| 113 } | 118 } |
| 114 | 119 |
| 115 } // namespace | 120 } // namespace |
| 116 | 121 |
| 117 CreateDirectoryOperation::CreateDirectoryOperation( | 122 CreateDirectoryOperation::CreateDirectoryOperation( |
| 118 base::SequencedTaskRunner* blocking_task_runner, | 123 base::SequencedTaskRunner* blocking_task_runner, |
| 119 OperationObserver* observer, | 124 OperationObserver* observer, |
| 120 internal::ResourceMetadata* metadata) | 125 internal::ResourceMetadata* metadata) |
| 121 : blocking_task_runner_(blocking_task_runner), | 126 : blocking_task_runner_(blocking_task_runner), |
| 122 observer_(observer), | 127 observer_(observer), |
| 123 metadata_(metadata), | 128 metadata_(metadata), |
| 124 weak_ptr_factory_(this) { | 129 weak_ptr_factory_(this) { |
| 125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 126 } | 131 } |
| 127 | 132 |
| 128 CreateDirectoryOperation::~CreateDirectoryOperation() { | 133 CreateDirectoryOperation::~CreateDirectoryOperation() { |
| 129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 130 } | 135 } |
| 131 | 136 |
| 132 void CreateDirectoryOperation::CreateDirectory( | 137 void CreateDirectoryOperation::CreateDirectory( |
| 133 const base::FilePath& directory_path, | 138 const base::FilePath& directory_path, |
| 134 bool is_exclusive, | 139 bool is_exclusive, |
| 135 bool is_recursive, | 140 bool is_recursive, |
| 136 const FileOperationCallback& callback) { | 141 const FileOperationCallback& callback) { |
| 137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 138 DCHECK(!callback.is_null()); | 143 DCHECK(!callback.is_null()); |
| 139 | 144 |
| 140 std::set<std::string>* updated_local_ids = new std::set<std::string>; | 145 std::set<std::string>* updated_local_ids = new std::set<std::string>; |
| 141 std::set<base::FilePath>* changed_directories = new std::set<base::FilePath>; | 146 FileChange* changed_files(new FileChange); |
| 142 base::PostTaskAndReplyWithResult( | 147 base::PostTaskAndReplyWithResult( |
| 143 blocking_task_runner_.get(), | 148 blocking_task_runner_.get(), |
| 144 FROM_HERE, | 149 FROM_HERE, |
| 145 base::Bind(&UpdateLocalState, | 150 base::Bind(&UpdateLocalState, |
| 146 metadata_, directory_path, is_exclusive, is_recursive, | 151 metadata_, |
| 147 updated_local_ids, changed_directories), | 152 directory_path, |
| 148 base::Bind(&CreateDirectoryOperation:: | 153 is_exclusive, |
| 149 CreateDirectoryAfterUpdateLocalState, | 154 is_recursive, |
| 150 weak_ptr_factory_.GetWeakPtr(), | 155 updated_local_ids, |
| 151 callback, | 156 changed_files), |
| 152 base::Owned(updated_local_ids), | 157 base::Bind( |
| 153 base::Owned(changed_directories))); | 158 &CreateDirectoryOperation::CreateDirectoryAfterUpdateLocalState, |
| 159 weak_ptr_factory_.GetWeakPtr(), |
| 160 callback, |
| 161 base::Owned(updated_local_ids), |
| 162 base::Owned(changed_files))); |
| 154 } | 163 } |
| 155 | 164 |
| 156 void CreateDirectoryOperation::CreateDirectoryAfterUpdateLocalState( | 165 void CreateDirectoryOperation::CreateDirectoryAfterUpdateLocalState( |
| 157 const FileOperationCallback& callback, | 166 const FileOperationCallback& callback, |
| 158 const std::set<std::string>* updated_local_ids, | 167 const std::set<std::string>* updated_local_ids, |
| 159 const std::set<base::FilePath>* changed_directories, | 168 const FileChange* changed_files, |
| 160 FileError error) { | 169 FileError error) { |
| 161 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 162 DCHECK(!callback.is_null()); | 171 DCHECK(!callback.is_null()); |
| 163 | 172 |
| 164 for (std::set<std::string>::const_iterator it = updated_local_ids->begin(); | 173 for (std::set<std::string>::const_iterator it = updated_local_ids->begin(); |
| 165 it != updated_local_ids->end(); ++it) | 174 it != updated_local_ids->end(); ++it) |
| 166 observer_->OnEntryUpdatedByOperation(*it); | 175 observer_->OnEntryUpdatedByOperation(*it); |
| 167 | 176 |
| 168 for (std::set<base::FilePath>::const_iterator it = | 177 observer_->OnFileChangedByOperation(*changed_files); |
| 169 changed_directories->begin(); it != changed_directories->end(); ++it) | |
| 170 observer_->OnDirectoryChangedByOperation(*it); | |
| 171 | 178 |
| 172 callback.Run(error); | 179 callback.Run(error); |
| 173 } | 180 } |
| 174 | 181 |
| 175 } // namespace file_system | 182 } // namespace file_system |
| 176 } // namespace drive | 183 } // namespace drive |
| OLD | NEW |