diff --git a/dom/devicestorage/DeviceStorage.h b/dom/devicestorage/DeviceStorage.h index 42405589078d..77ddf9a59bf0 100644 --- a/dom/devicestorage/DeviceStorage.h +++ b/dom/devicestorage/DeviceStorage.h @@ -14,7 +14,8 @@ #include "nsDOMEventTargetHelper.h" #include "mozilla/RefPtr.h" #include "mozilla/StaticPtr.h" -#include "DOMRequest.h" +#include "mozilla/dom/DOMRequest.h" +#include "mozilla/ipc/FileDescriptor.h" #define DEVICESTORAGE_PICTURES "pictures" #define DEVICESTORAGE_VIDEOS "videos" @@ -23,6 +24,7 @@ #define DEVICESTORAGE_SDCARD "sdcard" #define DEVICESTORAGE_CRASHES "crashes" +class DeviceStorageFile; class nsIInputStream; namespace mozilla { @@ -33,6 +35,14 @@ class DOMRequest; } // namespace dom } // namespace mozilla +class DeviceStorageFileDescriptor MOZ_FINAL + : public mozilla::RefCounted +{ +public: + nsRefPtr mDSFile; + mozilla::ipc::FileDescriptor mFileDescriptor; +}; + class DeviceStorageFile MOZ_FINAL : public nsISupports { public: @@ -102,6 +112,7 @@ public: nsresult CalculateSizeAndModifiedDate(); nsresult CalculateMimeType(); + nsresult CreateFileDescriptor(mozilla::ipc::FileDescriptor& aFileDescriptor); private: void Init(); diff --git a/dom/devicestorage/DeviceStorageRequestChild.cpp b/dom/devicestorage/DeviceStorageRequestChild.cpp index ff08fcea2a7a..aae73327780a 100644 --- a/dom/devicestorage/DeviceStorageRequestChild.cpp +++ b/dom/devicestorage/DeviceStorageRequestChild.cpp @@ -20,11 +20,27 @@ DeviceStorageRequestChild::DeviceStorageRequestChild() } DeviceStorageRequestChild::DeviceStorageRequestChild(DOMRequest* aRequest, - DeviceStorageFile* aFile) + DeviceStorageFile* aDSFile) : mRequest(aRequest) - , mFile(aFile) + , mDSFile(aDSFile) , 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); } @@ -53,7 +69,7 @@ DeviceStorageRequestChild:: case DeviceStorageResponseValue::TSuccessResponse: { nsString fullPath; - mFile->GetFullPath(fullPath); + mDSFile->GetFullPath(fullPath); AutoJSContext cx; JS::Rooted result(cx, StringToJsval(mRequest->GetOwner(), fullPath)); @@ -61,6 +77,22 @@ DeviceStorageRequestChild:: break; } + case DeviceStorageResponseValue::TFileDescriptorResponse: + { + FileDescriptorResponse r = aValue; + + nsString fullPath; + mDSFile->GetFullPath(fullPath); + AutoJSContext cx; + JS::Rooted result(cx, + StringToJsval(mRequest->GetOwner(), fullPath)); + + mDSFileDescriptor->mDSFile = mDSFile; + mDSFileDescriptor->mFileDescriptor = r.fileDescriptor(); + mRequest->FireSuccess(result); + break; + } + case DeviceStorageResponseValue::TBlobResponse: { BlobResponse r = aValue; diff --git a/dom/devicestorage/DeviceStorageRequestChild.h b/dom/devicestorage/DeviceStorageRequestChild.h index a04c45ee2bbb..83eae6cbff21 100644 --- a/dom/devicestorage/DeviceStorageRequestChild.h +++ b/dom/devicestorage/DeviceStorageRequestChild.h @@ -7,12 +7,15 @@ #define mozilla_dom_devicestorage_DeviceStorageRequestChild_h #include "mozilla/dom/devicestorage/PDeviceStorageRequestChild.h" -#include "DOMRequest.h" class DeviceStorageFile; +class DeviceStorageFileDescriptor; namespace mozilla { namespace dom { + +class DOMRequest; + namespace devicestorage { class DeviceStorageRequestChildCallback @@ -26,6 +29,8 @@ class DeviceStorageRequestChild : public PDeviceStorageRequestChild public: DeviceStorageRequestChild(); DeviceStorageRequestChild(DOMRequest* aRequest, DeviceStorageFile* aFile); + DeviceStorageRequestChild(DOMRequest* aRequest, DeviceStorageFile* aFile, + DeviceStorageFileDescriptor* aFileDescrptor); ~DeviceStorageRequestChild(); void SetCallback(class DeviceStorageRequestChildCallback *aCallback); @@ -34,7 +39,8 @@ public: private: nsRefPtr mRequest; - nsRefPtr mFile; + nsRefPtr mDSFile; + nsRefPtr mDSFileDescriptor; DeviceStorageRequestChildCallback* mCallback; }; diff --git a/dom/devicestorage/DeviceStorageRequestParent.cpp b/dom/devicestorage/DeviceStorageRequestParent.cpp index ecc2508c4450..c683b45891f5 100644 --- a/dom/devicestorage/DeviceStorageRequestParent.cpp +++ b/dom/devicestorage/DeviceStorageRequestParent.cpp @@ -35,6 +35,8 @@ DeviceStorageRequestParent::DeviceStorageRequestParent( void DeviceStorageRequestParent::Dispatch() { + nsresult rv; + switch (mParams.type()) { case DeviceStorageParams::TDeviceStorageAddParams: { @@ -58,6 +60,22 @@ DeviceStorageRequestParent::Dispatch() break; } + case DeviceStorageParams::TDeviceStorageCreateFdParams: + { + DeviceStorageCreateFdParams p = mParams; + + nsRefPtr dsf = + new DeviceStorageFile(p.type(), p.storageName(), p.relpath()); + + nsRefPtr r = new CreateFdEvent(this, dsf); + + nsCOMPtr target + = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); + NS_ASSERTION(target, "Must have stream transport service"); + target->Dispatch(r, NS_DISPATCH_NORMAL); + break; + } + case DeviceStorageParams::TDeviceStorageGetParams: { DeviceStorageGetParams p = mParams; @@ -127,7 +145,8 @@ DeviceStorageRequestParent::Dispatch() new DeviceStorageFile(p.type(), p.storageName()); nsRefPtr r = new PostAvailableResultEvent(this, dsf); - NS_DispatchToMainThread(r); + rv = NS_DispatchToMainThread(r); + MOZ_ASSERT(NS_SUCCEEDED(rv)); break; } @@ -139,7 +158,8 @@ DeviceStorageRequestParent::Dispatch() new DeviceStorageFile(p.type(), p.storageName()); nsRefPtr r = new PostFormatResultEvent(this, dsf); - NS_DispatchToMainThread(r); + rv = NS_DispatchToMainThread(r); + MOZ_ASSERT(NS_SUCCEEDED(rv)); break; } @@ -187,6 +207,14 @@ DeviceStorageRequestParent::EnsureRequiredPermissions( break; } + case DeviceStorageParams::TDeviceStorageCreateFdParams: + { + DeviceStorageCreateFdParams p = mParams; + type = p.type(); + requestType = DEVICE_STORAGE_REQUEST_CREATEFD; + break; + } + case DeviceStorageParams::TDeviceStorageGetParams: { DeviceStorageGetParams p = mParams; @@ -444,6 +472,46 @@ DeviceStorageRequestParent::PostEnumerationSuccessEvent::CancelableRun() { 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 r; + + bool check = false; + mFile->mFile->Exists(&check); + if (check) { + nsCOMPtr 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:: WriteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, @@ -467,8 +535,7 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun() if (!mInputStream) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } bool check = false; @@ -476,8 +543,7 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun() if (check) { nsCOMPtr event = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS); - NS_DispatchToMainThread(event); - return NS_OK; + return NS_DispatchToMainThread(event); } nsresult rv = mFile->Write(mInputStream); @@ -489,11 +555,9 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun() r = new PostPathResultEvent(mParent, mFile->mPath); } - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } - DeviceStorageRequestParent::DeleteFileEvent:: DeleteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile) : CancelableRunnable(aParent) @@ -523,8 +587,7 @@ DeviceStorageRequestParent::DeleteFileEvent::CancelableRun() r = new PostPathResultEvent(mParent, mFile->mPath); } - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } DeviceStorageRequestParent::FreeSpaceFileEvent:: @@ -551,8 +614,7 @@ DeviceStorageRequestParent::FreeSpaceFileEvent::CancelableRun() nsCOMPtr r; r = new PostFreeSpaceResultEvent(mParent, static_cast(freeSpace)); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } DeviceStorageRequestParent::UsedSpaceFileEvent:: @@ -588,8 +650,7 @@ DeviceStorageRequestParent::UsedSpaceFileEvent::CancelableRun() } else { r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, totalUsage); } - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } DeviceStorageRequestParent::ReadFileEvent:: @@ -622,30 +683,26 @@ DeviceStorageRequestParent::ReadFileEvent::CancelableRun() if (!check) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } int64_t fileSize; nsresult rv = mFile->mFile->GetFileSize(&fileSize); if (NS_FAILED(rv)) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } PRTime modDate; rv = mFile->mFile->GetLastModifiedTime(&modDate); if (NS_FAILED(rv)) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } r = new PostBlobSuccessEvent(mParent, mFile, static_cast(fileSize), mMimeType, modDate); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } DeviceStorageRequestParent::EnumerateFileEvent:: @@ -673,8 +730,7 @@ DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun() mFile->mFile->Exists(&check); if (!check) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } } @@ -691,8 +747,7 @@ DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun() r = new PostEnumerationSuccessEvent(mParent, mFile->mStorageType, mFile->mRootDir, values); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } @@ -718,6 +773,29 @@ DeviceStorageRequestParent::PostPathResultEvent::CancelableRun() 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:: PostAvailableResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile) diff --git a/dom/devicestorage/DeviceStorageRequestParent.h b/dom/devicestorage/DeviceStorageRequestParent.h index 8d8d18adff29..8801aa33a999 100644 --- a/dom/devicestorage/DeviceStorageRequestParent.h +++ b/dom/devicestorage/DeviceStorageRequestParent.h @@ -119,6 +119,16 @@ private: InfallibleTArray mPaths; }; + class CreateFdEvent : public CancelableRunnable + { + public: + CreateFdEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile); + virtual ~CreateFdEvent(); + virtual nsresult CancelableRun(); + private: + nsRefPtr mFile; + }; + class WriteFileEvent : public CancelableRunnable { public: @@ -193,6 +203,18 @@ private: nsString mPath; }; + class PostFileDescriptorResultEvent : public CancelableRunnable + { + public: + PostFileDescriptorResultEvent(DeviceStorageRequestParent* aParent, + const FileDescriptor& aFileDescriptor); + virtual ~PostFileDescriptorResultEvent(); + virtual nsresult CancelableRun(); + private: + nsRefPtr mFile; + FileDescriptor mFileDescriptor; + }; + class PostFreeSpaceResultEvent : public CancelableRunnable { public: diff --git a/dom/devicestorage/PDeviceStorageRequest.ipdl b/dom/devicestorage/PDeviceStorageRequest.ipdl index 8e57bf177bf2..2f4d5b505353 100644 --- a/dom/devicestorage/PDeviceStorageRequest.ipdl +++ b/dom/devicestorage/PDeviceStorageRequest.ipdl @@ -20,6 +20,11 @@ struct SuccessResponse { }; +struct FileDescriptorResponse +{ + FileDescriptor fileDescriptor; +}; + struct BlobResponse { PBlob blob; @@ -62,6 +67,7 @@ union DeviceStorageResponseValue { ErrorResponse; SuccessResponse; + FileDescriptorResponse; BlobResponse; EnumerationResponse; FreeSpaceStorageResponse; diff --git a/dom/devicestorage/nsDeviceStorage.cpp b/dom/devicestorage/nsDeviceStorage.cpp index b4bf85e1ff37..b252ca3cfcb9 100644 --- a/dom/devicestorage/nsDeviceStorage.cpp +++ b/dom/devicestorage/nsDeviceStorage.cpp @@ -49,6 +49,7 @@ #include "nsIStringBundle.h" #include "nsIDocument.h" #include +#include "private/pprio.h" #include "mozilla/dom/DeviceStorageBinding.h" @@ -67,6 +68,7 @@ using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::dom::devicestorage; +using namespace mozilla::ipc; #include "nsDirectoryServiceDefs.h" @@ -394,6 +396,7 @@ DeviceStorageTypeChecker::GetAccessForRequest( aAccessResult.AssignLiteral("write"); break; case DEVICE_STORAGE_REQUEST_CREATE: + case DEVICE_STORAGE_REQUEST_CREATEFD: aAccessResult.AssignLiteral("create"); break; default: @@ -923,6 +926,20 @@ DeviceStorageFile::AppendRelativePath(const nsAString& aPath) { #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 DeviceStorageFile::Write(nsIInputStream* aInputStream) { @@ -931,12 +948,15 @@ DeviceStorageFile::Write(nsIInputStream* aInputStream) } nsresult rv = mFile->Create(nsIFile::NORMAL_FILE_TYPE, 00600); - if (NS_FAILED(rv)) { + if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } nsCOMPtr 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; aInputStream->Available(&bufSize); @@ -967,11 +987,14 @@ DeviceStorageFile::Write(nsIInputStream* aInputStream) } iocomplete = new IOEventComplete(this, "modified"); - NS_DispatchToMainThread(iocomplete); + rv = NS_DispatchToMainThread(iocomplete); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } bufferedOutputStream->Close(); outputStream->Close(); - if (NS_FAILED(rv)) { + if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } return NS_OK; @@ -985,12 +1008,15 @@ DeviceStorageFile::Write(InfallibleTArray& aBits) } nsresult rv = mFile->Create(nsIFile::NORMAL_FILE_TYPE, 00600); - if (NS_FAILED(rv)) { + if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } nsCOMPtr iocomplete = new IOEventComplete(this, "created"); - NS_DispatchToMainThread(iocomplete); + rv = NS_DispatchToMainThread(iocomplete); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } nsCOMPtr outputStream; NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mFile); @@ -1004,7 +1030,10 @@ DeviceStorageFile::Write(InfallibleTArray& aBits) outputStream->Close(); 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) { return NS_ERROR_FAILURE; @@ -1032,13 +1061,12 @@ DeviceStorageFile::Remove() } rv = mFile->Remove(true); - if (NS_FAILED(rv)) { + if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } nsCOMPtr iocomplete = new IOEventComplete(this, "deleted"); - NS_DispatchToMainThread(iocomplete); - return NS_OK; + return NS_DispatchToMainThread(iocomplete); } nsresult @@ -1116,7 +1144,7 @@ DeviceStorageFile::collectFilesInternal( if (msecs < aSince) { continue; - } + } bool isDir; f->IsDirectory(&isDir); @@ -1619,8 +1647,11 @@ ContinueCursorEvent::~ContinueCursorEvent() {} void ContinueCursorEvent::Continue() { + nsresult rv; + if (XRE_GetProcessType() == GeckoProcessType_Default) { - NS_DispatchToMainThread(this); + rv = NS_DispatchToMainThread(this); + MOZ_ASSERT(NS_SUCCEEDED(rv)); return; } @@ -1628,7 +1659,8 @@ ContinueCursorEvent::Continue() if (!file) { // done with enumeration. - NS_DispatchToMainThread(this); + rv = NS_DispatchToMainThread(this); + MOZ_ASSERT(NS_SUCCEEDED(rv)); return; } @@ -1691,8 +1723,7 @@ public: nsCOMPtr event = new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_FILE_NOT_ENUMERABLE); - NS_DispatchToMainThread(event); - return NS_OK; + return NS_DispatchToMainThread(event); } } @@ -1782,8 +1813,7 @@ nsDOMDeviceStorageCursor::Cancel() { nsCOMPtr event = new PostErrorEvent(this, POST_ERROR_EVENT_PERMISSION_DENIED); - NS_DispatchToMainThread(event); - return NS_OK; + return NS_DispatchToMainThread(event); } NS_IMETHODIMP @@ -1792,8 +1822,7 @@ nsDOMDeviceStorageCursor::Allow() if (!mFile->IsSafePath()) { nsCOMPtr r = new PostErrorEvent(this, POST_ERROR_EVENT_PERMISSION_DENIED); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } if (XRE_GetProcessType() != GeckoProcessType_Default) { @@ -1870,6 +1899,7 @@ public: : mFile(aFile) , mRequest(aRequest) { + MOZ_ASSERT(mRequest); } ~PostAvailableResultEvent() {} @@ -1903,6 +1933,7 @@ public: : mFile(aFile) , mRequest(aRequest) { + MOZ_ASSERT(mRequest); } ~PostFormatResultEvent() {} @@ -1936,19 +1967,25 @@ public: DeviceStorageFile* aFile) : mFile(aFile) , mRequest(aRequest) - {} + { + MOZ_ASSERT(mRequest); + } PostResultEvent(already_AddRefed aRequest, const nsAString & aPath) : mPath(aPath) , mRequest(aRequest) - {} + { + MOZ_ASSERT(mRequest); + } PostResultEvent(already_AddRefed aRequest, const uint64_t aValue) : mValue(aValue) , mRequest(aRequest) - {} + { + MOZ_ASSERT(mRequest); + } ~PostResultEvent() {} @@ -1981,6 +2018,57 @@ private: nsRefPtr mRequest; }; +class CreateFdEvent : public nsRunnable +{ +public: + CreateFdEvent(DeviceStorageFileDescriptor* aDSFileDescriptor, + already_AddRefed 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 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 event = + new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_UNKNOWN); + return NS_DispatchToMainThread(event); + } + + nsCOMPtr event = + new PostResultEvent(mRequest.forget(), fullPath); + return NS_DispatchToMainThread(event); + } + +private: + nsRefPtr mDSFileDescriptor; + nsRefPtr mRequest; +}; + class WriteFileEvent : public nsRunnable { public: @@ -1990,7 +2078,10 @@ public: : mBlob(aBlob) , mFile(aFile) , mRequest(aRequest) - {} + { + MOZ_ASSERT(mFile); + MOZ_ASSERT(mRequest); + } ~WriteFileEvent() {} @@ -2006,8 +2097,7 @@ public: if (check) { nsCOMPtr event = new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_FILE_EXISTS); - NS_DispatchToMainThread(event); - return NS_OK; + return NS_DispatchToMainThread(event); } nsresult rv = mFile->Write(stream); @@ -2017,16 +2107,14 @@ public: nsCOMPtr event = new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_UNKNOWN); - NS_DispatchToMainThread(event); - return NS_OK; + return NS_DispatchToMainThread(event); } nsString fullPath; mFile->GetFullPath(fullPath); nsCOMPtr event = new PostResultEvent(mRequest.forget(), fullPath); - NS_DispatchToMainThread(event); - return NS_OK; + return NS_DispatchToMainThread(event); } private: @@ -2043,6 +2131,8 @@ public: : mFile(aFile) , mRequest(aRequest) { + MOZ_ASSERT(mFile); + MOZ_ASSERT(mRequest); mFile->CalculateMimeType(); } @@ -2072,8 +2162,7 @@ public: if (!r) { r = new PostResultEvent(mRequest.forget(), mFile); } - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } private: @@ -2088,7 +2177,10 @@ public: already_AddRefed aRequest) : mFile(aFile) , mRequest(aRequest) - {} + { + MOZ_ASSERT(mFile); + MOZ_ASSERT(mRequest); + } ~DeleteFileEvent() {} @@ -2109,8 +2201,7 @@ public: mFile->GetFullPath(fullPath); r = new PostResultEvent(mRequest.forget(), fullPath); } - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } private: @@ -2125,7 +2216,10 @@ public: already_AddRefed aRequest) : mFile(aFile) , mRequest(aRequest) - {} + { + MOZ_ASSERT(mFile); + MOZ_ASSERT(mRequest); + } ~UsedSpaceFileEvent() {} @@ -2148,8 +2242,7 @@ public: } else { r = new PostResultEvent(mRequest.forget(), totalUsage); } - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } private: @@ -2164,7 +2257,10 @@ public: already_AddRefed aRequest) : mFile(aFile) , mRequest(aRequest) - {} + { + MOZ_ASSERT(mFile); + MOZ_ASSERT(mRequest); + } ~FreeSpaceFileEvent() {} @@ -2180,8 +2276,7 @@ public: nsCOMPtr r; r = new PostResultEvent(mRequest.forget(), static_cast(freeSpace)); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToMainThread(r); } private: @@ -2196,32 +2291,65 @@ class DeviceStorageRequest MOZ_FINAL { public: - DeviceStorageRequest(const DeviceStorageRequestType aRequestType, - nsPIDOMWindow *aWindow, - nsIPrincipal *aPrincipal, - DeviceStorageFile *aFile, - DOMRequest* aRequest, - nsDOMDeviceStorage *aDeviceStorage) - : mRequestType(aRequestType) - , mWindow(aWindow) - , mPrincipal(aPrincipal) - , mFile(aFile) - , mRequest(aRequest) - , mDeviceStorage(aDeviceStorage) - {} + DeviceStorageRequest(const DeviceStorageRequestType aRequestType, + nsPIDOMWindow* aWindow, + nsIPrincipal* aPrincipal, + DeviceStorageFile* aFile, + DOMRequest* aRequest, + nsDOMDeviceStorage* aDeviceStorage) + : mRequestType(aRequestType) + , mWindow(aWindow) + , mPrincipal(aPrincipal) + , mFile(aFile) + , mRequest(aRequest) + , mDeviceStorage(aDeviceStorage) + { + MOZ_ASSERT(mWindow); + MOZ_ASSERT(mPrincipal); + MOZ_ASSERT(mFile); + MOZ_ASSERT(mRequest); + MOZ_ASSERT(mDeviceStorage); + } - DeviceStorageRequest(const DeviceStorageRequestType aRequestType, - nsPIDOMWindow *aWindow, - nsIPrincipal *aPrincipal, - DeviceStorageFile *aFile, - DOMRequest* aRequest, - nsIDOMBlob *aBlob = nullptr) - : mRequestType(aRequestType) - , mWindow(aWindow) - , mPrincipal(aPrincipal) - , mFile(aFile) - , mRequest(aRequest) - , mBlob(aBlob) {} + DeviceStorageRequest(const DeviceStorageRequestType aRequestType, + nsPIDOMWindow* aWindow, + nsIPrincipal* aPrincipal, + DeviceStorageFile* aFile, + DOMRequest* aRequest, + nsIDOMBlob* aBlob = nullptr) + : mRequestType(aRequestType) + , mWindow(aWindow) + , mPrincipal(aPrincipal) + , mFile(aFile) + , mRequest(aRequest) + , 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_COLLECTION_CLASS_AMBIGUOUS(DeviceStorageRequest, @@ -2321,19 +2449,59 @@ public: nsCOMPtr event = new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_PERMISSION_DENIED); - NS_DispatchToMainThread(event); - return NS_OK; + return NS_DispatchToMainThread(event); } NS_IMETHOD Allow() { - nsCOMPtr r; + MOZ_ASSERT(NS_IsMainThread()); if (!mRequest) { return NS_ERROR_FAILURE; } + nsCOMPtr r; + 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: { if (!mBlob || !mFile->mFile) { @@ -2350,8 +2518,7 @@ public: !typeChecker->Check(mFile->mStorageType, mBlob)) { r = new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_ILLEGAL_TYPE); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToCurrentThread(r); } if (XRE_GetProcessType() != GeckoProcessType_Default) { @@ -2394,8 +2561,7 @@ public: if (!typeChecker->Check(mFile->mStorageType, mFile->mFile)) { r = new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_ILLEGAL_TYPE); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToCurrentThread(r); } if (XRE_GetProcessType() != GeckoProcessType_Default) { @@ -2429,8 +2595,7 @@ public: if (!typeChecker->Check(mFile->mStorageType, mFile->mFile)) { r = new PostErrorEvent(mRequest.forget(), POST_ERROR_EVENT_ILLEGAL_TYPE); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToCurrentThread(r); } if (XRE_GetProcessType() != GeckoProcessType_Default) { @@ -2495,8 +2660,7 @@ public: return NS_OK; } r = new PostAvailableResultEvent(mFile, mRequest); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToCurrentThread(r); } case DEVICE_STORAGE_REQUEST_WATCH: @@ -2517,8 +2681,7 @@ public: return NS_OK; } r = new PostFormatResultEvent(mFile, mRequest); - NS_DispatchToMainThread(r); - return NS_OK; + return NS_DispatchToCurrentThread(r); } } @@ -2558,6 +2721,7 @@ private: nsRefPtr mRequest; nsCOMPtr mBlob; nsRefPtr mDeviceStorage; + nsRefPtr mDSFileDescriptor; }; NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeviceStorageRequest) @@ -2799,6 +2963,8 @@ nsDOMDeviceStorage::GetStorage(const nsAString& aFullPath, already_AddRefed nsDOMDeviceStorage::GetStorageByName(const nsAString& aStorageName) { + MOZ_ASSERT(NS_IsMainThread()); + nsRefPtr ds; if (mStorageName.Equals(aStorageName)) { @@ -2914,6 +3080,8 @@ already_AddRefed nsDOMDeviceStorage::AddNamed(nsIDOMBlob* aBlob, const nsAString& aPath, ErrorResult& aRv) { + MOZ_ASSERT(NS_IsMainThread()); + // if the blob is null here, bail if (!aBlob) { return nullptr; @@ -2933,6 +3101,7 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob* aBlob, const nsAString& aPath, } nsCOMPtr r; + nsresult rv; if (IsFullPath(aPath)) { nsString storagePath; @@ -2940,7 +3109,10 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob* aBlob, const nsAString& aPath, if (!ds) { nsRefPtr request = new DOMRequest(win); 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 ds->AddNamed(aBlob, storagePath, aRv); @@ -2961,7 +3133,10 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob* aBlob, const nsAString& aPath, win, mPrincipal, dsf, request, aBlob); } - NS_DispatchToMainThread(r); + rv = NS_DispatchToCurrentThread(r); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + } return request.forget(); } @@ -2988,6 +3163,8 @@ already_AddRefed nsDOMDeviceStorage::GetInternal(const nsAString& aPath, bool aEditable, ErrorResult& aRv) { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr win = GetOwner(); if (!win) { aRv.Throw(NS_ERROR_UNEXPECTED); @@ -3002,7 +3179,10 @@ nsDOMDeviceStorage::GetInternal(const nsAString& aPath, bool aEditable, if (!ds) { nsCOMPtr r = 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(); } ds->GetInternal(win, storagePath, request, aEditable); @@ -3018,6 +3198,8 @@ nsDOMDeviceStorage::GetInternal(nsPIDOMWindow *aWin, DOMRequest* aRequest, bool aEditable) { + MOZ_ASSERT(NS_IsMainThread()); + nsRefPtr dsf = new DeviceStorageFile(mStorageType, mStorageName, aPath); @@ -3031,7 +3213,8 @@ nsDOMDeviceStorage::GetInternal(nsPIDOMWindow *aWin, : DEVICE_STORAGE_REQUEST_READ, aWin, mPrincipal, dsf, aRequest); } - NS_DispatchToMainThread(r); + DebugOnly rv = NS_DispatchToCurrentThread(r); + MOZ_ASSERT(NS_SUCCEEDED(rv)); } NS_IMETHODIMP @@ -3046,6 +3229,8 @@ nsDOMDeviceStorage::Delete(const nsAString& aPath, nsIDOMDOMRequest** aRetval) already_AddRefed nsDOMDeviceStorage::Delete(const nsAString& aPath, ErrorResult& aRv) { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr win = GetOwner(); if (!win) { aRv.Throw(NS_ERROR_UNEXPECTED); @@ -3060,7 +3245,10 @@ nsDOMDeviceStorage::Delete(const nsAString& aPath, ErrorResult& aRv) if (!ds) { nsCOMPtr r = 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(); } ds->DeleteInternal(win, storagePath, request); @@ -3075,6 +3263,8 @@ nsDOMDeviceStorage::DeleteInternal(nsPIDOMWindow *aWin, const nsAString& aPath, DOMRequest* aRequest) { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr r; nsRefPtr dsf = new DeviceStorageFile(mStorageType, mStorageName, @@ -3085,7 +3275,8 @@ nsDOMDeviceStorage::DeleteInternal(nsPIDOMWindow *aWin, r = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_DELETE, aWin, mPrincipal, dsf, aRequest); } - NS_DispatchToMainThread(r); + DebugOnly rv = NS_DispatchToCurrentThread(r); + MOZ_ASSERT(NS_SUCCEEDED(rv)); } NS_IMETHODIMP @@ -3100,6 +3291,8 @@ nsDOMDeviceStorage::FreeSpace(nsIDOMDOMRequest** aRetval) already_AddRefed nsDOMDeviceStorage::FreeSpace(ErrorResult& aRv) { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr win = GetOwner(); if (!win) { aRv.Throw(NS_ERROR_UNEXPECTED); @@ -3113,7 +3306,10 @@ nsDOMDeviceStorage::FreeSpace(ErrorResult& aRv) nsCOMPtr r = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_FREE_SPACE, win, mPrincipal, dsf, request); - NS_DispatchToMainThread(r); + nsresult rv = NS_DispatchToCurrentThread(r); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + } return request.forget(); } @@ -3129,6 +3325,8 @@ nsDOMDeviceStorage::UsedSpace(nsIDOMDOMRequest** aRetval) already_AddRefed nsDOMDeviceStorage::UsedSpace(ErrorResult& aRv) { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr win = GetOwner(); if (!win) { aRv.Throw(NS_ERROR_UNEXPECTED); @@ -3146,7 +3344,10 @@ nsDOMDeviceStorage::UsedSpace(ErrorResult& aRv) nsCOMPtr r = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_USED_SPACE, win, mPrincipal, dsf, request); - NS_DispatchToMainThread(r); + nsresult rv = NS_DispatchToCurrentThread(r); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + } return request.forget(); } @@ -3162,6 +3363,8 @@ nsDOMDeviceStorage::Available(nsIDOMDOMRequest** aRetval) already_AddRefed nsDOMDeviceStorage::Available(ErrorResult& aRv) { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr win = GetOwner(); if (!win) { aRv.Throw(NS_ERROR_UNEXPECTED); @@ -3175,13 +3378,18 @@ nsDOMDeviceStorage::Available(ErrorResult& aRv) nsCOMPtr r = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_AVAILABLE, win, mPrincipal, dsf, request); - NS_DispatchToMainThread(r); + nsresult rv = NS_DispatchToCurrentThread(r); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + } return request.forget(); } already_AddRefed nsDOMDeviceStorage::Format(ErrorResult& aRv) { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr win = GetOwner(); if (!win) { aRv.Throw(NS_ERROR_UNEXPECTED); @@ -3195,26 +3403,66 @@ nsDOMDeviceStorage::Format(ErrorResult& aRv) nsCOMPtr r = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_FORMAT, win, mPrincipal, dsf, request); - NS_DispatchToMainThread(r); + nsresult rv = NS_DispatchToCurrentThread(r); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + } return request.forget(); } NS_IMETHODIMP -nsDOMDeviceStorage::GetRootDirectoryForFile(const nsAString& aName, - nsIFile** aRootDirectory) +nsDOMDeviceStorage::CreateFileDescriptor(const nsAString& aPath, + DeviceStorageFileDescriptor* aDSFileDescriptor, + nsIDOMDOMRequest** aRequest) { - nsRefPtr ds; + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aDSFileDescriptor); - if (IsFullPath(aName)) { - nsString storagePath; - ds = GetStorage(aName, storagePath); - } else { - ds = this; + nsCOMPtr win = GetOwner(); + if (!win) { + return NS_ERROR_UNEXPECTED; } - if (!ds || !ds->mRootDirectory) { + + DeviceStorageTypeChecker* typeChecker + = DeviceStorageTypeChecker::CreateOrGet(); + if (!typeChecker) { return NS_ERROR_FAILURE; } - return ds->mRootDirectory->Clone(aRootDirectory); + + nsCOMPtr r; + nsresult rv; + + if (IsFullPath(aPath)) { + nsString storagePath; + nsRefPtr ds = GetStorage(aPath, storagePath); + if (!ds) { + nsRefPtr 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 request = new DOMRequest(win); + + nsRefPtr 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 @@ -3453,6 +3701,8 @@ nsDOMDeviceStorage::AddEventListener(const nsAString & aType, bool aWantsUntrusted, uint8_t aArgc) { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr win = GetOwner(); if (!win) { return NS_ERROR_UNEXPECTED; @@ -3464,7 +3714,11 @@ nsDOMDeviceStorage::AddEventListener(const nsAString & aType, nsCOMPtr r = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_WATCH, 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, aWantsUntrusted, aArgc); } @@ -3476,6 +3730,8 @@ nsDOMDeviceStorage::AddEventListener(const nsAString & aType, const Nullable& aWantsUntrusted, ErrorResult& aRv) { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr win = GetOwner(); if (!win) { aRv.Throw(NS_ERROR_UNEXPECTED); @@ -3488,7 +3744,10 @@ nsDOMDeviceStorage::AddEventListener(const nsAString & aType, nsCOMPtr r = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_WATCH, 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, aWantsUntrusted, aRv); } diff --git a/dom/devicestorage/nsDeviceStorage.h b/dom/devicestorage/nsDeviceStorage.h index ad1fd1648466..c398e5c84f15 100644 --- a/dom/devicestorage/nsDeviceStorage.h +++ b/dom/devicestorage/nsDeviceStorage.h @@ -52,7 +52,8 @@ enum DeviceStorageRequestType { DEVICE_STORAGE_REQUEST_FREE_SPACE, DEVICE_STORAGE_REQUEST_USED_SPACE, DEVICE_STORAGE_REQUEST_AVAILABLE, - DEVICE_STORAGE_REQUEST_FORMAT + DEVICE_STORAGE_REQUEST_FORMAT, + DEVICE_STORAGE_REQUEST_CREATEFD }; class DeviceStorageUsedSpaceCache MOZ_FINAL diff --git a/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl b/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl index dd979fb20eb6..25b14fe1a725 100644 --- a/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl +++ b/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl @@ -11,7 +11,12 @@ interface nsIDOMDeviceStorageChangeEvent; interface nsIDOMEventListener; 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 { [implicit_jscontext] attribute jsval onchange; @@ -34,5 +39,8 @@ interface nsIDOMDeviceStorage : nsIDOMEventTarget // for storing new files. 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); }; diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 592835d7d6f3..a64e9a39eb73 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -94,6 +94,13 @@ struct DeviceStorageAddParams PBlob blob; }; +struct DeviceStorageCreateFdParams +{ + nsString type; + nsString storageName; + nsString relpath; +}; + struct DeviceStorageGetParams { nsString type; @@ -120,6 +127,7 @@ struct DeviceStorageEnumerationParams union DeviceStorageParams { DeviceStorageAddParams; + DeviceStorageCreateFdParams; DeviceStorageGetParams; DeviceStorageDeleteParams; DeviceStorageEnumerationParams;