tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

GetFilesTask.cpp (7019B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "GetFilesTask.h"
      8 
      9 #include "HTMLSplitOnSpacesTokenizer.h"
     10 #include "js/Value.h"
     11 #include "mozilla/dom/BlobImpl.h"
     12 #include "mozilla/dom/File.h"
     13 #include "mozilla/dom/FileSystemBase.h"
     14 #include "mozilla/dom/FileSystemUtils.h"
     15 #include "mozilla/dom/IPCBlobUtils.h"
     16 #include "mozilla/dom/PFileSystemParams.h"
     17 #include "mozilla/dom/Promise.h"
     18 #include "mozilla/ipc/BackgroundParent.h"
     19 #include "nsIFile.h"
     20 #include "nsString.h"
     21 
     22 namespace mozilla::dom {
     23 
     24 /**
     25 * GetFilesTaskChild
     26 */
     27 
     28 /* static */
     29 already_AddRefed<GetFilesTaskChild> GetFilesTaskChild::Create(
     30    FileSystemBase* aFileSystem, Directory* aDirectory, nsIFile* aTargetPath,
     31    bool aRecursiveFlag, ErrorResult& aRv) {
     32  MOZ_ASSERT(aFileSystem);
     33  MOZ_ASSERT(aDirectory);
     34  aFileSystem->AssertIsOnOwningThread();
     35 
     36  nsCOMPtr<nsIGlobalObject> globalObject = aFileSystem->GetParentObject();
     37  if (NS_WARN_IF(!globalObject)) {
     38    aRv.Throw(NS_ERROR_FAILURE);
     39    return nullptr;
     40  }
     41 
     42  RefPtr<GetFilesTaskChild> task = new GetFilesTaskChild(
     43      globalObject, aFileSystem, aDirectory, aTargetPath, aRecursiveFlag);
     44 
     45  // aTargetPath can be null. In this case SetError will be called.
     46 
     47  task->mPromise = Promise::Create(globalObject, aRv);
     48  if (NS_WARN_IF(aRv.Failed())) {
     49    return nullptr;
     50  }
     51 
     52  return task.forget();
     53 }
     54 
     55 GetFilesTaskChild::GetFilesTaskChild(nsIGlobalObject* aGlobalObject,
     56                                     FileSystemBase* aFileSystem,
     57                                     Directory* aDirectory,
     58                                     nsIFile* aTargetPath, bool aRecursiveFlag)
     59    : FileSystemTaskChildBase(aGlobalObject, aFileSystem),
     60      mDirectory(aDirectory),
     61      mTargetPath(aTargetPath),
     62      mRecursiveFlag(aRecursiveFlag) {
     63  MOZ_ASSERT(aFileSystem);
     64  MOZ_ASSERT(aDirectory);
     65  aFileSystem->AssertIsOnOwningThread();
     66 }
     67 
     68 GetFilesTaskChild::~GetFilesTaskChild() {
     69  mFileSystem->AssertIsOnOwningThread();
     70 }
     71 
     72 already_AddRefed<Promise> GetFilesTaskChild::GetPromise() {
     73  mFileSystem->AssertIsOnOwningThread();
     74  return RefPtr<Promise>(mPromise).forget();
     75 }
     76 
     77 FileSystemParams GetFilesTaskChild::GetRequestParams(
     78    const nsString& aSerializedDOMPath, ErrorResult& aRv) const {
     79  mFileSystem->AssertIsOnOwningThread();
     80 
     81  nsAutoString path;
     82  aRv = mTargetPath->GetPath(path);
     83  if (NS_WARN_IF(aRv.Failed())) {
     84    return FileSystemGetFilesParams();
     85  }
     86 
     87  nsAutoString domPath;
     88  mDirectory->GetPath(domPath, aRv);
     89  if (NS_WARN_IF(aRv.Failed())) {
     90    return FileSystemGetFilesParams();
     91  }
     92 
     93  return FileSystemGetFilesParams(aSerializedDOMPath, path, domPath,
     94                                  mRecursiveFlag);
     95 }
     96 
     97 void GetFilesTaskChild::SetSuccessRequestResult(
     98    const FileSystemResponseValue& aValue, ErrorResult& aRv) {
     99  mFileSystem->AssertIsOnOwningThread();
    100  MOZ_ASSERT(aValue.type() ==
    101             FileSystemResponseValue::TFileSystemFilesResponse);
    102 
    103  FileSystemFilesResponse r = aValue;
    104 
    105  if (!mTargetData.SetLength(r.data().Length(), mozilla::fallible_t())) {
    106    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    107    return;
    108  }
    109 
    110  nsCOMPtr<nsIGlobalObject> globalObject = mFileSystem->GetParentObject();
    111  MOZ_ASSERT(globalObject);
    112 
    113  for (uint32_t i = 0; i < r.data().Length(); ++i) {
    114    const FileSystemFileResponse& data = r.data()[i];
    115    RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(data.blob());
    116    MOZ_ASSERT(blobImpl);
    117 
    118    mTargetData[i] = File::Create(globalObject, blobImpl);
    119    if (NS_WARN_IF(!mTargetData[i])) {
    120      aRv.Throw(NS_ERROR_FAILURE);
    121      return;
    122    }
    123  }
    124 }
    125 
    126 void GetFilesTaskChild::HandlerCallback() {
    127  mFileSystem->AssertIsOnOwningThread();
    128  if (mFileSystem->IsShutdown()) {
    129    mPromise = nullptr;
    130    return;
    131  }
    132 
    133  if (HasError()) {
    134    mPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
    135    mPromise = nullptr;
    136    return;
    137  }
    138 
    139  mPromise->MaybeResolve(mTargetData);
    140  mPromise = nullptr;
    141 }
    142 
    143 /**
    144 * GetFilesTaskParent
    145 */
    146 
    147 /* static */
    148 already_AddRefed<GetFilesTaskParent> GetFilesTaskParent::Create(
    149    FileSystemBase* aFileSystem, const FileSystemGetFilesParams& aParam,
    150    FileSystemRequestParent* aParent, ErrorResult& aRv) {
    151  MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
    152  mozilla::ipc::AssertIsOnBackgroundThread();
    153  MOZ_ASSERT(aFileSystem);
    154 
    155  RefPtr<GetFilesTaskParent> task =
    156      new GetFilesTaskParent(aFileSystem, aParam, aParent);
    157 
    158  aRv = NS_NewLocalFile(aParam.realPath(), getter_AddRefs(task->mTargetPath));
    159  if (NS_WARN_IF(aRv.Failed())) {
    160    return nullptr;
    161  }
    162 
    163  return task.forget();
    164 }
    165 
    166 GetFilesTaskParent::GetFilesTaskParent(FileSystemBase* aFileSystem,
    167                                       const FileSystemGetFilesParams& aParam,
    168                                       FileSystemRequestParent* aParent)
    169    : FileSystemTaskParentBase(aFileSystem, aParam, aParent),
    170      GetFilesHelperBase(aParam.recursiveFlag()),
    171      mDirectoryDOMPath(aParam.domPath()) {
    172  MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
    173  mozilla::ipc::AssertIsOnBackgroundThread();
    174  MOZ_ASSERT(aFileSystem);
    175 }
    176 
    177 FileSystemResponseValue GetFilesTaskParent::GetSuccessRequestResult(
    178    ErrorResult& aRv) const {
    179  mozilla::ipc::AssertIsOnBackgroundThread();
    180 
    181  FallibleTArray<FileSystemFileResponse> inputs;
    182  if (!inputs.SetLength(mTargetBlobImplArray.Length(), mozilla::fallible_t())) {
    183    FileSystemFilesResponse response;
    184    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    185    return response;
    186  }
    187 
    188  for (unsigned i = 0; i < mTargetBlobImplArray.Length(); i++) {
    189    IPCBlob ipcBlob;
    190    aRv = IPCBlobUtils::Serialize(mTargetBlobImplArray[i], ipcBlob);
    191    if (NS_WARN_IF(aRv.Failed())) {
    192      FileSystemFilesResponse response;
    193      return response;
    194    }
    195 
    196    inputs[i] = FileSystemFileResponse(ipcBlob);
    197  }
    198 
    199  FileSystemFilesResponse response;
    200  response.data() = std::move(inputs);
    201  return response;
    202 }
    203 
    204 nsresult GetFilesTaskParent::IOWork() {
    205  MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
    206  MOZ_ASSERT(!NS_IsMainThread(), "Only call on I/O thread!");
    207 
    208  if (mFileSystem->IsShutdown()) {
    209    return NS_ERROR_FAILURE;
    210  }
    211 
    212  bool exists;
    213  nsresult rv = mTargetPath->Exists(&exists);
    214  if (NS_WARN_IF(NS_FAILED(rv))) {
    215    return rv;
    216  }
    217 
    218  if (!exists) {
    219    return NS_OK;
    220  }
    221 
    222  bool isDir;
    223  rv = mTargetPath->IsDirectory(&isDir);
    224  if (NS_WARN_IF(NS_FAILED(rv))) {
    225    return rv;
    226  }
    227 
    228  if (!isDir) {
    229    return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
    230  }
    231 
    232  // Get isDirectory.
    233  rv = ExploreDirectory(mDirectoryDOMPath, mTargetPath);
    234  if (NS_WARN_IF(NS_FAILED(rv))) {
    235    return rv;
    236  }
    237 
    238  return NS_OK;
    239 }
    240 
    241 nsresult GetFilesTaskParent::GetTargetPath(nsAString& aPath) const {
    242  return mTargetPath->GetPath(aPath);
    243 }
    244 
    245 }  // namespace mozilla::dom