Bug 910498 - Changes to device storage to support CreateFd. r=bent

This commit is contained in:
Dave Hylands 2014-01-16 17:01:27 -08:00
Родитель ff82acc0a5
Коммит 00a803aa36
10 изменённых файлов: 567 добавлений и 136 удалений

Просмотреть файл

@ -14,7 +14,8 @@
#include "nsDOMEventTargetHelper.h" #include "nsDOMEventTargetHelper.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "mozilla/StaticPtr.h" #include "mozilla/StaticPtr.h"
#include "DOMRequest.h" #include "mozilla/dom/DOMRequest.h"
#include "mozilla/ipc/FileDescriptor.h"
#define DEVICESTORAGE_PICTURES "pictures" #define DEVICESTORAGE_PICTURES "pictures"
#define DEVICESTORAGE_VIDEOS "videos" #define DEVICESTORAGE_VIDEOS "videos"
@ -23,6 +24,7 @@
#define DEVICESTORAGE_SDCARD "sdcard" #define DEVICESTORAGE_SDCARD "sdcard"
#define DEVICESTORAGE_CRASHES "crashes" #define DEVICESTORAGE_CRASHES "crashes"
class DeviceStorageFile;
class nsIInputStream; class nsIInputStream;
namespace mozilla { namespace mozilla {
@ -33,6 +35,14 @@ class DOMRequest;
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla
class DeviceStorageFileDescriptor MOZ_FINAL
: public mozilla::RefCounted<DeviceStorageFileDescriptor>
{
public:
nsRefPtr<DeviceStorageFile> mDSFile;
mozilla::ipc::FileDescriptor mFileDescriptor;
};
class DeviceStorageFile MOZ_FINAL class DeviceStorageFile MOZ_FINAL
: public nsISupports { : public nsISupports {
public: public:
@ -102,6 +112,7 @@ public:
nsresult CalculateSizeAndModifiedDate(); nsresult CalculateSizeAndModifiedDate();
nsresult CalculateMimeType(); nsresult CalculateMimeType();
nsresult CreateFileDescriptor(mozilla::ipc::FileDescriptor& aFileDescriptor);
private: private:
void Init(); void Init();

Просмотреть файл

@ -20,11 +20,27 @@ DeviceStorageRequestChild::DeviceStorageRequestChild()
} }
DeviceStorageRequestChild::DeviceStorageRequestChild(DOMRequest* aRequest, DeviceStorageRequestChild::DeviceStorageRequestChild(DOMRequest* aRequest,
DeviceStorageFile* aFile) DeviceStorageFile* aDSFile)
: mRequest(aRequest) : mRequest(aRequest)
, mFile(aFile) , mDSFile(aDSFile)
, mCallback(nullptr) , mCallback(nullptr)
{ {
MOZ_ASSERT(aRequest);
MOZ_ASSERT(aDSFile);
MOZ_COUNT_CTOR(DeviceStorageRequestChild);
}
DeviceStorageRequestChild::DeviceStorageRequestChild(DOMRequest* aRequest,
DeviceStorageFile* aDSFile,
DeviceStorageFileDescriptor* aDSFileDescriptor)
: mRequest(aRequest)
, mDSFile(aDSFile)
, mDSFileDescriptor(aDSFileDescriptor)
, mCallback(nullptr)
{
MOZ_ASSERT(aRequest);
MOZ_ASSERT(aDSFile);
MOZ_ASSERT(aDSFileDescriptor);
MOZ_COUNT_CTOR(DeviceStorageRequestChild); MOZ_COUNT_CTOR(DeviceStorageRequestChild);
} }
@ -53,7 +69,7 @@ DeviceStorageRequestChild::
case DeviceStorageResponseValue::TSuccessResponse: case DeviceStorageResponseValue::TSuccessResponse:
{ {
nsString fullPath; nsString fullPath;
mFile->GetFullPath(fullPath); mDSFile->GetFullPath(fullPath);
AutoJSContext cx; AutoJSContext cx;
JS::Rooted<JS::Value> result(cx, JS::Rooted<JS::Value> result(cx,
StringToJsval(mRequest->GetOwner(), fullPath)); StringToJsval(mRequest->GetOwner(), fullPath));
@ -61,6 +77,22 @@ DeviceStorageRequestChild::
break; break;
} }
case DeviceStorageResponseValue::TFileDescriptorResponse:
{
FileDescriptorResponse r = aValue;
nsString fullPath;
mDSFile->GetFullPath(fullPath);
AutoJSContext cx;
JS::Rooted<JS::Value> result(cx,
StringToJsval(mRequest->GetOwner(), fullPath));
mDSFileDescriptor->mDSFile = mDSFile;
mDSFileDescriptor->mFileDescriptor = r.fileDescriptor();
mRequest->FireSuccess(result);
break;
}
case DeviceStorageResponseValue::TBlobResponse: case DeviceStorageResponseValue::TBlobResponse:
{ {
BlobResponse r = aValue; BlobResponse r = aValue;

Просмотреть файл

@ -7,12 +7,15 @@
#define mozilla_dom_devicestorage_DeviceStorageRequestChild_h #define mozilla_dom_devicestorage_DeviceStorageRequestChild_h
#include "mozilla/dom/devicestorage/PDeviceStorageRequestChild.h" #include "mozilla/dom/devicestorage/PDeviceStorageRequestChild.h"
#include "DOMRequest.h"
class DeviceStorageFile; class DeviceStorageFile;
class DeviceStorageFileDescriptor;
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
class DOMRequest;
namespace devicestorage { namespace devicestorage {
class DeviceStorageRequestChildCallback class DeviceStorageRequestChildCallback
@ -26,6 +29,8 @@ class DeviceStorageRequestChild : public PDeviceStorageRequestChild
public: public:
DeviceStorageRequestChild(); DeviceStorageRequestChild();
DeviceStorageRequestChild(DOMRequest* aRequest, DeviceStorageFile* aFile); DeviceStorageRequestChild(DOMRequest* aRequest, DeviceStorageFile* aFile);
DeviceStorageRequestChild(DOMRequest* aRequest, DeviceStorageFile* aFile,
DeviceStorageFileDescriptor* aFileDescrptor);
~DeviceStorageRequestChild(); ~DeviceStorageRequestChild();
void SetCallback(class DeviceStorageRequestChildCallback *aCallback); void SetCallback(class DeviceStorageRequestChildCallback *aCallback);
@ -34,7 +39,8 @@ public:
private: private:
nsRefPtr<DOMRequest> mRequest; nsRefPtr<DOMRequest> mRequest;
nsRefPtr<DeviceStorageFile> mFile; nsRefPtr<DeviceStorageFile> mDSFile;
nsRefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
DeviceStorageRequestChildCallback* mCallback; DeviceStorageRequestChildCallback* mCallback;
}; };

Просмотреть файл

@ -35,6 +35,8 @@ DeviceStorageRequestParent::DeviceStorageRequestParent(
void void
DeviceStorageRequestParent::Dispatch() DeviceStorageRequestParent::Dispatch()
{ {
nsresult rv;
switch (mParams.type()) { switch (mParams.type()) {
case DeviceStorageParams::TDeviceStorageAddParams: case DeviceStorageParams::TDeviceStorageAddParams:
{ {
@ -58,6 +60,22 @@ DeviceStorageRequestParent::Dispatch()
break; break;
} }
case DeviceStorageParams::TDeviceStorageCreateFdParams:
{
DeviceStorageCreateFdParams p = mParams;
nsRefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
nsRefPtr<CancelableRunnable> r = new CreateFdEvent(this, dsf);
nsCOMPtr<nsIEventTarget> target
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
NS_ASSERTION(target, "Must have stream transport service");
target->Dispatch(r, NS_DISPATCH_NORMAL);
break;
}
case DeviceStorageParams::TDeviceStorageGetParams: case DeviceStorageParams::TDeviceStorageGetParams:
{ {
DeviceStorageGetParams p = mParams; DeviceStorageGetParams p = mParams;
@ -127,7 +145,8 @@ DeviceStorageRequestParent::Dispatch()
new DeviceStorageFile(p.type(), p.storageName()); new DeviceStorageFile(p.type(), p.storageName());
nsRefPtr<PostAvailableResultEvent> r nsRefPtr<PostAvailableResultEvent> r
= new PostAvailableResultEvent(this, dsf); = new PostAvailableResultEvent(this, dsf);
NS_DispatchToMainThread(r); rv = NS_DispatchToMainThread(r);
MOZ_ASSERT(NS_SUCCEEDED(rv));
break; break;
} }
@ -139,7 +158,8 @@ DeviceStorageRequestParent::Dispatch()
new DeviceStorageFile(p.type(), p.storageName()); new DeviceStorageFile(p.type(), p.storageName());
nsRefPtr<PostFormatResultEvent> r nsRefPtr<PostFormatResultEvent> r
= new PostFormatResultEvent(this, dsf); = new PostFormatResultEvent(this, dsf);
NS_DispatchToMainThread(r); rv = NS_DispatchToMainThread(r);
MOZ_ASSERT(NS_SUCCEEDED(rv));
break; break;
} }
@ -187,6 +207,14 @@ DeviceStorageRequestParent::EnsureRequiredPermissions(
break; break;
} }
case DeviceStorageParams::TDeviceStorageCreateFdParams:
{
DeviceStorageCreateFdParams p = mParams;
type = p.type();
requestType = DEVICE_STORAGE_REQUEST_CREATEFD;
break;
}
case DeviceStorageParams::TDeviceStorageGetParams: case DeviceStorageParams::TDeviceStorageGetParams:
{ {
DeviceStorageGetParams p = mParams; DeviceStorageGetParams p = mParams;
@ -444,6 +472,46 @@ DeviceStorageRequestParent::PostEnumerationSuccessEvent::CancelableRun() {
return NS_OK; return NS_OK;
} }
DeviceStorageRequestParent::CreateFdEvent::
CreateFdEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile)
: CancelableRunnable(aParent)
, mFile(aFile)
{
}
DeviceStorageRequestParent::CreateFdEvent::~CreateFdEvent()
{
}
nsresult
DeviceStorageRequestParent::CreateFdEvent::CancelableRun()
{
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
nsRefPtr<nsRunnable> r;
bool check = false;
mFile->mFile->Exists(&check);
if (check) {
nsCOMPtr<PostErrorEvent> event
= new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS);
return NS_DispatchToMainThread(event);
}
FileDescriptor fileDescriptor;
nsresult rv = mFile->CreateFileDescriptor(fileDescriptor);
if (NS_FAILED(rv)) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
}
else {
r = new PostFileDescriptorResultEvent(mParent, fileDescriptor);
}
return NS_DispatchToMainThread(r);
}
DeviceStorageRequestParent::WriteFileEvent:: DeviceStorageRequestParent::WriteFileEvent::
WriteFileEvent(DeviceStorageRequestParent* aParent, WriteFileEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile, DeviceStorageFile* aFile,
@ -467,8 +535,7 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
if (!mInputStream) { if (!mInputStream) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
bool check = false; bool check = false;
@ -476,8 +543,7 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
if (check) { if (check) {
nsCOMPtr<PostErrorEvent> event nsCOMPtr<PostErrorEvent> event
= new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS); = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS);
NS_DispatchToMainThread(event); return NS_DispatchToMainThread(event);
return NS_OK;
} }
nsresult rv = mFile->Write(mInputStream); nsresult rv = mFile->Write(mInputStream);
@ -489,11 +555,9 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
r = new PostPathResultEvent(mParent, mFile->mPath); r = new PostPathResultEvent(mParent, mFile->mPath);
} }
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
DeviceStorageRequestParent::DeleteFileEvent:: DeviceStorageRequestParent::DeleteFileEvent::
DeleteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile) DeleteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile)
: CancelableRunnable(aParent) : CancelableRunnable(aParent)
@ -523,8 +587,7 @@ DeviceStorageRequestParent::DeleteFileEvent::CancelableRun()
r = new PostPathResultEvent(mParent, mFile->mPath); r = new PostPathResultEvent(mParent, mFile->mPath);
} }
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
DeviceStorageRequestParent::FreeSpaceFileEvent:: DeviceStorageRequestParent::FreeSpaceFileEvent::
@ -551,8 +614,7 @@ DeviceStorageRequestParent::FreeSpaceFileEvent::CancelableRun()
nsCOMPtr<nsIRunnable> r; nsCOMPtr<nsIRunnable> r;
r = new PostFreeSpaceResultEvent(mParent, static_cast<uint64_t>(freeSpace)); r = new PostFreeSpaceResultEvent(mParent, static_cast<uint64_t>(freeSpace));
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
DeviceStorageRequestParent::UsedSpaceFileEvent:: DeviceStorageRequestParent::UsedSpaceFileEvent::
@ -588,8 +650,7 @@ DeviceStorageRequestParent::UsedSpaceFileEvent::CancelableRun()
} else { } else {
r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, totalUsage); r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, totalUsage);
} }
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
DeviceStorageRequestParent::ReadFileEvent:: DeviceStorageRequestParent::ReadFileEvent::
@ -622,30 +683,26 @@ DeviceStorageRequestParent::ReadFileEvent::CancelableRun()
if (!check) { if (!check) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST); r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
int64_t fileSize; int64_t fileSize;
nsresult rv = mFile->mFile->GetFileSize(&fileSize); nsresult rv = mFile->mFile->GetFileSize(&fileSize);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
PRTime modDate; PRTime modDate;
rv = mFile->mFile->GetLastModifiedTime(&modDate); rv = mFile->mFile->GetLastModifiedTime(&modDate);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
r = new PostBlobSuccessEvent(mParent, mFile, static_cast<uint64_t>(fileSize), r = new PostBlobSuccessEvent(mParent, mFile, static_cast<uint64_t>(fileSize),
mMimeType, modDate); mMimeType, modDate);
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
DeviceStorageRequestParent::EnumerateFileEvent:: DeviceStorageRequestParent::EnumerateFileEvent::
@ -673,8 +730,7 @@ DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun()
mFile->mFile->Exists(&check); mFile->mFile->Exists(&check);
if (!check) { if (!check) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST); r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
} }
@ -691,8 +747,7 @@ DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun()
r = new PostEnumerationSuccessEvent(mParent, mFile->mStorageType, r = new PostEnumerationSuccessEvent(mParent, mFile->mStorageType,
mFile->mRootDir, values); mFile->mRootDir, values);
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
@ -718,6 +773,29 @@ DeviceStorageRequestParent::PostPathResultEvent::CancelableRun()
return NS_OK; return NS_OK;
} }
DeviceStorageRequestParent::PostFileDescriptorResultEvent::
PostFileDescriptorResultEvent(DeviceStorageRequestParent* aParent,
const FileDescriptor& aFileDescriptor)
: CancelableRunnable(aParent)
, mFileDescriptor(aFileDescriptor)
{
}
DeviceStorageRequestParent::PostFileDescriptorResultEvent::
~PostFileDescriptorResultEvent()
{
}
nsresult
DeviceStorageRequestParent::PostFileDescriptorResultEvent::CancelableRun()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
FileDescriptorResponse response(mFileDescriptor);
unused << mParent->Send__delete__(mParent, response);
return NS_OK;
}
DeviceStorageRequestParent::PostAvailableResultEvent:: DeviceStorageRequestParent::PostAvailableResultEvent::
PostAvailableResultEvent(DeviceStorageRequestParent* aParent, PostAvailableResultEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile) DeviceStorageFile* aFile)

Просмотреть файл

@ -119,6 +119,16 @@ private:
InfallibleTArray<DeviceStorageFileValue> mPaths; InfallibleTArray<DeviceStorageFileValue> mPaths;
}; };
class CreateFdEvent : public CancelableRunnable
{
public:
CreateFdEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
virtual ~CreateFdEvent();
virtual nsresult CancelableRun();
private:
nsRefPtr<DeviceStorageFile> mFile;
};
class WriteFileEvent : public CancelableRunnable class WriteFileEvent : public CancelableRunnable
{ {
public: public:
@ -193,6 +203,18 @@ private:
nsString mPath; nsString mPath;
}; };
class PostFileDescriptorResultEvent : public CancelableRunnable
{
public:
PostFileDescriptorResultEvent(DeviceStorageRequestParent* aParent,
const FileDescriptor& aFileDescriptor);
virtual ~PostFileDescriptorResultEvent();
virtual nsresult CancelableRun();
private:
nsRefPtr<DeviceStorageFile> mFile;
FileDescriptor mFileDescriptor;
};
class PostFreeSpaceResultEvent : public CancelableRunnable class PostFreeSpaceResultEvent : public CancelableRunnable
{ {
public: public:

Просмотреть файл

@ -20,6 +20,11 @@ struct SuccessResponse
{ {
}; };
struct FileDescriptorResponse
{
FileDescriptor fileDescriptor;
};
struct BlobResponse struct BlobResponse
{ {
PBlob blob; PBlob blob;
@ -62,6 +67,7 @@ union DeviceStorageResponseValue
{ {
ErrorResponse; ErrorResponse;
SuccessResponse; SuccessResponse;
FileDescriptorResponse;
BlobResponse; BlobResponse;
EnumerationResponse; EnumerationResponse;
FreeSpaceStorageResponse; FreeSpaceStorageResponse;

Просмотреть файл

@ -49,6 +49,7 @@
#include "nsIStringBundle.h" #include "nsIStringBundle.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include <algorithm> #include <algorithm>
#include "private/pprio.h"
#include "mozilla/dom/DeviceStorageBinding.h" #include "mozilla/dom/DeviceStorageBinding.h"
@ -67,6 +68,7 @@
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom; using namespace mozilla::dom;
using namespace mozilla::dom::devicestorage; using namespace mozilla::dom::devicestorage;
using namespace mozilla::ipc;
#include "nsDirectoryServiceDefs.h" #include "nsDirectoryServiceDefs.h"
@ -394,6 +396,7 @@ DeviceStorageTypeChecker::GetAccessForRequest(
aAccessResult.AssignLiteral("write"); aAccessResult.AssignLiteral("write");
break; break;
case DEVICE_STORAGE_REQUEST_CREATE: case DEVICE_STORAGE_REQUEST_CREATE:
case DEVICE_STORAGE_REQUEST_CREATEFD:
aAccessResult.AssignLiteral("create"); aAccessResult.AssignLiteral("create");
break; break;
default: default:
@ -923,6 +926,20 @@ DeviceStorageFile::AppendRelativePath(const nsAString& aPath) {
#endif #endif
} }
nsresult
DeviceStorageFile::CreateFileDescriptor(FileDescriptor& aFileDescriptor)
{
PRFileDesc* fd;
nsresult rv = mFile->OpenNSPRFileDesc(PR_RDWR | PR_CREATE_FILE,
0660, &fd);
NS_ENSURE_SUCCESS(rv, rv);
aFileDescriptor =
FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(fd));
return NS_OK;
}
nsresult nsresult
DeviceStorageFile::Write(nsIInputStream* aInputStream) DeviceStorageFile::Write(nsIInputStream* aInputStream)
{ {
@ -931,12 +948,15 @@ DeviceStorageFile::Write(nsIInputStream* aInputStream)
} }
nsresult rv = mFile->Create(nsIFile::NORMAL_FILE_TYPE, 00600); nsresult rv = mFile->Create(nsIFile::NORMAL_FILE_TYPE, 00600);
if (NS_FAILED(rv)) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
nsCOMPtr<IOEventComplete> iocomplete = new IOEventComplete(this, "created"); nsCOMPtr<IOEventComplete> iocomplete = new IOEventComplete(this, "created");
NS_DispatchToMainThread(iocomplete); rv = NS_DispatchToMainThread(iocomplete);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
uint64_t bufSize = 0; uint64_t bufSize = 0;
aInputStream->Available(&bufSize); aInputStream->Available(&bufSize);
@ -967,11 +987,14 @@ DeviceStorageFile::Write(nsIInputStream* aInputStream)
} }
iocomplete = new IOEventComplete(this, "modified"); iocomplete = new IOEventComplete(this, "modified");
NS_DispatchToMainThread(iocomplete); rv = NS_DispatchToMainThread(iocomplete);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bufferedOutputStream->Close(); bufferedOutputStream->Close();
outputStream->Close(); outputStream->Close();
if (NS_FAILED(rv)) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
return NS_OK; return NS_OK;
@ -985,12 +1008,15 @@ DeviceStorageFile::Write(InfallibleTArray<uint8_t>& aBits)
} }
nsresult rv = mFile->Create(nsIFile::NORMAL_FILE_TYPE, 00600); nsresult rv = mFile->Create(nsIFile::NORMAL_FILE_TYPE, 00600);
if (NS_FAILED(rv)) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
nsCOMPtr<IOEventComplete> iocomplete = new IOEventComplete(this, "created"); nsCOMPtr<IOEventComplete> iocomplete = new IOEventComplete(this, "created");
NS_DispatchToMainThread(iocomplete); rv = NS_DispatchToMainThread(iocomplete);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIOutputStream> outputStream; nsCOMPtr<nsIOutputStream> outputStream;
NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mFile); NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mFile);
@ -1004,7 +1030,10 @@ DeviceStorageFile::Write(InfallibleTArray<uint8_t>& aBits)
outputStream->Close(); outputStream->Close();
iocomplete = new IOEventComplete(this, "modified"); iocomplete = new IOEventComplete(this, "modified");
NS_DispatchToMainThread(iocomplete); rv = NS_DispatchToMainThread(iocomplete);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (aBits.Length() != wrote) { if (aBits.Length() != wrote) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -1032,13 +1061,12 @@ DeviceStorageFile::Remove()
} }
rv = mFile->Remove(true); rv = mFile->Remove(true);
if (NS_FAILED(rv)) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
nsCOMPtr<IOEventComplete> iocomplete = new IOEventComplete(this, "deleted"); nsCOMPtr<IOEventComplete> iocomplete = new IOEventComplete(this, "deleted");
NS_DispatchToMainThread(iocomplete); return NS_DispatchToMainThread(iocomplete);
return NS_OK;
} }
nsresult nsresult
@ -1116,7 +1144,7 @@ DeviceStorageFile::collectFilesInternal(
if (msecs < aSince) { if (msecs < aSince) {
continue; continue;
} }
bool isDir; bool isDir;
f->IsDirectory(&isDir); f->IsDirectory(&isDir);
@ -1619,8 +1647,11 @@ ContinueCursorEvent::~ContinueCursorEvent() {}
void void
ContinueCursorEvent::Continue() ContinueCursorEvent::Continue()
{ {
nsresult rv;
if (XRE_GetProcessType() == GeckoProcessType_Default) { if (XRE_GetProcessType() == GeckoProcessType_Default) {
NS_DispatchToMainThread(this); rv = NS_DispatchToMainThread(this);
MOZ_ASSERT(NS_SUCCEEDED(rv));
return; return;
} }
@ -1628,7 +1659,8 @@ ContinueCursorEvent::Continue()
if (!file) { if (!file) {
// done with enumeration. // done with enumeration.
NS_DispatchToMainThread(this); rv = NS_DispatchToMainThread(this);
MOZ_ASSERT(NS_SUCCEEDED(rv));
return; return;
} }
@ -1691,8 +1723,7 @@ public:
nsCOMPtr<PostErrorEvent> event = nsCOMPtr<PostErrorEvent> event =
new PostErrorEvent(mRequest.forget(), new PostErrorEvent(mRequest.forget(),
POST_ERROR_EVENT_FILE_NOT_ENUMERABLE); POST_ERROR_EVENT_FILE_NOT_ENUMERABLE);
NS_DispatchToMainThread(event); return NS_DispatchToMainThread(event);
return NS_OK;
} }
} }
@ -1782,8 +1813,7 @@ nsDOMDeviceStorageCursor::Cancel()
{ {
nsCOMPtr<PostErrorEvent> event nsCOMPtr<PostErrorEvent> event
= new PostErrorEvent(this, POST_ERROR_EVENT_PERMISSION_DENIED); = new PostErrorEvent(this, POST_ERROR_EVENT_PERMISSION_DENIED);
NS_DispatchToMainThread(event); return NS_DispatchToMainThread(event);
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -1792,8 +1822,7 @@ nsDOMDeviceStorageCursor::Allow()
if (!mFile->IsSafePath()) { if (!mFile->IsSafePath()) {
nsCOMPtr<nsIRunnable> r nsCOMPtr<nsIRunnable> r
= new PostErrorEvent(this, POST_ERROR_EVENT_PERMISSION_DENIED); = new PostErrorEvent(this, POST_ERROR_EVENT_PERMISSION_DENIED);
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
if (XRE_GetProcessType() != GeckoProcessType_Default) { if (XRE_GetProcessType() != GeckoProcessType_Default) {
@ -1870,6 +1899,7 @@ public:
: mFile(aFile) : mFile(aFile)
, mRequest(aRequest) , mRequest(aRequest)
{ {
MOZ_ASSERT(mRequest);
} }
~PostAvailableResultEvent() {} ~PostAvailableResultEvent() {}
@ -1903,6 +1933,7 @@ public:
: mFile(aFile) : mFile(aFile)
, mRequest(aRequest) , mRequest(aRequest)
{ {
MOZ_ASSERT(mRequest);
} }
~PostFormatResultEvent() {} ~PostFormatResultEvent() {}
@ -1936,19 +1967,25 @@ public:
DeviceStorageFile* aFile) DeviceStorageFile* aFile)
: mFile(aFile) : mFile(aFile)
, mRequest(aRequest) , mRequest(aRequest)
{} {
MOZ_ASSERT(mRequest);
}
PostResultEvent(already_AddRefed<DOMRequest> aRequest, PostResultEvent(already_AddRefed<DOMRequest> aRequest,
const nsAString & aPath) const nsAString & aPath)
: mPath(aPath) : mPath(aPath)
, mRequest(aRequest) , mRequest(aRequest)
{} {
MOZ_ASSERT(mRequest);
}
PostResultEvent(already_AddRefed<DOMRequest> aRequest, PostResultEvent(already_AddRefed<DOMRequest> aRequest,
const uint64_t aValue) const uint64_t aValue)
: mValue(aValue) : mValue(aValue)
, mRequest(aRequest) , mRequest(aRequest)
{} {
MOZ_ASSERT(mRequest);
}
~PostResultEvent() {} ~PostResultEvent() {}
@ -1981,6 +2018,57 @@ private:
nsRefPtr<DOMRequest> mRequest; nsRefPtr<DOMRequest> mRequest;
}; };
class CreateFdEvent : public nsRunnable
{
public:
CreateFdEvent(DeviceStorageFileDescriptor* aDSFileDescriptor,
already_AddRefed<DOMRequest> aRequest)
: mDSFileDescriptor(aDSFileDescriptor)
, mRequest(aRequest)
{
MOZ_ASSERT(mDSFileDescriptor);
MOZ_ASSERT(mRequest);
}
NS_IMETHOD Run()
{
MOZ_ASSERT(!NS_IsMainThread());
DeviceStorageFile* dsFile = mDSFileDescriptor->mDSFile;
MOZ_ASSERT(dsFile);
nsString fullPath;
dsFile->GetFullPath(fullPath);
MOZ_ASSERT(!fullPath.IsEmpty());
bool check = false;
dsFile->mFile->Exists(&check);
if (check) {
nsCOMPtr<PostErrorEvent> event =
new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_FILE_EXISTS);
return NS_DispatchToMainThread(event);
}
nsresult rv = dsFile->CreateFileDescriptor(mDSFileDescriptor->mFileDescriptor);
if (NS_FAILED(rv)) {
dsFile->mFile->Remove(false);
nsCOMPtr<PostErrorEvent> event =
new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_UNKNOWN);
return NS_DispatchToMainThread(event);
}
nsCOMPtr<PostResultEvent> event =
new PostResultEvent(mRequest.forget(), fullPath);
return NS_DispatchToMainThread(event);
}
private:
nsRefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
nsRefPtr<DOMRequest> mRequest;
};
class WriteFileEvent : public nsRunnable class WriteFileEvent : public nsRunnable
{ {
public: public:
@ -1990,7 +2078,10 @@ public:
: mBlob(aBlob) : mBlob(aBlob)
, mFile(aFile) , mFile(aFile)
, mRequest(aRequest) , mRequest(aRequest)
{} {
MOZ_ASSERT(mFile);
MOZ_ASSERT(mRequest);
}
~WriteFileEvent() {} ~WriteFileEvent() {}
@ -2006,8 +2097,7 @@ public:
if (check) { if (check) {
nsCOMPtr<PostErrorEvent> event = nsCOMPtr<PostErrorEvent> event =
new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_FILE_EXISTS); new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_FILE_EXISTS);
NS_DispatchToMainThread(event); return NS_DispatchToMainThread(event);
return NS_OK;
} }
nsresult rv = mFile->Write(stream); nsresult rv = mFile->Write(stream);
@ -2017,16 +2107,14 @@ public:
nsCOMPtr<PostErrorEvent> event = nsCOMPtr<PostErrorEvent> event =
new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_UNKNOWN); new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_UNKNOWN);
NS_DispatchToMainThread(event); return NS_DispatchToMainThread(event);
return NS_OK;
} }
nsString fullPath; nsString fullPath;
mFile->GetFullPath(fullPath); mFile->GetFullPath(fullPath);
nsCOMPtr<PostResultEvent> event = nsCOMPtr<PostResultEvent> event =
new PostResultEvent(mRequest.forget(), fullPath); new PostResultEvent(mRequest.forget(), fullPath);
NS_DispatchToMainThread(event); return NS_DispatchToMainThread(event);
return NS_OK;
} }
private: private:
@ -2043,6 +2131,8 @@ public:
: mFile(aFile) : mFile(aFile)
, mRequest(aRequest) , mRequest(aRequest)
{ {
MOZ_ASSERT(mFile);
MOZ_ASSERT(mRequest);
mFile->CalculateMimeType(); mFile->CalculateMimeType();
} }
@ -2072,8 +2162,7 @@ public:
if (!r) { if (!r) {
r = new PostResultEvent(mRequest.forget(), mFile); r = new PostResultEvent(mRequest.forget(), mFile);
} }
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
private: private:
@ -2088,7 +2177,10 @@ public:
already_AddRefed<DOMRequest> aRequest) already_AddRefed<DOMRequest> aRequest)
: mFile(aFile) : mFile(aFile)
, mRequest(aRequest) , mRequest(aRequest)
{} {
MOZ_ASSERT(mFile);
MOZ_ASSERT(mRequest);
}
~DeleteFileEvent() {} ~DeleteFileEvent() {}
@ -2109,8 +2201,7 @@ public:
mFile->GetFullPath(fullPath); mFile->GetFullPath(fullPath);
r = new PostResultEvent(mRequest.forget(), fullPath); r = new PostResultEvent(mRequest.forget(), fullPath);
} }
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
private: private:
@ -2125,7 +2216,10 @@ public:
already_AddRefed<DOMRequest> aRequest) already_AddRefed<DOMRequest> aRequest)
: mFile(aFile) : mFile(aFile)
, mRequest(aRequest) , mRequest(aRequest)
{} {
MOZ_ASSERT(mFile);
MOZ_ASSERT(mRequest);
}
~UsedSpaceFileEvent() {} ~UsedSpaceFileEvent() {}
@ -2148,8 +2242,7 @@ public:
} else { } else {
r = new PostResultEvent(mRequest.forget(), totalUsage); r = new PostResultEvent(mRequest.forget(), totalUsage);
} }
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
private: private:
@ -2164,7 +2257,10 @@ public:
already_AddRefed<DOMRequest> aRequest) already_AddRefed<DOMRequest> aRequest)
: mFile(aFile) : mFile(aFile)
, mRequest(aRequest) , mRequest(aRequest)
{} {
MOZ_ASSERT(mFile);
MOZ_ASSERT(mRequest);
}
~FreeSpaceFileEvent() {} ~FreeSpaceFileEvent() {}
@ -2180,8 +2276,7 @@ public:
nsCOMPtr<nsIRunnable> r; nsCOMPtr<nsIRunnable> r;
r = new PostResultEvent(mRequest.forget(), r = new PostResultEvent(mRequest.forget(),
static_cast<uint64_t>(freeSpace)); static_cast<uint64_t>(freeSpace));
NS_DispatchToMainThread(r); return NS_DispatchToMainThread(r);
return NS_OK;
} }
private: private:
@ -2196,32 +2291,65 @@ class DeviceStorageRequest MOZ_FINAL
{ {
public: public:
DeviceStorageRequest(const DeviceStorageRequestType aRequestType, DeviceStorageRequest(const DeviceStorageRequestType aRequestType,
nsPIDOMWindow *aWindow, nsPIDOMWindow* aWindow,
nsIPrincipal *aPrincipal, nsIPrincipal* aPrincipal,
DeviceStorageFile *aFile, DeviceStorageFile* aFile,
DOMRequest* aRequest, DOMRequest* aRequest,
nsDOMDeviceStorage *aDeviceStorage) nsDOMDeviceStorage* aDeviceStorage)
: mRequestType(aRequestType) : mRequestType(aRequestType)
, mWindow(aWindow) , mWindow(aWindow)
, mPrincipal(aPrincipal) , mPrincipal(aPrincipal)
, mFile(aFile) , mFile(aFile)
, mRequest(aRequest) , mRequest(aRequest)
, mDeviceStorage(aDeviceStorage) , mDeviceStorage(aDeviceStorage)
{} {
MOZ_ASSERT(mWindow);
MOZ_ASSERT(mPrincipal);
MOZ_ASSERT(mFile);
MOZ_ASSERT(mRequest);
MOZ_ASSERT(mDeviceStorage);
}
DeviceStorageRequest(const DeviceStorageRequestType aRequestType, DeviceStorageRequest(const DeviceStorageRequestType aRequestType,
nsPIDOMWindow *aWindow, nsPIDOMWindow* aWindow,
nsIPrincipal *aPrincipal, nsIPrincipal* aPrincipal,
DeviceStorageFile *aFile, DeviceStorageFile* aFile,
DOMRequest* aRequest, DOMRequest* aRequest,
nsIDOMBlob *aBlob = nullptr) nsIDOMBlob* aBlob = nullptr)
: mRequestType(aRequestType) : mRequestType(aRequestType)
, mWindow(aWindow) , mWindow(aWindow)
, mPrincipal(aPrincipal) , mPrincipal(aPrincipal)
, mFile(aFile) , mFile(aFile)
, mRequest(aRequest) , mRequest(aRequest)
, mBlob(aBlob) {} , mBlob(aBlob)
{
MOZ_ASSERT(mWindow);
MOZ_ASSERT(mPrincipal);
MOZ_ASSERT(mFile);
MOZ_ASSERT(mRequest);
}
DeviceStorageRequest(const DeviceStorageRequestType aRequestType,
nsPIDOMWindow* aWindow,
nsIPrincipal* aPrincipal,
DeviceStorageFile* aFile,
DOMRequest* aRequest,
DeviceStorageFileDescriptor* aDSFileDescriptor)
: mRequestType(aRequestType)
, mWindow(aWindow)
, mPrincipal(aPrincipal)
, mFile(aFile)
, mRequest(aRequest)
, mDSFileDescriptor(aDSFileDescriptor)
{
MOZ_ASSERT(mRequestType == DEVICE_STORAGE_REQUEST_CREATEFD);
MOZ_ASSERT(mWindow);
MOZ_ASSERT(mPrincipal);
MOZ_ASSERT(mFile);
MOZ_ASSERT(mRequest);
MOZ_ASSERT(mDSFileDescriptor);
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DeviceStorageRequest, NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DeviceStorageRequest,
@ -2321,19 +2449,59 @@ public:
nsCOMPtr<PostErrorEvent> event nsCOMPtr<PostErrorEvent> event
= new PostErrorEvent(mRequest.forget(), = new PostErrorEvent(mRequest.forget(),
POST_ERROR_EVENT_PERMISSION_DENIED); POST_ERROR_EVENT_PERMISSION_DENIED);
NS_DispatchToMainThread(event); return NS_DispatchToMainThread(event);
return NS_OK;
} }
NS_IMETHOD Allow() NS_IMETHOD Allow()
{ {
nsCOMPtr<nsIRunnable> r; MOZ_ASSERT(NS_IsMainThread());
if (!mRequest) { if (!mRequest) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
nsCOMPtr<nsIRunnable> r;
switch(mRequestType) { switch(mRequestType) {
case DEVICE_STORAGE_REQUEST_CREATEFD:
{
if (!mFile->mFile) {
return NS_ERROR_FAILURE;
}
DeviceStorageTypeChecker* typeChecker
= DeviceStorageTypeChecker::CreateOrGet();
if (!typeChecker) {
return NS_OK;
}
if (!typeChecker->Check(mFile->mStorageType, mFile->mFile)) {
r = new PostErrorEvent(mRequest.forget(),
POST_ERROR_EVENT_ILLEGAL_TYPE);
return NS_DispatchToCurrentThread(r);
}
if (XRE_GetProcessType() != GeckoProcessType_Default) {
DeviceStorageCreateFdParams params;
params.type() = mFile->mStorageType;
params.storageName() = mFile->mStorageName;
params.relpath() = mFile->mPath;
mFile->Dump("DeviceStorageCreateFdParams");
PDeviceStorageRequestChild* child
= new DeviceStorageRequestChild(mRequest, mFile,
mDSFileDescriptor.get());
ContentChild::GetSingleton()
->SendPDeviceStorageRequestConstructor(child, params);
return NS_OK;
}
mDSFileDescriptor->mDSFile = mFile;
r = new CreateFdEvent(mDSFileDescriptor.get(), mRequest.forget());
break;
}
case DEVICE_STORAGE_REQUEST_CREATE: case DEVICE_STORAGE_REQUEST_CREATE:
{ {
if (!mBlob || !mFile->mFile) { if (!mBlob || !mFile->mFile) {
@ -2350,8 +2518,7 @@ public:
!typeChecker->Check(mFile->mStorageType, mBlob)) { !typeChecker->Check(mFile->mStorageType, mBlob)) {
r = new PostErrorEvent(mRequest.forget(), r = new PostErrorEvent(mRequest.forget(),
POST_ERROR_EVENT_ILLEGAL_TYPE); POST_ERROR_EVENT_ILLEGAL_TYPE);
NS_DispatchToMainThread(r); return NS_DispatchToCurrentThread(r);
return NS_OK;
} }
if (XRE_GetProcessType() != GeckoProcessType_Default) { if (XRE_GetProcessType() != GeckoProcessType_Default) {
@ -2394,8 +2561,7 @@ public:
if (!typeChecker->Check(mFile->mStorageType, mFile->mFile)) { if (!typeChecker->Check(mFile->mStorageType, mFile->mFile)) {
r = new PostErrorEvent(mRequest.forget(), r = new PostErrorEvent(mRequest.forget(),
POST_ERROR_EVENT_ILLEGAL_TYPE); POST_ERROR_EVENT_ILLEGAL_TYPE);
NS_DispatchToMainThread(r); return NS_DispatchToCurrentThread(r);
return NS_OK;
} }
if (XRE_GetProcessType() != GeckoProcessType_Default) { if (XRE_GetProcessType() != GeckoProcessType_Default) {
@ -2429,8 +2595,7 @@ public:
if (!typeChecker->Check(mFile->mStorageType, mFile->mFile)) { if (!typeChecker->Check(mFile->mStorageType, mFile->mFile)) {
r = new PostErrorEvent(mRequest.forget(), r = new PostErrorEvent(mRequest.forget(),
POST_ERROR_EVENT_ILLEGAL_TYPE); POST_ERROR_EVENT_ILLEGAL_TYPE);
NS_DispatchToMainThread(r); return NS_DispatchToCurrentThread(r);
return NS_OK;
} }
if (XRE_GetProcessType() != GeckoProcessType_Default) { if (XRE_GetProcessType() != GeckoProcessType_Default) {
@ -2495,8 +2660,7 @@ public:
return NS_OK; return NS_OK;
} }
r = new PostAvailableResultEvent(mFile, mRequest); r = new PostAvailableResultEvent(mFile, mRequest);
NS_DispatchToMainThread(r); return NS_DispatchToCurrentThread(r);
return NS_OK;
} }
case DEVICE_STORAGE_REQUEST_WATCH: case DEVICE_STORAGE_REQUEST_WATCH:
@ -2517,8 +2681,7 @@ public:
return NS_OK; return NS_OK;
} }
r = new PostFormatResultEvent(mFile, mRequest); r = new PostFormatResultEvent(mFile, mRequest);
NS_DispatchToMainThread(r); return NS_DispatchToCurrentThread(r);
return NS_OK;
} }
} }
@ -2558,6 +2721,7 @@ private:
nsRefPtr<DOMRequest> mRequest; nsRefPtr<DOMRequest> mRequest;
nsCOMPtr<nsIDOMBlob> mBlob; nsCOMPtr<nsIDOMBlob> mBlob;
nsRefPtr<nsDOMDeviceStorage> mDeviceStorage; nsRefPtr<nsDOMDeviceStorage> mDeviceStorage;
nsRefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
}; };
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeviceStorageRequest) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeviceStorageRequest)
@ -2799,6 +2963,8 @@ nsDOMDeviceStorage::GetStorage(const nsAString& aFullPath,
already_AddRefed<nsDOMDeviceStorage> already_AddRefed<nsDOMDeviceStorage>
nsDOMDeviceStorage::GetStorageByName(const nsAString& aStorageName) nsDOMDeviceStorage::GetStorageByName(const nsAString& aStorageName)
{ {
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<nsDOMDeviceStorage> ds; nsRefPtr<nsDOMDeviceStorage> ds;
if (mStorageName.Equals(aStorageName)) { if (mStorageName.Equals(aStorageName)) {
@ -2914,6 +3080,8 @@ already_AddRefed<DOMRequest>
nsDOMDeviceStorage::AddNamed(nsIDOMBlob* aBlob, const nsAString& aPath, nsDOMDeviceStorage::AddNamed(nsIDOMBlob* aBlob, const nsAString& aPath,
ErrorResult& aRv) ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread());
// if the blob is null here, bail // if the blob is null here, bail
if (!aBlob) { if (!aBlob) {
return nullptr; return nullptr;
@ -2933,6 +3101,7 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob* aBlob, const nsAString& aPath,
} }
nsCOMPtr<nsIRunnable> r; nsCOMPtr<nsIRunnable> r;
nsresult rv;
if (IsFullPath(aPath)) { if (IsFullPath(aPath)) {
nsString storagePath; nsString storagePath;
@ -2940,7 +3109,10 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob* aBlob, const nsAString& aPath,
if (!ds) { if (!ds) {
nsRefPtr<DOMRequest> request = new DOMRequest(win); nsRefPtr<DOMRequest> request = new DOMRequest(win);
r = new PostErrorEvent(request, POST_ERROR_EVENT_UNKNOWN); r = new PostErrorEvent(request, POST_ERROR_EVENT_UNKNOWN);
NS_DispatchToMainThread(r); rv = NS_DispatchToCurrentThread(r);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
return request.forget(); return request.forget();
} }
return ds->AddNamed(aBlob, storagePath, aRv); return ds->AddNamed(aBlob, storagePath, aRv);
@ -2961,7 +3133,10 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob* aBlob, const nsAString& aPath,
win, mPrincipal, dsf, request, aBlob); win, mPrincipal, dsf, request, aBlob);
} }
NS_DispatchToMainThread(r); rv = NS_DispatchToCurrentThread(r);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
return request.forget(); return request.forget();
} }
@ -2988,6 +3163,8 @@ already_AddRefed<DOMRequest>
nsDOMDeviceStorage::GetInternal(const nsAString& aPath, bool aEditable, nsDOMDeviceStorage::GetInternal(const nsAString& aPath, bool aEditable,
ErrorResult& aRv) ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsPIDOMWindow> win = GetOwner(); nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) { if (!win) {
aRv.Throw(NS_ERROR_UNEXPECTED); aRv.Throw(NS_ERROR_UNEXPECTED);
@ -3002,7 +3179,10 @@ nsDOMDeviceStorage::GetInternal(const nsAString& aPath, bool aEditable,
if (!ds) { if (!ds) {
nsCOMPtr<nsIRunnable> r = nsCOMPtr<nsIRunnable> r =
new PostErrorEvent(request, POST_ERROR_EVENT_UNKNOWN); new PostErrorEvent(request, POST_ERROR_EVENT_UNKNOWN);
NS_DispatchToMainThread(r); nsresult rv = NS_DispatchToCurrentThread(r);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
return request.forget(); return request.forget();
} }
ds->GetInternal(win, storagePath, request, aEditable); ds->GetInternal(win, storagePath, request, aEditable);
@ -3018,6 +3198,8 @@ nsDOMDeviceStorage::GetInternal(nsPIDOMWindow *aWin,
DOMRequest* aRequest, DOMRequest* aRequest,
bool aEditable) bool aEditable)
{ {
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType, nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
mStorageName, mStorageName,
aPath); aPath);
@ -3031,7 +3213,8 @@ nsDOMDeviceStorage::GetInternal(nsPIDOMWindow *aWin,
: DEVICE_STORAGE_REQUEST_READ, : DEVICE_STORAGE_REQUEST_READ,
aWin, mPrincipal, dsf, aRequest); aWin, mPrincipal, dsf, aRequest);
} }
NS_DispatchToMainThread(r); DebugOnly<nsresult> rv = NS_DispatchToCurrentThread(r);
MOZ_ASSERT(NS_SUCCEEDED(rv));
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -3046,6 +3229,8 @@ nsDOMDeviceStorage::Delete(const nsAString& aPath, nsIDOMDOMRequest** aRetval)
already_AddRefed<DOMRequest> already_AddRefed<DOMRequest>
nsDOMDeviceStorage::Delete(const nsAString& aPath, ErrorResult& aRv) nsDOMDeviceStorage::Delete(const nsAString& aPath, ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsPIDOMWindow> win = GetOwner(); nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) { if (!win) {
aRv.Throw(NS_ERROR_UNEXPECTED); aRv.Throw(NS_ERROR_UNEXPECTED);
@ -3060,7 +3245,10 @@ nsDOMDeviceStorage::Delete(const nsAString& aPath, ErrorResult& aRv)
if (!ds) { if (!ds) {
nsCOMPtr<nsIRunnable> r = nsCOMPtr<nsIRunnable> r =
new PostErrorEvent(request, POST_ERROR_EVENT_UNKNOWN); new PostErrorEvent(request, POST_ERROR_EVENT_UNKNOWN);
NS_DispatchToMainThread(r); nsresult rv = NS_DispatchToCurrentThread(r);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
return request.forget(); return request.forget();
} }
ds->DeleteInternal(win, storagePath, request); ds->DeleteInternal(win, storagePath, request);
@ -3075,6 +3263,8 @@ nsDOMDeviceStorage::DeleteInternal(nsPIDOMWindow *aWin,
const nsAString& aPath, const nsAString& aPath,
DOMRequest* aRequest) DOMRequest* aRequest)
{ {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIRunnable> r; nsCOMPtr<nsIRunnable> r;
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType, nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
mStorageName, mStorageName,
@ -3085,7 +3275,8 @@ nsDOMDeviceStorage::DeleteInternal(nsPIDOMWindow *aWin,
r = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_DELETE, r = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_DELETE,
aWin, mPrincipal, dsf, aRequest); aWin, mPrincipal, dsf, aRequest);
} }
NS_DispatchToMainThread(r); DebugOnly<nsresult> rv = NS_DispatchToCurrentThread(r);
MOZ_ASSERT(NS_SUCCEEDED(rv));
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -3100,6 +3291,8 @@ nsDOMDeviceStorage::FreeSpace(nsIDOMDOMRequest** aRetval)
already_AddRefed<DOMRequest> already_AddRefed<DOMRequest>
nsDOMDeviceStorage::FreeSpace(ErrorResult& aRv) nsDOMDeviceStorage::FreeSpace(ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsPIDOMWindow> win = GetOwner(); nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) { if (!win) {
aRv.Throw(NS_ERROR_UNEXPECTED); aRv.Throw(NS_ERROR_UNEXPECTED);
@ -3113,7 +3306,10 @@ nsDOMDeviceStorage::FreeSpace(ErrorResult& aRv)
nsCOMPtr<nsIRunnable> r nsCOMPtr<nsIRunnable> r
= new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_FREE_SPACE, = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_FREE_SPACE,
win, mPrincipal, dsf, request); win, mPrincipal, dsf, request);
NS_DispatchToMainThread(r); nsresult rv = NS_DispatchToCurrentThread(r);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
return request.forget(); return request.forget();
} }
@ -3129,6 +3325,8 @@ nsDOMDeviceStorage::UsedSpace(nsIDOMDOMRequest** aRetval)
already_AddRefed<DOMRequest> already_AddRefed<DOMRequest>
nsDOMDeviceStorage::UsedSpace(ErrorResult& aRv) nsDOMDeviceStorage::UsedSpace(ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsPIDOMWindow> win = GetOwner(); nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) { if (!win) {
aRv.Throw(NS_ERROR_UNEXPECTED); aRv.Throw(NS_ERROR_UNEXPECTED);
@ -3146,7 +3344,10 @@ nsDOMDeviceStorage::UsedSpace(ErrorResult& aRv)
nsCOMPtr<nsIRunnable> r nsCOMPtr<nsIRunnable> r
= new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_USED_SPACE, = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_USED_SPACE,
win, mPrincipal, dsf, request); win, mPrincipal, dsf, request);
NS_DispatchToMainThread(r); nsresult rv = NS_DispatchToCurrentThread(r);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
return request.forget(); return request.forget();
} }
@ -3162,6 +3363,8 @@ nsDOMDeviceStorage::Available(nsIDOMDOMRequest** aRetval)
already_AddRefed<DOMRequest> already_AddRefed<DOMRequest>
nsDOMDeviceStorage::Available(ErrorResult& aRv) nsDOMDeviceStorage::Available(ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsPIDOMWindow> win = GetOwner(); nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) { if (!win) {
aRv.Throw(NS_ERROR_UNEXPECTED); aRv.Throw(NS_ERROR_UNEXPECTED);
@ -3175,13 +3378,18 @@ nsDOMDeviceStorage::Available(ErrorResult& aRv)
nsCOMPtr<nsIRunnable> r nsCOMPtr<nsIRunnable> r
= new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_AVAILABLE, = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_AVAILABLE,
win, mPrincipal, dsf, request); win, mPrincipal, dsf, request);
NS_DispatchToMainThread(r); nsresult rv = NS_DispatchToCurrentThread(r);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
return request.forget(); return request.forget();
} }
already_AddRefed<DOMRequest> already_AddRefed<DOMRequest>
nsDOMDeviceStorage::Format(ErrorResult& aRv) nsDOMDeviceStorage::Format(ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsPIDOMWindow> win = GetOwner(); nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) { if (!win) {
aRv.Throw(NS_ERROR_UNEXPECTED); aRv.Throw(NS_ERROR_UNEXPECTED);
@ -3195,26 +3403,66 @@ nsDOMDeviceStorage::Format(ErrorResult& aRv)
nsCOMPtr<nsIRunnable> r nsCOMPtr<nsIRunnable> r
= new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_FORMAT, = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_FORMAT,
win, mPrincipal, dsf, request); win, mPrincipal, dsf, request);
NS_DispatchToMainThread(r); nsresult rv = NS_DispatchToCurrentThread(r);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
return request.forget(); return request.forget();
} }
NS_IMETHODIMP NS_IMETHODIMP
nsDOMDeviceStorage::GetRootDirectoryForFile(const nsAString& aName, nsDOMDeviceStorage::CreateFileDescriptor(const nsAString& aPath,
nsIFile** aRootDirectory) DeviceStorageFileDescriptor* aDSFileDescriptor,
nsIDOMDOMRequest** aRequest)
{ {
nsRefPtr<nsDOMDeviceStorage> ds; MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aDSFileDescriptor);
if (IsFullPath(aName)) { nsCOMPtr<nsPIDOMWindow> win = GetOwner();
nsString storagePath; if (!win) {
ds = GetStorage(aName, storagePath); return NS_ERROR_UNEXPECTED;
} else {
ds = this;
} }
if (!ds || !ds->mRootDirectory) {
DeviceStorageTypeChecker* typeChecker
= DeviceStorageTypeChecker::CreateOrGet();
if (!typeChecker) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
return ds->mRootDirectory->Clone(aRootDirectory);
nsCOMPtr<nsIRunnable> r;
nsresult rv;
if (IsFullPath(aPath)) {
nsString storagePath;
nsRefPtr<nsDOMDeviceStorage> ds = GetStorage(aPath, storagePath);
if (!ds) {
nsRefPtr<DOMRequest> request = new DOMRequest(win);
r = new PostErrorEvent(request, POST_ERROR_EVENT_UNKNOWN);
rv = NS_DispatchToCurrentThread(r);
request.forget(aRequest);
return rv;
}
return ds->CreateFileDescriptor(storagePath, aDSFileDescriptor, aRequest);
}
nsRefPtr<DOMRequest> request = new DOMRequest(win);
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
mStorageName,
aPath);
if (!dsf->IsSafePath()) {
r = new PostErrorEvent(request, POST_ERROR_EVENT_PERMISSION_DENIED);
} else if (!typeChecker->Check(mStorageType, dsf->mFile)) {
r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_TYPE);
} else {
r = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_CREATEFD,
win, mPrincipal, dsf, request,
aDSFileDescriptor);
}
rv = NS_DispatchToCurrentThread(r);
request.forget(aRequest);
return rv;
} }
bool bool
@ -3453,6 +3701,8 @@ nsDOMDeviceStorage::AddEventListener(const nsAString & aType,
bool aWantsUntrusted, bool aWantsUntrusted,
uint8_t aArgc) uint8_t aArgc)
{ {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsPIDOMWindow> win = GetOwner(); nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) { if (!win) {
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
@ -3464,7 +3714,11 @@ nsDOMDeviceStorage::AddEventListener(const nsAString & aType,
nsCOMPtr<nsIRunnable> r nsCOMPtr<nsIRunnable> r
= new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_WATCH, = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_WATCH,
win, mPrincipal, dsf, request, this); win, mPrincipal, dsf, request, this);
NS_DispatchToMainThread(r); nsresult rv = NS_DispatchToCurrentThread(r);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return nsDOMEventTargetHelper::AddEventListener(aType, aListener, aUseCapture, return nsDOMEventTargetHelper::AddEventListener(aType, aListener, aUseCapture,
aWantsUntrusted, aArgc); aWantsUntrusted, aArgc);
} }
@ -3476,6 +3730,8 @@ nsDOMDeviceStorage::AddEventListener(const nsAString & aType,
const Nullable<bool>& aWantsUntrusted, const Nullable<bool>& aWantsUntrusted,
ErrorResult& aRv) ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsPIDOMWindow> win = GetOwner(); nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) { if (!win) {
aRv.Throw(NS_ERROR_UNEXPECTED); aRv.Throw(NS_ERROR_UNEXPECTED);
@ -3488,7 +3744,10 @@ nsDOMDeviceStorage::AddEventListener(const nsAString & aType,
nsCOMPtr<nsIRunnable> r nsCOMPtr<nsIRunnable> r
= new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_WATCH, = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_WATCH,
win, mPrincipal, dsf, request, this); win, mPrincipal, dsf, request, this);
NS_DispatchToMainThread(r); nsresult rv = NS_DispatchToCurrentThread(r);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
nsDOMEventTargetHelper::AddEventListener(aType, aListener, aUseCapture, nsDOMEventTargetHelper::AddEventListener(aType, aListener, aUseCapture,
aWantsUntrusted, aRv); aWantsUntrusted, aRv);
} }

Просмотреть файл

@ -52,7 +52,8 @@ enum DeviceStorageRequestType {
DEVICE_STORAGE_REQUEST_FREE_SPACE, DEVICE_STORAGE_REQUEST_FREE_SPACE,
DEVICE_STORAGE_REQUEST_USED_SPACE, DEVICE_STORAGE_REQUEST_USED_SPACE,
DEVICE_STORAGE_REQUEST_AVAILABLE, DEVICE_STORAGE_REQUEST_AVAILABLE,
DEVICE_STORAGE_REQUEST_FORMAT DEVICE_STORAGE_REQUEST_FORMAT,
DEVICE_STORAGE_REQUEST_CREATEFD
}; };
class DeviceStorageUsedSpaceCache MOZ_FINAL class DeviceStorageUsedSpaceCache MOZ_FINAL

Просмотреть файл

@ -11,7 +11,12 @@ interface nsIDOMDeviceStorageChangeEvent;
interface nsIDOMEventListener; interface nsIDOMEventListener;
interface nsIFile; interface nsIFile;
[scriptable, uuid(7c1b2305-0f14-4c07-8a8a-359eeb850068), builtinclass] %{C++
class DeviceStorageFileDescriptor;
%}
[ptr] native DeviceStorageFdPtr(DeviceStorageFileDescriptor);
[scriptable, uuid(8b724547-3c78-4244-969a-f00a1f4ae0c3), builtinclass]
interface nsIDOMDeviceStorage : nsIDOMEventTarget interface nsIDOMDeviceStorage : nsIDOMEventTarget
{ {
[implicit_jscontext] attribute jsval onchange; [implicit_jscontext] attribute jsval onchange;
@ -34,5 +39,8 @@ interface nsIDOMDeviceStorage : nsIDOMEventTarget
// for storing new files. // for storing new files.
readonly attribute bool default; readonly attribute bool default;
[noscript] nsIFile getRootDirectoryForFile(in DOMString aName); // Note: aFileDescriptor is reference counted, which is why we're using
// a pointer rather than a reference.
[noscript] nsIDOMDOMRequest createFileDescriptor(in DOMString aName,
in DeviceStorageFdPtr aFileDescriptor);
}; };

Просмотреть файл

@ -94,6 +94,13 @@ struct DeviceStorageAddParams
PBlob blob; PBlob blob;
}; };
struct DeviceStorageCreateFdParams
{
nsString type;
nsString storageName;
nsString relpath;
};
struct DeviceStorageGetParams struct DeviceStorageGetParams
{ {
nsString type; nsString type;
@ -120,6 +127,7 @@ struct DeviceStorageEnumerationParams
union DeviceStorageParams union DeviceStorageParams
{ {
DeviceStorageAddParams; DeviceStorageAddParams;
DeviceStorageCreateFdParams;
DeviceStorageGetParams; DeviceStorageGetParams;
DeviceStorageDeleteParams; DeviceStorageDeleteParams;
DeviceStorageEnumerationParams; DeviceStorageEnumerationParams;