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

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

Powered by Google App Engine
This is Rietveld 408576698