media/gmp-clearkey/0.1/ClearKeyStorage.cpp
author Gregory Szorc <gps@mozilla.com>
Thu, 19 Feb 2015 10:58:41 -0800
changeset 245738 c97c977c92b97c9585011651b13a088f0cd4ed4f
parent 242266 533acf8bbd7f5b5f7aa609e5cc5a8290e6d3c372
child 252249 ac4464790ec4896a5188fa50cfc69ae0ffeddc08
permissions -rw-r--r--
Bug 1132771 - moz.build fixups to enable execution in no config mode Various moz.build files fail to execute when a build config is not present. Many of these are due to assuming certain CONFIG entries are present. This patch attempts to fix that and enable every moz.build to be read without a build config.

/* 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 "ClearKeyStorage.h"
#include "ClearKeyUtils.h"

#include "gmp-task-utils.h"

#include "mozilla/Assertions.h"
#include "mozilla/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) MOZ_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) MOZ_OVERRIDE {
    MOZ_ASSERT(false, "Should not reach here.");
  }

  virtual void WriteComplete(GMPErr aStatus) MOZ_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) {
    MOZ_ASSERT(aContinuation);
    (new ReadRecordClient(aContinuation))->Do(aRecordName);
  }

  virtual void OpenComplete(GMPErr aStatus) MOZ_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) MOZ_OVERRIDE {
    Done(aStatus, aData, aDataSize);
  }

  virtual void WriteComplete(GMPErr aStatus) MOZ_OVERRIDE {
    MOZ_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);
}