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

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

Issue 194693002: [fsp] Add requestUnmount() method together with the request manager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments. Created 6 years, 9 months 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 | Annotate | Revision Log
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/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "base/values.h"
9 #include "chrome/browser/chromeos/file_system_provider/observer.h" 10 #include "chrome/browser/chromeos/file_system_provider/observer.h"
10 #include "chrome/browser/chromeos/file_system_provider/provided_file_system.h" 11 #include "chrome/browser/chromeos/file_system_provider/provided_file_system.h"
11 #include "chrome/browser/chromeos/file_system_provider/service_factory.h" 12 #include "chrome/browser/chromeos/file_system_provider/service_factory.h"
12 #include "chrome/browser/chromeos/login/user.h" 13 #include "chrome/browser/chromeos/login/user.h"
13 #include "chrome/browser/chromeos/login/user_manager.h" 14 #include "chrome/browser/chromeos/login/user_manager.h"
15 #include "chrome/common/extensions/api/file_system_provider.h"
14 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
17 #include "extensions/browser/event_router.h"
18 #include "extensions/browser/extension_system.h"
15 #include "webkit/browser/fileapi/external_mount_points.h" 19 #include "webkit/browser/fileapi/external_mount_points.h"
16 20
17 namespace chromeos { 21 namespace chromeos {
18 namespace file_system_provider { 22 namespace file_system_provider {
19 namespace { 23 namespace {
20 24
21 // Root mount path for all of the provided file systems. 25 // Root mount path for all of the provided file systems.
22 static const base::FilePath::CharType kProvidedMountPointRoot[] = 26 const base::FilePath::CharType kProvidedMountPointRoot[] =
23 FILE_PATH_LITERAL("/provided"); 27 FILE_PATH_LITERAL("/provided");
24 28
25 // Maximum number of file systems to be mounted in the same time, per profile. 29 // Maximum number of file systems to be mounted in the same time, per profile.
26 static const size_t kMaxFileSystems = 16; 30 const size_t kMaxFileSystems = 16;
27 31
32 // Utility function, which constructs a safe and unique mount point path for
satorux1 2014/03/26 08:15:03 Just start with "Constructs"?
mtomasz 2014/03/26 10:27:42 Done.
33 // the provided file system.
28 base::FilePath GetMountPointPath(Profile* profile, 34 base::FilePath GetMountPointPath(Profile* profile,
29 std::string extension_id, 35 std::string extension_id,
30 int file_system_id) { 36 int file_system_id) {
31 chromeos::User* const user = 37 chromeos::User* const user =
32 chromeos::UserManager::IsInitialized() 38 chromeos::UserManager::IsInitialized()
33 ? chromeos::UserManager::Get()->GetUserByProfile( 39 ? chromeos::UserManager::Get()->GetUserByProfile(
34 profile->GetOriginalProfile()) 40 profile->GetOriginalProfile())
35 : NULL; 41 : NULL;
36 const std::string user_suffix = user ? "-" + user->username_hash() : ""; 42 const std::string user_suffix = user ? "-" + user->username_hash() : "";
37 return base::FilePath(kProvidedMountPointRoot).AppendASCII( 43 return base::FilePath(kProvidedMountPointRoot).AppendASCII(
38 extension_id + "-" + base::IntToString(file_system_id) + user_suffix); 44 extension_id + "-" + base::IntToString(file_system_id) + user_suffix);
39 } 45 }
40 46
47 // Utility function, creates values to be passed to request events. These values
satorux1 2014/03/26 08:15:03 ditto.
mtomasz 2014/03/26 10:27:42 Done.
48 // can be extended by additional fields.
49 scoped_ptr<base::ListValue> CreateRequestValues(int file_system_id,
50 int request_id) {
51 scoped_ptr<base::ListValue> values(new base::ListValue());
52 values->AppendInteger(file_system_id);
53 values->AppendInteger(request_id);
54 return values.Pass();
55 }
56
41 } // namespace 57 } // namespace
42 58
43 Service::Service(Profile* profile) : profile_(profile), next_id_(1) {} 59 Service::Service(Profile* profile)
60 : profile_(profile), next_id_(1), weak_ptr_factory_(this) {
61 AddObserver(&request_manager_);
62 }
44 63
45 Service::~Service() {} 64 Service::~Service() {}
46 65
47 // static 66 // static
48 Service* Service::Get(content::BrowserContext* context) { 67 Service* Service::Get(content::BrowserContext* context) {
49 return ServiceFactory::Get(context); 68 return ServiceFactory::Get(context);
50 } 69 }
51 70
52 void Service::AddObserver(Observer* observer) { 71 void Service::AddObserver(Observer* observer) {
53 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 72 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
54 DCHECK(observer); 73 DCHECK(observer);
55 observers_.AddObserver(observer); 74 observers_.AddObserver(observer);
56 } 75 }
57 76
58 void Service::RemoveObserver(Observer* observer) { 77 void Service::RemoveObserver(Observer* observer) {
59 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 78 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
60 DCHECK(observer); 79 DCHECK(observer);
61 observers_.RemoveObserver(observer); 80 observers_.RemoveObserver(observer);
62 } 81 }
63 82
64 int Service::RegisterFileSystem(const std::string& extension_id, 83 int Service::MountFileSystem(const std::string& extension_id,
65 const std::string& file_system_name) { 84 const std::string& file_system_name) {
66 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 85 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
67 86
68 // Restrict number of file systems to prevent system abusing. 87 // Restrict number of file systems to prevent system abusing.
69 if (file_systems_.size() + 1 > kMaxFileSystems) 88 if (file_systems_.size() + 1 > kMaxFileSystems) {
89 FOR_EACH_OBSERVER(
90 Observer,
91 observers_,
92 OnProvidedFileSystemMount(ProvidedFileSystem(),
93 base::File::FILE_ERROR_TOO_MANY_OPENED));
70 return 0; 94 return 0;
95 }
71 96
72 // The file system id is unique per service, so per profile. 97 // The file system id is unique per service, so per profile.
73 int file_system_id = next_id_; 98 int file_system_id = next_id_;
74 99
75 fileapi::ExternalMountPoints* const mount_points = 100 fileapi::ExternalMountPoints* const mount_points =
76 fileapi::ExternalMountPoints::GetSystemInstance(); 101 fileapi::ExternalMountPoints::GetSystemInstance();
77 DCHECK(mount_points); 102 DCHECK(mount_points);
78 103
79 // The mount point path and name are unique per system, since they are system 104 // The mount point path and name are unique per system, since they are system
80 // wide. This is necessary for copying between profiles. 105 // wide. This is necessary for copying between profiles.
81 const base::FilePath& mount_point_path = 106 const base::FilePath& mount_point_path =
82 GetMountPointPath(profile_, extension_id, file_system_id); 107 GetMountPointPath(profile_, extension_id, file_system_id);
83 const std::string mount_point_name = 108 const std::string mount_point_name =
84 mount_point_path.BaseName().AsUTF8Unsafe(); 109 mount_point_path.BaseName().AsUTF8Unsafe();
85 110
86 if (!mount_points->RegisterFileSystem(mount_point_name, 111 if (!mount_points->RegisterFileSystem(mount_point_name,
87 fileapi::kFileSystemTypeProvided, 112 fileapi::kFileSystemTypeProvided,
88 fileapi::FileSystemMountOption(), 113 fileapi::FileSystemMountOption(),
89 mount_point_path)) { 114 mount_point_path)) {
115 FOR_EACH_OBSERVER(
116 Observer,
117 observers_,
118 OnProvidedFileSystemMount(ProvidedFileSystem(),
119 base::File::FILE_ERROR_INVALID_OPERATION));
90 return 0; 120 return 0;
91 } 121 }
92 122
93 // Store the file system descriptor. Use the mount point name as the file 123 // Store the file system descriptor. Use the mount point name as the file
94 // system provider file system id. 124 // system provider file system id.
95 // Examples: 125 // Examples:
96 // file_system_id = 41 126 // file_system_id = 41
97 // mount_point_name = file_system_id = b33f1337-41-5aa5 127 // mount_point_name = file_system_id = b33f1337-41-5aa5
98 // mount_point_path = /provided/b33f1337-41-5aa5 128 // mount_point_path = /provided/b33f1337-41-5aa5
99 ProvidedFileSystem file_system( 129 ProvidedFileSystem file_system(
100 extension_id, file_system_id, file_system_name, mount_point_path); 130 extension_id, file_system_id, file_system_name, mount_point_path);
101 file_systems_[file_system_id] = file_system; 131 file_systems_[file_system_id] = file_system;
102 132
103 FOR_EACH_OBSERVER( 133 FOR_EACH_OBSERVER(
104 Observer, observers_, OnProvidedFileSystemRegistered(file_system)); 134 Observer,
135 observers_,
136 OnProvidedFileSystemMount(file_system, base::File::FILE_OK));
105 137
106 next_id_++; 138 next_id_++;
107 return file_system_id; 139 return file_system_id;
108 } 140 }
109 141
110 bool Service::UnregisterFileSystem(const std::string& extension_id, 142 bool Service::UnmountFileSystem(const std::string& extension_id,
111 int file_system_id) { 143 int file_system_id) {
112 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 144 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
113 145
114 FileSystemMap::iterator file_system_it = file_systems_.find(file_system_id); 146 FileSystemMap::iterator file_system_it = file_systems_.find(file_system_id);
115 if (file_system_it == file_systems_.end() || 147 if (file_system_it == file_systems_.end() ||
116 file_system_it->second.extension_id() != extension_id) { 148 file_system_it->second.extension_id() != extension_id) {
149 const ProvidedFileSystem empty_file_system;
150 FOR_EACH_OBSERVER(Observer,
151 observers_,
152 OnProvidedFileSystemUnmount(
153 empty_file_system, base::File::FILE_ERROR_NOT_FOUND));
117 return false; 154 return false;
118 } 155 }
119 156
120 fileapi::ExternalMountPoints* const mount_points = 157 fileapi::ExternalMountPoints* const mount_points =
121 fileapi::ExternalMountPoints::GetSystemInstance(); 158 fileapi::ExternalMountPoints::GetSystemInstance();
122 DCHECK(mount_points); 159 DCHECK(mount_points);
123 160
124 const std::string mount_point_name = 161 const std::string mount_point_name =
125 file_system_it->second.mount_path().BaseName().value(); 162 file_system_it->second.mount_path().BaseName().value();
126 if (!mount_points->RevokeFileSystem(mount_point_name)) 163 if (!mount_points->RevokeFileSystem(mount_point_name)) {
164 FOR_EACH_OBSERVER(
165 Observer,
166 observers_,
167 OnProvidedFileSystemUnmount(file_system_it->second,
168 base::File::FILE_ERROR_INVALID_OPERATION));
127 return false; 169 return false;
170 }
128 171
129 FOR_EACH_OBSERVER(Observer, 172 FOR_EACH_OBSERVER(
130 observers_, 173 Observer,
131 OnProvidedFileSystemUnregistered(file_system_it->second)); 174 observers_,
175 OnProvidedFileSystemUnmount(file_system_it->second, base::File::FILE_OK));
132 176
133 file_systems_.erase(file_system_it); 177 file_systems_.erase(file_system_it);
134 return true; 178 return true;
135 } 179 }
136 180
137 std::vector<ProvidedFileSystem> Service::GetRegisteredFileSystems() { 181 std::vector<ProvidedFileSystem> Service::GetMountedFileSystems() {
138 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 182 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
139 183
140 std::vector<ProvidedFileSystem> result; 184 std::vector<ProvidedFileSystem> result;
141 for (FileSystemMap::const_iterator it = file_systems_.begin(); 185 for (FileSystemMap::const_iterator it = file_systems_.begin();
142 it != file_systems_.end(); 186 it != file_systems_.end();
143 ++it) { 187 ++it) {
144 result.push_back(it->second); 188 result.push_back(it->second);
145 } 189 }
146 return result; 190 return result;
147 } 191 }
148 192
193 bool Service::FulfillRequest(const std::string& extension_id,
194 int file_system_id,
195 int request_id,
196 scoped_ptr<base::DictionaryValue> result,
197 bool has_next) {
198 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
199
200 FileSystemMap::iterator file_system_it = file_systems_.find(file_system_id);
201 if (file_system_it == file_systems_.end() ||
202 file_system_it->second.extension_id() != extension_id) {
203 return false;
204 }
205
206 return request_manager_.FulfillRequest(
207 file_system_it->second, request_id, result.Pass(), has_next);
208 }
209
210 bool Service::RejectRequest(const std::string& extension_id,
211 int file_system_id,
212 int request_id,
213 base::File::Error error) {
214 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
215
216 FileSystemMap::iterator file_system_it = file_systems_.find(file_system_id);
217 if (file_system_it == file_systems_.end() ||
218 file_system_it->second.extension_id() != extension_id) {
219 return false;
220 }
221
222 return request_manager_.RejectRequest(
223 file_system_it->second, request_id, error);
224 }
225
226 bool Service::RequestUnmount(int file_system_id) {
227 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
228
229 FileSystemMap::iterator file_system_it = file_systems_.find(file_system_id);
230 if (file_system_it == file_systems_.end())
231 return false;
232
233 int request_id =
234 request_manager_.CreateRequest(file_system_it->second,
235 SuccessCallback(),
236 base::Bind(&Service::OnRequestUnmountError,
237 weak_ptr_factory_.GetWeakPtr(),
238 file_system_it->second));
239
240 if (!request_id)
241 return false;
242
243 scoped_ptr<base::ListValue> values(
244 CreateRequestValues(file_system_id, request_id));
245
246 extensions::EventRouter* event_router =
247 extensions::ExtensionSystem::Get(profile_)->event_router();
248 DCHECK(event_router);
249
250 event_router->DispatchEventToExtension(
251 file_system_it->second.extension_id(),
252 make_scoped_ptr(new extensions::Event(
253 extensions::api::file_system_provider::OnUnmountRequested::kEventName,
254 values.Pass())));
255
256 return true;
257 }
258
259 void Service::Shutdown() { RemoveObserver(&request_manager_); }
260
261 void Service::OnRequestUnmountError(const ProvidedFileSystem& file_system,
262 base::File::Error error) {
263 FOR_EACH_OBSERVER(
264 Observer, observers_, OnProvidedFileSystemUnmount(file_system, error));
265 }
266
149 } // namespace file_system_provider 267 } // namespace file_system_provider
150 } // namespace chromeos 268 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698