mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Backed out changeset b416fc68c0a2 (bug 1257180) for crash in test_performance_user_timing.html on Android debug. r=backout on a CLOSED TREE
This commit is contained in:
parent
da254cafcc
commit
f25d35d7af
@ -115,8 +115,7 @@ bool
|
||||
FileList::ClonableToDifferentThreadOrProcess() const
|
||||
{
|
||||
for (uint32_t i = 0; i < mFilesOrDirectories.Length(); ++i) {
|
||||
if (mFilesOrDirectories[i].IsDirectory() &&
|
||||
!mFilesOrDirectories[i].GetAsDirectory()->ClonableToDifferentThreadOrProcess()) {
|
||||
if (mFilesOrDirectories[i].IsDirectory()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -61,15 +61,15 @@ function compare(a, b) {
|
||||
}
|
||||
|
||||
var clonableObjects = [
|
||||
'hello world',
|
||||
123,
|
||||
null,
|
||||
true,
|
||||
new Date(),
|
||||
[ 1, 'test', true, new Date() ],
|
||||
{ a: true, b: null, c: new Date(), d: [ true, false, {} ] },
|
||||
new Blob([123], { type: 'plain/text' }),
|
||||
new ImageData(2, 2),
|
||||
{ crossThreads: true, data: 'hello world' },
|
||||
{ crossThreads: true, data: 123 },
|
||||
{ crossThreads: true, data: null },
|
||||
{ crossThreads: true, data: true },
|
||||
{ crossThreads: true, data: new Date() },
|
||||
{ crossThreads: true, data: [ 1, 'test', true, new Date() ] },
|
||||
{ crossThreads: true, data: { a: true, b: null, c: new Date(), d: [ true, false, {} ] } },
|
||||
{ crossThreads: true, data: new Blob([123], { type: 'plain/text' }) },
|
||||
{ crossThreads: true, data: new ImageData(2, 2) },
|
||||
];
|
||||
|
||||
function create_fileList_forFile() {
|
||||
@ -84,7 +84,7 @@ function create_fileList_forFile() {
|
||||
var domFile = fileList.files[0];
|
||||
is(domFile.name, "prefs.js", "fileName should be prefs.js");
|
||||
|
||||
clonableObjects.push(fileList.files);
|
||||
clonableObjects.push({ crossThreads: true, data: fileList.files });
|
||||
script.destroy();
|
||||
next();
|
||||
}
|
||||
@ -105,7 +105,7 @@ function create_fileList_forDir() {
|
||||
is(fileList.files.length, 1, "Filelist has 1 element");
|
||||
ok(fileList.files[0] instanceof Directory, "We have a directory.");
|
||||
|
||||
clonableObjects.push(fileList.files);
|
||||
clonableObjects.push({ crossThreads: false, data: fileList.files });
|
||||
script.destroy();
|
||||
next();
|
||||
}
|
||||
@ -135,8 +135,15 @@ function runTests(obj) {
|
||||
|
||||
var object = clonableObjects[clonableObjectsId++];
|
||||
|
||||
obj.send(object, []).then(function(received) {
|
||||
compare(received.data, object);
|
||||
// If this test requires a cross-thread structured clone algorithm, maybe
|
||||
// we have to skip it.
|
||||
if (!object.crossThread && obj.crossThread) {
|
||||
runClonableTest();
|
||||
return;
|
||||
}
|
||||
|
||||
obj.send(object.data, []).then(function(received) {
|
||||
compare(received.data, object.data);
|
||||
runClonableTest();
|
||||
});
|
||||
}
|
||||
@ -225,6 +232,7 @@ function test_windowToWindow() {
|
||||
runTests({
|
||||
clonableObjects: true,
|
||||
transferableObjects: true,
|
||||
crossThread: false,
|
||||
send: function(what, ports) {
|
||||
return new Promise(function(r, rr) {
|
||||
resolve = r;
|
||||
@ -278,6 +286,7 @@ function test_windowToIframeURL(url) {
|
||||
runTests({
|
||||
clonableObjects: true,
|
||||
transferableObjects: true,
|
||||
crossThread: false,
|
||||
send: function(what, ports) {
|
||||
return new Promise(function(r, rr) {
|
||||
resolve = r;
|
||||
@ -325,6 +334,7 @@ function test_workers() {
|
||||
runTests({
|
||||
clonableObjects: true,
|
||||
transferableObjects: true,
|
||||
crossThread: true,
|
||||
send: function(what, ports) {
|
||||
return new Promise(function(r, rr) {
|
||||
resolve = r;
|
||||
@ -368,6 +378,7 @@ function test_broadcastChannel() {
|
||||
runTests({
|
||||
clonableObjects: true,
|
||||
transferableObjects: false,
|
||||
crossThread: true,
|
||||
send: function(what, ports) {
|
||||
return new Promise(function(r, rr) {
|
||||
if (ports.length) {
|
||||
@ -413,6 +424,7 @@ function test_broadcastChannel_inWorkers() {
|
||||
runTests({
|
||||
clonableObjects: true,
|
||||
transferableObjects: false,
|
||||
crossThread: true,
|
||||
send: function(what, ports) {
|
||||
return new Promise(function(r, rr) {
|
||||
if (ports.length) {
|
||||
@ -454,6 +466,7 @@ function test_messagePort() {
|
||||
runTests({
|
||||
clonableObjects: true,
|
||||
transferableObjects: true,
|
||||
crossThread: true,
|
||||
send: function(what, ports) {
|
||||
return new Promise(function(r, rr) {
|
||||
resolve = r;
|
||||
@ -499,6 +512,7 @@ function test_messagePort_inWorkers() {
|
||||
runTests({
|
||||
clonableObjects: true,
|
||||
transferableObjects: true,
|
||||
crossThread: true,
|
||||
send: function(what, ports) {
|
||||
return new Promise(function(r, rr) {
|
||||
resolve = r;
|
||||
|
@ -111,21 +111,10 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Directory)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
/* static */ bool
|
||||
Directory::DeviceStorageEnabled(JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Preferences::GetBool("device.storage.enabled", false);
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<Promise>
|
||||
// static
|
||||
already_AddRefed<Promise>
|
||||
Directory::GetRoot(FileSystemBase* aFileSystem, ErrorResult& aRv)
|
||||
{
|
||||
// Only exposed for DeviceStorage.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aFileSystem);
|
||||
|
||||
nsCOMPtr<nsIFile> path;
|
||||
@ -150,6 +139,7 @@ Directory::GetRoot(FileSystemBase* aFileSystem, ErrorResult& aRv)
|
||||
Directory::Create(nsISupports* aParent, nsIFile* aFile,
|
||||
DirectoryType aType, FileSystemBase* aFileSystem)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aParent);
|
||||
MOZ_ASSERT(aFile);
|
||||
|
||||
@ -179,6 +169,7 @@ Directory::Directory(nsISupports* aParent,
|
||||
, mFile(aFile)
|
||||
, mType(aType)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aFile);
|
||||
|
||||
// aFileSystem can be null. In this case we create a OSFileSystem when needed.
|
||||
@ -230,9 +221,6 @@ already_AddRefed<Promise>
|
||||
Directory::CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// Only exposed for DeviceStorage.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<Blob> blobData;
|
||||
InfallibleTArray<uint8_t> arrayData;
|
||||
bool replace = (aOptions.mIfExists == CreateIfExistsMode::Replace);
|
||||
@ -280,9 +268,6 @@ Directory::CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions,
|
||||
already_AddRefed<Promise>
|
||||
Directory::CreateDirectory(const nsAString& aPath, ErrorResult& aRv)
|
||||
{
|
||||
// Only exposed for DeviceStorage.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIFile> realPath;
|
||||
nsresult error = DOMPathToRealPath(aPath, getter_AddRefs(realPath));
|
||||
|
||||
@ -305,9 +290,6 @@ Directory::CreateDirectory(const nsAString& aPath, ErrorResult& aRv)
|
||||
already_AddRefed<Promise>
|
||||
Directory::Get(const nsAString& aPath, ErrorResult& aRv)
|
||||
{
|
||||
// Only exposed for DeviceStorage.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIFile> realPath;
|
||||
nsresult error = DOMPathToRealPath(aPath, getter_AddRefs(realPath));
|
||||
|
||||
@ -331,16 +313,12 @@ Directory::Get(const nsAString& aPath, ErrorResult& aRv)
|
||||
already_AddRefed<Promise>
|
||||
Directory::Remove(const StringOrFileOrDirectory& aPath, ErrorResult& aRv)
|
||||
{
|
||||
// Only exposed for DeviceStorage.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return RemoveInternal(aPath, false, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Directory::RemoveDeep(const StringOrFileOrDirectory& aPath, ErrorResult& aRv)
|
||||
{
|
||||
// Only exposed for DeviceStorage.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return RemoveInternal(aPath, true, aRv);
|
||||
}
|
||||
|
||||
@ -348,9 +326,6 @@ already_AddRefed<Promise>
|
||||
Directory::RemoveInternal(const StringOrFileOrDirectory& aPath, bool aRecursive,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// Only exposed for DeviceStorage.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsresult error = NS_OK;
|
||||
nsCOMPtr<nsIFile> realPath;
|
||||
|
||||
@ -507,17 +482,5 @@ Directory::DOMPathToRealPath(const nsAString& aPath, nsIFile** aFile) const
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
Directory::ClonableToDifferentThreadOrProcess() const
|
||||
{
|
||||
// If we don't have a fileSystem we are going to create a OSFileSystem that is
|
||||
// clonable everywhere.
|
||||
if (!mFileSystem) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return mFileSystem->ClonableToDifferentThreadOrProcess();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -53,9 +53,6 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Directory)
|
||||
|
||||
static bool
|
||||
DeviceStorageEnabled(JSContext* aCx, JSObject* aObj);
|
||||
|
||||
static already_AddRefed<Promise>
|
||||
GetRoot(FileSystemBase* aFileSystem, ErrorResult& aRv);
|
||||
|
||||
@ -147,9 +144,6 @@ public:
|
||||
return mType;
|
||||
}
|
||||
|
||||
bool
|
||||
ClonableToDifferentThreadOrProcess() const;
|
||||
|
||||
private:
|
||||
Directory(nsISupports* aParent,
|
||||
nsIFile* aFile, DirectoryType aType,
|
||||
|
@ -127,9 +127,6 @@ public:
|
||||
virtual nsresult
|
||||
MainThreadWork() { return NS_ERROR_FAILURE; }
|
||||
|
||||
virtual bool
|
||||
ClonableToDifferentThreadOrProcess() const { return false; }
|
||||
|
||||
// CC methods
|
||||
virtual void Unlink() {}
|
||||
virtual void Traverse(nsCycleCollectionTraversalCallback &cb) {}
|
||||
|
@ -11,117 +11,20 @@
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIIPCBackgroundChildCreateCallback.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsContentPermissionHelper.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
namespace {
|
||||
|
||||
// This class takes care of the PBackground initialization and, once this step
|
||||
// is completed, it starts the task.
|
||||
class PBackgroundInitializer final : public nsIIPCBackgroundChildCreateCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
|
||||
|
||||
static void
|
||||
ScheduleTask(FileSystemTaskChildBase* aTask)
|
||||
{
|
||||
MOZ_ASSERT(aTask);
|
||||
RefPtr<PBackgroundInitializer> pb = new PBackgroundInitializer(aTask);
|
||||
}
|
||||
|
||||
private:
|
||||
explicit PBackgroundInitializer(FileSystemTaskChildBase* aTask)
|
||||
: mTask(aTask)
|
||||
{
|
||||
MOZ_ASSERT(aTask);
|
||||
|
||||
PBackgroundChild* actor =
|
||||
mozilla::ipc::BackgroundChild::GetForCurrentThread();
|
||||
if (actor) {
|
||||
ActorCreated(actor);
|
||||
} else {
|
||||
if (NS_WARN_IF(
|
||||
!mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread(this))) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~PBackgroundInitializer()
|
||||
{}
|
||||
|
||||
RefPtr<FileSystemTaskChildBase> mTask;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(PBackgroundInitializer,
|
||||
nsIIPCBackgroundChildCreateCallback)
|
||||
|
||||
void
|
||||
PBackgroundInitializer::ActorFailed()
|
||||
{
|
||||
MOZ_CRASH("Failed to create a PBackgroundChild actor!");
|
||||
}
|
||||
|
||||
void
|
||||
PBackgroundInitializer::ActorCreated(mozilla::ipc::PBackgroundChild* aActor)
|
||||
{
|
||||
mTask->Start();
|
||||
}
|
||||
|
||||
// This must be a CancelableRunnable because it can be dispatched to a worker
|
||||
// thread. But we don't care about the Cancel() because in that case, Run() is
|
||||
// not called and the task is deleted by the DTOR.
|
||||
class AsyncStartRunnable final : public nsCancelableRunnable
|
||||
{
|
||||
public:
|
||||
explicit AsyncStartRunnable(FileSystemTaskChildBase* aTask)
|
||||
: mTask(aTask)
|
||||
{
|
||||
MOZ_ASSERT(aTask);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
PBackgroundInitializer::ScheduleTask(mTask);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<FileSystemTaskChildBase> mTask;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
NS_IMPL_ISUPPORTS(FileSystemPermissionRequest, nsIRunnable,
|
||||
nsIContentPermissionRequest)
|
||||
nsIContentPermissionRequest,
|
||||
nsIIPCBackgroundChildCreateCallback)
|
||||
|
||||
/* static */ void
|
||||
FileSystemPermissionRequest::RequestForTask(FileSystemTaskChildBase* aTask)
|
||||
{
|
||||
MOZ_ASSERT(aTask);
|
||||
|
||||
RefPtr<FileSystemBase> filesystem = aTask->GetFileSystem();
|
||||
if (!filesystem) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (filesystem->PermissionCheckType() == FileSystemBase::ePermissionCheckNotRequired) {
|
||||
// Let's make the scheduling of this task asynchronous.
|
||||
RefPtr<AsyncStartRunnable> runnable = new AsyncStartRunnable(aTask);
|
||||
NS_DispatchToCurrentThread(runnable);
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't need any permission check for the FileSystem API. If we are here
|
||||
// it's because we are dealing with a DeviceStorage API that is main-thread
|
||||
// only.
|
||||
MOZ_ASSERT(aTask, "aTask should not be null!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<FileSystemPermissionRequest> request =
|
||||
@ -252,10 +155,31 @@ FileSystemPermissionRequest::GetRequester(nsIContentPermissionRequester** aReque
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
FileSystemPermissionRequest::ActorFailed()
|
||||
{
|
||||
MOZ_CRASH("Failed to create a PBackgroundChild actor!");
|
||||
}
|
||||
|
||||
void
|
||||
FileSystemPermissionRequest::ActorCreated(mozilla::ipc::PBackgroundChild* aActor)
|
||||
{
|
||||
mTask->Start();
|
||||
}
|
||||
|
||||
void
|
||||
FileSystemPermissionRequest::ScheduleTask()
|
||||
{
|
||||
PBackgroundInitializer::ScheduleTask(mTask);
|
||||
PBackgroundChild* actor =
|
||||
mozilla::ipc::BackgroundChild::GetForCurrentThread();
|
||||
if (actor) {
|
||||
ActorCreated(actor);
|
||||
} else {
|
||||
if (NS_WARN_IF(
|
||||
!mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread(this))) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace dom */
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsIContentPermissionPrompt.h"
|
||||
#include "nsIIPCBackgroundChildCreateCallback.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsPIDOMWindowInner;
|
||||
@ -22,6 +23,7 @@ class FileSystemTaskChildBase;
|
||||
class FileSystemPermissionRequest final
|
||||
: public nsIContentPermissionRequest
|
||||
, public nsIRunnable
|
||||
, public nsIIPCBackgroundChildCreateCallback
|
||||
{
|
||||
public:
|
||||
// Request permission for the given task.
|
||||
@ -31,6 +33,7 @@ public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSICONTENTPERMISSIONREQUEST
|
||||
NS_DECL_NSIRUNNABLE
|
||||
NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
|
||||
|
||||
private:
|
||||
explicit FileSystemPermissionRequest(FileSystemTaskChildBase* aTask);
|
||||
@ -39,8 +42,7 @@ private:
|
||||
|
||||
// Once the permission check has been done, we must run the task using IPC and
|
||||
// PBackground. This method checks if the PBackground thread is ready to
|
||||
// receive the task and in case waits for ActorCreated() to be called using
|
||||
// the PBackgroundInitializer class (see FileSystemPermissionRequest.cpp).
|
||||
// receive the task and in case waits for ActorCreated() to be called.
|
||||
void
|
||||
ScheduleTask();
|
||||
|
||||
|
@ -75,32 +75,6 @@ DispatchToIOThread(nsIRunnable* aRunnable)
|
||||
return target->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
// This runnable is used when an error value is set before doing any real
|
||||
// operation on the I/O thread. In this case we skip all and we directly
|
||||
// communicate the error.
|
||||
class ErrorRunnable final : public nsCancelableRunnable
|
||||
{
|
||||
public:
|
||||
explicit ErrorRunnable(FileSystemTaskChildBase* aTask)
|
||||
: mTask(aTask)
|
||||
{
|
||||
MOZ_ASSERT(aTask);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mTask->HasError());
|
||||
|
||||
mTask->HandlerCallback();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<FileSystemTaskChildBase> mTask;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/**
|
||||
@ -111,8 +85,8 @@ FileSystemTaskChildBase::FileSystemTaskChildBase(FileSystemBase* aFileSystem)
|
||||
: mErrorValue(NS_OK)
|
||||
, mFileSystem(aFileSystem)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
|
||||
MOZ_ASSERT(aFileSystem, "aFileSystem should not be null.");
|
||||
aFileSystem->AssertIsOnOwningThread();
|
||||
}
|
||||
|
||||
FileSystemTaskChildBase::~FileSystemTaskChildBase()
|
||||
@ -133,10 +107,9 @@ FileSystemTaskChildBase::Start()
|
||||
mFileSystem->AssertIsOnOwningThread();
|
||||
|
||||
if (HasError()) {
|
||||
// In this case we don't want to use IPC at all.
|
||||
RefPtr<ErrorRunnable> runnable = new ErrorRunnable(this);
|
||||
nsresult rv = NS_DispatchToCurrentThread(runnable);
|
||||
NS_WARN_IF(NS_FAILED(rv));
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NS_NewRunnableMethod(this, &FileSystemTaskChildBase::HandlerCallback);
|
||||
NS_DispatchToMainThread(runnable);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,8 @@ GetDirectoryListingTaskChild::Create(FileSystemBase* aFileSystem,
|
||||
const nsAString& aFilters,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
|
||||
MOZ_ASSERT(aFileSystem);
|
||||
aFileSystem->AssertIsOnOwningThread();
|
||||
|
||||
RefPtr<GetDirectoryListingTaskChild> task =
|
||||
new GetDirectoryListingTaskChild(aFileSystem, aTargetPath, aType, aFilters);
|
||||
@ -66,20 +66,19 @@ GetDirectoryListingTaskChild::GetDirectoryListingTaskChild(FileSystemBase* aFile
|
||||
, mFilters(aFilters)
|
||||
, mType(aType)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
|
||||
MOZ_ASSERT(aFileSystem);
|
||||
aFileSystem->AssertIsOnOwningThread();
|
||||
}
|
||||
|
||||
GetDirectoryListingTaskChild::~GetDirectoryListingTaskChild()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mFileSystem->AssertIsOnOwningThread();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
GetDirectoryListingTaskChild::GetPromise()
|
||||
{
|
||||
mFileSystem->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
|
||||
return RefPtr<Promise>(mPromise).forget();
|
||||
}
|
||||
|
||||
@ -87,7 +86,7 @@ FileSystemParams
|
||||
GetDirectoryListingTaskChild::GetRequestParams(const nsString& aSerializedDOMPath,
|
||||
ErrorResult& aRv) const
|
||||
{
|
||||
mFileSystem->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
|
||||
|
||||
nsAutoString path;
|
||||
aRv = mTargetPath->GetPath(path);
|
||||
@ -104,7 +103,7 @@ void
|
||||
GetDirectoryListingTaskChild::SetSuccessRequestResult(const FileSystemResponseValue& aValue,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
mFileSystem->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
|
||||
MOZ_ASSERT(aValue.type() ==
|
||||
FileSystemResponseValue::TFileSystemDirectoryListingResponse);
|
||||
|
||||
@ -134,8 +133,7 @@ GetDirectoryListingTaskChild::SetSuccessRequestResult(const FileSystemResponseVa
|
||||
void
|
||||
GetDirectoryListingTaskChild::HandlerCallback()
|
||||
{
|
||||
mFileSystem->AssertIsOnOwningThread();
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
|
||||
if (mFileSystem->IsShutdown()) {
|
||||
mPromise = nullptr;
|
||||
return;
|
||||
|
@ -44,6 +44,7 @@ void
|
||||
OSFileSystem::Init(nsISupports* aParent)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
|
||||
MOZ_ASSERT(!mParent, "No duple Init() calls");
|
||||
MOZ_ASSERT(aParent);
|
||||
|
||||
|
@ -40,9 +40,6 @@ public:
|
||||
virtual void
|
||||
SerializeDOMPath(nsAString& aOutput) const override;
|
||||
|
||||
virtual bool
|
||||
ClonableToDifferentThreadOrProcess() const override { return true; }
|
||||
|
||||
// CC methods
|
||||
virtual void Unlink() override;
|
||||
virtual void Traverse(nsCycleCollectionTraversalCallback &cb) override;
|
||||
|
@ -1,7 +1,5 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
script_fileList.js
|
||||
worker_basic.js
|
||||
|
||||
[test_basic.html]
|
||||
[test_worker_basic.html]
|
||||
|
@ -1,70 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Directory API in workers</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<input id="fileList" type="file"></input>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
function create_fileList() {
|
||||
var url = SimpleTest.getTestFileURL("script_fileList.js");
|
||||
var script = SpecialPowers.loadChromeScript(url);
|
||||
|
||||
function onOpened(message) {
|
||||
var fileList = document.getElementById('fileList');
|
||||
SpecialPowers.wrap(fileList).mozSetDirectory(message.dir);
|
||||
|
||||
// Just a simple test
|
||||
is(fileList.files.length, 1, "Filelist has 1 element");
|
||||
ok(fileList.files[0] instanceof Directory, "We have a directory.");
|
||||
|
||||
script.destroy();
|
||||
next();
|
||||
}
|
||||
|
||||
script.addMessageListener("dir.opened", onOpened);
|
||||
script.sendAsyncMessage("dir.open", { path: 'ProfD' });
|
||||
}
|
||||
|
||||
function test_worker() {
|
||||
var fileList = document.getElementById('fileList');
|
||||
|
||||
var worker = new Worker('worker_basic.js');
|
||||
worker.onmessage = function(e) {
|
||||
if (e.data.type == 'finish') {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.data.type == 'test') {
|
||||
ok(e.data.test, e.data.message);
|
||||
}
|
||||
}
|
||||
|
||||
worker.postMessage(fileList.files);
|
||||
}
|
||||
|
||||
var tests = [
|
||||
create_fileList,
|
||||
test_worker,
|
||||
];
|
||||
|
||||
function next() {
|
||||
if (!tests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
next();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,58 +0,0 @@
|
||||
function finish() {
|
||||
postMessage({ type: 'finish' });
|
||||
}
|
||||
|
||||
function ok(a, msg) {
|
||||
postMessage({ type: 'test', test: !!a, message: msg });
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
ok(a === b, msg);
|
||||
}
|
||||
|
||||
function isnot(a, b, msg) {
|
||||
ok(a != b, msg);
|
||||
}
|
||||
|
||||
function checkSubDir(dir) {
|
||||
return dir.getFilesAndDirectories().then(
|
||||
function(data) {
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
ok (data[i] instanceof File || data[i] instanceof Directory, "Just Files or Directories");
|
||||
if (data[i] instanceof Directory) {
|
||||
isnot(data[i].name, '/', "Subdirectory should be called with the leafname");
|
||||
isnot(data[i].path, '/', "Subdirectory path should be called with the leafname");
|
||||
isnot(data[i].path, dir.path, "Subdirectory path should contain the parent path.");
|
||||
is(data[i].path,dir.path + '/' + data[i].name, "Subdirectory path should be called parentdir.path + '/' + leafname");
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
onmessage = function(e) {
|
||||
var fileList = e.data;
|
||||
ok(fileList instanceof FileList, "This is a fileList.");
|
||||
is(fileList.length, 1, "We want just 1 element.");
|
||||
ok(fileList[0] instanceof Directory, "This is a directory.");
|
||||
|
||||
fileList[0].getFilesAndDirectories().then(
|
||||
function(data) {
|
||||
ok(data.length, "We should have some data.");
|
||||
var promises = [];
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
ok (data[i] instanceof File || data[i] instanceof Directory, "Just Files or Directories");
|
||||
if (data[i] instanceof Directory) {
|
||||
isnot(data[i].name, '/', "Subdirectory should be called with the leafname");
|
||||
is(data[i].path, '/' + data[i].name, "Subdirectory path should be called '/' + leafname");
|
||||
promises.push(checkSubDir(data[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
},
|
||||
function() {
|
||||
ok(false, "Something when wrong");
|
||||
}
|
||||
).then(finish);
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
* http://w3c.github.io/filesystem-api/#idl-def-Directory
|
||||
* https://microsoftedge.github.io/directory-upload/proposal.html#directory-interface
|
||||
*/
|
||||
[Exposed=(Window,Worker)]
|
||||
[Exposed=Window]
|
||||
interface Directory {
|
||||
/*
|
||||
* The leaf name of the directory.
|
||||
@ -39,7 +39,7 @@ interface Directory {
|
||||
* @return If succeeds, the promise is resolved with the new created
|
||||
* File object. Otherwise, rejected with a DOM error.
|
||||
*/
|
||||
[Func="mozilla::dom::Directory::DeviceStorageEnabled", NewObject]
|
||||
[Pref="device.storage.enabled", NewObject]
|
||||
Promise<File> createFile(DOMString path, optional CreateFileOptions options);
|
||||
|
||||
/*
|
||||
@ -51,7 +51,7 @@ interface Directory {
|
||||
* @return If succeeds, the promise is resolved with the new created
|
||||
* Directory object. Otherwise, rejected with a DOM error.
|
||||
*/
|
||||
[Func="mozilla::dom::Directory::DeviceStorageEnabled", NewObject]
|
||||
[Pref="device.storage.enabled", NewObject]
|
||||
Promise<Directory> createDirectory(DOMString path);
|
||||
|
||||
/*
|
||||
@ -62,7 +62,7 @@ interface Directory {
|
||||
* with a File or Directory object, depending on the entry's type. Otherwise,
|
||||
* rejected with a DOM error.
|
||||
*/
|
||||
[Func="mozilla::dom::Directory::DeviceStorageEnabled", NewObject]
|
||||
[Pref="device.storage.enabled", NewObject]
|
||||
Promise<(File or Directory)> get(DOMString path);
|
||||
|
||||
/*
|
||||
@ -76,7 +76,7 @@ interface Directory {
|
||||
* exist, the promise is resolved with boolean false. If the target did exist
|
||||
* and was successfully deleted, the promise is resolved with boolean true.
|
||||
*/
|
||||
[Func="mozilla::dom::Directory::DeviceStorageEnabled", NewObject]
|
||||
[Pref="device.storage.enabled", NewObject]
|
||||
Promise<boolean> remove((DOMString or File or Directory) path);
|
||||
|
||||
/*
|
||||
@ -90,11 +90,11 @@ interface Directory {
|
||||
* resolved with boolean false. If the target did exist and was successfully
|
||||
* deleted, the promise is resolved with boolean true.
|
||||
*/
|
||||
[Func="mozilla::dom::Directory::DeviceStorageEnabled", NewObject]
|
||||
[Pref="device.storage.enabled", NewObject]
|
||||
Promise<boolean> removeDeep((DOMString or File or Directory) path);
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker)]
|
||||
[Exposed=Window]
|
||||
partial interface Directory {
|
||||
// Already defined in the main interface declaration:
|
||||
//readonly attribute DOMString name;
|
||||
|
@ -96,8 +96,6 @@ var interfaceNamesInGlobalScope =
|
||||
{ name: "DataStore", b2g: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "DataStoreCursor", b2g: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Directory",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"DOMCursor",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -94,8 +94,6 @@ var interfaceNamesInGlobalScope =
|
||||
{ name: "DataStore", b2g: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "DataStoreCursor", b2g: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Directory",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"DOMCursor",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
Loading…
Reference in New Issue
Block a user