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