media/gmp-clearkey/0.1/ClearKeyStorage.cpp
author Kartikaya Gupta <kgupta@mozilla.com>
Sun, 03 Apr 2016 13:13:58 -0400
changeset 291516 110538d89648260440c66045dcde9e0f1eb6dde1
parent 237875 38f4f036b6119f8c3d00480426c505fb07a80306
permissions -rw-r--r--
Bug 1246290 - Add the ability for APZCs to not expose async transforms. r=botond The call site is responsible for indicating whether or not the APZC should respect the force-disable flag in the APZCs. This is because we only want to respect that flag when doing visual transforms (similar to how scrollinfo layers work) and not when doing transforms on input events. MozReview-Commit-ID: Dqgz6fqJGXG

/*
 * 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);
}