dom/filesystem/GetFileOrDirectoryTask.cpp

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
     2 /* vim: set ts=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/. */
     7 #include "GetFileOrDirectoryTask.h"
     9 #include "js/Value.h"
    10 #include "mozilla/dom/Directory.h"
    11 #include "mozilla/dom/FileSystemBase.h"
    12 #include "mozilla/dom/FileSystemUtils.h"
    13 #include "mozilla/dom/Promise.h"
    14 #include "nsDOMFile.h"
    15 #include "nsIFile.h"
    16 #include "nsStringGlue.h"
    18 namespace mozilla {
    19 namespace dom {
    21 GetFileOrDirectoryTask::GetFileOrDirectoryTask(
    22   FileSystemBase* aFileSystem,
    23   const nsAString& aTargetPath,
    24   bool aDirectoryOnly)
    25   : FileSystemTaskBase(aFileSystem)
    26   , mTargetRealPath(aTargetPath)
    27   , mIsDirectory(aDirectoryOnly)
    28 {
    29   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
    30   MOZ_ASSERT(aFileSystem);
    31   nsCOMPtr<nsIGlobalObject> globalObject =
    32     do_QueryInterface(aFileSystem->GetWindow());
    33   if (!globalObject) {
    34     return;
    35   }
    36   mPromise = new Promise(globalObject);
    37 }
    39 GetFileOrDirectoryTask::GetFileOrDirectoryTask(
    40   FileSystemBase* aFileSystem,
    41   const FileSystemGetFileOrDirectoryParams& aParam,
    42   FileSystemRequestParent* aParent)
    43   : FileSystemTaskBase(aFileSystem, aParam, aParent)
    44   , mIsDirectory(false)
    45 {
    46   MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
    47              "Only call from parent process!");
    48   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
    49   MOZ_ASSERT(aFileSystem);
    50   mTargetRealPath = aParam.realPath();
    51 }
    53 GetFileOrDirectoryTask::~GetFileOrDirectoryTask()
    54 {
    55   MOZ_ASSERT(!mPromise || NS_IsMainThread(),
    56              "mPromise should be released on main thread!");
    57 }
    59 already_AddRefed<Promise>
    60 GetFileOrDirectoryTask::GetPromise()
    61 {
    62   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
    63   return nsRefPtr<Promise>(mPromise).forget();
    64 }
    66 FileSystemParams
    67 GetFileOrDirectoryTask::GetRequestParams(const nsString& aFileSystem) const
    68 {
    69   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
    70   return FileSystemGetFileOrDirectoryParams(aFileSystem, mTargetRealPath);
    71 }
    73 FileSystemResponseValue
    74 GetFileOrDirectoryTask::GetSuccessRequestResult() const
    75 {
    76   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
    77   if (mIsDirectory) {
    78     return FileSystemDirectoryResponse(mTargetRealPath);
    79   }
    80   BlobParent* actor = GetBlobParent(mTargetFile);
    81   if (!actor) {
    82     return FileSystemErrorResponse(NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR);
    83   }
    84   FileSystemFileResponse response;
    85   response.blobParent() = actor;
    86   return response;
    87 }
    89 void
    90 GetFileOrDirectoryTask::SetSuccessRequestResult(const FileSystemResponseValue& aValue)
    91 {
    92   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
    93   switch (aValue.type()) {
    94     case FileSystemResponseValue::TFileSystemFileResponse: {
    95       FileSystemFileResponse r = aValue;
    96       BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
    97       nsCOMPtr<nsIDOMBlob> blob = actor->GetBlob();
    98       mTargetFile = do_QueryInterface(blob);
    99       mIsDirectory = false;
   100       break;
   101     }
   102     case FileSystemResponseValue::TFileSystemDirectoryResponse: {
   103       FileSystemDirectoryResponse r = aValue;
   104       mTargetRealPath = r.realPath();
   105       mIsDirectory = true;
   106       break;
   107     }
   108     default: {
   109       NS_RUNTIMEABORT("not reached");
   110       break;
   111     }
   112   }
   113 }
   115 nsresult
   116 GetFileOrDirectoryTask::Work()
   117 {
   118   MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
   119              "Only call from parent process!");
   120   MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!");
   122   if (mFileSystem->IsShutdown()) {
   123     return NS_ERROR_FAILURE;
   124   }
   126   // Whether we want to get the root directory.
   127   bool getRoot = mTargetRealPath.IsEmpty();
   129   nsCOMPtr<nsIFile> file = mFileSystem->GetLocalFile(mTargetRealPath);
   130   if (!file) {
   131     return NS_ERROR_DOM_FILESYSTEM_INVALID_PATH_ERR;
   132   }
   134   bool exists;
   135   nsresult rv = file->Exists(&exists);
   136   if (NS_WARN_IF(NS_FAILED(rv))) {
   137     return rv;
   138   }
   140   if (!exists) {
   141     if (!getRoot) {
   142       return NS_ERROR_DOM_FILE_NOT_FOUND_ERR;
   143     }
   145     // If the root directory doesn't exit, create it.
   146     rv = file->Create(nsIFile::DIRECTORY_TYPE, 0777);
   147     if (NS_WARN_IF(NS_FAILED(rv))) {
   148       return rv;
   149     }
   150   }
   152   // Get isDirectory.
   153   rv = file->IsDirectory(&mIsDirectory);
   154   if (NS_WARN_IF(NS_FAILED(rv))) {
   155     return rv;
   156   }
   158   if (mIsDirectory) {
   159     return NS_OK;
   160   }
   162   // Check if the root is a directory.
   163   if (getRoot) {
   164     return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
   165   }
   167   bool isFile;
   168   // Get isFile
   169   rv = file->IsFile(&isFile);
   170   if (NS_WARN_IF(NS_FAILED(rv))) {
   171     return rv;
   172   }
   174   if (!isFile) {
   175     // Neither directory or file.
   176     return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
   177   }
   179   if (!mFileSystem->IsSafeFile(file)) {
   180     return NS_ERROR_DOM_SECURITY_ERR;
   181   }
   183   mTargetFile = new nsDOMFileFile(file);
   185   return NS_OK;
   186 }
   188 void
   189 GetFileOrDirectoryTask::HandlerCallback()
   190 {
   191   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   192   if (mFileSystem->IsShutdown()) {
   193     mPromise = nullptr;
   194     return;
   195   }
   197   if (HasError()) {
   198     nsRefPtr<DOMError> domError = new DOMError(mFileSystem->GetWindow(),
   199       mErrorValue);
   200     mPromise->MaybeReject(domError);
   201     mPromise = nullptr;
   202     return;
   203   }
   205   if (mIsDirectory) {
   206     nsRefPtr<Directory> dir = new Directory(mFileSystem, mTargetRealPath);
   207     mPromise->MaybeResolve(dir);
   208     mPromise = nullptr;
   209     return;
   210   }
   212   mPromise->MaybeResolve(mTargetFile);
   213   mPromise = nullptr;
   214 }
   216 void
   217 GetFileOrDirectoryTask::GetPermissionAccessType(nsCString& aAccess) const
   218 {
   219   aAccess.AssignLiteral("read");
   220 }
   222 } // namespace dom
   223 } // namespace mozilla

mercurial