mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-01 08:48:25 +02:00
Bug 1424689 - Expose the File.type for File objects created via FileSystem API, r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D223396
This commit is contained in:
parent
ee1f5ecbde
commit
c08c22e705
4 changed files with 122 additions and 5 deletions
|
|
@ -218,7 +218,28 @@ NS_IMETHODIMP
|
|||
FileSystemTaskParentBase::Run() {
|
||||
// This method can run in 2 different threads. Here why:
|
||||
// 1. We are are on the I/O thread and we call IOWork().
|
||||
// 2. After step 1, it returns back to the PBackground thread.
|
||||
// 2. After step 1, if we need to run some code in the main-thread, we
|
||||
// dispatch a runnable to this thread.
|
||||
// 3. The final step happens in the PBackground thread.
|
||||
|
||||
// If we are here, it's because the I/O work has been done, but we have
|
||||
// something to do on the main-thread.
|
||||
if (NS_IsMainThread()) {
|
||||
MOZ_ASSERT(MainThreadNeeded());
|
||||
|
||||
nsresult rv = MainThreadWork();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
SetError(rv);
|
||||
}
|
||||
|
||||
// Let's go back to PBackground thread to finish the work.
|
||||
rv = mBackgroundEventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Run I/O thread tasks
|
||||
if (!mozilla::ipc::IsOnBackgroundThread()) {
|
||||
|
|
@ -227,6 +248,14 @@ FileSystemTaskParentBase::Run() {
|
|||
SetError(rv);
|
||||
}
|
||||
|
||||
if (MainThreadNeeded()) {
|
||||
rv = GetMainThreadSerialEventTarget()->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Let's go back to PBackground thread to finish the work.
|
||||
rv = mBackgroundEventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
|
|
|||
|
|
@ -53,9 +53,18 @@ class FileSystemParams;
|
|||
* | | | | ---------> [IOWork] | |
|
||||
* | | IPC | | | | |
|
||||
* | | | | | | (5) | |
|
||||
* | | | | -------------- | |
|
||||
* | | | | | |_____________| |
|
||||
* | | | | | |
|
||||
* | | | | -------------* | |
|
||||
* | | | | | |_____|_______| |
|
||||
* | | | | | __________|_______ |
|
||||
* | | | | | | | | |
|
||||
* | | | | | | Main | | |
|
||||
* | | | | | | Thread | | |
|
||||
* | | | | | | V | |
|
||||
* | | | | | | [MainThreadWork] | |
|
||||
* | | IPC | | | (5.1) | | |
|
||||
* | | | | | | | | |
|
||||
* | | | | |<------------ | |
|
||||
* | | | | | |__________________| |
|
||||
* | | | | V |
|
||||
* | | | | [HandleResult] |
|
||||
* | | | | | |
|
||||
|
|
@ -87,6 +96,7 @@ class FileSystemParams;
|
|||
* during the operation, call [SetError] to record the error and then abort.
|
||||
* (5) After finishing the task operation, call [HandleResult] to send the
|
||||
* result back to the child process though the IPC.
|
||||
* (5.1) Optional, we need to run some code in the main-thread.
|
||||
* (6) Call [GetRequestResult] request result to prepare the parameters of the
|
||||
* IPC. Because the formats of the error result for different task are the
|
||||
* same, FileSystemTaskChildBase can handle the error message without
|
||||
|
|
@ -199,6 +209,16 @@ class FileSystemTaskParentBase : public Runnable {
|
|||
*/
|
||||
virtual nsresult IOWork() = 0;
|
||||
|
||||
// In case `MainThreadNeeded()` returns true, the following method is called.
|
||||
virtual nsresult MainThreadWork() {
|
||||
MOZ_CRASH("This method should be implemented");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If this returns true, after I/O work, we schedule a runnable to the
|
||||
// main-thread before resolving the task on the PBackground one.
|
||||
virtual bool MainThreadNeeded() const { return false; };
|
||||
|
||||
/*
|
||||
* Wrap the task success result to FileSystemResponseValue for sending it
|
||||
* through IPC. This method runs in the PBackground thread.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@
|
|||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/UnionTypes.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "nsCExternalHandlerService.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
|
@ -218,8 +220,18 @@ FileSystemResponseValue GetDirectoryListingTaskParent::GetSuccessRequestResult(
|
|||
continue;
|
||||
}
|
||||
|
||||
nsAutoString fileName;
|
||||
path->GetLeafName(fileName);
|
||||
|
||||
int64_t fileSize = 0;
|
||||
rv = path->GetFileSize(&fileSize);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FileSystemDirectoryListingResponseFile fileData;
|
||||
RefPtr<BlobImpl> blobImpl = new FileBlobImpl(path);
|
||||
RefPtr<BlobImpl> blobImpl = new FileBlobImpl(
|
||||
fileName, mTargetData[i].mContentType, fileSize, path);
|
||||
|
||||
nsAutoString filePath;
|
||||
filePath.Assign(mDOMPath);
|
||||
|
|
@ -364,6 +376,55 @@ nsresult GetDirectoryListingTaskParent::IOWork() {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult GetDirectoryListingTaskParent::MainThreadWork() {
|
||||
MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Only call on main-thread!");
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIMIMEService> mimeService =
|
||||
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < mTargetData.Length(); i++) {
|
||||
if (mTargetData[i].mType != FileOrDirectoryPath::eFilePath) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv =
|
||||
NS_NewLocalFile(mTargetData[i].mPath, true, getter_AddRefs(file));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAutoCString mimeType;
|
||||
rv = mimeService->GetTypeFromFile(file, mimeType);
|
||||
if (NS_FAILED(rv)) {
|
||||
mimeType.Truncate();
|
||||
}
|
||||
|
||||
AppendUTF8toUTF16(mimeType, mTargetData[i].mContentType);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool GetDirectoryListingTaskParent::MainThreadNeeded() const {
|
||||
MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
|
||||
|
||||
// We need to go to the main-thread only if we have files in the list of
|
||||
// target.
|
||||
for (const FileOrDirectoryPath& data : mTargetData) {
|
||||
if (data.mType == FileOrDirectoryPath::eFilePath) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult GetDirectoryListingTaskParent::GetTargetPath(nsAString& aPath) const {
|
||||
return mTargetPath->GetPath(aPath);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,10 @@ class GetDirectoryListingTaskParent final : public FileSystemTaskParentBase {
|
|||
|
||||
virtual nsresult IOWork() override;
|
||||
|
||||
virtual nsresult MainThreadWork() override;
|
||||
|
||||
virtual bool MainThreadNeeded() const override;
|
||||
|
||||
nsCOMPtr<nsIFile> mTargetPath;
|
||||
nsString mDOMPath;
|
||||
nsString mFilters;
|
||||
|
|
@ -79,6 +83,9 @@ class GetDirectoryListingTaskParent final : public FileSystemTaskParentBase {
|
|||
struct FileOrDirectoryPath {
|
||||
nsString mPath;
|
||||
|
||||
// Set on the main-thread
|
||||
nsString mContentType;
|
||||
|
||||
enum { eFilePath, eDirectoryPath } mType;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue