OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/file_system_provider/service.h" | 5 #include "chrome/browser/chromeos/file_system_provider/service.h" |
6 | 6 |
7 #include "base/files/file_path.h" | 7 #include "base/files/file_path.h" |
8 #include "base/prefs/pref_service.h" | 8 #include "base/prefs/pref_service.h" |
9 #include "base/prefs/scoped_user_pref_update.h" | 9 #include "base/prefs/scoped_user_pref_update.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 // OnExtensionUnload calls for each installed extension. However, for tests | 53 // OnExtensionUnload calls for each installed extension. However, for tests |
54 // we may still have mounted extensions. | 54 // we may still have mounted extensions. |
55 // TODO(mtomasz): Create a TestingService class and remove this code. | 55 // TODO(mtomasz): Create a TestingService class and remove this code. |
56 ProvidedFileSystemMap::iterator it = file_system_map_.begin(); | 56 ProvidedFileSystemMap::iterator it = file_system_map_.begin(); |
57 while (it != file_system_map_.end()) { | 57 while (it != file_system_map_.end()) { |
58 const std::string file_system_id = | 58 const std::string file_system_id = |
59 it->second->GetFileSystemInfo().file_system_id(); | 59 it->second->GetFileSystemInfo().file_system_id(); |
60 const std::string extension_id = | 60 const std::string extension_id = |
61 it->second->GetFileSystemInfo().extension_id(); | 61 it->second->GetFileSystemInfo().extension_id(); |
62 ++it; | 62 ++it; |
63 const bool unmount_result = UnmountFileSystem( | 63 const base::File::Error unmount_result = UnmountFileSystem( |
64 extension_id, file_system_id, UNMOUNT_REASON_SHUTDOWN); | 64 extension_id, file_system_id, UNMOUNT_REASON_SHUTDOWN); |
65 DCHECK(unmount_result); | 65 DCHECK_EQ(base::File::FILE_OK, unmount_result); |
66 } | 66 } |
67 | 67 |
68 DCHECK_EQ(0u, file_system_map_.size()); | 68 DCHECK_EQ(0u, file_system_map_.size()); |
69 STLDeleteValues(&file_system_map_); | 69 STLDeleteValues(&file_system_map_); |
70 } | 70 } |
71 | 71 |
72 // static | 72 // static |
73 Service* Service::Get(content::BrowserContext* context) { | 73 Service* Service::Get(content::BrowserContext* context) { |
74 return ServiceFactory::Get(context); | 74 return ServiceFactory::Get(context); |
75 } | 75 } |
(...skipping 12 matching lines...) Expand all Loading... |
88 const FileSystemFactoryCallback& factory_callback) { | 88 const FileSystemFactoryCallback& factory_callback) { |
89 DCHECK(!factory_callback.is_null()); | 89 DCHECK(!factory_callback.is_null()); |
90 file_system_factory_ = factory_callback; | 90 file_system_factory_ = factory_callback; |
91 } | 91 } |
92 | 92 |
93 void Service::SetRegistryForTesting(scoped_ptr<RegistryInterface> registry) { | 93 void Service::SetRegistryForTesting(scoped_ptr<RegistryInterface> registry) { |
94 DCHECK(registry); | 94 DCHECK(registry); |
95 registry_.reset(registry.release()); | 95 registry_.reset(registry.release()); |
96 } | 96 } |
97 | 97 |
98 bool Service::MountFileSystem(const std::string& extension_id, | 98 base::File::Error Service::MountFileSystem(const std::string& extension_id, |
99 const MountOptions& options) { | 99 const MountOptions& options) { |
100 DCHECK(thread_checker_.CalledOnValidThread()); | 100 DCHECK(thread_checker_.CalledOnValidThread()); |
101 | 101 |
102 // If already exists a file system provided by the same extension with this | 102 // If already exists a file system provided by the same extension with this |
103 // id, then abort. | 103 // id, then abort. |
104 if (GetProvidedFileSystem(extension_id, options.file_system_id)) { | 104 if (GetProvidedFileSystem(extension_id, options.file_system_id)) { |
105 FOR_EACH_OBSERVER(Observer, | 105 FOR_EACH_OBSERVER(Observer, |
106 observers_, | 106 observers_, |
107 OnProvidedFileSystemMount(ProvidedFileSystemInfo(), | 107 OnProvidedFileSystemMount(ProvidedFileSystemInfo(), |
108 base::File::FILE_ERROR_EXISTS)); | 108 base::File::FILE_ERROR_EXISTS)); |
109 return false; | 109 return base::File::FILE_ERROR_EXISTS; |
110 } | 110 } |
111 | 111 |
112 // Restrict number of file systems to prevent system abusing. | 112 // Restrict number of file systems to prevent system abusing. |
113 if (file_system_map_.size() + 1 > kMaxFileSystems) { | 113 if (file_system_map_.size() + 1 > kMaxFileSystems) { |
114 FOR_EACH_OBSERVER( | 114 FOR_EACH_OBSERVER( |
115 Observer, | 115 Observer, |
116 observers_, | 116 observers_, |
117 OnProvidedFileSystemMount(ProvidedFileSystemInfo(), | 117 OnProvidedFileSystemMount(ProvidedFileSystemInfo(), |
118 base::File::FILE_ERROR_TOO_MANY_OPENED)); | 118 base::File::FILE_ERROR_TOO_MANY_OPENED)); |
119 return false; | 119 return base::File::FILE_ERROR_TOO_MANY_OPENED; |
120 } | 120 } |
121 | 121 |
122 storage::ExternalMountPoints* const mount_points = | 122 storage::ExternalMountPoints* const mount_points = |
123 storage::ExternalMountPoints::GetSystemInstance(); | 123 storage::ExternalMountPoints::GetSystemInstance(); |
124 DCHECK(mount_points); | 124 DCHECK(mount_points); |
125 | 125 |
126 // The mount point path and name are unique per system, since they are system | 126 // The mount point path and name are unique per system, since they are system |
127 // wide. This is necessary for copying between profiles. | 127 // wide. This is necessary for copying between profiles. |
128 const base::FilePath& mount_path = | 128 const base::FilePath& mount_path = |
129 util::GetMountPath(profile_, extension_id, options.file_system_id); | 129 util::GetMountPath(profile_, extension_id, options.file_system_id); |
130 const std::string mount_point_name = mount_path.BaseName().AsUTF8Unsafe(); | 130 const std::string mount_point_name = mount_path.BaseName().AsUTF8Unsafe(); |
131 | 131 |
132 if (!mount_points->RegisterFileSystem(mount_point_name, | 132 if (!mount_points->RegisterFileSystem(mount_point_name, |
133 storage::kFileSystemTypeProvided, | 133 storage::kFileSystemTypeProvided, |
134 storage::FileSystemMountOption(), | 134 storage::FileSystemMountOption(), |
135 mount_path)) { | 135 mount_path)) { |
136 FOR_EACH_OBSERVER( | 136 FOR_EACH_OBSERVER( |
137 Observer, | 137 Observer, |
138 observers_, | 138 observers_, |
139 OnProvidedFileSystemMount(ProvidedFileSystemInfo(), | 139 OnProvidedFileSystemMount(ProvidedFileSystemInfo(), |
140 base::File::FILE_ERROR_INVALID_OPERATION)); | 140 base::File::FILE_ERROR_INVALID_OPERATION)); |
141 return false; | 141 return base::File::FILE_ERROR_INVALID_OPERATION; |
142 } | 142 } |
143 | 143 |
144 // Store the file system descriptor. Use the mount point name as the file | 144 // Store the file system descriptor. Use the mount point name as the file |
145 // system provider file system id. | 145 // system provider file system id. |
146 // Examples: | 146 // Examples: |
147 // file_system_id = hello_world | 147 // file_system_id = hello_world |
148 // mount_point_name = b33f1337-hello_world-5aa5 | 148 // mount_point_name = b33f1337-hello_world-5aa5 |
149 // writable = false | 149 // writable = false |
150 // supports_notify_tag = false | 150 // supports_notify_tag = false |
151 // mount_path = /provided/b33f1337-hello_world-5aa5 | 151 // mount_path = /provided/b33f1337-hello_world-5aa5 |
152 ProvidedFileSystemInfo file_system_info(extension_id, options, mount_path); | 152 ProvidedFileSystemInfo file_system_info(extension_id, options, mount_path); |
153 | 153 |
154 ProvidedFileSystemInterface* file_system = | 154 ProvidedFileSystemInterface* file_system = |
155 file_system_factory_.Run(profile_, file_system_info); | 155 file_system_factory_.Run(profile_, file_system_info); |
156 DCHECK(file_system); | 156 DCHECK(file_system); |
157 file_system_map_[FileSystemKey(extension_id, options.file_system_id)] = | 157 file_system_map_[FileSystemKey(extension_id, options.file_system_id)] = |
158 file_system; | 158 file_system; |
159 mount_point_name_to_key_map_[mount_point_name] = | 159 mount_point_name_to_key_map_[mount_point_name] = |
160 FileSystemKey(extension_id, options.file_system_id); | 160 FileSystemKey(extension_id, options.file_system_id); |
161 registry_->RememberFileSystem(file_system_info, *file_system->GetWatchers()); | 161 registry_->RememberFileSystem(file_system_info, *file_system->GetWatchers()); |
162 | 162 |
163 FOR_EACH_OBSERVER( | 163 FOR_EACH_OBSERVER( |
164 Observer, | 164 Observer, |
165 observers_, | 165 observers_, |
166 OnProvidedFileSystemMount(file_system_info, base::File::FILE_OK)); | 166 OnProvidedFileSystemMount(file_system_info, base::File::FILE_OK)); |
167 | 167 |
168 return true; | 168 return base::File::FILE_OK; |
169 } | 169 } |
170 | 170 |
171 bool Service::UnmountFileSystem(const std::string& extension_id, | 171 base::File::Error Service::UnmountFileSystem(const std::string& extension_id, |
172 const std::string& file_system_id, | 172 const std::string& file_system_id, |
173 UnmountReason reason) { | 173 UnmountReason reason) { |
174 DCHECK(thread_checker_.CalledOnValidThread()); | 174 DCHECK(thread_checker_.CalledOnValidThread()); |
175 | 175 |
176 const ProvidedFileSystemMap::iterator file_system_it = | 176 const ProvidedFileSystemMap::iterator file_system_it = |
177 file_system_map_.find(FileSystemKey(extension_id, file_system_id)); | 177 file_system_map_.find(FileSystemKey(extension_id, file_system_id)); |
178 if (file_system_it == file_system_map_.end()) { | 178 if (file_system_it == file_system_map_.end()) { |
179 const ProvidedFileSystemInfo empty_file_system_info; | 179 const ProvidedFileSystemInfo empty_file_system_info; |
180 FOR_EACH_OBSERVER( | 180 FOR_EACH_OBSERVER( |
181 Observer, | 181 Observer, |
182 observers_, | 182 observers_, |
183 OnProvidedFileSystemUnmount(empty_file_system_info, | 183 OnProvidedFileSystemUnmount(empty_file_system_info, |
184 base::File::FILE_ERROR_NOT_FOUND)); | 184 base::File::FILE_ERROR_NOT_FOUND)); |
185 return false; | 185 return base::File::FILE_ERROR_NOT_FOUND; |
186 } | 186 } |
187 | 187 |
188 storage::ExternalMountPoints* const mount_points = | 188 storage::ExternalMountPoints* const mount_points = |
189 storage::ExternalMountPoints::GetSystemInstance(); | 189 storage::ExternalMountPoints::GetSystemInstance(); |
190 DCHECK(mount_points); | 190 DCHECK(mount_points); |
191 | 191 |
192 const ProvidedFileSystemInfo& file_system_info = | 192 const ProvidedFileSystemInfo& file_system_info = |
193 file_system_it->second->GetFileSystemInfo(); | 193 file_system_it->second->GetFileSystemInfo(); |
194 | 194 |
195 const std::string mount_point_name = | 195 const std::string mount_point_name = |
196 file_system_info.mount_path().BaseName().value(); | 196 file_system_info.mount_path().BaseName().value(); |
197 if (!mount_points->RevokeFileSystem(mount_point_name)) { | 197 if (!mount_points->RevokeFileSystem(mount_point_name)) { |
198 FOR_EACH_OBSERVER( | 198 FOR_EACH_OBSERVER( |
199 Observer, | 199 Observer, |
200 observers_, | 200 observers_, |
201 OnProvidedFileSystemUnmount(file_system_info, | 201 OnProvidedFileSystemUnmount(file_system_info, |
202 base::File::FILE_ERROR_INVALID_OPERATION)); | 202 base::File::FILE_ERROR_INVALID_OPERATION)); |
203 return false; | 203 return base::File::FILE_ERROR_INVALID_OPERATION; |
204 } | 204 } |
205 | 205 |
206 FOR_EACH_OBSERVER( | 206 FOR_EACH_OBSERVER( |
207 Observer, | 207 Observer, |
208 observers_, | 208 observers_, |
209 OnProvidedFileSystemUnmount(file_system_info, base::File::FILE_OK)); | 209 OnProvidedFileSystemUnmount(file_system_info, base::File::FILE_OK)); |
210 | 210 |
211 mount_point_name_to_key_map_.erase(mount_point_name); | 211 mount_point_name_to_key_map_.erase(mount_point_name); |
212 | 212 |
213 if (reason == UNMOUNT_REASON_USER) { | 213 if (reason == UNMOUNT_REASON_USER) { |
214 registry_->ForgetFileSystem(file_system_info.extension_id(), | 214 registry_->ForgetFileSystem(file_system_info.extension_id(), |
215 file_system_info.file_system_id()); | 215 file_system_info.file_system_id()); |
216 } | 216 } |
217 | 217 |
218 delete file_system_it->second; | 218 delete file_system_it->second; |
219 file_system_map_.erase(file_system_it); | 219 file_system_map_.erase(file_system_it); |
220 | 220 |
221 return true; | 221 return base::File::FILE_OK; |
222 } | 222 } |
223 | 223 |
224 bool Service::RequestUnmount(const std::string& extension_id, | 224 bool Service::RequestUnmount(const std::string& extension_id, |
225 const std::string& file_system_id) { | 225 const std::string& file_system_id) { |
226 DCHECK(thread_checker_.CalledOnValidThread()); | 226 DCHECK(thread_checker_.CalledOnValidThread()); |
227 | 227 |
228 ProvidedFileSystemMap::iterator file_system_it = | 228 ProvidedFileSystemMap::iterator file_system_it = |
229 file_system_map_.find(FileSystemKey(extension_id, file_system_id)); | 229 file_system_map_.find(FileSystemKey(extension_id, file_system_id)); |
230 if (file_system_it == file_system_map_.end()) | 230 if (file_system_it == file_system_map_.end()) |
231 return false; | 231 return false; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 extensions::UnloadedExtensionInfo::Reason reason) { | 268 extensions::UnloadedExtensionInfo::Reason reason) { |
269 // Unmount all of the provided file systems associated with this extension. | 269 // Unmount all of the provided file systems associated with this extension. |
270 ProvidedFileSystemMap::iterator it = file_system_map_.begin(); | 270 ProvidedFileSystemMap::iterator it = file_system_map_.begin(); |
271 while (it != file_system_map_.end()) { | 271 while (it != file_system_map_.end()) { |
272 const ProvidedFileSystemInfo& file_system_info = | 272 const ProvidedFileSystemInfo& file_system_info = |
273 it->second->GetFileSystemInfo(); | 273 it->second->GetFileSystemInfo(); |
274 // Advance the iterator beforehand, otherwise it will become invalidated | 274 // Advance the iterator beforehand, otherwise it will become invalidated |
275 // by the UnmountFileSystem() call. | 275 // by the UnmountFileSystem() call. |
276 ++it; | 276 ++it; |
277 if (file_system_info.extension_id() == extension->id()) { | 277 if (file_system_info.extension_id() == extension->id()) { |
278 const bool unmount_result = UnmountFileSystem( | 278 const base::File::Error unmount_result = UnmountFileSystem( |
279 file_system_info.extension_id(), | 279 file_system_info.extension_id(), file_system_info.file_system_id(), |
280 file_system_info.file_system_id(), | |
281 reason == extensions::UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN | 280 reason == extensions::UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN |
282 ? UNMOUNT_REASON_SHUTDOWN | 281 ? UNMOUNT_REASON_SHUTDOWN |
283 : UNMOUNT_REASON_USER); | 282 : UNMOUNT_REASON_USER); |
284 DCHECK(unmount_result); | 283 DCHECK_EQ(base::File::FILE_OK, unmount_result); |
285 } | 284 } |
286 } | 285 } |
287 } | 286 } |
288 | 287 |
289 void Service::OnExtensionLoaded(content::BrowserContext* browser_context, | 288 void Service::OnExtensionLoaded(content::BrowserContext* browser_context, |
290 const extensions::Extension* extension) { | 289 const extensions::Extension* extension) { |
291 scoped_ptr<RegistryInterface::RestoredFileSystems> restored_file_systems = | 290 scoped_ptr<RegistryInterface::RestoredFileSystems> restored_file_systems = |
292 registry_->RestoreFileSystems(extension->id()); | 291 registry_->RestoreFileSystems(extension->id()); |
293 | 292 |
294 for (const auto& restored_file_system : *restored_file_systems) { | 293 for (const auto& restored_file_system : *restored_file_systems) { |
295 const bool result = MountFileSystem(restored_file_system.extension_id, | 294 const base::File::Error result = MountFileSystem( |
296 restored_file_system.options); | 295 restored_file_system.extension_id, restored_file_system.options); |
297 if (!result) { | 296 if (result != base::File::FILE_OK) { |
298 LOG(ERROR) << "Failed to restore a provided file system from " | 297 LOG(ERROR) << "Failed to restore a provided file system from " |
299 << "registry: " << restored_file_system.extension_id << ", " | 298 << "registry: " << restored_file_system.extension_id << ", " |
300 << restored_file_system.options.file_system_id << ", " | 299 << restored_file_system.options.file_system_id << ", " |
301 << restored_file_system.options.display_name << "."; | 300 << restored_file_system.options.display_name << "."; |
302 // Since remounting of the file system failed, then remove it from | 301 // Since remounting of the file system failed, then remove it from |
303 // preferences to avoid remounting it over and over again with a failure. | 302 // preferences to avoid remounting it over and over again with a failure. |
304 registry_->ForgetFileSystem(restored_file_system.extension_id, | 303 registry_->ForgetFileSystem(restored_file_system.extension_id, |
305 restored_file_system.options.file_system_id); | 304 restored_file_system.options.file_system_id); |
306 continue; | 305 continue; |
307 } | 306 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 } | 362 } |
364 | 363 |
365 void Service::OnWatcherListChanged( | 364 void Service::OnWatcherListChanged( |
366 const ProvidedFileSystemInfo& file_system_info, | 365 const ProvidedFileSystemInfo& file_system_info, |
367 const Watchers& watchers) { | 366 const Watchers& watchers) { |
368 registry_->RememberFileSystem(file_system_info, watchers); | 367 registry_->RememberFileSystem(file_system_info, watchers); |
369 } | 368 } |
370 | 369 |
371 } // namespace file_system_provider | 370 } // namespace file_system_provider |
372 } // namespace chromeos | 371 } // namespace chromeos |
OLD | NEW |