1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/filesystem/GetFileOrDirectoryTask.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,223 @@ 1.4 +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "GetFileOrDirectoryTask.h" 1.11 + 1.12 +#include "js/Value.h" 1.13 +#include "mozilla/dom/Directory.h" 1.14 +#include "mozilla/dom/FileSystemBase.h" 1.15 +#include "mozilla/dom/FileSystemUtils.h" 1.16 +#include "mozilla/dom/Promise.h" 1.17 +#include "nsDOMFile.h" 1.18 +#include "nsIFile.h" 1.19 +#include "nsStringGlue.h" 1.20 + 1.21 +namespace mozilla { 1.22 +namespace dom { 1.23 + 1.24 +GetFileOrDirectoryTask::GetFileOrDirectoryTask( 1.25 + FileSystemBase* aFileSystem, 1.26 + const nsAString& aTargetPath, 1.27 + bool aDirectoryOnly) 1.28 + : FileSystemTaskBase(aFileSystem) 1.29 + , mTargetRealPath(aTargetPath) 1.30 + , mIsDirectory(aDirectoryOnly) 1.31 +{ 1.32 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.33 + MOZ_ASSERT(aFileSystem); 1.34 + nsCOMPtr<nsIGlobalObject> globalObject = 1.35 + do_QueryInterface(aFileSystem->GetWindow()); 1.36 + if (!globalObject) { 1.37 + return; 1.38 + } 1.39 + mPromise = new Promise(globalObject); 1.40 +} 1.41 + 1.42 +GetFileOrDirectoryTask::GetFileOrDirectoryTask( 1.43 + FileSystemBase* aFileSystem, 1.44 + const FileSystemGetFileOrDirectoryParams& aParam, 1.45 + FileSystemRequestParent* aParent) 1.46 + : FileSystemTaskBase(aFileSystem, aParam, aParent) 1.47 + , mIsDirectory(false) 1.48 +{ 1.49 + MOZ_ASSERT(FileSystemUtils::IsParentProcess(), 1.50 + "Only call from parent process!"); 1.51 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.52 + MOZ_ASSERT(aFileSystem); 1.53 + mTargetRealPath = aParam.realPath(); 1.54 +} 1.55 + 1.56 +GetFileOrDirectoryTask::~GetFileOrDirectoryTask() 1.57 +{ 1.58 + MOZ_ASSERT(!mPromise || NS_IsMainThread(), 1.59 + "mPromise should be released on main thread!"); 1.60 +} 1.61 + 1.62 +already_AddRefed<Promise> 1.63 +GetFileOrDirectoryTask::GetPromise() 1.64 +{ 1.65 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.66 + return nsRefPtr<Promise>(mPromise).forget(); 1.67 +} 1.68 + 1.69 +FileSystemParams 1.70 +GetFileOrDirectoryTask::GetRequestParams(const nsString& aFileSystem) const 1.71 +{ 1.72 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.73 + return FileSystemGetFileOrDirectoryParams(aFileSystem, mTargetRealPath); 1.74 +} 1.75 + 1.76 +FileSystemResponseValue 1.77 +GetFileOrDirectoryTask::GetSuccessRequestResult() const 1.78 +{ 1.79 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.80 + if (mIsDirectory) { 1.81 + return FileSystemDirectoryResponse(mTargetRealPath); 1.82 + } 1.83 + BlobParent* actor = GetBlobParent(mTargetFile); 1.84 + if (!actor) { 1.85 + return FileSystemErrorResponse(NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR); 1.86 + } 1.87 + FileSystemFileResponse response; 1.88 + response.blobParent() = actor; 1.89 + return response; 1.90 +} 1.91 + 1.92 +void 1.93 +GetFileOrDirectoryTask::SetSuccessRequestResult(const FileSystemResponseValue& aValue) 1.94 +{ 1.95 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.96 + switch (aValue.type()) { 1.97 + case FileSystemResponseValue::TFileSystemFileResponse: { 1.98 + FileSystemFileResponse r = aValue; 1.99 + BlobChild* actor = static_cast<BlobChild*>(r.blobChild()); 1.100 + nsCOMPtr<nsIDOMBlob> blob = actor->GetBlob(); 1.101 + mTargetFile = do_QueryInterface(blob); 1.102 + mIsDirectory = false; 1.103 + break; 1.104 + } 1.105 + case FileSystemResponseValue::TFileSystemDirectoryResponse: { 1.106 + FileSystemDirectoryResponse r = aValue; 1.107 + mTargetRealPath = r.realPath(); 1.108 + mIsDirectory = true; 1.109 + break; 1.110 + } 1.111 + default: { 1.112 + NS_RUNTIMEABORT("not reached"); 1.113 + break; 1.114 + } 1.115 + } 1.116 +} 1.117 + 1.118 +nsresult 1.119 +GetFileOrDirectoryTask::Work() 1.120 +{ 1.121 + MOZ_ASSERT(FileSystemUtils::IsParentProcess(), 1.122 + "Only call from parent process!"); 1.123 + MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!"); 1.124 + 1.125 + if (mFileSystem->IsShutdown()) { 1.126 + return NS_ERROR_FAILURE; 1.127 + } 1.128 + 1.129 + // Whether we want to get the root directory. 1.130 + bool getRoot = mTargetRealPath.IsEmpty(); 1.131 + 1.132 + nsCOMPtr<nsIFile> file = mFileSystem->GetLocalFile(mTargetRealPath); 1.133 + if (!file) { 1.134 + return NS_ERROR_DOM_FILESYSTEM_INVALID_PATH_ERR; 1.135 + } 1.136 + 1.137 + bool exists; 1.138 + nsresult rv = file->Exists(&exists); 1.139 + if (NS_WARN_IF(NS_FAILED(rv))) { 1.140 + return rv; 1.141 + } 1.142 + 1.143 + if (!exists) { 1.144 + if (!getRoot) { 1.145 + return NS_ERROR_DOM_FILE_NOT_FOUND_ERR; 1.146 + } 1.147 + 1.148 + // If the root directory doesn't exit, create it. 1.149 + rv = file->Create(nsIFile::DIRECTORY_TYPE, 0777); 1.150 + if (NS_WARN_IF(NS_FAILED(rv))) { 1.151 + return rv; 1.152 + } 1.153 + } 1.154 + 1.155 + // Get isDirectory. 1.156 + rv = file->IsDirectory(&mIsDirectory); 1.157 + if (NS_WARN_IF(NS_FAILED(rv))) { 1.158 + return rv; 1.159 + } 1.160 + 1.161 + if (mIsDirectory) { 1.162 + return NS_OK; 1.163 + } 1.164 + 1.165 + // Check if the root is a directory. 1.166 + if (getRoot) { 1.167 + return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR; 1.168 + } 1.169 + 1.170 + bool isFile; 1.171 + // Get isFile 1.172 + rv = file->IsFile(&isFile); 1.173 + if (NS_WARN_IF(NS_FAILED(rv))) { 1.174 + return rv; 1.175 + } 1.176 + 1.177 + if (!isFile) { 1.178 + // Neither directory or file. 1.179 + return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR; 1.180 + } 1.181 + 1.182 + if (!mFileSystem->IsSafeFile(file)) { 1.183 + return NS_ERROR_DOM_SECURITY_ERR; 1.184 + } 1.185 + 1.186 + mTargetFile = new nsDOMFileFile(file); 1.187 + 1.188 + return NS_OK; 1.189 +} 1.190 + 1.191 +void 1.192 +GetFileOrDirectoryTask::HandlerCallback() 1.193 +{ 1.194 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.195 + if (mFileSystem->IsShutdown()) { 1.196 + mPromise = nullptr; 1.197 + return; 1.198 + } 1.199 + 1.200 + if (HasError()) { 1.201 + nsRefPtr<DOMError> domError = new DOMError(mFileSystem->GetWindow(), 1.202 + mErrorValue); 1.203 + mPromise->MaybeReject(domError); 1.204 + mPromise = nullptr; 1.205 + return; 1.206 + } 1.207 + 1.208 + if (mIsDirectory) { 1.209 + nsRefPtr<Directory> dir = new Directory(mFileSystem, mTargetRealPath); 1.210 + mPromise->MaybeResolve(dir); 1.211 + mPromise = nullptr; 1.212 + return; 1.213 + } 1.214 + 1.215 + mPromise->MaybeResolve(mTargetFile); 1.216 + mPromise = nullptr; 1.217 +} 1.218 + 1.219 +void 1.220 +GetFileOrDirectoryTask::GetPermissionAccessType(nsCString& aAccess) const 1.221 +{ 1.222 + aAccess.AssignLiteral("read"); 1.223 +} 1.224 + 1.225 +} // namespace dom 1.226 +} // namespace mozilla