Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(324)

Side by Side Diff: chrome/browser/chromeos/file_system_provider/service.cc

Issue 703123003: [fsp] Pass more detailed errors to the providing extension. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed a bug. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698