mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1100499 - Add GMP API to enumerate records stored on disk. r=jesup
This commit is contained in:
parent
e3c9f4ba39
commit
725607e8e6
@ -285,6 +285,45 @@ public:
|
||||
string mRecordId;
|
||||
};
|
||||
|
||||
static void
|
||||
RecvGMPRecordIterator(GMPRecordIterator* aRecordIterator,
|
||||
void* aUserArg,
|
||||
GMPErr aStatus)
|
||||
{
|
||||
FakeDecryptor* decryptor = reinterpret_cast<FakeDecryptor*>(aUserArg);
|
||||
decryptor->ProcessRecordNames(aRecordIterator, aStatus);
|
||||
}
|
||||
|
||||
void
|
||||
FakeDecryptor::ProcessRecordNames(GMPRecordIterator* aRecordIterator,
|
||||
GMPErr aStatus)
|
||||
{
|
||||
if (sInstance != this) {
|
||||
FakeDecryptor::Message("Error aUserArg was not passed through GetRecordIterator");
|
||||
return;
|
||||
}
|
||||
if (GMP_FAILED(aStatus)) {
|
||||
FakeDecryptor::Message("Error GetRecordIterator failed");
|
||||
return;
|
||||
}
|
||||
std::string response("record-names ");
|
||||
bool first = true;
|
||||
const char* name = nullptr;
|
||||
uint32_t len = 0;
|
||||
while (GMP_SUCCEEDED(aRecordIterator->GetName(&name, &len))) {
|
||||
std::string s(name, name+len);
|
||||
if (!first) {
|
||||
response += ",";
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
response += s;
|
||||
aRecordIterator->NextRecord();
|
||||
}
|
||||
aRecordIterator->Close();
|
||||
FakeDecryptor::Message(response);
|
||||
}
|
||||
|
||||
enum ShutdownMode {
|
||||
ShutdownNormal,
|
||||
ShutdownTimeout,
|
||||
@ -335,6 +374,8 @@ FakeDecryptor::UpdateSession(uint32_t aPromiseId,
|
||||
mHost->GetPluginVoucher(&rawVoucher, &length);
|
||||
std::string voucher((const char*)rawVoucher, (const char*)(rawVoucher + length));
|
||||
Message("retrieved plugin-voucher: " + voucher);
|
||||
} else if (task == "retrieve-record-names") {
|
||||
GMPEnumRecordNames(&RecvGMPRecordIterator, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,9 @@ public:
|
||||
|
||||
static void Message(const std::string& aMessage);
|
||||
|
||||
void ProcessRecordNames(GMPRecordIterator* aRecordIterator,
|
||||
GMPErr aStatus);
|
||||
|
||||
private:
|
||||
|
||||
virtual ~FakeDecryptor() {}
|
||||
|
@ -193,3 +193,10 @@ GMPOpenRecord(const std::string& aRecordName,
|
||||
}
|
||||
return client->Init(record, aContinuation);
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPEnumRecordNames(RecvGMPRecordIteratorPtr aRecvIteratorFunc,
|
||||
void* aUserArg)
|
||||
{
|
||||
return g_platform_api->getrecordenumerator(aRecvIteratorFunc, aUserArg);
|
||||
}
|
||||
|
@ -54,4 +54,8 @@ GMPErr
|
||||
GMPOpenRecord(const std::string& aRecordName,
|
||||
OpenContinuation* aContinuation);
|
||||
|
||||
GMPErr
|
||||
GMPEnumRecordNames(RecvGMPRecordIteratorPtr aRecvIteratorFunc,
|
||||
void* aUserArg);
|
||||
|
||||
#endif // TEST_GMP_STORAGE_H__
|
||||
|
@ -158,8 +158,10 @@ CreateRecord(const char* aRecordName,
|
||||
GMPRecord** aOutRecord,
|
||||
GMPRecordClient* aClient)
|
||||
{
|
||||
MOZ_ASSERT(IsOnChildMainThread());
|
||||
|
||||
if (sMainLoop != MessageLoop::current()) {
|
||||
NS_WARNING("GMP called CreateRecord() on non-main thread!");
|
||||
MOZ_ASSERT(false, "GMP called CreateRecord() on non-main thread!");
|
||||
return GMPGenericErr;
|
||||
}
|
||||
if (aRecordNameSize > GMP_MAX_RECORD_NAME_SIZE) {
|
||||
@ -194,6 +196,25 @@ GetClock(GMPTimestamp* aOutTime)
|
||||
return GMPNoErr;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
CreateRecordIterator(RecvGMPRecordIteratorPtr aRecvIteratorFunc,
|
||||
void* aUserArg)
|
||||
{
|
||||
if (sMainLoop != MessageLoop::current()) {
|
||||
MOZ_ASSERT(false, "GMP called CreateRecord() on non-main thread!");
|
||||
return GMPGenericErr;
|
||||
}
|
||||
if (!aRecvIteratorFunc) {
|
||||
return GMPInvalidArgErr;
|
||||
}
|
||||
GMPStorageChild* storage = sChild->GetGMPStorage();
|
||||
if (!storage) {
|
||||
return GMPGenericErr;
|
||||
}
|
||||
MOZ_ASSERT(storage);
|
||||
return storage->EnumerateRecords(aRecvIteratorFunc, aUserArg);
|
||||
}
|
||||
|
||||
void
|
||||
InitPlatformAPI(GMPPlatformAPI& aPlatformAPI, GMPChild* aChild)
|
||||
{
|
||||
@ -212,6 +233,7 @@ InitPlatformAPI(GMPPlatformAPI& aPlatformAPI, GMPChild* aChild)
|
||||
aPlatformAPI.createrecord = &CreateRecord;
|
||||
aPlatformAPI.settimer = &SetTimerOnMainThread;
|
||||
aPlatformAPI.getcurrenttime = &GetClock;
|
||||
aPlatformAPI.getrecordenumerator = &CreateRecordIterator;
|
||||
}
|
||||
|
||||
GMPThreadImpl::GMPThreadImpl()
|
||||
|
@ -268,6 +268,82 @@ GMPStorageChild::RecvWriteComplete(const nsCString& aRecordName,
|
||||
return true;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPStorageChild::EnumerateRecords(RecvGMPRecordIteratorPtr aRecvIteratorFunc,
|
||||
void* aUserArg)
|
||||
{
|
||||
if (mPlugin->GMPMessageLoop() != MessageLoop::current()) {
|
||||
MOZ_ASSERT(false, "GMP used GMPStorage on non-main thread.");
|
||||
return GMPGenericErr;
|
||||
}
|
||||
if (mShutdown) {
|
||||
NS_WARNING("GMPStorage used after it's been shutdown!");
|
||||
return GMPClosedErr;
|
||||
}
|
||||
if (!SendGetRecordNames()) {
|
||||
return GMPGenericErr;
|
||||
}
|
||||
MOZ_ASSERT(aRecvIteratorFunc);
|
||||
mPendingRecordIterators.push(RecordIteratorContext(aRecvIteratorFunc, aUserArg));
|
||||
return GMPNoErr;
|
||||
}
|
||||
|
||||
class GMPRecordIteratorImpl : public GMPRecordIterator {
|
||||
public:
|
||||
GMPRecordIteratorImpl(const InfallibleTArray<nsCString>& aRecordNames)
|
||||
: mRecordNames(aRecordNames)
|
||||
, mIndex(0)
|
||||
{
|
||||
mRecordNames.Sort();
|
||||
}
|
||||
|
||||
virtual GMPErr GetName(const char** aOutName, uint32_t* aOutNameLength) MOZ_OVERRIDE {
|
||||
if (!aOutName || !aOutNameLength) {
|
||||
return GMPInvalidArgErr;
|
||||
}
|
||||
if (mIndex == mRecordNames.Length()) {
|
||||
return GMPEndOfEnumeration;
|
||||
}
|
||||
*aOutName = mRecordNames[mIndex].get();
|
||||
*aOutNameLength = mRecordNames[mIndex].Length();
|
||||
return GMPNoErr;
|
||||
}
|
||||
|
||||
virtual GMPErr NextRecord() MOZ_OVERRIDE {
|
||||
if (mIndex < mRecordNames.Length()) {
|
||||
mIndex++;
|
||||
}
|
||||
return (mIndex < mRecordNames.Length()) ? GMPNoErr
|
||||
: GMPEndOfEnumeration;
|
||||
}
|
||||
|
||||
virtual void Close() MOZ_OVERRIDE {
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
nsTArray<nsCString> mRecordNames;
|
||||
size_t mIndex;
|
||||
};
|
||||
|
||||
bool
|
||||
GMPStorageChild::RecvRecordNames(const InfallibleTArray<nsCString>& aRecordNames,
|
||||
const GMPErr& aStatus)
|
||||
{
|
||||
if (mShutdown || mPendingRecordIterators.empty()) {
|
||||
return true;
|
||||
}
|
||||
RecordIteratorContext ctx = mPendingRecordIterators.front();
|
||||
mPendingRecordIterators.pop();
|
||||
|
||||
if (GMP_FAILED(aStatus)) {
|
||||
ctx.mFunc(nullptr, ctx.mUserArg, aStatus);
|
||||
} else {
|
||||
ctx.mFunc(new GMPRecordIteratorImpl(aRecordNames), ctx.mUserArg, GMPNoErr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPStorageChild::RecvShutdown()
|
||||
{
|
||||
@ -275,6 +351,9 @@ GMPStorageChild::RecvShutdown()
|
||||
// parent. We don't delete any objects here, as that may invalidate
|
||||
// GMPRecord pointers held by the GMP.
|
||||
mShutdown = true;
|
||||
while (!mPendingRecordIterators.empty()) {
|
||||
mPendingRecordIterators.pop();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,9 @@
|
||||
#include "gmp-storage.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "gmp-platform.h"
|
||||
|
||||
#include <queue>
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
@ -70,6 +73,9 @@ public:
|
||||
|
||||
GMPErr Close(GMPRecordImpl* aRecord);
|
||||
|
||||
GMPErr EnumerateRecords(RecvGMPRecordIteratorPtr aRecvIteratorFunc,
|
||||
void* aUserArg);
|
||||
|
||||
protected:
|
||||
~GMPStorageChild() {}
|
||||
|
||||
@ -81,11 +87,25 @@ protected:
|
||||
const InfallibleTArray<uint8_t>& aBytes) MOZ_OVERRIDE;
|
||||
virtual bool RecvWriteComplete(const nsCString& aRecordName,
|
||||
const GMPErr& aStatus) MOZ_OVERRIDE;
|
||||
virtual bool RecvRecordNames(const InfallibleTArray<nsCString>& aRecordNames,
|
||||
const GMPErr& aStatus) MOZ_OVERRIDE;
|
||||
virtual bool RecvShutdown() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
nsRefPtrHashtable<nsCStringHashKey, GMPRecordImpl> mRecords;
|
||||
GMPChild* mPlugin;
|
||||
|
||||
struct RecordIteratorContext {
|
||||
explicit RecordIteratorContext(RecvGMPRecordIteratorPtr aFunc,
|
||||
void* aUserArg)
|
||||
: mFunc(aFunc)
|
||||
, mUserArg(aUserArg)
|
||||
{}
|
||||
RecvGMPRecordIteratorPtr mFunc;
|
||||
void* mUserArg;
|
||||
};
|
||||
|
||||
std::queue<RecordIteratorContext> mPendingRecordIterators;
|
||||
bool mShutdown;
|
||||
};
|
||||
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "mozIGeckoMediaPluginService.h"
|
||||
#include "nsContentCID.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "mozilla/Base64.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -104,9 +106,17 @@ OpenStorageFile(const nsCString& aRecordName,
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsAutoString recordNameHash;
|
||||
recordNameHash.AppendInt(HashString(aRecordName.get()));
|
||||
f->Append(recordNameHash);
|
||||
nsAutoCString recordNameBase64;
|
||||
rv = Base64Encode(aRecordName, recordNameBase64);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Base64 can encode to a '/' character, which will mess with file paths,
|
||||
// so we need to replace that here with something that won't mess with paths.
|
||||
recordNameBase64.ReplaceChar('/', '-');
|
||||
|
||||
f->AppendNative(recordNameBase64);
|
||||
|
||||
auto mode = PR_RDWR | PR_CREATE_FILE;
|
||||
if (aMode == Truncate) {
|
||||
@ -193,6 +203,54 @@ public:
|
||||
return (bytesWritten == (int32_t)aBytes.Length()) ? GMPNoErr : GMPGenericErr;
|
||||
}
|
||||
|
||||
virtual GMPErr GetRecordNames(nsTArray<nsCString>& aOutRecordNames) MOZ_OVERRIDE
|
||||
{
|
||||
nsCOMPtr<nsIFile> storageDir;
|
||||
nsresult rv = GetGMPStorageDir(getter_AddRefs(storageDir), mNodeId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return GMPGenericErr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> iter;
|
||||
rv = storageDir->GetDirectoryEntries(getter_AddRefs(iter));
|
||||
if (NS_FAILED(rv)) {
|
||||
return GMPGenericErr;
|
||||
}
|
||||
|
||||
bool hasMore;
|
||||
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
rv = iter->GetNext(getter_AddRefs(supports));
|
||||
if (NS_FAILED(rv)) {
|
||||
continue;
|
||||
}
|
||||
nsCOMPtr<nsIFile> dirEntry(do_QueryInterface(supports, &rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAutoCString leafName;
|
||||
rv = dirEntry->GetNativeLeafName(leafName);
|
||||
if (NS_FAILED(rv)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// The record's file name is the Base64 encode of the record name,
|
||||
// with '/' characters replaced with '-' characters. Base64 decode
|
||||
// to extract the file name.
|
||||
leafName.ReplaceChar('-', '/');
|
||||
nsAutoCString recordName;
|
||||
rv = Base64Decode(leafName, recordName);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
aOutRecordNames.AppendElement(recordName);
|
||||
}
|
||||
|
||||
return GMPNoErr;
|
||||
}
|
||||
|
||||
virtual void Close(const nsCString& aRecordName) MOZ_OVERRIDE
|
||||
{
|
||||
PRFileDesc* fd = mFiles.Get(aRecordName);
|
||||
@ -255,6 +313,12 @@ public:
|
||||
return GMPNoErr;
|
||||
}
|
||||
|
||||
virtual GMPErr GetRecordNames(nsTArray<nsCString>& aOutRecordNames) MOZ_OVERRIDE
|
||||
{
|
||||
mRecords.EnumerateRead(EnumRecordNames, &aOutRecordNames);
|
||||
return GMPNoErr;
|
||||
}
|
||||
|
||||
virtual void Close(const nsCString& aRecordName) MOZ_OVERRIDE
|
||||
{
|
||||
Record* record = nullptr;
|
||||
@ -277,6 +341,16 @@ private:
|
||||
bool mIsOpen;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
EnumRecordNames(const nsACString& aKey,
|
||||
Record* aRecord,
|
||||
void* aUserArg)
|
||||
{
|
||||
nsTArray<nsCString>* names = reinterpret_cast<nsTArray<nsCString>*>(aUserArg);
|
||||
names->AppendElement(aKey);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsClassHashtable<nsCStringHashKey, Record> mRecords;
|
||||
};
|
||||
|
||||
@ -389,6 +463,22 @@ GMPStorageParent::RecvWrite(const nsCString& aRecordName,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPStorageParent::RecvGetRecordNames()
|
||||
{
|
||||
LOGD(("%s::%s: %p", __CLASS__, __FUNCTION__, this));
|
||||
|
||||
if (mShutdown) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsTArray<nsCString> recordNames;
|
||||
GMPErr status = mStorage->GetRecordNames(recordNames);
|
||||
unused << SendRecordNames(recordNames, status);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPStorageParent::RecvClose(const nsCString& aRecordName)
|
||||
{
|
||||
|
@ -25,6 +25,7 @@ public:
|
||||
nsTArray<uint8_t>& aOutBytes) = 0;
|
||||
virtual GMPErr Write(const nsCString& aRecordName,
|
||||
const nsTArray<uint8_t>& aBytes) = 0;
|
||||
virtual GMPErr GetRecordNames(nsTArray<nsCString>& aOutRecordNames) = 0;
|
||||
virtual void Close(const nsCString& aRecordName) = 0;
|
||||
};
|
||||
|
||||
@ -42,6 +43,7 @@ protected:
|
||||
virtual bool RecvRead(const nsCString& aRecordName) MOZ_OVERRIDE;
|
||||
virtual bool RecvWrite(const nsCString& aRecordName,
|
||||
const InfallibleTArray<uint8_t>& aBytes) MOZ_OVERRIDE;
|
||||
virtual bool RecvGetRecordNames() MOZ_OVERRIDE;
|
||||
virtual bool RecvClose(const nsCString& aRecordName) MOZ_OVERRIDE;
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
|
||||
|
@ -19,6 +19,7 @@ child:
|
||||
OpenComplete(nsCString aRecordName, GMPErr aStatus);
|
||||
ReadComplete(nsCString aRecordName, GMPErr aStatus, uint8_t[] aBytes);
|
||||
WriteComplete(nsCString aRecordName, GMPErr aStatus);
|
||||
RecordNames(nsCString[] aRecordNames, GMPErr aStatus);
|
||||
Shutdown();
|
||||
|
||||
parent:
|
||||
@ -26,6 +27,7 @@ parent:
|
||||
Read(nsCString aRecordName);
|
||||
Write(nsCString aRecordName, uint8_t[] aBytes);
|
||||
Close(nsCString aRecordName);
|
||||
GetRecordNames();
|
||||
__delete__();
|
||||
|
||||
};
|
||||
|
@ -37,7 +37,7 @@ struct GMPAudioCodec
|
||||
// AAC AudioSpecificConfig.
|
||||
// These are null/0 if not externally negotiated
|
||||
const uint8_t* mExtraData;
|
||||
size_t mExtraDataLen;
|
||||
uint32_t mExtraDataLen;
|
||||
};
|
||||
|
||||
#endif // GMP_AUDIO_CODEC_h_
|
||||
|
@ -45,6 +45,8 @@ typedef enum {
|
||||
GMPEncodeErr = 8,
|
||||
GMPNoKeyErr = 9,
|
||||
GMPCryptoErr = 10,
|
||||
GMPEndOfEnumeration = 11,
|
||||
GMPInvalidArgErr = 12,
|
||||
GMPLastErr // Placeholder, must be last. This enum's values must remain consecutive!
|
||||
} GMPErr;
|
||||
|
||||
|
@ -82,6 +82,22 @@ typedef GMPErr (*GMPCreateRecordPtr)(const char* aRecordName,
|
||||
typedef GMPErr (*GMPSetTimerOnMainThreadPtr)(GMPTask* aTask, int64_t aTimeoutMS);
|
||||
typedef GMPErr (*GMPGetCurrentTimePtr)(GMPTimestamp* aOutTime);
|
||||
|
||||
typedef void (*RecvGMPRecordIteratorPtr)(GMPRecordIterator* aRecordIterator,
|
||||
void* aUserArg,
|
||||
GMPErr aStatus);
|
||||
|
||||
// Creates a GMPCreateRecordIterator to enumerate the records in storage.
|
||||
// When the iterator is ready, the function at aRecvIteratorFunc
|
||||
// is called with the GMPRecordIterator as an argument. If the operation
|
||||
// fails, RecvGMPRecordIteratorPtr is called with a failure aStatus code.
|
||||
// The list that the iterator is covering is fixed when
|
||||
// GMPCreateRecordIterator is called, it is *not* updated when changes are
|
||||
// made to storage.
|
||||
// Iterator begins pointing at first record.
|
||||
// aUserArg is passed to the aRecvIteratorFunc upon completion.
|
||||
typedef GMPErr (*GMPCreateRecordIteratorPtr)(RecvGMPRecordIteratorPtr aRecvIteratorFunc,
|
||||
void* aUserArg);
|
||||
|
||||
struct GMPPlatformAPI {
|
||||
// Increment the version when things change. Can only add to the struct,
|
||||
// do not change what already exists. Pointers to functions may be NULL
|
||||
@ -96,6 +112,7 @@ struct GMPPlatformAPI {
|
||||
GMPCreateRecordPtr createrecord;
|
||||
GMPSetTimerOnMainThreadPtr settimer;
|
||||
GMPGetCurrentTimePtr getcurrenttime;
|
||||
GMPCreateRecordIteratorPtr getrecordenumerator;
|
||||
};
|
||||
|
||||
#endif // GMP_PLATFORM_h_
|
||||
|
@ -110,4 +110,31 @@ class GMPRecordClient {
|
||||
virtual ~GMPRecordClient() {}
|
||||
};
|
||||
|
||||
// Iterates over the records that are available. Note: this list maintains
|
||||
// a snapshot of the records that were present when the iterator was created.
|
||||
// Create by calling the GMPCreateRecordIteratorPtr function on the
|
||||
// GMPPlatformAPI struct.
|
||||
// Iteration is in alphabetical order.
|
||||
class GMPRecordIterator {
|
||||
public:
|
||||
// Retrieve the name for the current record.
|
||||
// Returns GMPNoErr if successful, or GMPEndOfEnumeration if iteration has
|
||||
// reached the end.
|
||||
virtual GMPErr GetName(const char ** aOutName, uint32_t * aOutNameLength) = 0;
|
||||
|
||||
// Advance iteration to the next record.
|
||||
// Returns GMPNoErr if successful, or GMPEndOfEnumeration if iteration has
|
||||
// reached the end.
|
||||
virtual GMPErr NextRecord() = 0;
|
||||
|
||||
// Signals to the GMP host that the GMP is finished with the
|
||||
// GMPRecordIterator. GMPs must call this to release memory held by
|
||||
// the GMPRecordIterator. Do not access the GMPRecordIterator pointer
|
||||
// after calling this!
|
||||
// Memory retrieved by GetName is *not* valid after calling Close()!
|
||||
virtual void Close() = 0;
|
||||
|
||||
virtual ~GMPRecordIterator() {}
|
||||
};
|
||||
|
||||
#endif // GMP_STORAGE_h_
|
||||
|
@ -580,6 +580,67 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||
Update(NS_LITERAL_CSTRING("retrieve-plugin-voucher"));
|
||||
}
|
||||
|
||||
void TestGetRecordNamesInMemoryStorage() {
|
||||
TestGetRecordNames(true);
|
||||
}
|
||||
|
||||
nsCString mRecordNames;
|
||||
|
||||
void AppendIntPadded(nsACString& aString, uint32_t aInt) {
|
||||
if (aInt > 0 && aInt < 10) {
|
||||
aString.AppendLiteral("0");
|
||||
}
|
||||
aString.AppendInt(aInt);
|
||||
}
|
||||
|
||||
void TestGetRecordNames(bool aPrivateBrowsing) {
|
||||
CreateDecryptor(NS_LITERAL_STRING("foo.com"),
|
||||
NS_LITERAL_STRING("bar.com"),
|
||||
aPrivateBrowsing);
|
||||
|
||||
// Create a number of records of different names.
|
||||
const uint32_t num = 100;
|
||||
for (uint32_t i = 0; i < num; i++) {
|
||||
nsAutoCString response;
|
||||
response.AppendLiteral("stored data");
|
||||
AppendIntPadded(response, i);
|
||||
response.AppendLiteral(" test-data");
|
||||
AppendIntPadded(response, i);
|
||||
|
||||
if (i != 0) {
|
||||
mRecordNames.AppendLiteral(",");
|
||||
}
|
||||
mRecordNames.AppendLiteral("data");
|
||||
AppendIntPadded(mRecordNames, i);
|
||||
|
||||
nsAutoCString update;
|
||||
update.AppendLiteral("store data");
|
||||
AppendIntPadded(update, i);
|
||||
update.AppendLiteral(" test-data");
|
||||
AppendIntPadded(update, i);
|
||||
|
||||
nsIRunnable* continuation = nullptr;
|
||||
if (i + 1 == num) {
|
||||
continuation =
|
||||
NS_NewRunnableMethod(this, &GMPStorageTest::TestGetRecordNames_QueryNames);
|
||||
}
|
||||
Expect(response, continuation);
|
||||
Update(update);
|
||||
}
|
||||
}
|
||||
|
||||
void TestGetRecordNames_QueryNames() {
|
||||
nsCString response("record-names ");
|
||||
response.Append(mRecordNames);
|
||||
Expect(response,
|
||||
NS_NewRunnableMethod(this, &GMPStorageTest::SetFinished));
|
||||
Update(NS_LITERAL_CSTRING("retrieve-record-names"));
|
||||
}
|
||||
|
||||
void GetRecordNamesPersistentStorage() {
|
||||
TestGetRecordNames(false);
|
||||
}
|
||||
|
||||
void Expect(const nsCString& aMessage, nsIRunnable* aContinuation) {
|
||||
mExpected.AppendElement(ExpectedMessage(aMessage, aContinuation));
|
||||
}
|
||||
@ -751,3 +812,13 @@ TEST(GeckoMediaPlugins, GMPOutputProtection) {
|
||||
runner->DoTest(&GMPStorageTest::TestOutputProtection);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(GeckoMediaPlugins, GMPStorageGetRecordNamesInMemoryStorage) {
|
||||
nsRefPtr<GMPStorageTest> runner = new GMPStorageTest();
|
||||
runner->DoTest(&GMPStorageTest::TestGetRecordNamesInMemoryStorage);
|
||||
}
|
||||
|
||||
TEST(GeckoMediaPlugins, GMPStorageGetRecordNamesPersistentStorage) {
|
||||
nsRefPtr<GMPStorageTest> runner = new GMPStorageTest();
|
||||
runner->DoTest(&GMPStorageTest::GetRecordNamesPersistentStorage);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user