diff options
Diffstat (limited to 'media/gmp-clearkey/0.1/ClearKeyStorage.cpp')
-rw-r--r-- | media/gmp-clearkey/0.1/ClearKeyStorage.cpp | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/media/gmp-clearkey/0.1/ClearKeyStorage.cpp b/media/gmp-clearkey/0.1/ClearKeyStorage.cpp new file mode 100644 index 000000000..0db51c9b7 --- /dev/null +++ b/media/gmp-clearkey/0.1/ClearKeyStorage.cpp @@ -0,0 +1,194 @@ +/* + * Copyright 2015, Mozilla Foundation and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ClearKeyStorage.h" +#include "ClearKeyUtils.h" + +#include "gmp-task-utils.h" + +#include <assert.h> +#include "ArrayUtils.h" + +#include <vector> + +static GMPErr +RunOnMainThread(GMPTask* aTask) +{ + return GetPlatform()->runonmainthread(aTask); +} + +GMPErr +OpenRecord(const char* aName, + uint32_t aNameLength, + GMPRecord** aOutRecord, + GMPRecordClient* aClient) +{ + return GetPlatform()->createrecord(aName, aNameLength, aOutRecord, aClient); +} + +class WriteRecordClient : public GMPRecordClient { +public: + /* + * This function will take the memory ownership of the parameters and + * delete them when done. + */ + static void Write(const std::string& aRecordName, + const std::vector<uint8_t>& aData, + GMPTask* aOnSuccess, + GMPTask* aOnFailure) { + (new WriteRecordClient(aData, aOnSuccess, aOnFailure))->Do(aRecordName); + } + + virtual void OpenComplete(GMPErr aStatus) override { + if (GMP_FAILED(aStatus) || + GMP_FAILED(mRecord->Write(&mData.front(), mData.size()))) { + Done(mOnFailure, mOnSuccess); + } + } + + virtual void ReadComplete(GMPErr aStatus, + const uint8_t* aData, + uint32_t aDataSize) override { + assert(false); // Should not reach here. + } + + virtual void WriteComplete(GMPErr aStatus) override { + if (GMP_FAILED(aStatus)) { + Done(mOnFailure, mOnSuccess); + } else { + Done(mOnSuccess, mOnFailure); + } + } + +private: + WriteRecordClient(const std::vector<uint8_t>& aData, + GMPTask* aOnSuccess, + GMPTask* aOnFailure) + : mRecord(nullptr) + , mOnSuccess(aOnSuccess) + , mOnFailure(aOnFailure) + , mData(aData) {} + + void Do(const std::string& aName) { + auto err = OpenRecord(aName.c_str(), aName.size(), &mRecord, this); + if (GMP_FAILED(err) || + GMP_FAILED(mRecord->Open())) { + Done(mOnFailure, mOnSuccess); + } + } + + void Done(GMPTask* aToRun, GMPTask* aToDestroy) { + // Note: Call Close() before running continuation, in case the + // continuation tries to open the same record; if we call Close() + // after running the continuation, the Close() call will arrive + // just after the Open() call succeeds, immediately closing the + // record we just opened. + if (mRecord) { + mRecord->Close(); + } + aToDestroy->Destroy(); + RunOnMainThread(aToRun); + delete this; + } + + GMPRecord* mRecord; + GMPTask* mOnSuccess; + GMPTask* mOnFailure; + const std::vector<uint8_t> mData; +}; + +void +StoreData(const std::string& aRecordName, + const std::vector<uint8_t>& aData, + GMPTask* aOnSuccess, + GMPTask* aOnFailure) +{ + WriteRecordClient::Write(aRecordName, aData, aOnSuccess, aOnFailure); +} + +class ReadRecordClient : public GMPRecordClient { +public: + /* + * This function will take the memory ownership of the parameters and + * delete them when done. + */ + static void Read(const std::string& aRecordName, + ReadContinuation* aContinuation) { + assert(aContinuation); + (new ReadRecordClient(aContinuation))->Do(aRecordName); + } + + virtual void OpenComplete(GMPErr aStatus) override { + auto err = aStatus; + if (GMP_FAILED(err) || + GMP_FAILED(err = mRecord->Read())) { + Done(err, nullptr, 0); + } + } + + virtual void ReadComplete(GMPErr aStatus, + const uint8_t* aData, + uint32_t aDataSize) override { + Done(aStatus, aData, aDataSize); + } + + virtual void WriteComplete(GMPErr aStatus) override { + assert(false); // Should not reach here. + } + +private: + explicit ReadRecordClient(ReadContinuation* aContinuation) + : mRecord(nullptr) + , mContinuation(aContinuation) {} + + void Do(const std::string& aName) { + auto err = OpenRecord(aName.c_str(), aName.size(), &mRecord, this); + if (GMP_FAILED(err) || + GMP_FAILED(err = mRecord->Open())) { + Done(err, nullptr, 0); + } + } + + void Done(GMPErr err, const uint8_t* aData, uint32_t aDataSize) { + // Note: Call Close() before running continuation, in case the + // continuation tries to open the same record; if we call Close() + // after running the continuation, the Close() call will arrive + // just after the Open() call succeeds, immediately closing the + // record we just opened. + if (mRecord) { + mRecord->Close(); + } + mContinuation->ReadComplete(err, aData, aDataSize); + delete mContinuation; + delete this; + } + + GMPRecord* mRecord; + ReadContinuation* mContinuation; +}; + +void +ReadData(const std::string& aRecordName, + ReadContinuation* aContinuation) +{ + ReadRecordClient::Read(aRecordName, aContinuation); +} + +GMPErr +EnumRecordNames(RecvGMPRecordIteratorPtr aRecvIteratorFunc) +{ + return GetPlatform()->getrecordenumerator(aRecvIteratorFunc, nullptr); +} |