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 |