/* -*- 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