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

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

Issue 625463002: [fsp] Add support for observing entries and notifying about changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased. For comments see the previous patchset. Created 6 years, 2 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
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/provided_file_system.h" 5 #include "chrome/browser/chromeos/file_system_provider/provided_file_system.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/files/file.h" 10 #include "base/files/file.h"
11 #include "chrome/browser/chromeos/file_system_provider/notification_manager.h" 11 #include "chrome/browser/chromeos/file_system_provider/notification_manager.h"
12 #include "chrome/browser/chromeos/file_system_provider/operations/abort.h" 12 #include "chrome/browser/chromeos/file_system_provider/operations/abort.h"
13 #include "chrome/browser/chromeos/file_system_provider/operations/close_file.h" 13 #include "chrome/browser/chromeos/file_system_provider/operations/close_file.h"
14 #include "chrome/browser/chromeos/file_system_provider/operations/copy_entry.h" 14 #include "chrome/browser/chromeos/file_system_provider/operations/copy_entry.h"
15 #include "chrome/browser/chromeos/file_system_provider/operations/create_directo ry.h" 15 #include "chrome/browser/chromeos/file_system_provider/operations/create_directo ry.h"
16 #include "chrome/browser/chromeos/file_system_provider/operations/create_file.h" 16 #include "chrome/browser/chromeos/file_system_provider/operations/create_file.h"
17 #include "chrome/browser/chromeos/file_system_provider/operations/delete_entry.h " 17 #include "chrome/browser/chromeos/file_system_provider/operations/delete_entry.h "
18 #include "chrome/browser/chromeos/file_system_provider/operations/get_metadata.h " 18 #include "chrome/browser/chromeos/file_system_provider/operations/get_metadata.h "
19 #include "chrome/browser/chromeos/file_system_provider/operations/move_entry.h" 19 #include "chrome/browser/chromeos/file_system_provider/operations/move_entry.h"
20 #include "chrome/browser/chromeos/file_system_provider/operations/observe_direct ory.h"
20 #include "chrome/browser/chromeos/file_system_provider/operations/open_file.h" 21 #include "chrome/browser/chromeos/file_system_provider/operations/open_file.h"
21 #include "chrome/browser/chromeos/file_system_provider/operations/read_directory .h" 22 #include "chrome/browser/chromeos/file_system_provider/operations/read_directory .h"
22 #include "chrome/browser/chromeos/file_system_provider/operations/read_file.h" 23 #include "chrome/browser/chromeos/file_system_provider/operations/read_file.h"
23 #include "chrome/browser/chromeos/file_system_provider/operations/truncate.h" 24 #include "chrome/browser/chromeos/file_system_provider/operations/truncate.h"
24 #include "chrome/browser/chromeos/file_system_provider/operations/unmount.h" 25 #include "chrome/browser/chromeos/file_system_provider/operations/unmount.h"
26 #include "chrome/browser/chromeos/file_system_provider/operations/unobserve_entr y.h"
25 #include "chrome/browser/chromeos/file_system_provider/operations/write_file.h" 27 #include "chrome/browser/chromeos/file_system_provider/operations/write_file.h"
26 #include "chrome/browser/chromeos/file_system_provider/request_manager.h" 28 #include "chrome/browser/chromeos/file_system_provider/request_manager.h"
27 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/common/extensions/api/file_system_provider.h" 30 #include "chrome/common/extensions/api/file_system_provider.h"
29 #include "extensions/browser/event_router.h" 31 #include "extensions/browser/event_router.h"
30 32
31 namespace net { 33 namespace net {
32 class IOBuffer; 34 class IOBuffer;
33 } // namespace net 35 } // namespace net
34 36
35 namespace chromeos { 37 namespace chromeos {
36 namespace file_system_provider { 38 namespace file_system_provider {
37 namespace { 39 namespace {
38 40
39 // Dicards the result of Abort() when called from the destructor. 41 // Discards the result of Abort() when called from the destructor.
40 void EmptyStatusCallback(base::File::Error /* result */) { 42 void EmptyStatusCallback(base::File::Error /* result */) {
41 } 43 }
42 44
43 } // namespace 45 } // namespace
44 46
47 AutoUpdater::AutoUpdater(const base::Closure& update_callback)
48 : update_callback_(update_callback),
49 created_callbacks_(0),
50 pending_callbacks_(0) {
51 }
52
53 base::Closure AutoUpdater::CreateCallback() {
54 ++created_callbacks_;
55 ++pending_callbacks_;
56 return base::Bind(&AutoUpdater::OnPendingCallback, this);
57 }
58
59 void AutoUpdater::OnPendingCallback() {
60 DCHECK_LT(0, pending_callbacks_);
61 if (--pending_callbacks_ == 0)
62 update_callback_.Run();
63 }
64
65 AutoUpdater::~AutoUpdater() {
66 // If no callbacks are created, then we need to invoke updating in the
67 // destructor.
68 if (!created_callbacks_)
69 update_callback_.Run();
70 else if (pending_callbacks_)
71 LOG(ERROR) << "Not all callbacks called. This may happen on shutdown.";
72 }
73
45 ProvidedFileSystem::ProvidedFileSystem( 74 ProvidedFileSystem::ProvidedFileSystem(
46 Profile* profile, 75 Profile* profile,
47 const ProvidedFileSystemInfo& file_system_info) 76 const ProvidedFileSystemInfo& file_system_info)
48 : profile_(profile), 77 : profile_(profile),
49 event_router_(extensions::EventRouter::Get(profile)), // May be NULL. 78 event_router_(extensions::EventRouter::Get(profile)), // May be NULL.
50 file_system_info_(file_system_info), 79 file_system_info_(file_system_info),
51 notification_manager_( 80 notification_manager_(
52 new NotificationManager(profile_, file_system_info_)), 81 new NotificationManager(profile_, file_system_info_)),
53 request_manager_(notification_manager_.get()), 82 request_manager_(new RequestManager(notification_manager_.get())),
54 weak_ptr_factory_(this) { 83 weak_ptr_factory_(this) {
55 } 84 }
56 85
57 ProvidedFileSystem::~ProvidedFileSystem() { 86 ProvidedFileSystem::~ProvidedFileSystem() {
58 const std::vector<int> request_ids = request_manager_.GetActiveRequestIds(); 87 const std::vector<int> request_ids = request_manager_->GetActiveRequestIds();
59 for (size_t i = 0; i < request_ids.size(); ++i) { 88 for (size_t i = 0; i < request_ids.size(); ++i) {
60 Abort(request_ids[i], base::Bind(&EmptyStatusCallback)); 89 Abort(request_ids[i], base::Bind(&EmptyStatusCallback));
61 } 90 }
62 } 91 }
63 92
93 void ProvidedFileSystem::SetEventRouterForTesting(
94 extensions::EventRouter* event_router) {
95 event_router_ = event_router;
96 }
97
98 void ProvidedFileSystem::SetNotificationManagerForTesting(
99 scoped_ptr<NotificationManagerInterface> notification_manager) {
100 notification_manager_ = notification_manager.Pass();
101 request_manager_.reset(new RequestManager(notification_manager_.get()));
102 }
103
64 ProvidedFileSystem::AbortCallback ProvidedFileSystem::RequestUnmount( 104 ProvidedFileSystem::AbortCallback ProvidedFileSystem::RequestUnmount(
65 const storage::AsyncFileUtil::StatusCallback& callback) { 105 const storage::AsyncFileUtil::StatusCallback& callback) {
66 const int request_id = request_manager_.CreateRequest( 106 const int request_id = request_manager_->CreateRequest(
67 REQUEST_UNMOUNT, 107 REQUEST_UNMOUNT,
68 scoped_ptr<RequestManager::HandlerInterface>( 108 scoped_ptr<RequestManager::HandlerInterface>(
69 new operations::Unmount(event_router_, file_system_info_, callback))); 109 new operations::Unmount(event_router_, file_system_info_, callback)));
70 if (!request_id) { 110 if (!request_id) {
71 callback.Run(base::File::FILE_ERROR_SECURITY); 111 callback.Run(base::File::FILE_ERROR_SECURITY);
72 return AbortCallback(); 112 return AbortCallback();
73 } 113 }
74 114
75 return base::Bind( 115 return base::Bind(
76 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 116 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
77 } 117 }
78 118
79 ProvidedFileSystem::AbortCallback ProvidedFileSystem::GetMetadata( 119 ProvidedFileSystem::AbortCallback ProvidedFileSystem::GetMetadata(
80 const base::FilePath& entry_path, 120 const base::FilePath& entry_path,
81 MetadataFieldMask fields, 121 MetadataFieldMask fields,
82 const GetMetadataCallback& callback) { 122 const GetMetadataCallback& callback) {
83 const int request_id = request_manager_.CreateRequest( 123 const int request_id = request_manager_->CreateRequest(
84 GET_METADATA, 124 GET_METADATA,
85 scoped_ptr<RequestManager::HandlerInterface>(new operations::GetMetadata( 125 scoped_ptr<RequestManager::HandlerInterface>(new operations::GetMetadata(
86 event_router_, file_system_info_, entry_path, fields, callback))); 126 event_router_, file_system_info_, entry_path, fields, callback)));
87 if (!request_id) { 127 if (!request_id) {
88 callback.Run(make_scoped_ptr<EntryMetadata>(NULL), 128 callback.Run(make_scoped_ptr<EntryMetadata>(NULL),
89 base::File::FILE_ERROR_SECURITY); 129 base::File::FILE_ERROR_SECURITY);
90 return AbortCallback(); 130 return AbortCallback();
91 } 131 }
92 132
93 return base::Bind( 133 return base::Bind(
94 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 134 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
95 } 135 }
96 136
97 ProvidedFileSystem::AbortCallback ProvidedFileSystem::ReadDirectory( 137 ProvidedFileSystem::AbortCallback ProvidedFileSystem::ReadDirectory(
98 const base::FilePath& directory_path, 138 const base::FilePath& directory_path,
99 const storage::AsyncFileUtil::ReadDirectoryCallback& callback) { 139 const storage::AsyncFileUtil::ReadDirectoryCallback& callback) {
100 const int request_id = request_manager_.CreateRequest( 140 const int request_id = request_manager_->CreateRequest(
101 READ_DIRECTORY, 141 READ_DIRECTORY,
102 scoped_ptr<RequestManager::HandlerInterface>( 142 scoped_ptr<RequestManager::HandlerInterface>(
103 new operations::ReadDirectory( 143 new operations::ReadDirectory(
104 event_router_, file_system_info_, directory_path, callback))); 144 event_router_, file_system_info_, directory_path, callback)));
105 if (!request_id) { 145 if (!request_id) {
106 callback.Run(base::File::FILE_ERROR_SECURITY, 146 callback.Run(base::File::FILE_ERROR_SECURITY,
107 storage::AsyncFileUtil::EntryList(), 147 storage::AsyncFileUtil::EntryList(),
108 false /* has_more */); 148 false /* has_more */);
109 return AbortCallback(); 149 return AbortCallback();
110 } 150 }
111 151
112 return base::Bind( 152 return base::Bind(
113 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 153 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
114 } 154 }
115 155
116 ProvidedFileSystem::AbortCallback ProvidedFileSystem::ReadFile( 156 ProvidedFileSystem::AbortCallback ProvidedFileSystem::ReadFile(
117 int file_handle, 157 int file_handle,
118 net::IOBuffer* buffer, 158 net::IOBuffer* buffer,
119 int64 offset, 159 int64 offset,
120 int length, 160 int length,
121 const ReadChunkReceivedCallback& callback) { 161 const ReadChunkReceivedCallback& callback) {
122 TRACE_EVENT1( 162 TRACE_EVENT1(
123 "file_system_provider", "ProvidedFileSystem::ReadFile", "length", length); 163 "file_system_provider", "ProvidedFileSystem::ReadFile", "length", length);
124 const int request_id = request_manager_.CreateRequest( 164 const int request_id = request_manager_->CreateRequest(
125 READ_FILE, 165 READ_FILE,
126 make_scoped_ptr<RequestManager::HandlerInterface>( 166 make_scoped_ptr<RequestManager::HandlerInterface>(
127 new operations::ReadFile(event_router_, 167 new operations::ReadFile(event_router_,
128 file_system_info_, 168 file_system_info_,
129 file_handle, 169 file_handle,
130 buffer, 170 buffer,
131 offset, 171 offset,
132 length, 172 length,
133 callback))); 173 callback)));
134 if (!request_id) { 174 if (!request_id) {
135 callback.Run(0 /* chunk_length */, 175 callback.Run(0 /* chunk_length */,
136 false /* has_more */, 176 false /* has_more */,
137 base::File::FILE_ERROR_SECURITY); 177 base::File::FILE_ERROR_SECURITY);
138 return AbortCallback(); 178 return AbortCallback();
139 } 179 }
140 180
141 return base::Bind( 181 return base::Bind(
142 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 182 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
143 } 183 }
144 184
145 ProvidedFileSystem::AbortCallback ProvidedFileSystem::OpenFile( 185 ProvidedFileSystem::AbortCallback ProvidedFileSystem::OpenFile(
146 const base::FilePath& file_path, 186 const base::FilePath& file_path,
147 OpenFileMode mode, 187 OpenFileMode mode,
148 const OpenFileCallback& callback) { 188 const OpenFileCallback& callback) {
149 const int request_id = request_manager_.CreateRequest( 189 const int request_id = request_manager_->CreateRequest(
150 OPEN_FILE, 190 OPEN_FILE,
151 scoped_ptr<RequestManager::HandlerInterface>(new operations::OpenFile( 191 scoped_ptr<RequestManager::HandlerInterface>(new operations::OpenFile(
152 event_router_, file_system_info_, file_path, mode, callback))); 192 event_router_, file_system_info_, file_path, mode, callback)));
153 if (!request_id) { 193 if (!request_id) {
154 callback.Run(0 /* file_handle */, base::File::FILE_ERROR_SECURITY); 194 callback.Run(0 /* file_handle */, base::File::FILE_ERROR_SECURITY);
155 return AbortCallback(); 195 return AbortCallback();
156 } 196 }
157 197
158 return base::Bind( 198 return base::Bind(
159 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 199 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
160 } 200 }
161 201
162 ProvidedFileSystem::AbortCallback ProvidedFileSystem::CloseFile( 202 ProvidedFileSystem::AbortCallback ProvidedFileSystem::CloseFile(
163 int file_handle, 203 int file_handle,
164 const storage::AsyncFileUtil::StatusCallback& callback) { 204 const storage::AsyncFileUtil::StatusCallback& callback) {
165 const int request_id = request_manager_.CreateRequest( 205 const int request_id = request_manager_->CreateRequest(
166 CLOSE_FILE, 206 CLOSE_FILE,
167 scoped_ptr<RequestManager::HandlerInterface>(new operations::CloseFile( 207 scoped_ptr<RequestManager::HandlerInterface>(new operations::CloseFile(
168 event_router_, file_system_info_, file_handle, callback))); 208 event_router_, file_system_info_, file_handle, callback)));
169 if (!request_id) { 209 if (!request_id) {
170 callback.Run(base::File::FILE_ERROR_SECURITY); 210 callback.Run(base::File::FILE_ERROR_SECURITY);
171 return AbortCallback(); 211 return AbortCallback();
172 } 212 }
173 213
174 return base::Bind( 214 return base::Bind(
175 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 215 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
176 } 216 }
177 217
178 ProvidedFileSystem::AbortCallback ProvidedFileSystem::CreateDirectory( 218 ProvidedFileSystem::AbortCallback ProvidedFileSystem::CreateDirectory(
179 const base::FilePath& directory_path, 219 const base::FilePath& directory_path,
180 bool recursive, 220 bool recursive,
181 const storage::AsyncFileUtil::StatusCallback& callback) { 221 const storage::AsyncFileUtil::StatusCallback& callback) {
182 const int request_id = request_manager_.CreateRequest( 222 const int request_id = request_manager_->CreateRequest(
183 CREATE_DIRECTORY, 223 CREATE_DIRECTORY,
184 scoped_ptr<RequestManager::HandlerInterface>( 224 scoped_ptr<RequestManager::HandlerInterface>(
185 new operations::CreateDirectory(event_router_, 225 new operations::CreateDirectory(event_router_,
186 file_system_info_, 226 file_system_info_,
187 directory_path, 227 directory_path,
188 recursive, 228 recursive,
189 callback))); 229 callback)));
190 if (!request_id) { 230 if (!request_id) {
191 callback.Run(base::File::FILE_ERROR_SECURITY); 231 callback.Run(base::File::FILE_ERROR_SECURITY);
192 return AbortCallback(); 232 return AbortCallback();
193 } 233 }
194 234
195 return base::Bind( 235 return base::Bind(
196 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 236 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
197 } 237 }
198 238
199 ProvidedFileSystem::AbortCallback ProvidedFileSystem::DeleteEntry( 239 ProvidedFileSystem::AbortCallback ProvidedFileSystem::DeleteEntry(
200 const base::FilePath& entry_path, 240 const base::FilePath& entry_path,
201 bool recursive, 241 bool recursive,
202 const storage::AsyncFileUtil::StatusCallback& callback) { 242 const storage::AsyncFileUtil::StatusCallback& callback) {
203 const int request_id = request_manager_.CreateRequest( 243 const int request_id = request_manager_->CreateRequest(
204 DELETE_ENTRY, 244 DELETE_ENTRY,
205 scoped_ptr<RequestManager::HandlerInterface>(new operations::DeleteEntry( 245 scoped_ptr<RequestManager::HandlerInterface>(new operations::DeleteEntry(
206 event_router_, file_system_info_, entry_path, recursive, callback))); 246 event_router_, file_system_info_, entry_path, recursive, callback)));
207 if (!request_id) { 247 if (!request_id) {
208 callback.Run(base::File::FILE_ERROR_SECURITY); 248 callback.Run(base::File::FILE_ERROR_SECURITY);
209 return AbortCallback(); 249 return AbortCallback();
210 } 250 }
211 251
212 return base::Bind( 252 return base::Bind(
213 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 253 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
214 } 254 }
215 255
216 ProvidedFileSystem::AbortCallback ProvidedFileSystem::CreateFile( 256 ProvidedFileSystem::AbortCallback ProvidedFileSystem::CreateFile(
217 const base::FilePath& file_path, 257 const base::FilePath& file_path,
218 const storage::AsyncFileUtil::StatusCallback& callback) { 258 const storage::AsyncFileUtil::StatusCallback& callback) {
219 const int request_id = request_manager_.CreateRequest( 259 const int request_id = request_manager_->CreateRequest(
220 CREATE_FILE, 260 CREATE_FILE,
221 scoped_ptr<RequestManager::HandlerInterface>(new operations::CreateFile( 261 scoped_ptr<RequestManager::HandlerInterface>(new operations::CreateFile(
222 event_router_, file_system_info_, file_path, callback))); 262 event_router_, file_system_info_, file_path, callback)));
223 if (!request_id) { 263 if (!request_id) {
224 callback.Run(base::File::FILE_ERROR_SECURITY); 264 callback.Run(base::File::FILE_ERROR_SECURITY);
225 return AbortCallback(); 265 return AbortCallback();
226 } 266 }
227 267
228 return base::Bind( 268 return base::Bind(
229 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 269 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
230 } 270 }
231 271
232 ProvidedFileSystem::AbortCallback ProvidedFileSystem::CopyEntry( 272 ProvidedFileSystem::AbortCallback ProvidedFileSystem::CopyEntry(
233 const base::FilePath& source_path, 273 const base::FilePath& source_path,
234 const base::FilePath& target_path, 274 const base::FilePath& target_path,
235 const storage::AsyncFileUtil::StatusCallback& callback) { 275 const storage::AsyncFileUtil::StatusCallback& callback) {
236 const int request_id = request_manager_.CreateRequest( 276 const int request_id = request_manager_->CreateRequest(
237 COPY_ENTRY, 277 COPY_ENTRY,
238 scoped_ptr<RequestManager::HandlerInterface>( 278 scoped_ptr<RequestManager::HandlerInterface>(
239 new operations::CopyEntry(event_router_, 279 new operations::CopyEntry(event_router_,
240 file_system_info_, 280 file_system_info_,
241 source_path, 281 source_path,
242 target_path, 282 target_path,
243 callback))); 283 callback)));
244 if (!request_id) { 284 if (!request_id) {
245 callback.Run(base::File::FILE_ERROR_SECURITY); 285 callback.Run(base::File::FILE_ERROR_SECURITY);
246 return AbortCallback(); 286 return AbortCallback();
247 } 287 }
248 288
249 return base::Bind( 289 return base::Bind(
250 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 290 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
251 } 291 }
252 292
253 ProvidedFileSystem::AbortCallback ProvidedFileSystem::WriteFile( 293 ProvidedFileSystem::AbortCallback ProvidedFileSystem::WriteFile(
254 int file_handle, 294 int file_handle,
255 net::IOBuffer* buffer, 295 net::IOBuffer* buffer,
256 int64 offset, 296 int64 offset,
257 int length, 297 int length,
258 const storage::AsyncFileUtil::StatusCallback& callback) { 298 const storage::AsyncFileUtil::StatusCallback& callback) {
259 TRACE_EVENT1("file_system_provider", 299 TRACE_EVENT1("file_system_provider",
260 "ProvidedFileSystem::WriteFile", 300 "ProvidedFileSystem::WriteFile",
261 "length", 301 "length",
262 length); 302 length);
263 const int request_id = request_manager_.CreateRequest( 303 const int request_id = request_manager_->CreateRequest(
264 WRITE_FILE, 304 WRITE_FILE,
265 make_scoped_ptr<RequestManager::HandlerInterface>( 305 make_scoped_ptr<RequestManager::HandlerInterface>(
266 new operations::WriteFile(event_router_, 306 new operations::WriteFile(event_router_,
267 file_system_info_, 307 file_system_info_,
268 file_handle, 308 file_handle,
269 make_scoped_refptr(buffer), 309 make_scoped_refptr(buffer),
270 offset, 310 offset,
271 length, 311 length,
272 callback))); 312 callback)));
273 if (!request_id) { 313 if (!request_id) {
274 callback.Run(base::File::FILE_ERROR_SECURITY); 314 callback.Run(base::File::FILE_ERROR_SECURITY);
275 return AbortCallback(); 315 return AbortCallback();
276 } 316 }
277 317
278 return base::Bind( 318 return base::Bind(
279 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 319 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
280 } 320 }
281 321
282 ProvidedFileSystem::AbortCallback ProvidedFileSystem::MoveEntry( 322 ProvidedFileSystem::AbortCallback ProvidedFileSystem::MoveEntry(
283 const base::FilePath& source_path, 323 const base::FilePath& source_path,
284 const base::FilePath& target_path, 324 const base::FilePath& target_path,
285 const storage::AsyncFileUtil::StatusCallback& callback) { 325 const storage::AsyncFileUtil::StatusCallback& callback) {
286 const int request_id = request_manager_.CreateRequest( 326 const int request_id = request_manager_->CreateRequest(
287 MOVE_ENTRY, 327 MOVE_ENTRY,
288 scoped_ptr<RequestManager::HandlerInterface>( 328 scoped_ptr<RequestManager::HandlerInterface>(
289 new operations::MoveEntry(event_router_, 329 new operations::MoveEntry(event_router_,
290 file_system_info_, 330 file_system_info_,
291 source_path, 331 source_path,
292 target_path, 332 target_path,
293 callback))); 333 callback)));
294 if (!request_id) { 334 if (!request_id) {
295 callback.Run(base::File::FILE_ERROR_SECURITY); 335 callback.Run(base::File::FILE_ERROR_SECURITY);
296 return AbortCallback(); 336 return AbortCallback();
297 } 337 }
298 338
299 return base::Bind( 339 return base::Bind(
300 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 340 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
301 } 341 }
302 342
303 ProvidedFileSystem::AbortCallback ProvidedFileSystem::Truncate( 343 ProvidedFileSystem::AbortCallback ProvidedFileSystem::Truncate(
304 const base::FilePath& file_path, 344 const base::FilePath& file_path,
305 int64 length, 345 int64 length,
306 const storage::AsyncFileUtil::StatusCallback& callback) { 346 const storage::AsyncFileUtil::StatusCallback& callback) {
307 const int request_id = request_manager_.CreateRequest( 347 const int request_id = request_manager_->CreateRequest(
308 TRUNCATE, 348 TRUNCATE,
309 scoped_ptr<RequestManager::HandlerInterface>(new operations::Truncate( 349 scoped_ptr<RequestManager::HandlerInterface>(new operations::Truncate(
310 event_router_, file_system_info_, file_path, length, callback))); 350 event_router_, file_system_info_, file_path, length, callback)));
311 if (!request_id) { 351 if (!request_id) {
312 callback.Run(base::File::FILE_ERROR_SECURITY); 352 callback.Run(base::File::FILE_ERROR_SECURITY);
313 return AbortCallback(); 353 return AbortCallback();
314 } 354 }
315 355
316 return base::Bind( 356 return base::Bind(
317 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 357 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
318 } 358 }
319 359
360 ProvidedFileSystem::AbortCallback ProvidedFileSystem::ObserveDirectory(
361 const base::FilePath& directory_path,
362 bool recursive,
363 const storage::AsyncFileUtil::StatusCallback& callback) {
364 const ObservedEntries::const_iterator it =
365 observed_entries_.find(directory_path);
366 if (it != observed_entries_.end()) {
367 if (!recursive || it->second.recursive) {
hirono 2014/10/03 07:25:33 The following steps seem succeed. Should it failed
hirono 2014/10/03 07:25:33 recursive = false -> recursive = true succeeds. re
mtomasz 2014/10/03 08:35:34 Good point. It is not easy to solve it though. I w
mtomasz 2014/10/03 08:35:34 Recursive = false -> recursive = true makes sense,
hirono 2014/10/06 02:41:37 SGTM
368 callback.Run(base::File::FILE_ERROR_EXISTS);
369 return AbortCallback();
370 }
371 }
372
hirono 2014/10/03 07:25:33 Should we check the number of observed entries her
mtomasz 2014/10/03 08:35:34 Why? Do you mean for security reasons?
hirono 2014/10/06 02:41:37 I misunderstood. We don't have the upper limit of
373 const int request_id = request_manager_->CreateRequest(
374 OBSERVE_DIRECTORY,
375 scoped_ptr<RequestManager::HandlerInterface>(
376 new operations::ObserveDirectory(
377 event_router_,
378 file_system_info_,
379 directory_path,
380 recursive,
381 base::Bind(&ProvidedFileSystem::OnObserveDirectoryCompleted,
382 weak_ptr_factory_.GetWeakPtr(),
383 directory_path,
384 recursive,
385 callback))));
386 if (!request_id) {
387 callback.Run(base::File::FILE_ERROR_SECURITY);
388 return AbortCallback();
389 }
390
391 return base::Bind(
392 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
393 }
394
395 ProvidedFileSystem::AbortCallback ProvidedFileSystem::UnobserveEntry(
396 const base::FilePath& entry_path,
397 const storage::AsyncFileUtil::StatusCallback& callback) {
398 const ObservedEntries::const_iterator it = observed_entries_.find(entry_path);
399 if (it == observed_entries_.end()) {
400 callback.Run(base::File::FILE_ERROR_NOT_FOUND);
401 return AbortCallback();
402 }
403
404 // Delete the watcher in advance since the list of observed entries is owned
405 // by the C++ layer, not by the extension.
406 observed_entries_.erase(it);
407
408 FOR_EACH_OBSERVER(ProvidedFileSystemObserver,
409 observers_,
410 OnObservedEntryListChanged(file_system_info_));
411
412 // TODO(mtomasz): Consider returning always an OK error code, since for the
413 // callers it's important that the entry is not watched anymore. The watcher
414 // is removed even if the extension returns an error.
415 const int request_id = request_manager_->CreateRequest(
416 UNOBSERVE_ENTRY,
417 scoped_ptr<RequestManager::HandlerInterface>(
418 new operations::UnobserveEntry(
419 event_router_, file_system_info_, entry_path, callback)));
420 if (!request_id) {
421 callback.Run(base::File::FILE_ERROR_SECURITY);
422 return AbortCallback();
423 }
424
425 return base::Bind(
426 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
427 }
428
320 const ProvidedFileSystemInfo& ProvidedFileSystem::GetFileSystemInfo() const { 429 const ProvidedFileSystemInfo& ProvidedFileSystem::GetFileSystemInfo() const {
321 return file_system_info_; 430 return file_system_info_;
322 } 431 }
323 432
324 RequestManager* ProvidedFileSystem::GetRequestManager() { 433 RequestManager* ProvidedFileSystem::GetRequestManager() {
325 return &request_manager_; 434 return request_manager_.get();
435 }
436
437 ProvidedFileSystem::ObservedEntries* ProvidedFileSystem::GetObservedEntries() {
438 return &observed_entries_;
439 }
440
441 void ProvidedFileSystem::AddObserver(ProvidedFileSystemObserver* observer) {
442 DCHECK(observer);
443 observers_.AddObserver(observer);
444 }
445
446 void ProvidedFileSystem::RemoveObserver(ProvidedFileSystemObserver* observer) {
447 DCHECK(observer);
448 observers_.RemoveObserver(observer);
449 }
450
451 bool ProvidedFileSystem::Notify(
452 const base::FilePath& observed_path,
453 ProvidedFileSystemObserver::ChangeType change_type,
454 const ProvidedFileSystemObserver::ChildChanges& child_changes,
455 const std::string& tag) {
456 const ObservedEntries::iterator it = observed_entries_.find(observed_path);
457 if (it == observed_entries_.end())
458 return false;
459
460 // The tag must be provided if and only if it's explicitly supported.
461 if (file_system_info_.supports_notify_tag() == tag.empty())
462 return false;
463
464 scoped_refptr<AutoUpdater> auto_updater(
465 new AutoUpdater(base::Bind(&ProvidedFileSystem::OnNotifyCompleted,
466 weak_ptr_factory_.GetWeakPtr(),
467 observed_path,
468 change_type,
469 it->second.last_tag,
470 tag)));
471
472 FOR_EACH_OBSERVER(ProvidedFileSystemObserver,
473 observers_,
474 OnObservedEntryChanged(file_system_info_,
475 observed_path,
476 change_type,
477 child_changes,
478 auto_updater->CreateCallback()));
479
480 return true;
326 } 481 }
327 482
328 base::WeakPtr<ProvidedFileSystemInterface> ProvidedFileSystem::GetWeakPtr() { 483 base::WeakPtr<ProvidedFileSystemInterface> ProvidedFileSystem::GetWeakPtr() {
329 return weak_ptr_factory_.GetWeakPtr(); 484 return weak_ptr_factory_.GetWeakPtr();
330 } 485 }
331 486
332 void ProvidedFileSystem::Abort( 487 void ProvidedFileSystem::Abort(
333 int operation_request_id, 488 int operation_request_id,
334 const storage::AsyncFileUtil::StatusCallback& callback) { 489 const storage::AsyncFileUtil::StatusCallback& callback) {
335 request_manager_.RejectRequest(operation_request_id, 490 request_manager_->RejectRequest(operation_request_id,
336 make_scoped_ptr(new RequestValue()), 491 make_scoped_ptr(new RequestValue()),
337 base::File::FILE_ERROR_ABORT); 492 base::File::FILE_ERROR_ABORT);
338 if (!request_manager_.CreateRequest( 493 if (!request_manager_->CreateRequest(
339 ABORT, 494 ABORT,
340 scoped_ptr<RequestManager::HandlerInterface>( 495 scoped_ptr<RequestManager::HandlerInterface>(
341 new operations::Abort(event_router_, 496 new operations::Abort(event_router_,
342 file_system_info_, 497 file_system_info_,
343 operation_request_id, 498 operation_request_id,
344 callback)))) { 499 callback)))) {
345 callback.Run(base::File::FILE_ERROR_SECURITY); 500 callback.Run(base::File::FILE_ERROR_SECURITY);
346 } 501 }
347 } 502 }
348 503
504 void ProvidedFileSystem::OnObserveDirectoryCompleted(
505 const base::FilePath& directory_path,
506 bool recursive,
507 const storage::AsyncFileUtil::StatusCallback& callback,
508 base::File::Error result) {
509 if (result != base::File::FILE_OK) {
510 callback.Run(result);
511 return;
512 }
513
514 observed_entries_[directory_path].entry_path = directory_path;
515 observed_entries_[directory_path].recursive |= recursive;
516
517 FOR_EACH_OBSERVER(ProvidedFileSystemObserver,
518 observers_,
519 OnObservedEntryListChanged(file_system_info_));
520
521 callback.Run(result);
522 }
523
524 void ProvidedFileSystem::OnNotifyCompleted(
525 const base::FilePath& observed_path,
526 ProvidedFileSystemObserver::ChangeType change_type,
527 const std::string& last_tag,
528 const std::string& tag) {
529 const ObservedEntries::iterator it = observed_entries_.find(observed_path);
530 // Check if the entry is still observed.
531 if (it == observed_entries_.end())
532 return;
533
534 // Another following notification finished earlier.
535 if (it->second.last_tag != last_tag)
536 return;
537
538 // It's illegal to provide a tag which is not unique. As for now only an error
539 // message is printed, but we may want to pass the error to the providing
540 // extension. TODO(mtomasz): Consider it.
541 if (!tag.empty() && tag == it->second.last_tag)
542 LOG(ERROR) << "Tag specified, but same as the previous one.";
543
544 it->second.last_tag = tag;
545
546 FOR_EACH_OBSERVER(
547 ProvidedFileSystemObserver,
548 observers_,
549 OnObservedEntryTagUpdated(file_system_info_, observed_path));
550
551 // If the observed entry is deleted, then unobserve it.
552 if (change_type == ProvidedFileSystemObserver::DELETED)
553 UnobserveEntry(observed_path, base::Bind(&EmptyStatusCallback));
554 }
555
349 } // namespace file_system_provider 556 } // namespace file_system_provider
350 } // namespace chromeos 557 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698