diff options
Diffstat (limited to 'dom/media/gmp/GMPStorageParent.cpp')
-rw-r--r-- | dom/media/gmp/GMPStorageParent.cpp | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/dom/media/gmp/GMPStorageParent.cpp b/dom/media/gmp/GMPStorageParent.cpp new file mode 100644 index 000000000..e3eadeccf --- /dev/null +++ b/dom/media/gmp/GMPStorageParent.cpp @@ -0,0 +1,220 @@ +/* -*- 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 "GMPStorageParent.h" +#include "GMPParent.h" +#include "gmp-storage.h" +#include "mozilla/Unused.h" +#include "mozIGeckoMediaPluginService.h" + +namespace mozilla { + +#ifdef LOG +#undef LOG +#endif + +extern LogModule* GetGMPLog(); + +#define LOGD(msg) MOZ_LOG(GetGMPLog(), mozilla::LogLevel::Debug, msg) +#define LOG(level, msg) MOZ_LOG(GetGMPLog(), (level), msg) + +namespace gmp { + +GMPStorageParent::GMPStorageParent(const nsCString& aNodeId, + GMPParent* aPlugin) + : mNodeId(aNodeId) + , mPlugin(aPlugin) + , mShutdown(true) +{ +} + +nsresult +GMPStorageParent::Init() +{ + LOGD(("GMPStorageParent[%p]::Init()", this)); + + if (NS_WARN_IF(mNodeId.IsEmpty())) { + return NS_ERROR_FAILURE; + } + RefPtr<GeckoMediaPluginServiceParent> mps(GeckoMediaPluginServiceParent::GetSingleton()); + if (NS_WARN_IF(!mps)) { + return NS_ERROR_FAILURE; + } + + bool persistent = false; + if (NS_WARN_IF(NS_FAILED(mps->IsPersistentStorageAllowed(mNodeId, &persistent)))) { + return NS_ERROR_FAILURE; + } + if (persistent) { + mStorage = CreateGMPDiskStorage(mNodeId, mPlugin->GetPluginBaseName()); + } else { + mStorage = mps->GetMemoryStorageFor(mNodeId); + } + if (!mStorage) { + return NS_ERROR_FAILURE; + } + + mShutdown = false; + return NS_OK; +} + +bool +GMPStorageParent::RecvOpen(const nsCString& aRecordName) +{ + LOGD(("GMPStorageParent[%p]::RecvOpen(record='%s')", + this, aRecordName.get())); + + if (mShutdown) { + return false; + } + + if (mNodeId.EqualsLiteral("null")) { + // Refuse to open storage if the page is opened from local disk, + // or shared across origin. + LOGD(("GMPStorageParent[%p]::RecvOpen(record='%s') failed; null nodeId", + this, aRecordName.get())); + Unused << SendOpenComplete(aRecordName, GMPGenericErr); + return true; + } + + if (aRecordName.IsEmpty()) { + LOGD(("GMPStorageParent[%p]::RecvOpen(record='%s') failed; record name empty", + this, aRecordName.get())); + Unused << SendOpenComplete(aRecordName, GMPGenericErr); + return true; + } + + if (mStorage->IsOpen(aRecordName)) { + LOGD(("GMPStorageParent[%p]::RecvOpen(record='%s') failed; record in use", + this, aRecordName.get())); + Unused << SendOpenComplete(aRecordName, GMPRecordInUse); + return true; + } + + auto err = mStorage->Open(aRecordName); + MOZ_ASSERT(GMP_FAILED(err) || mStorage->IsOpen(aRecordName)); + LOGD(("GMPStorageParent[%p]::RecvOpen(record='%s') complete; rv=%d", + this, aRecordName.get(), err)); + Unused << SendOpenComplete(aRecordName, err); + + return true; +} + +bool +GMPStorageParent::RecvRead(const nsCString& aRecordName) +{ + LOGD(("GMPStorageParent[%p]::RecvRead(record='%s')", + this, aRecordName.get())); + + if (mShutdown) { + return false; + } + + nsTArray<uint8_t> data; + if (!mStorage->IsOpen(aRecordName)) { + LOGD(("GMPStorageParent[%p]::RecvRead(record='%s') failed; record not open", + this, aRecordName.get())); + Unused << SendReadComplete(aRecordName, GMPClosedErr, data); + } else { + GMPErr rv = mStorage->Read(aRecordName, data); + LOGD(("GMPStorageParent[%p]::RecvRead(record='%s') read %d bytes rv=%d", + this, aRecordName.get(), data.Length(), rv)); + Unused << SendReadComplete(aRecordName, rv, data); + } + + return true; +} + +bool +GMPStorageParent::RecvWrite(const nsCString& aRecordName, + InfallibleTArray<uint8_t>&& aBytes) +{ + LOGD(("GMPStorageParent[%p]::RecvWrite(record='%s') %d bytes", + this, aRecordName.get(), aBytes.Length())); + + if (mShutdown) { + return false; + } + + if (!mStorage->IsOpen(aRecordName)) { + LOGD(("GMPStorageParent[%p]::RecvWrite(record='%s') failed record not open", + this, aRecordName.get())); + Unused << SendWriteComplete(aRecordName, GMPClosedErr); + return true; + } + + if (aBytes.Length() > GMP_MAX_RECORD_SIZE) { + LOGD(("GMPStorageParent[%p]::RecvWrite(record='%s') failed record too big", + this, aRecordName.get())); + Unused << SendWriteComplete(aRecordName, GMPQuotaExceededErr); + return true; + } + + GMPErr rv = mStorage->Write(aRecordName, aBytes); + LOGD(("GMPStorageParent[%p]::RecvWrite(record='%s') write complete rv=%d", + this, aRecordName.get(), rv)); + + Unused << SendWriteComplete(aRecordName, rv); + + return true; +} + +bool +GMPStorageParent::RecvGetRecordNames() +{ + if (mShutdown) { + return true; + } + + nsTArray<nsCString> recordNames; + GMPErr status = mStorage->GetRecordNames(recordNames); + + LOGD(("GMPStorageParent[%p]::RecvGetRecordNames() status=%d numRecords=%d", + this, status, recordNames.Length())); + + Unused << SendRecordNames(recordNames, status); + + return true; +} + +bool +GMPStorageParent::RecvClose(const nsCString& aRecordName) +{ + LOGD(("GMPStorageParent[%p]::RecvClose(record='%s')", + this, aRecordName.get())); + + if (mShutdown) { + return true; + } + + mStorage->Close(aRecordName); + + return true; +} + +void +GMPStorageParent::ActorDestroy(ActorDestroyReason aWhy) +{ + LOGD(("GMPStorageParent[%p]::ActorDestroy(reason=%d)", this, aWhy)); + Shutdown(); +} + +void +GMPStorageParent::Shutdown() +{ + LOGD(("GMPStorageParent[%p]::Shutdown()", this)); + + if (mShutdown) { + return; + } + mShutdown = true; + Unused << SendShutdown(); + + mStorage = nullptr; + +} + +} // namespace gmp +} // namespace mozilla |