Backed out changeset 55ea2c2fb857 (bug 1034368) for bustage

This commit is contained in:
Nigel Babu 2014-08-19 12:07:01 +05:30
Родитель 2f0df889d5
Коммит 493e418c84
14 изменённых файлов: 11 добавлений и 874 удалений

Просмотреть файл

@ -399,32 +399,6 @@ GMPChild::GetGMPTimers()
return mTimerChild;
}
PGMPStorageChild*
GMPChild::AllocPGMPStorageChild()
{
return new GMPStorageChild(this);
}
bool
GMPChild::DeallocPGMPStorageChild(PGMPStorageChild* aActor)
{
mStorage = nullptr;
return true;
}
GMPStorageChild*
GMPChild::GetGMPStorage()
{
if (!mStorage) {
PGMPStorageChild* sc = SendPGMPStorageConstructor();
if (!sc) {
return nullptr;
}
mStorage = static_cast<GMPStorageChild*>(sc);
}
return mStorage;
}
bool
GMPChild::RecvCrashPluginNow()
{

Просмотреть файл

@ -9,7 +9,6 @@
#include "mozilla/gmp/PGMPChild.h"
#include "GMPSharedMemManager.h"
#include "GMPTimerChild.h"
#include "GMPStorageChild.h"
#include "gmp-async-shutdown.h"
#include "gmp-entrypoints.h"
#include "prlink.h"
@ -38,7 +37,6 @@ public:
// Main thread only.
GMPTimerChild* GetGMPTimers();
GMPStorageChild* GetGMPStorage();
// GMPSharedMem
virtual void CheckThread() MOZ_OVERRIDE;
@ -69,9 +67,6 @@ private:
virtual PGMPTimerChild* AllocPGMPTimerChild() MOZ_OVERRIDE;
virtual bool DeallocPGMPTimerChild(PGMPTimerChild* aActor) MOZ_OVERRIDE;
virtual PGMPStorageChild* AllocPGMPStorageChild() MOZ_OVERRIDE;
virtual bool DeallocPGMPStorageChild(PGMPStorageChild* aActor) MOZ_OVERRIDE;
virtual bool RecvCrashPluginNow() MOZ_OVERRIDE;
virtual bool RecvBeginAsyncShutdown() MOZ_OVERRIDE;
@ -80,7 +75,6 @@ private:
GMPAsyncShutdown* mAsyncShutdown;
nsRefPtr<GMPTimerChild> mTimerChild;
nsRefPtr<GMPStorageChild> mStorage;
PRLibrary* mLib;
GMPGetAPIFunc mGetAPIFunc;

Просмотреть файл

@ -171,10 +171,6 @@ GMPParent::CloseIfUnused()
}
}
} else {
// Any async shutdown must be complete. Shutdown GMPStorage.
for (size_t i = mStorage.Length(); i > 0; i--) {
mStorage[i - 1]->Shutdown();
}
Shutdown();
}
}
@ -222,14 +218,17 @@ GMPParent::CloseActive(bool aDieWhenUnloaded)
mVideoDecoders[i - 1]->Shutdown();
}
// Invalidate and remove any remaining API objects.
for (uint32_t i = mVideoEncoders.Length(); i > 0; i--) {
mVideoEncoders[i - 1]->Shutdown();
}
// Invalidate and remove any remaining API objects.
for (uint32_t i = mDecryptors.Length(); i > 0; i--) {
mDecryptors[i - 1]->Shutdown();
}
// Invalidate and remove any remaining API objects.
for (uint32_t i = mAudioDecoders.Length(); i > 0; i--) {
mAudioDecoders[i - 1]->Shutdown();
}
@ -238,9 +237,6 @@ GMPParent::CloseActive(bool aDieWhenUnloaded)
mTimers[i - 1]->Shutdown();
}
// Note: We don't shutdown storage API objects here, as they need to
// work during async shutdown of GMPs.
// Note: the shutdown of the codecs is async! don't kill
// the plugin-container until they're all safely shut down via
// CloseIfUnused();
@ -662,29 +658,6 @@ GMPParent::DeallocPGMPAudioDecoderParent(PGMPAudioDecoderParent* aActor)
return true;
}
PGMPStorageParent*
GMPParent::AllocPGMPStorageParent()
{
GMPStorageParent* p = new GMPStorageParent(mOrigin, this);
mStorage.AppendElement(p); // Addrefs, released in DeallocPGMPStorageParent.
return p;
}
bool
GMPParent::DeallocPGMPStorageParent(PGMPStorageParent* aActor)
{
GMPStorageParent* p = static_cast<GMPStorageParent*>(aActor);
p->Shutdown();
mStorage.RemoveElement(p);
return true;
}
bool
GMPParent::RecvPGMPStorageConstructor(PGMPStorageParent* actor)
{
return true;
}
bool
GMPParent::RecvPGMPTimerConstructor(PGMPTimerParent* actor)
{

Просмотреть файл

@ -13,7 +13,6 @@
#include "GMPVideoDecoderParent.h"
#include "GMPVideoEncoderParent.h"
#include "GMPTimerParent.h"
#include "GMPStorageParent.h"
#include "mozilla/gmp/PGMPParent.h"
#include "nsCOMPtr.h"
#include "nscore.h"
@ -155,10 +154,6 @@ private:
virtual PGMPAudioDecoderParent* AllocPGMPAudioDecoderParent() MOZ_OVERRIDE;
virtual bool DeallocPGMPAudioDecoderParent(PGMPAudioDecoderParent* aActor) MOZ_OVERRIDE;
virtual bool RecvPGMPStorageConstructor(PGMPStorageParent* actor) MOZ_OVERRIDE;
virtual PGMPStorageParent* AllocPGMPStorageParent() MOZ_OVERRIDE;
virtual bool DeallocPGMPStorageParent(PGMPStorageParent* aActor) MOZ_OVERRIDE;
virtual bool RecvPGMPTimerConstructor(PGMPTimerParent* actor) MOZ_OVERRIDE;
virtual PGMPTimerParent* AllocPGMPTimerParent() MOZ_OVERRIDE;
virtual bool DeallocPGMPTimerParent(PGMPTimerParent* aActor) MOZ_OVERRIDE;
@ -182,7 +177,6 @@ private:
nsTArray<nsRefPtr<GMPDecryptorParent>> mDecryptors;
nsTArray<nsRefPtr<GMPAudioDecoderParent>> mAudioDecoders;
nsTArray<nsRefPtr<GMPTimerParent>> mTimers;
nsTArray<nsRefPtr<GMPStorageParent>> mStorage;
nsCOMPtr<nsIThread> mGMPThread;
// Origin the plugin is assigned to, or empty if the the plugin is not
// assigned to an origin.

Просмотреть файл

@ -4,7 +4,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GMPPlatform.h"
#include "GMPStorageChild.h"
#include "GMPTimerChild.h"
#include "mozilla/Monitor.h"
#include "nsAutoPtr.h"
@ -152,30 +151,6 @@ CreateMutex(GMPMutex** aMutex)
return GMPNoErr;
}
GMPErr
CreateRecord(const char* aRecordName,
uint32_t aRecordNameSize,
GMPRecord** aOutRecord,
GMPRecordClient* aClient)
{
if (sMainLoop != MessageLoop::current()) {
NS_WARNING("GMP called CreateRecord() on non-main thread!");
return GMPGenericErr;
}
if (aRecordNameSize > GMP_MAX_RECORD_NAME_SIZE) {
NS_WARNING("GMP tried to CreateRecord with too long record name");
return GMPGenericErr;
}
GMPStorageChild* storage = sChild->GetGMPStorage();
if (!storage) {
return GMPGenericErr;
}
MOZ_ASSERT(storage);
return storage->CreateRecord(nsDependentCString(aRecordName, aRecordNameSize),
aOutRecord,
aClient);
}
GMPErr
SetTimerOnMainThread(GMPTask* aTask, int64_t aTimeoutMS)
{
@ -209,7 +184,7 @@ InitPlatformAPI(GMPPlatformAPI& aPlatformAPI, GMPChild* aChild)
aPlatformAPI.runonmainthread = &RunOnMainThread;
aPlatformAPI.syncrunonmainthread = &SyncRunOnMainThread;
aPlatformAPI.createmutex = &CreateMutex;
aPlatformAPI.createrecord = &CreateRecord;
aPlatformAPI.createrecord = nullptr;
aPlatformAPI.settimer = &SetTimerOnMainThread;
aPlatformAPI.getcurrenttime = &GetClock;
}

Просмотреть файл

@ -1,282 +0,0 @@
/* -*- 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 "GMPStorageChild.h"
#include "GMPChild.h"
#include "gmp-storage.h"
namespace mozilla {
namespace gmp {
GMPRecordImpl::GMPRecordImpl(GMPStorageChild* aOwner,
const nsCString& aName,
GMPRecordClient* aClient)
: mName(aName)
, mClient(aClient)
, mOwner(aOwner)
, mIsClosed(true)
{
}
GMPErr
GMPRecordImpl::Open()
{
if (!mIsClosed) {
return GMPRecordInUse;
}
return mOwner->Open(this);
}
void
GMPRecordImpl::OpenComplete(GMPErr aStatus)
{
mIsClosed = false;
mClient->OpenComplete(aStatus);
}
GMPErr
GMPRecordImpl::Read()
{
if (mIsClosed) {
return GMPClosedErr;
}
return mOwner->Read(this);
}
void
GMPRecordImpl::ReadComplete(GMPErr aStatus,
const uint8_t* aBytes,
uint32_t aLength)
{
mClient->ReadComplete(aStatus, aBytes, aLength);
}
GMPErr
GMPRecordImpl::Write(const uint8_t* aData, uint32_t aDataSize)
{
if (mIsClosed) {
return GMPClosedErr;
}
return mOwner->Write(this, aData, aDataSize);
}
void
GMPRecordImpl::WriteComplete(GMPErr aStatus)
{
mClient->WriteComplete(aStatus);
}
GMPErr
GMPRecordImpl::Close()
{
nsRefPtr<GMPRecordImpl> kungfuDeathGrip(this);
if (!mIsClosed) {
// Delete the storage child's reference to us.
mOwner->Close(this);
// Owner should callback MarkClosed().
MOZ_ASSERT(mIsClosed);
}
// Delete our self reference.
Release();
return GMPNoErr;
}
void
GMPRecordImpl::MarkClosed()
{
mIsClosed = true;
}
GMPStorageChild::GMPStorageChild(GMPChild* aPlugin)
: mPlugin(aPlugin)
, mShutdown(false)
{
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
}
GMPErr
GMPStorageChild::CreateRecord(const nsCString& aRecordName,
GMPRecord** aOutRecord,
GMPRecordClient* aClient)
{
if (mPlugin->GMPMessageLoop() != MessageLoop::current()) {
NS_WARNING("GMP used GMPStorage on non-main thread.");
return GMPGenericErr;
}
if (mShutdown) {
NS_WARNING("GMPStorage used after it's been shutdown!");
return GMPClosedErr;
}
MOZ_ASSERT(aRecordName.Length() && aOutRecord);
nsRefPtr<GMPRecordImpl> record(new GMPRecordImpl(this, aRecordName, aClient));
mRecords.Put(aRecordName, record); // Addrefs
// The GMPRecord holds a self reference until the GMP calls Close() on
// it. This means the object is always valid (even if neutered) while
// the GMP expects it to be.
record.forget(aOutRecord);
return GMPNoErr;
}
GMPErr
GMPStorageChild::Open(GMPRecordImpl* aRecord)
{
if (mPlugin->GMPMessageLoop() != MessageLoop::current()) {
NS_WARNING("GMP used GMPStorage on non-main thread.");
return GMPGenericErr;
}
if (mShutdown) {
NS_WARNING("GMPStorage used after it's been shutdown!");
return GMPClosedErr;
}
if (!SendOpen(aRecord->Name())) {
Close(aRecord);
return GMPClosedErr;
}
return GMPNoErr;
}
GMPErr
GMPStorageChild::Read(GMPRecordImpl* aRecord)
{
if (mPlugin->GMPMessageLoop() != MessageLoop::current()) {
NS_WARNING("GMP used GMPStorage on non-main thread.");
return GMPGenericErr;
}
if (mShutdown) {
NS_WARNING("GMPStorage used after it's been shutdown!");
return GMPClosedErr;
}
if (!SendRead(aRecord->Name())) {
Close(aRecord);
return GMPClosedErr;
}
return GMPNoErr;
}
GMPErr
GMPStorageChild::Write(GMPRecordImpl* aRecord,
const uint8_t* aData,
uint32_t aDataSize)
{
if (mPlugin->GMPMessageLoop() != MessageLoop::current()) {
NS_WARNING("GMP used GMPStorage on non-main thread.");
return GMPGenericErr;
}
if (mShutdown) {
NS_WARNING("GMPStorage used after it's been shutdown!");
return GMPClosedErr;
}
if (aDataSize > GMP_MAX_RECORD_SIZE) {
return GMPQuotaExceededErr;
}
nsTArray<uint8_t> data;
data.AppendElements(aData, aDataSize);
if (!SendWrite(aRecord->Name(), data)) {
Close(aRecord);
return GMPClosedErr;
}
return GMPNoErr;
}
GMPErr
GMPStorageChild::Close(GMPRecordImpl* aRecord)
{
if (mPlugin->GMPMessageLoop() != MessageLoop::current()) {
NS_WARNING("GMP used GMPStorage on non-main thread.");
return GMPGenericErr;
}
if (!mRecords.Contains(aRecord->Name())) {
// Already closed.
return GMPClosedErr;
}
GMPErr rv = GMPNoErr;
if (!mShutdown && !SendClose(aRecord->Name())) {
rv = GMPGenericErr;
}
aRecord->MarkClosed();
mRecords.Remove(aRecord->Name());
return rv;
}
bool
GMPStorageChild::RecvOpenComplete(const nsCString& aRecordName,
const GMPErr& aStatus)
{
if (mShutdown) {
return true;
}
nsRefPtr<GMPRecordImpl> record;
if (!mRecords.Get(aRecordName, getter_AddRefs(record)) || !record) {
// Not fatal.
return true;
}
record->OpenComplete(aStatus);
if (GMP_FAILED(aStatus)) {
Close(record);
}
return true;
}
bool
GMPStorageChild::RecvReadComplete(const nsCString& aRecordName,
const GMPErr& aStatus,
const InfallibleTArray<uint8_t>& aBytes)
{
if (mShutdown) {
return true;
}
nsRefPtr<GMPRecordImpl> record;
if (!mRecords.Get(aRecordName, getter_AddRefs(record)) || !record) {
// Not fatal.
return true;
}
record->ReadComplete(aStatus,
aBytes.Elements(),
aBytes.Length());
if (GMP_FAILED(aStatus)) {
Close(record);
}
return true;
}
bool
GMPStorageChild::RecvWriteComplete(const nsCString& aRecordName,
const GMPErr& aStatus)
{
if (mShutdown) {
return true;
}
nsRefPtr<GMPRecordImpl> record;
if (!mRecords.Get(aRecordName, getter_AddRefs(record)) || !record) {
// Not fatal.
return true;
}
record->WriteComplete(aStatus);
if (GMP_FAILED(aStatus)) {
Close(record);
}
return true;
}
bool
GMPStorageChild::RecvShutdown()
{
// Block any new storage requests, and thus any messages back to the
// parent. We don't delete any objects here, as that may invalidate
// GMPRecord pointers held by the GMP.
mShutdown = true;
return true;
}
} // namespace gmp
} // namespace mozilla

Просмотреть файл

@ -1,95 +0,0 @@
/* -*- 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/. */
#ifndef GMPStorageChild_h_
#define GMPStorageChild_h_
#include "mozilla/gmp/PGMPStorageChild.h"
#include "gmp-storage.h"
#include "nsTHashtable.h"
#include "nsRefPtrHashtable.h"
namespace mozilla {
namespace gmp {
class GMPChild;
class GMPStorageChild;
class GMPRecordImpl : public GMPRecord
{
public:
NS_INLINE_DECL_REFCOUNTING(GMPRecordImpl)
GMPRecordImpl(GMPStorageChild* aOwner,
const nsCString& aName,
GMPRecordClient* aClient);
// GMPRecord.
virtual GMPErr Open() MOZ_OVERRIDE;
virtual GMPErr Read() MOZ_OVERRIDE;
virtual GMPErr Write(const uint8_t* aData,
uint32_t aDataSize) MOZ_OVERRIDE;
virtual GMPErr Close() MOZ_OVERRIDE;
const nsCString& Name() const { return mName; }
void OpenComplete(GMPErr aStatus);
void ReadComplete(GMPErr aStatus, const uint8_t* aBytes, uint32_t aLength);
void WriteComplete(GMPErr aStatus);
void MarkClosed();
private:
~GMPRecordImpl() {}
const nsCString mName;
GMPRecordClient* const mClient;
GMPStorageChild* const mOwner;
bool mIsClosed;
};
class GMPStorageChild : public PGMPStorageChild
{
public:
NS_INLINE_DECL_REFCOUNTING(GMPStorageChild)
GMPStorageChild(GMPChild* aPlugin);
GMPErr CreateRecord(const nsCString& aRecordName,
GMPRecord** aOutRecord,
GMPRecordClient* aClient);
GMPErr Open(GMPRecordImpl* aRecord);
GMPErr Read(GMPRecordImpl* aRecord);
GMPErr Write(GMPRecordImpl* aRecord,
const uint8_t* aData,
uint32_t aDataSize);
GMPErr Close(GMPRecordImpl* aRecord);
protected:
~GMPStorageChild() {}
// PGMPStorageChild
virtual bool RecvOpenComplete(const nsCString& aRecordName,
const GMPErr& aStatus) MOZ_OVERRIDE;
virtual bool RecvReadComplete(const nsCString& aRecordName,
const GMPErr& aStatus,
const InfallibleTArray<uint8_t>& aBytes) MOZ_OVERRIDE;
virtual bool RecvWriteComplete(const nsCString& aRecordName,
const GMPErr& aStatus) MOZ_OVERRIDE;
virtual bool RecvShutdown() MOZ_OVERRIDE;
private:
nsRefPtrHashtable<nsCStringHashKey, GMPRecordImpl> mRecords;
GMPChild* mPlugin;
bool mShutdown;
};
} // namespace gmp
} // namespace mozilla
#endif // GMPStorageChild_h_

Просмотреть файл

@ -1,287 +0,0 @@
/* -*- 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 "mozilla/SyncRunnable.h"
#include "plhash.h"
#include "nsDirectoryServiceUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "GMPParent.h"
#include "gmp-storage.h"
#include "mozilla/unused.h"
namespace mozilla {
#ifdef LOG
#undef LOG
#endif
#ifdef PR_LOGGING
extern PRLogModuleInfo* GetGMPLog();
#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
#else
#define LOGD(msg)
#define LOG(level, msg)
#endif
#ifdef __CLASS__
#undef __CLASS__
#endif
#define __CLASS__ "GMPParent"
namespace gmp {
class GetTempDirTask : public nsRunnable
{
public:
NS_IMETHOD Run() {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIFile> tmpFile;
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
tmpFile->GetPath(mPath);
return NS_OK;
}
nsString mPath;
};
// We store the records in files in the system temp dir.
static nsresult
GetGMPStorageDir(nsIFile** aTempDir, const nsString& aOrigin)
{
if (NS_WARN_IF(!aTempDir)) {
return NS_ERROR_INVALID_ARG;
}
// Directory service is main thread only...
nsRefPtr<GetTempDirTask> task = new GetTempDirTask();
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
mozilla::SyncRunnable::DispatchToThread(mainThread, task);
nsCOMPtr<nsIFile> tmpFile;
nsresult rv = NS_NewLocalFile(task->mPath, false, getter_AddRefs(tmpFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = tmpFile->AppendNative(nsDependentCString("mozilla-gmp-storage"));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// TODO: When aOrigin is the same node-id as the GMP sees in the child
// process (a UUID or somesuch), we can just append it un-hashed here.
// This should reduce the chance of hash collsions exposing data.
nsAutoString nodeIdHash;
nodeIdHash.AppendInt(HashString(aOrigin.get()));
rv = tmpFile->Append(nodeIdHash);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = tmpFile->Create(nsIFile::DIRECTORY_TYPE, 0700);
if (rv != NS_ERROR_FILE_ALREADY_EXISTS && NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
tmpFile.forget(aTempDir);
return NS_OK;
}
GMPStorageParent::GMPStorageParent(const nsString& aOrigin,
GMPParent* aPlugin)
: mOrigin(aOrigin)
, mPlugin(aPlugin)
, mShutdown(false)
{
}
enum OpenFileMode { ReadWrite, Truncate };
nsresult
OpenStorageFile(const nsCString& aRecordName,
const nsString& aNodeId,
const OpenFileMode aMode,
PRFileDesc** aOutFD)
{
MOZ_ASSERT(aOutFD);
nsCOMPtr<nsIFile> f;
nsresult rv = GetGMPStorageDir(getter_AddRefs(f), aNodeId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsAutoString recordNameHash;
recordNameHash.AppendInt(HashString(aRecordName.get()));
f->Append(recordNameHash);
auto mode = PR_RDWR | PR_CREATE_FILE;
if (aMode == Truncate) {
mode |= PR_TRUNCATE;
}
return f->OpenNSPRFileDesc(mode, PR_IRWXU, aOutFD);
}
bool
GMPStorageParent::RecvOpen(const nsCString& aRecordName)
{
if (mShutdown) {
return true;
}
if (mOrigin.EqualsASCII("null")) {
// Refuse to open storage if the page is the "null" origin; if the page
// is opened from disk.
NS_WARNING("Refusing to open storage for null origin");
unused << SendOpenComplete(aRecordName, GMPGenericErr);
return true;
}
if (aRecordName.IsEmpty() || mFiles.Contains(aRecordName)) {
unused << SendOpenComplete(aRecordName, GMPRecordInUse);
return true;
}
PRFileDesc* fd = nullptr;
nsresult rv = OpenStorageFile(aRecordName, mOrigin, ReadWrite, &fd);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to open storage file.");
unused << SendOpenComplete(aRecordName, GMPGenericErr);
return true;
}
mFiles.Put(aRecordName, fd);
unused << SendOpenComplete(aRecordName, GMPNoErr);
return true;
}
bool
GMPStorageParent::RecvRead(const nsCString& aRecordName)
{
LOGD(("%s::%s: %p record=%s", __CLASS__, __FUNCTION__, this, aRecordName.get()));
if (mShutdown) {
return true;
}
PRFileDesc* fd = mFiles.Get(aRecordName);
nsTArray<uint8_t> data;
if (!fd) {
unused << SendReadComplete(aRecordName, GMPClosedErr, data);
return true;
}
int32_t len = PR_Seek(fd, 0, PR_SEEK_END);
PR_Seek(fd, 0, PR_SEEK_SET);
if (len > GMP_MAX_RECORD_SIZE) {
// Refuse to read big records.
unused << SendReadComplete(aRecordName, GMPQuotaExceededErr, data);
return true;
}
data.SetLength(len);
auto bytesRead = PR_Read(fd, data.Elements(), len);
auto res = (bytesRead == len) ? GMPNoErr : GMPGenericErr;
unused << SendReadComplete(aRecordName, res, data);
return true;
}
bool
GMPStorageParent::RecvWrite(const nsCString& aRecordName,
const InfallibleTArray<uint8_t>& aBytes)
{
LOGD(("%s::%s: %p record=%s", __CLASS__, __FUNCTION__, this, aRecordName.get()));
if (mShutdown) {
return true;
}
if (aBytes.Length() > GMP_MAX_RECORD_SIZE) {
unused << SendWriteComplete(aRecordName, GMPQuotaExceededErr);
return true;
}
PRFileDesc* fd = mFiles.Get(aRecordName);
if (!fd) {
unused << SendWriteComplete(aRecordName, GMPGenericErr);
return true;
}
// Write operations overwrite the entire record. So re-open the file
// in truncate mode, to clear its contents.
PR_Close(fd);
mFiles.Remove(aRecordName);
if (NS_FAILED(OpenStorageFile(aRecordName, mOrigin, Truncate, &fd))) {
unused << SendWriteComplete(aRecordName, GMPGenericErr);
return true;
}
mFiles.Put(aRecordName, fd);
int32_t bytesWritten = PR_Write(fd, aBytes.Elements(), aBytes.Length());
auto res = (bytesWritten == (int32_t)aBytes.Length()) ? GMPNoErr : GMPGenericErr;
unused << SendWriteComplete(aRecordName, res);
return true;
}
bool
GMPStorageParent::RecvClose(const nsCString& aRecordName)
{
LOGD(("%s::%s: %p record=%s", __CLASS__, __FUNCTION__, this, aRecordName.get()));
if (mShutdown) {
return true;
}
PRFileDesc* fd = mFiles.Get(aRecordName);
if (!fd) {
return true;
}
PR_Close(fd);
mFiles.Remove(aRecordName);
return true;
}
void
GMPStorageParent::ActorDestroy(ActorDestroyReason aWhy)
{
LOGD(("%s::%s: %p", __CLASS__, __FUNCTION__, this));
Shutdown();
}
PLDHashOperator
CloseFile(const nsACString& key, PRFileDesc*& entry, void* cx)
{
PR_Close(entry);
return PL_DHASH_REMOVE;
}
void
GMPStorageParent::Shutdown()
{
LOGD(("%s::%s: %p", __CLASS__, __FUNCTION__, this));
if (mShutdown) {
return;
}
mShutdown = true;
unused << SendShutdown();
mFiles.Enumerate(CloseFile, nullptr);
MOZ_ASSERT(!mFiles.Count());
}
} // namespace gmp
} // namespace mozilla

Просмотреть файл

@ -1,45 +0,0 @@
/* -*- 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/. */
#ifndef GMPStorageParent_h_
#define GMPStorageParent_h_
#include "mozilla/gmp/PGMPStorageParent.h"
#include "gmp-storage.h"
#include "nsTHashtable.h"
#include "nsDataHashtable.h"
#include "prio.h"
namespace mozilla {
namespace gmp {
class GMPParent;
class GMPStorageParent : public PGMPStorageParent {
public:
NS_INLINE_DECL_REFCOUNTING(GMPStorageParent)
GMPStorageParent(const nsString& aOrigin, GMPParent* aPlugin);
void Shutdown();
protected:
virtual bool RecvOpen(const nsCString& aRecordName) MOZ_OVERRIDE;
virtual bool RecvRead(const nsCString& aRecordName) MOZ_OVERRIDE;
virtual bool RecvWrite(const nsCString& aRecordName,
const InfallibleTArray<uint8_t>& aBytes) MOZ_OVERRIDE;
virtual bool RecvClose(const nsCString& aRecordName) MOZ_OVERRIDE;
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
private:
nsDataHashtable<nsCStringHashKey, PRFileDesc*> mFiles;
const nsString mOrigin;
nsRefPtr<GMPParent> mPlugin;
bool mShutdown;
};
} // namespace gmp
} // namespace mozilla
#endif // GMPStorageParent_h_

Просмотреть файл

@ -9,7 +9,6 @@ include protocol PCrashReporter;
include protocol PGMPDecryptor;
include protocol PGMPAudioDecoder;
include protocol PGMPTimer;
include protocol PGMPStorage;
using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
@ -24,12 +23,10 @@ intr protocol PGMP
manages PGMPVideoEncoder;
manages PCrashReporter;
manages PGMPTimer;
manages PGMPStorage;
parent:
async PCrashReporter(NativeThreadId tid);
async PGMPTimer();
async PGMPStorage();
async AsyncShutdownComplete();
async AsyncShutdownRequired();

Просмотреть файл

@ -1,34 +0,0 @@
/* -*- 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 protocol PGMP;
include GMPTypes;
using GMPErr from "gmp-errors.h";
namespace mozilla {
namespace gmp {
async protocol PGMPStorage
{
manager PGMP;
child:
OpenComplete(nsCString aRecordName, GMPErr aStatus);
ReadComplete(nsCString aRecordName, GMPErr aStatus, uint8_t[] aBytes);
WriteComplete(nsCString aRecordName, GMPErr aStatus);
Shutdown();
parent:
Open(nsCString aRecordName);
Read(nsCString aRecordName);
Write(nsCString aRecordName, uint8_t[] aBytes);
Close(nsCString aRecordName);
__delete__();
};
} // namespace gmp
} // namespace mozilla

Просмотреть файл

@ -69,8 +69,6 @@ typedef GMPErr (*GMPCreateThreadPtr)(GMPThread** aThread);
typedef GMPErr (*GMPRunOnMainThreadPtr)(GMPTask* aTask);
typedef GMPErr (*GMPSyncRunOnMainThreadPtr)(GMPTask* aTask);
typedef GMPErr (*GMPCreateMutexPtr)(GMPMutex** aMutex);
// Call on main thread only.
typedef GMPErr (*GMPCreateRecordPtr)(const char* aRecordName,
uint32_t aRecordNameSize,
GMPRecord** aOutRecord,

Просмотреть файл

@ -20,31 +20,16 @@
#include "gmp-errors.h"
#include <stdint.h>
// Maximum size of a record, in bytes.
#define GMP_MAX_RECORD_SIZE (1024 * 1024 * 1024)
// Maximum length of a record name.
#define GMP_MAX_RECORD_NAME_SIZE 200
// Provides basic per-origin storage for CDMs. GMPRecord instances can be
// retrieved by calling GMPPlatformAPI->openstorage. Multiple GMPRecords
// with different names can be open at once, but a single record can only
// be opened by one client at a time. This interface is asynchronous, with
// results being returned via callbacks to the GMPRecordClient pointer
// provided to the GMPPlatformAPI->openstorage call, on the main thread.
//
// Lifecycle: Once opened, the GMPRecord object remains allocated until
// GMPRecord::Close() is called. If any GMPRecord function, either
// synchronously or asynchronously through a GMPRecordClient callback,
// returns an error, the GMP is responsible for calling Close() on the
// GMPRecord to delete the GMPRecord object's memory. If your GMP does not
// call Close(), the GMPRecord's memory will leak.
class GMPRecord {
public:
// Opens the record. Calls OpenComplete() once the record is open.
// Note: Only work when GMP is loading content from a webserver.
// Does not work for web pages on loaded from disk.
// Note: OpenComplete() is only called if this returns GMPNoErr.
virtual GMPErr Open() = 0;
@ -54,15 +39,13 @@ public:
virtual GMPErr Read() = 0;
// Writes aDataSize bytes of aData into the record, overwriting the
// contents of the record, truncating it to aDataSize length.
// Overwriting with 0 bytes "deletes" the record.
// contents of the record. Overwriting with 0 bytes "deletes" the file.
// Note: WriteComplete is only called if this returns GMPNoErr.
virtual GMPErr Write(const uint8_t* aData, uint32_t aDataSize) = 0;
// Closes a record, deletes the GMPRecord object. The GMPRecord object
// must not be used after this is called, request a new one with
// GMPPlatformAPI->openstorage to re-open this record. Cancels all
// callbacks.
// Closes a record. GMPRecord object must not be used after this is
// called, request a new one with GMPPlatformAPI->openstorage to re-open
// this record. Cancels all callbacks.
virtual GMPErr Close() = 0;
virtual ~GMPRecord() {}
@ -78,8 +61,7 @@ class GMPRecordClient {
// - GMPNoErr - Record opened successfully. Record may be empty.
// - GMPRecordInUse - This record is in use by another client.
// - GMPGenericErr - Unspecified error.
// If aStatus is not GMPNoErr, the GMPRecord is unusable, and you must
// call Close() on the GMPRecord to dispose of it.
// Do not use the GMPRecord if aStatus is not GMPNoErr.
virtual void OpenComplete(GMPErr aStatus) = 0;
// Response to a GMPRecord::Read() call, where aData is the record contents,
@ -92,8 +74,7 @@ class GMPRecordClient {
// - GMPRecordInUse - There are other operations or clients in use on
// this record.
// - GMPGenericErr - Unspecified error.
// If aStatus is not GMPNoErr, the GMPRecord is unusable, and you must
// call Close() on the GMPRecord to dispose of it.
// Do not continue to use the GMPRecord if aStatus is not GMPNoErr.
virtual void ReadComplete(GMPErr aStatus,
const uint8_t* aData,
uint32_t aDataSize) = 0;
@ -103,8 +84,7 @@ class GMPRecordClient {
// - GMPRecordInUse - There are other operations or clients in use on
// this record.
// - GMPGenericErr - Unspecified error.
// If aStatus is not GMPNoErr, the GMPRecord is unusable, and you must
// call Close() on the GMPRecord to dispose of it.
// Do not continue to use the GMPRecord if aStatus is not GMPNoErr.
virtual void WriteComplete(GMPErr aStatus) = 0;
virtual ~GMPRecordClient() {}

Просмотреть файл

@ -46,8 +46,6 @@ EXPORTS += [
'GMPProcessParent.h',
'GMPService.h',
'GMPSharedMemManager.h',
'GMPStorageChild.h',
'GMPStorageParent.h',
'GMPTimerChild.h',
'GMPTimerParent.h',
'GMPVideoDecoderChild.h',
@ -76,8 +74,6 @@ UNIFIED_SOURCES += [
'GMPProcessParent.cpp',
'GMPService.cpp',
'GMPSharedMemManager.cpp',
'GMPStorageChild.cpp',
'GMPStorageParent.cpp',
'GMPTimerChild.cpp',
'GMPTimerParent.cpp',
'GMPVideoDecoderChild.cpp',
@ -95,7 +91,6 @@ IPDL_SOURCES += [
'PGMP.ipdl',
'PGMPAudioDecoder.ipdl',
'PGMPDecryptor.ipdl',
'PGMPStorage.ipdl',
'PGMPTimer.ipdl',
'PGMPVideoDecoder.ipdl',
'PGMPVideoEncoder.ipdl',