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 |