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 3// found in the LICENSE file. 4 5#include "chrome/browser/chromeos/file_system_provider/provided_file_system.h" 6 7#include <vector> 8 9#include "base/debug/trace_event.h" 10#include "base/files/file.h" 11#include "chrome/browser/chromeos/file_system_provider/notification_manager.h" 12#include "chrome/browser/chromeos/file_system_provider/operations/abort.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" 15#include "chrome/browser/chromeos/file_system_provider/operations/create_directory.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" 18#include "chrome/browser/chromeos/file_system_provider/operations/get_metadata.h" 19#include "chrome/browser/chromeos/file_system_provider/operations/move_entry.h" 20#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_file.h" 23#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/write_file.h" 26#include "chrome/browser/chromeos/file_system_provider/request_manager.h" 27#include "chrome/browser/profiles/profile.h" 28#include "chrome/common/extensions/api/file_system_provider.h" 29#include "extensions/browser/event_router.h" 30 31namespace net { 32class IOBuffer; 33} // namespace net 34 35namespace chromeos { 36namespace file_system_provider { 37namespace { 38 39// Dicards the result of Abort() when called from the destructor. 40void EmptyStatusCallback(base::File::Error /* result */) { 41} 42 43} // namespace 44 45ProvidedFileSystem::ProvidedFileSystem( 46 Profile* profile, 47 const ProvidedFileSystemInfo& file_system_info) 48 : profile_(profile), 49 event_router_(extensions::EventRouter::Get(profile)), // May be NULL. 50 file_system_info_(file_system_info), 51 notification_manager_( 52 new NotificationManager(profile_, file_system_info_)), 53 request_manager_(notification_manager_.get()), 54 weak_ptr_factory_(this) { 55} 56 57ProvidedFileSystem::~ProvidedFileSystem() { 58 const std::vector<int> request_ids = request_manager_.GetActiveRequestIds(); 59 for (size_t i = 0; i < request_ids.size(); ++i) { 60 Abort(request_ids[i], base::Bind(&EmptyStatusCallback)); 61 } 62} 63 64ProvidedFileSystem::AbortCallback ProvidedFileSystem::RequestUnmount( 65 const storage::AsyncFileUtil::StatusCallback& callback) { 66 const int request_id = request_manager_.CreateRequest( 67 REQUEST_UNMOUNT, 68 scoped_ptr<RequestManager::HandlerInterface>( 69 new operations::Unmount(event_router_, file_system_info_, callback))); 70 if (!request_id) { 71 callback.Run(base::File::FILE_ERROR_SECURITY); 72 return AbortCallback(); 73 } 74 75 return base::Bind( 76 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 77} 78 79ProvidedFileSystem::AbortCallback ProvidedFileSystem::GetMetadata( 80 const base::FilePath& entry_path, 81 MetadataFieldMask fields, 82 const GetMetadataCallback& callback) { 83 const int request_id = request_manager_.CreateRequest( 84 GET_METADATA, 85 scoped_ptr<RequestManager::HandlerInterface>(new operations::GetMetadata( 86 event_router_, file_system_info_, entry_path, fields, callback))); 87 if (!request_id) { 88 callback.Run(make_scoped_ptr<EntryMetadata>(NULL), 89 base::File::FILE_ERROR_SECURITY); 90 return AbortCallback(); 91 } 92 93 return base::Bind( 94 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 95} 96 97ProvidedFileSystem::AbortCallback ProvidedFileSystem::ReadDirectory( 98 const base::FilePath& directory_path, 99 const storage::AsyncFileUtil::ReadDirectoryCallback& callback) { 100 const int request_id = request_manager_.CreateRequest( 101 READ_DIRECTORY, 102 scoped_ptr<RequestManager::HandlerInterface>( 103 new operations::ReadDirectory( 104 event_router_, file_system_info_, directory_path, callback))); 105 if (!request_id) { 106 callback.Run(base::File::FILE_ERROR_SECURITY, 107 storage::AsyncFileUtil::EntryList(), 108 false /* has_more */); 109 return AbortCallback(); 110 } 111 112 return base::Bind( 113 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 114} 115 116ProvidedFileSystem::AbortCallback ProvidedFileSystem::ReadFile( 117 int file_handle, 118 net::IOBuffer* buffer, 119 int64 offset, 120 int length, 121 const ReadChunkReceivedCallback& callback) { 122 TRACE_EVENT1( 123 "file_system_provider", "ProvidedFileSystem::ReadFile", "length", length); 124 const int request_id = request_manager_.CreateRequest( 125 READ_FILE, 126 make_scoped_ptr<RequestManager::HandlerInterface>( 127 new operations::ReadFile(event_router_, 128 file_system_info_, 129 file_handle, 130 buffer, 131 offset, 132 length, 133 callback))); 134 if (!request_id) { 135 callback.Run(0 /* chunk_length */, 136 false /* has_more */, 137 base::File::FILE_ERROR_SECURITY); 138 return AbortCallback(); 139 } 140 141 return base::Bind( 142 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 143} 144 145ProvidedFileSystem::AbortCallback ProvidedFileSystem::OpenFile( 146 const base::FilePath& file_path, 147 OpenFileMode mode, 148 const OpenFileCallback& callback) { 149 const int request_id = request_manager_.CreateRequest( 150 OPEN_FILE, 151 scoped_ptr<RequestManager::HandlerInterface>(new operations::OpenFile( 152 event_router_, file_system_info_, file_path, mode, callback))); 153 if (!request_id) { 154 callback.Run(0 /* file_handle */, base::File::FILE_ERROR_SECURITY); 155 return AbortCallback(); 156 } 157 158 return base::Bind( 159 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 160} 161 162ProvidedFileSystem::AbortCallback ProvidedFileSystem::CloseFile( 163 int file_handle, 164 const storage::AsyncFileUtil::StatusCallback& callback) { 165 const int request_id = request_manager_.CreateRequest( 166 CLOSE_FILE, 167 scoped_ptr<RequestManager::HandlerInterface>(new operations::CloseFile( 168 event_router_, file_system_info_, file_handle, callback))); 169 if (!request_id) { 170 callback.Run(base::File::FILE_ERROR_SECURITY); 171 return AbortCallback(); 172 } 173 174 return base::Bind( 175 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 176} 177 178ProvidedFileSystem::AbortCallback ProvidedFileSystem::CreateDirectory( 179 const base::FilePath& directory_path, 180 bool recursive, 181 const storage::AsyncFileUtil::StatusCallback& callback) { 182 const int request_id = request_manager_.CreateRequest( 183 CREATE_DIRECTORY, 184 scoped_ptr<RequestManager::HandlerInterface>( 185 new operations::CreateDirectory(event_router_, 186 file_system_info_, 187 directory_path, 188 recursive, 189 callback))); 190 if (!request_id) { 191 callback.Run(base::File::FILE_ERROR_SECURITY); 192 return AbortCallback(); 193 } 194 195 return base::Bind( 196 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 197} 198 199ProvidedFileSystem::AbortCallback ProvidedFileSystem::DeleteEntry( 200 const base::FilePath& entry_path, 201 bool recursive, 202 const storage::AsyncFileUtil::StatusCallback& callback) { 203 const int request_id = request_manager_.CreateRequest( 204 DELETE_ENTRY, 205 scoped_ptr<RequestManager::HandlerInterface>(new operations::DeleteEntry( 206 event_router_, file_system_info_, entry_path, recursive, callback))); 207 if (!request_id) { 208 callback.Run(base::File::FILE_ERROR_SECURITY); 209 return AbortCallback(); 210 } 211 212 return base::Bind( 213 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 214} 215 216ProvidedFileSystem::AbortCallback ProvidedFileSystem::CreateFile( 217 const base::FilePath& file_path, 218 const storage::AsyncFileUtil::StatusCallback& callback) { 219 const int request_id = request_manager_.CreateRequest( 220 CREATE_FILE, 221 scoped_ptr<RequestManager::HandlerInterface>(new operations::CreateFile( 222 event_router_, file_system_info_, file_path, callback))); 223 if (!request_id) { 224 callback.Run(base::File::FILE_ERROR_SECURITY); 225 return AbortCallback(); 226 } 227 228 return base::Bind( 229 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 230} 231 232ProvidedFileSystem::AbortCallback ProvidedFileSystem::CopyEntry( 233 const base::FilePath& source_path, 234 const base::FilePath& target_path, 235 const storage::AsyncFileUtil::StatusCallback& callback) { 236 const int request_id = request_manager_.CreateRequest( 237 COPY_ENTRY, 238 scoped_ptr<RequestManager::HandlerInterface>( 239 new operations::CopyEntry(event_router_, 240 file_system_info_, 241 source_path, 242 target_path, 243 callback))); 244 if (!request_id) { 245 callback.Run(base::File::FILE_ERROR_SECURITY); 246 return AbortCallback(); 247 } 248 249 return base::Bind( 250 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 251} 252 253ProvidedFileSystem::AbortCallback ProvidedFileSystem::WriteFile( 254 int file_handle, 255 net::IOBuffer* buffer, 256 int64 offset, 257 int length, 258 const storage::AsyncFileUtil::StatusCallback& callback) { 259 TRACE_EVENT1("file_system_provider", 260 "ProvidedFileSystem::WriteFile", 261 "length", 262 length); 263 const int request_id = request_manager_.CreateRequest( 264 WRITE_FILE, 265 make_scoped_ptr<RequestManager::HandlerInterface>( 266 new operations::WriteFile(event_router_, 267 file_system_info_, 268 file_handle, 269 make_scoped_refptr(buffer), 270 offset, 271 length, 272 callback))); 273 if (!request_id) { 274 callback.Run(base::File::FILE_ERROR_SECURITY); 275 return AbortCallback(); 276 } 277 278 return base::Bind( 279 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 280} 281 282ProvidedFileSystem::AbortCallback ProvidedFileSystem::MoveEntry( 283 const base::FilePath& source_path, 284 const base::FilePath& target_path, 285 const storage::AsyncFileUtil::StatusCallback& callback) { 286 const int request_id = request_manager_.CreateRequest( 287 MOVE_ENTRY, 288 scoped_ptr<RequestManager::HandlerInterface>( 289 new operations::MoveEntry(event_router_, 290 file_system_info_, 291 source_path, 292 target_path, 293 callback))); 294 if (!request_id) { 295 callback.Run(base::File::FILE_ERROR_SECURITY); 296 return AbortCallback(); 297 } 298 299 return base::Bind( 300 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 301} 302 303ProvidedFileSystem::AbortCallback ProvidedFileSystem::Truncate( 304 const base::FilePath& file_path, 305 int64 length, 306 const storage::AsyncFileUtil::StatusCallback& callback) { 307 const int request_id = request_manager_.CreateRequest( 308 TRUNCATE, 309 scoped_ptr<RequestManager::HandlerInterface>(new operations::Truncate( 310 event_router_, file_system_info_, file_path, length, callback))); 311 if (!request_id) { 312 callback.Run(base::File::FILE_ERROR_SECURITY); 313 return AbortCallback(); 314 } 315 316 return base::Bind( 317 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 318} 319 320const ProvidedFileSystemInfo& ProvidedFileSystem::GetFileSystemInfo() const { 321 return file_system_info_; 322} 323 324RequestManager* ProvidedFileSystem::GetRequestManager() { 325 return &request_manager_; 326} 327 328base::WeakPtr<ProvidedFileSystemInterface> ProvidedFileSystem::GetWeakPtr() { 329 return weak_ptr_factory_.GetWeakPtr(); 330} 331 332void ProvidedFileSystem::Abort( 333 int operation_request_id, 334 const storage::AsyncFileUtil::StatusCallback& callback) { 335 request_manager_.RejectRequest(operation_request_id, 336 make_scoped_ptr(new RequestValue()), 337 base::File::FILE_ERROR_ABORT); 338 if (!request_manager_.CreateRequest( 339 ABORT, 340 scoped_ptr<RequestManager::HandlerInterface>( 341 new operations::Abort(event_router_, 342 file_system_info_, 343 operation_request_id, 344 callback)))) { 345 callback.Run(base::File::FILE_ERROR_SECURITY); 346 } 347} 348 349} // namespace file_system_provider 350} // namespace chromeos 351