/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "DeviceStorageRequestParent.h" #include "nsIMIMEService.h" #include "nsCExternalHandlerService.h" #include "mozilla/unused.h" #include "mozilla/dom/File.h" #include "mozilla/dom/ipc/BlobParent.h" #include "ContentParent.h" #include "nsProxyRelease.h" #include "AppProcessChecker.h" #include "mozilla/Preferences.h" #include "nsNetCID.h" namespace mozilla { namespace dom { namespace devicestorage { DeviceStorageRequestParent::DeviceStorageRequestParent( const DeviceStorageParams& aParams) : mParams(aParams) , mMutex("DeviceStorageRequestParent::mMutex") , mActorDestoryed(false) { MOZ_COUNT_CTOR(DeviceStorageRequestParent); DebugOnly usedSpaceCache = DeviceStorageUsedSpaceCache::CreateOrGet(); MOZ_ASSERT(usedSpaceCache); } void DeviceStorageRequestParent::Dispatch() { switch (mParams.type()) { case DeviceStorageParams::TDeviceStorageAddParams: { DeviceStorageAddParams p = mParams; nsRefPtr dsf = new DeviceStorageFile(p.type(), p.storageName(), p.relpath()); BlobParent* bp = static_cast(p.blobParent()); nsRefPtr blobImpl = bp->GetBlobImpl(); nsCOMPtr stream; blobImpl->GetInternalStream(getter_AddRefs(stream)); nsRefPtr r = new WriteFileEvent(this, dsf, stream, DEVICE_STORAGE_REQUEST_CREATE); nsCOMPtr target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); MOZ_ASSERT(target); target->Dispatch(r, NS_DISPATCH_NORMAL); break; } case DeviceStorageParams::TDeviceStorageAppendParams: { DeviceStorageAppendParams p = mParams; nsRefPtr dsf = new DeviceStorageFile(p.type(), p.storageName(), p.relpath()); BlobParent* bp = static_cast(p.blobParent()); nsRefPtr blobImpl = bp->GetBlobImpl(); nsCOMPtr stream; blobImpl->GetInternalStream(getter_AddRefs(stream)); nsRefPtr r = new WriteFileEvent(this, dsf, stream, DEVICE_STORAGE_REQUEST_APPEND); nsCOMPtr target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); MOZ_ASSERT(target); target->Dispatch(r, NS_DISPATCH_NORMAL); 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); MOZ_ASSERT(target); target->Dispatch(r, NS_DISPATCH_NORMAL); break; } case DeviceStorageParams::TDeviceStorageGetParams: { DeviceStorageGetParams p = mParams; nsRefPtr dsf = new DeviceStorageFile(p.type(), p.storageName(), p.rootDir(), p.relpath()); nsRefPtr r = new ReadFileEvent(this, dsf); nsCOMPtr target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); MOZ_ASSERT(target); target->Dispatch(r, NS_DISPATCH_NORMAL); break; } case DeviceStorageParams::TDeviceStorageDeleteParams: { DeviceStorageDeleteParams p = mParams; nsRefPtr dsf = new DeviceStorageFile(p.type(), p.storageName(), p.relpath()); nsRefPtr r = new DeleteFileEvent(this, dsf); nsCOMPtr target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); MOZ_ASSERT(target); target->Dispatch(r, NS_DISPATCH_NORMAL); break; } case DeviceStorageParams::TDeviceStorageFreeSpaceParams: { DeviceStorageFreeSpaceParams p = mParams; nsRefPtr dsf = new DeviceStorageFile(p.type(), p.storageName()); nsRefPtr r = new FreeSpaceFileEvent(this, dsf); nsCOMPtr target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); MOZ_ASSERT(target); target->Dispatch(r, NS_DISPATCH_NORMAL); break; } case DeviceStorageParams::TDeviceStorageUsedSpaceParams: { DeviceStorageUsedSpaceCache* usedSpaceCache = DeviceStorageUsedSpaceCache::CreateOrGet(); MOZ_ASSERT(usedSpaceCache); DeviceStorageUsedSpaceParams p = mParams; nsRefPtr dsf = new DeviceStorageFile(p.type(), p.storageName()); nsRefPtr r = new UsedSpaceFileEvent(this, dsf); usedSpaceCache->Dispatch(r); break; } case DeviceStorageParams::TDeviceStorageAvailableParams: { DeviceStorageAvailableParams p = mParams; nsRefPtr dsf = new DeviceStorageFile(p.type(), p.storageName()); nsRefPtr r = new PostAvailableResultEvent(this, dsf); DebugOnly rv = NS_DispatchToMainThread(r); MOZ_ASSERT(NS_SUCCEEDED(rv)); break; } case DeviceStorageParams::TDeviceStorageStatusParams: { DeviceStorageStatusParams p = mParams; nsRefPtr dsf = new DeviceStorageFile(p.type(), p.storageName()); nsRefPtr r = new PostStatusResultEvent(this, dsf); DebugOnly rv = NS_DispatchToMainThread(r); MOZ_ASSERT(NS_SUCCEEDED(rv)); break; } case DeviceStorageParams::TDeviceStorageFormatParams: { DeviceStorageFormatParams p = mParams; nsRefPtr dsf = new DeviceStorageFile(p.type(), p.storageName()); nsRefPtr r = new PostFormatResultEvent(this, dsf); DebugOnly rv = NS_DispatchToMainThread(r); MOZ_ASSERT(NS_SUCCEEDED(rv)); break; } case DeviceStorageParams::TDeviceStorageMountParams: { DeviceStorageMountParams p = mParams; nsRefPtr dsf = new DeviceStorageFile(p.type(), p.storageName()); nsRefPtr r = new PostMountResultEvent(this, dsf); DebugOnly rv = NS_DispatchToMainThread(r); MOZ_ASSERT(NS_SUCCEEDED(rv)); break; } case DeviceStorageParams::TDeviceStorageUnmountParams: { DeviceStorageUnmountParams p = mParams; nsRefPtr dsf = new DeviceStorageFile(p.type(), p.storageName()); nsRefPtr r = new PostUnmountResultEvent(this, dsf); DebugOnly rv = NS_DispatchToMainThread(r); MOZ_ASSERT(NS_SUCCEEDED(rv)); break; } case DeviceStorageParams::TDeviceStorageEnumerationParams: { DeviceStorageEnumerationParams p = mParams; nsRefPtr dsf = new DeviceStorageFile(p.type(), p.storageName(), p.rootdir(), NS_LITERAL_STRING("")); nsRefPtr r = new EnumerateFileEvent(this, dsf, p.since()); nsCOMPtr target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); MOZ_ASSERT(target); target->Dispatch(r, NS_DISPATCH_NORMAL); break; } default: { NS_RUNTIMEABORT("not reached"); break; } } } bool DeviceStorageRequestParent::EnsureRequiredPermissions( mozilla::dom::ContentParent* aParent) { if (mozilla::Preferences::GetBool("device.storage.testing", false)) { return true; } nsString type; DeviceStorageRequestType requestType; switch (mParams.type()) { case DeviceStorageParams::TDeviceStorageAddParams: { DeviceStorageAddParams p = mParams; type = p.type(); requestType = DEVICE_STORAGE_REQUEST_CREATE; break; } case DeviceStorageParams::TDeviceStorageAppendParams: { DeviceStorageAppendParams p = mParams; type = p.type(); requestType = DEVICE_STORAGE_REQUEST_APPEND; break; } case DeviceStorageParams::TDeviceStorageCreateFdParams: { DeviceStorageCreateFdParams p = mParams; type = p.type(); requestType = DEVICE_STORAGE_REQUEST_CREATEFD; break; } case DeviceStorageParams::TDeviceStorageGetParams: { DeviceStorageGetParams p = mParams; type = p.type(); requestType = DEVICE_STORAGE_REQUEST_READ; break; } case DeviceStorageParams::TDeviceStorageDeleteParams: { DeviceStorageDeleteParams p = mParams; type = p.type(); requestType = DEVICE_STORAGE_REQUEST_DELETE; break; } case DeviceStorageParams::TDeviceStorageFreeSpaceParams: { DeviceStorageFreeSpaceParams p = mParams; type = p.type(); requestType = DEVICE_STORAGE_REQUEST_FREE_SPACE; break; } case DeviceStorageParams::TDeviceStorageUsedSpaceParams: { DeviceStorageUsedSpaceParams p = mParams; type = p.type(); requestType = DEVICE_STORAGE_REQUEST_FREE_SPACE; break; } case DeviceStorageParams::TDeviceStorageAvailableParams: { DeviceStorageAvailableParams p = mParams; type = p.type(); requestType = DEVICE_STORAGE_REQUEST_AVAILABLE; break; } case DeviceStorageParams::TDeviceStorageStatusParams: { DeviceStorageStatusParams p = mParams; type = p.type(); requestType = DEVICE_STORAGE_REQUEST_STATUS; break; } case DeviceStorageParams::TDeviceStorageFormatParams: { DeviceStorageFormatParams p = mParams; type = p.type(); requestType = DEVICE_STORAGE_REQUEST_FORMAT; break; } case DeviceStorageParams::TDeviceStorageMountParams: { DeviceStorageMountParams p = mParams; type = p.type(); requestType = DEVICE_STORAGE_REQUEST_MOUNT; break; } case DeviceStorageParams::TDeviceStorageUnmountParams: { DeviceStorageUnmountParams p = mParams; type = p.type(); requestType = DEVICE_STORAGE_REQUEST_UNMOUNT; break; } case DeviceStorageParams::TDeviceStorageEnumerationParams: { DeviceStorageEnumerationParams p = mParams; type = p.type(); requestType = DEVICE_STORAGE_REQUEST_READ; break; } default: { return false; } } // The 'apps' type is special. We only want this exposed // if the caller has the "webapps-manage" permission. if (type.EqualsLiteral("apps")) { if (!AssertAppProcessPermission(aParent, "webapps-manage")) { return false; } } nsAutoCString permissionName; nsresult rv = DeviceStorageTypeChecker::GetPermissionForType(type, permissionName); if (NS_FAILED(rv)) { return false; } nsCString access; rv = DeviceStorageTypeChecker::GetAccessForRequest(requestType, access); if (NS_FAILED(rv)) { return false; } permissionName.Append('-'); permissionName.Append(access); if (!AssertAppProcessPermission(aParent, permissionName.get())) { return false; } return true; } DeviceStorageRequestParent::~DeviceStorageRequestParent() { MOZ_COUNT_DTOR(DeviceStorageRequestParent); } NS_IMPL_ADDREF(DeviceStorageRequestParent) NS_IMPL_RELEASE(DeviceStorageRequestParent) void DeviceStorageRequestParent::ActorDestroy(ActorDestroyReason) { MutexAutoLock lock(mMutex); mActorDestoryed = true; int32_t count = mRunnables.Length(); for (int32_t index = 0; index < count; index++) { mRunnables[index]->Cancel(); } } DeviceStorageRequestParent::PostFreeSpaceResultEvent::PostFreeSpaceResultEvent( DeviceStorageRequestParent* aParent, uint64_t aFreeSpace) : CancelableRunnable(aParent) , mFreeSpace(aFreeSpace) { } DeviceStorageRequestParent::PostFreeSpaceResultEvent:: ~PostFreeSpaceResultEvent() {} nsresult DeviceStorageRequestParent::PostFreeSpaceResultEvent::CancelableRun() { MOZ_ASSERT(NS_IsMainThread()); FreeSpaceStorageResponse response(mFreeSpace); unused << mParent->Send__delete__(mParent, response); return NS_OK; } DeviceStorageRequestParent::PostUsedSpaceResultEvent:: PostUsedSpaceResultEvent(DeviceStorageRequestParent* aParent, const nsAString& aType, uint64_t aUsedSpace) : CancelableRunnable(aParent) , mType(aType) , mUsedSpace(aUsedSpace) { } DeviceStorageRequestParent::PostUsedSpaceResultEvent:: ~PostUsedSpaceResultEvent() {} nsresult DeviceStorageRequestParent::PostUsedSpaceResultEvent::CancelableRun() { MOZ_ASSERT(NS_IsMainThread()); UsedSpaceStorageResponse response(mUsedSpace); unused << mParent->Send__delete__(mParent, response); return NS_OK; } DeviceStorageRequestParent::PostErrorEvent:: PostErrorEvent(DeviceStorageRequestParent* aParent, const char* aError) : CancelableRunnable(aParent) { CopyASCIItoUTF16(aError, mError); } DeviceStorageRequestParent::PostErrorEvent::~PostErrorEvent() {} nsresult DeviceStorageRequestParent::PostErrorEvent::CancelableRun() { MOZ_ASSERT(NS_IsMainThread()); ErrorResponse response(mError); unused << mParent->Send__delete__(mParent, response); return NS_OK; } DeviceStorageRequestParent::PostSuccessEvent:: PostSuccessEvent(DeviceStorageRequestParent* aParent) : CancelableRunnable(aParent) { } DeviceStorageRequestParent::PostSuccessEvent::~PostSuccessEvent() {} nsresult DeviceStorageRequestParent::PostSuccessEvent::CancelableRun() { MOZ_ASSERT(NS_IsMainThread()); SuccessResponse response; unused << mParent->Send__delete__(mParent, response); return NS_OK; } DeviceStorageRequestParent::PostBlobSuccessEvent:: PostBlobSuccessEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, uint32_t aLength, nsACString& aMimeType, uint64_t aLastModifiedDate) : CancelableRunnable(aParent) , mLength(aLength) , mLastModificationDate(aLastModifiedDate) , mFile(aFile) , mMimeType(aMimeType) { } DeviceStorageRequestParent::PostBlobSuccessEvent::~PostBlobSuccessEvent() {} nsresult DeviceStorageRequestParent::PostBlobSuccessEvent::CancelableRun() { MOZ_ASSERT(NS_IsMainThread()); nsString mime; CopyASCIItoUTF16(mMimeType, mime); nsString fullPath; mFile->GetFullPath(fullPath); nsRefPtr blob = new File(nullptr, new FileImplFile(fullPath, mime, mLength, mFile->mFile, mLastModificationDate)); ContentParent* cp = static_cast(mParent->Manager()); BlobParent* actor = cp->GetOrCreateActorForBlob(blob); if (!actor) { ErrorResponse response(NS_LITERAL_STRING(POST_ERROR_EVENT_UNKNOWN)); unused << mParent->Send__delete__(mParent, response); return NS_OK; } BlobResponse response; response.blobParent() = actor; unused << mParent->Send__delete__(mParent, response); return NS_OK; } DeviceStorageRequestParent::PostEnumerationSuccessEvent:: PostEnumerationSuccessEvent(DeviceStorageRequestParent* aParent, const nsAString& aStorageType, const nsAString& aRelPath, InfallibleTArray& aPaths) : CancelableRunnable(aParent) , mStorageType(aStorageType) , mRelPath(aRelPath) , mPaths(aPaths) { } DeviceStorageRequestParent::PostEnumerationSuccessEvent:: ~PostEnumerationSuccessEvent() {} nsresult DeviceStorageRequestParent::PostEnumerationSuccessEvent::CancelableRun() { MOZ_ASSERT(NS_IsMainThread()); EnumerationResponse response(mStorageType, mRelPath, mPaths); unused << mParent->Send__delete__(mParent, response); return NS_OK; } DeviceStorageRequestParent::CreateFdEvent:: CreateFdEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile) : CancelableRunnable(aParent) , mFile(aFile) { } DeviceStorageRequestParent::CreateFdEvent::~CreateFdEvent() { } nsresult DeviceStorageRequestParent::CreateFdEvent::CancelableRun() { MOZ_ASSERT(!NS_IsMainThread()); nsCOMPtr r; if (!mFile->mFile) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); return NS_DispatchToMainThread(r); } bool check = false; mFile->mFile->Exists(&check); if (check) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS); return NS_DispatchToMainThread(r); } FileDescriptor fileDescriptor; nsresult rv = mFile->CreateFileDescriptor(fileDescriptor); if (NS_FAILED(rv)) { NS_WARNING("CreateFileDescriptor failed"); mFile->Dump("CreateFileDescriptor failed"); 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, nsIInputStream* aInputStream, int32_t aRequestType) : CancelableRunnable(aParent) , mFile(aFile) , mInputStream(aInputStream) , mRequestType(aRequestType) { } DeviceStorageRequestParent::WriteFileEvent::~WriteFileEvent() { } nsresult DeviceStorageRequestParent::WriteFileEvent::CancelableRun() { MOZ_ASSERT(!NS_IsMainThread()); nsCOMPtr r; if (!mInputStream || !mFile->mFile) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); return NS_DispatchToMainThread(r); } bool check = false; nsresult rv; mFile->mFile->Exists(&check); if (mRequestType == DEVICE_STORAGE_REQUEST_CREATE) { if (check) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS); return NS_DispatchToMainThread(r); } rv = mFile->Write(mInputStream); } else if (mRequestType == DEVICE_STORAGE_REQUEST_APPEND) { if (!check) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST); return NS_DispatchToMainThread(r); } rv = mFile->Append(mInputStream); } else { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); return NS_DispatchToMainThread(r); } if (NS_FAILED(rv)) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); } else { r = new PostPathResultEvent(mParent, mFile->mPath); } return NS_DispatchToMainThread(r); } DeviceStorageRequestParent::DeleteFileEvent:: DeleteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile) : CancelableRunnable(aParent) , mFile(aFile) { } DeviceStorageRequestParent::DeleteFileEvent::~DeleteFileEvent() { } nsresult DeviceStorageRequestParent::DeleteFileEvent::CancelableRun() { MOZ_ASSERT(!NS_IsMainThread()); mFile->Remove(); nsCOMPtr r; if (!mFile->mFile) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); return NS_DispatchToMainThread(r); } bool check = false; mFile->mFile->Exists(&check); if (check) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); } else { r = new PostPathResultEvent(mParent, mFile->mPath); } return NS_DispatchToMainThread(r); } DeviceStorageRequestParent::FreeSpaceFileEvent:: FreeSpaceFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile) : CancelableRunnable(aParent) , mFile(aFile) { } DeviceStorageRequestParent::FreeSpaceFileEvent::~FreeSpaceFileEvent() { } nsresult DeviceStorageRequestParent::FreeSpaceFileEvent::CancelableRun() { MOZ_ASSERT(!NS_IsMainThread()); int64_t freeSpace = 0; if (mFile) { mFile->GetDiskFreeSpace(&freeSpace); } nsCOMPtr r; r = new PostFreeSpaceResultEvent(mParent, static_cast(freeSpace)); return NS_DispatchToMainThread(r); } DeviceStorageRequestParent::UsedSpaceFileEvent:: UsedSpaceFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile) : CancelableRunnable(aParent) , mFile(aFile) { } DeviceStorageRequestParent::UsedSpaceFileEvent::~UsedSpaceFileEvent() { } nsresult DeviceStorageRequestParent::UsedSpaceFileEvent::CancelableRun() { MOZ_ASSERT(!NS_IsMainThread()); uint64_t picturesUsage = 0, videosUsage = 0, musicUsage = 0, totalUsage = 0; mFile->AccumDiskUsage(&picturesUsage, &videosUsage, &musicUsage, &totalUsage); nsCOMPtr r; if (mFile->mStorageType.EqualsLiteral(DEVICESTORAGE_PICTURES)) { r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, picturesUsage); } else if (mFile->mStorageType.EqualsLiteral(DEVICESTORAGE_VIDEOS)) { r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, videosUsage); } else if (mFile->mStorageType.EqualsLiteral(DEVICESTORAGE_MUSIC)) { r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, musicUsage); } else { r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, totalUsage); } return NS_DispatchToMainThread(r); } DeviceStorageRequestParent::ReadFileEvent:: ReadFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile) : CancelableRunnable(aParent) , mFile(aFile) { nsCOMPtr mimeService = do_GetService(NS_MIMESERVICE_CONTRACTID); if (mimeService) { nsresult rv = mimeService->GetTypeFromFile(mFile->mFile, mMimeType); if (NS_FAILED(rv)) { mMimeType.Truncate(); } } } DeviceStorageRequestParent::ReadFileEvent::~ReadFileEvent() { } nsresult DeviceStorageRequestParent::ReadFileEvent::CancelableRun() { MOZ_ASSERT(!NS_IsMainThread()); nsCOMPtr r; if (!mFile->mFile) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); return NS_DispatchToMainThread(r); } bool check = false; mFile->mFile->Exists(&check); if (!check) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST); 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); return NS_DispatchToMainThread(r); } PRTime modDate; rv = mFile->mFile->GetLastModifiedTime(&modDate); if (NS_FAILED(rv)) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN); return NS_DispatchToMainThread(r); } r = new PostBlobSuccessEvent(mParent, mFile, static_cast(fileSize), mMimeType, modDate); return NS_DispatchToMainThread(r); } DeviceStorageRequestParent::EnumerateFileEvent:: EnumerateFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, uint64_t aSince) : CancelableRunnable(aParent) , mFile(aFile) , mSince(aSince) { } DeviceStorageRequestParent::EnumerateFileEvent::~EnumerateFileEvent() { } nsresult DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun() { MOZ_ASSERT(!NS_IsMainThread()); nsCOMPtr r; if (mFile->mFile) { bool check = false; mFile->mFile->Exists(&check); if (!check) { r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST); return NS_DispatchToMainThread(r); } } nsTArray > files; mFile->CollectFiles(files, mSince); InfallibleTArray values; uint32_t count = files.Length(); for (uint32_t i = 0; i < count; i++) { DeviceStorageFileValue dsvf(files[i]->mStorageName, files[i]->mPath); values.AppendElement(dsvf); } r = new PostEnumerationSuccessEvent(mParent, mFile->mStorageType, mFile->mRootDir, values); return NS_DispatchToMainThread(r); } DeviceStorageRequestParent::PostPathResultEvent:: PostPathResultEvent(DeviceStorageRequestParent* aParent, const nsAString& aPath) : CancelableRunnable(aParent) , mPath(aPath) { } DeviceStorageRequestParent::PostPathResultEvent::~PostPathResultEvent() { } nsresult DeviceStorageRequestParent::PostPathResultEvent::CancelableRun() { MOZ_ASSERT(NS_IsMainThread()); SuccessResponse response; unused << mParent->Send__delete__(mParent, response); return NS_OK; } DeviceStorageRequestParent::PostFileDescriptorResultEvent:: PostFileDescriptorResultEvent(DeviceStorageRequestParent* aParent, const FileDescriptor& aFileDescriptor) : CancelableRunnable(aParent) , mFileDescriptor(aFileDescriptor) { } DeviceStorageRequestParent::PostFileDescriptorResultEvent:: ~PostFileDescriptorResultEvent() { } nsresult DeviceStorageRequestParent::PostFileDescriptorResultEvent::CancelableRun() { MOZ_ASSERT(NS_IsMainThread()); FileDescriptorResponse response(mFileDescriptor); unused << mParent->Send__delete__(mParent, response); return NS_OK; } DeviceStorageRequestParent::PostAvailableResultEvent:: PostAvailableResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile) : CancelableRunnable(aParent) , mFile(aFile) { } DeviceStorageRequestParent::PostAvailableResultEvent:: ~PostAvailableResultEvent() { } nsresult DeviceStorageRequestParent::PostAvailableResultEvent::CancelableRun() { MOZ_ASSERT(NS_IsMainThread()); nsString state = NS_LITERAL_STRING("unavailable"); if (mFile) { mFile->GetStatus(state); } AvailableStorageResponse response(state); unused << mParent->Send__delete__(mParent, response); return NS_OK; } DeviceStorageRequestParent::PostStatusResultEvent:: PostStatusResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile) : CancelableRunnable(aParent) , mFile(aFile) { } DeviceStorageRequestParent::PostStatusResultEvent:: ~PostStatusResultEvent() { } nsresult DeviceStorageRequestParent::PostStatusResultEvent::CancelableRun() { MOZ_ASSERT(NS_IsMainThread()); nsString state = NS_LITERAL_STRING("undefined"); if (mFile) { mFile->GetStorageStatus(state); } StorageStatusResponse response(state); unused << mParent->Send__delete__(mParent, response); return NS_OK; } DeviceStorageRequestParent::PostFormatResultEvent:: PostFormatResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile) : CancelableRunnable(aParent) , mFile(aFile) { } DeviceStorageRequestParent::PostFormatResultEvent:: ~PostFormatResultEvent() { } nsresult DeviceStorageRequestParent::PostFormatResultEvent::CancelableRun() { MOZ_ASSERT(NS_IsMainThread()); nsString state = NS_LITERAL_STRING("unavailable"); if (mFile) { mFile->DoFormat(state); } FormatStorageResponse response(state); unused << mParent->Send__delete__(mParent, response); return NS_OK; } DeviceStorageRequestParent::PostMountResultEvent:: PostMountResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile) : CancelableRunnable(aParent) , mFile(aFile) { } DeviceStorageRequestParent::PostMountResultEvent:: ~PostMountResultEvent() { } nsresult DeviceStorageRequestParent::PostMountResultEvent::CancelableRun() { MOZ_ASSERT(NS_IsMainThread()); nsString state = NS_LITERAL_STRING("unavailable"); if (mFile) { mFile->DoMount(state); } MountStorageResponse response(state); unused << mParent->Send__delete__(mParent, response); return NS_OK; } DeviceStorageRequestParent::PostUnmountResultEvent:: PostUnmountResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile) : CancelableRunnable(aParent) , mFile(aFile) { } DeviceStorageRequestParent::PostUnmountResultEvent:: ~PostUnmountResultEvent() { } nsresult DeviceStorageRequestParent::PostUnmountResultEvent::CancelableRun() { MOZ_ASSERT(NS_IsMainThread()); nsString state = NS_LITERAL_STRING("unavailable"); if (mFile) { mFile->DoUnmount(state); } UnmountStorageResponse response(state); unused << mParent->Send__delete__(mParent, response); return NS_OK; } } // namespace devicestorage } // namespace dom } // namespace mozilla