// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/cdm/ppapi/ppapi_cdm_adapter.h"

#include <string.h>

#include "base/macros.h"
#include "build/build_config.h"
#include "media/base/limits.h"
#include "media/cdm/ppapi/cdm_file_io_impl.h"
#include "media/cdm/ppapi/cdm_logging.h"
#include "media/cdm/supported_cdm_versions.h"
#include "ppapi/c/ppb_console.h"
#include "ppapi/cpp/private/uma_private.h"

#if defined(CHECK_DOCUMENT_URL)
#include "ppapi/cpp/dev/url_util_dev.h"
#include "ppapi/cpp/instance_handle.h"
#endif  // defined(CHECK_DOCUMENT_URL)

namespace {

// Constants for UMA reporting of file size (in KB) via HistogramCustomCounts().
// Note that the histogram is log-scaled (rather than linear).
const uint32_t kSizeKBMin = 1;
const uint32_t kSizeKBMax = 512 * 1024;  // 512MB
const uint32_t kSizeKBBuckets = 100;

#if !defined(NDEBUG)
#define DLOG_TO_CONSOLE(message) LogToConsole(message);
#else
#define DLOG_TO_CONSOLE(message) (void)(message);
#endif

bool IsMainThread() {
  return pp::Module::Get()->core()->IsMainThread();
}

// Posts a task to run |cb| on the main thread. The task is posted even if the
// current thread is the main thread.
void PostOnMain(pp::CompletionCallback cb) {
  pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK);
}

// Ensures |cb| is called on the main thread, either because the current thread
// is the main thread or by posting it to the main thread.
void CallOnMain(pp::CompletionCallback cb) {
  // TODO(tomfinegan): This is only necessary because PPAPI doesn't allow calls
  // off the main thread yet. Remove this once the change lands.
  if (IsMainThread())
    cb.Run(PP_OK);
  else
    PostOnMain(cb);
}

// Configures a cdm::InputBuffer. |subsamples| must exist as long as
// |input_buffer| is in use.
void ConfigureInputBuffer(const pp::Buffer_Dev& encrypted_buffer,
                          const PP_EncryptedBlockInfo& encrypted_block_info,
                          std::vector<cdm::SubsampleEntry>* subsamples,
                          cdm::InputBuffer* input_buffer) {
  PP_DCHECK(subsamples);
  PP_DCHECK(!encrypted_buffer.is_null());

  input_buffer->data = static_cast<uint8_t*>(encrypted_buffer.data());
  input_buffer->data_size = encrypted_block_info.data_size;
  PP_DCHECK(encrypted_buffer.size() >= input_buffer->data_size);

  PP_DCHECK(encrypted_block_info.key_id_size <=
            arraysize(encrypted_block_info.key_id));
  input_buffer->key_id_size = encrypted_block_info.key_id_size;
  input_buffer->key_id =
      input_buffer->key_id_size > 0 ? encrypted_block_info.key_id : NULL;

  PP_DCHECK(encrypted_block_info.iv_size <= arraysize(encrypted_block_info.iv));
  input_buffer->iv_size = encrypted_block_info.iv_size;
  input_buffer->iv =
      encrypted_block_info.iv_size > 0 ? encrypted_block_info.iv : NULL;

  input_buffer->num_subsamples = encrypted_block_info.num_subsamples;
  if (encrypted_block_info.num_subsamples > 0) {
    subsamples->reserve(encrypted_block_info.num_subsamples);

    for (uint32_t i = 0; i < encrypted_block_info.num_subsamples; ++i) {
      subsamples->push_back(
          cdm::SubsampleEntry(encrypted_block_info.subsamples[i].clear_bytes,
                              encrypted_block_info.subsamples[i].cipher_bytes));
    }

    input_buffer->subsamples = &(*subsamples)[0];
  }

  input_buffer->timestamp = encrypted_block_info.tracking_info.timestamp;
}

PP_DecryptResult CdmStatusToPpDecryptResult(cdm::Status status) {
  switch (status) {
    case cdm::kSuccess:
      return PP_DECRYPTRESULT_SUCCESS;
    case cdm::kNoKey:
      return PP_DECRYPTRESULT_DECRYPT_NOKEY;
    case cdm::kNeedMoreData:
      return PP_DECRYPTRESULT_NEEDMOREDATA;
    case cdm::kDecryptError:
      return PP_DECRYPTRESULT_DECRYPT_ERROR;
    case cdm::kDecodeError:
      return PP_DECRYPTRESULT_DECODE_ERROR;
    case cdm::kSessionError:
    case cdm::kDeferredInitialization:
      // kSessionError and kDeferredInitialization are only used by the
      // Initialize* methods internally and never returned. Deliver*
      // methods should never use these values.
      break;
  }

  PP_NOTREACHED();
  return PP_DECRYPTRESULT_DECRYPT_ERROR;
}

PP_DecryptedFrameFormat CdmVideoFormatToPpDecryptedFrameFormat(
    cdm::VideoFormat format) {
  switch (format) {
    case cdm::kYv12:
      return PP_DECRYPTEDFRAMEFORMAT_YV12;
    case cdm::kI420:
      return PP_DECRYPTEDFRAMEFORMAT_I420;
    default:
      return PP_DECRYPTEDFRAMEFORMAT_UNKNOWN;
  }
}

PP_DecryptedSampleFormat CdmAudioFormatToPpDecryptedSampleFormat(
    cdm::AudioFormat format) {
  switch (format) {
    case cdm::kAudioFormatU8:
      return PP_DECRYPTEDSAMPLEFORMAT_U8;
    case cdm::kAudioFormatS16:
      return PP_DECRYPTEDSAMPLEFORMAT_S16;
    case cdm::kAudioFormatS32:
      return PP_DECRYPTEDSAMPLEFORMAT_S32;
    case cdm::kAudioFormatF32:
      return PP_DECRYPTEDSAMPLEFORMAT_F32;
    case cdm::kAudioFormatPlanarS16:
      return PP_DECRYPTEDSAMPLEFORMAT_PLANAR_S16;
    case cdm::kAudioFormatPlanarF32:
      return PP_DECRYPTEDSAMPLEFORMAT_PLANAR_F32;
    default:
      return PP_DECRYPTEDSAMPLEFORMAT_UNKNOWN;
  }
}

cdm::AudioDecoderConfig::AudioCodec PpAudioCodecToCdmAudioCodec(
    PP_AudioCodec codec) {
  switch (codec) {
    case PP_AUDIOCODEC_VORBIS:
      return cdm::AudioDecoderConfig::kCodecVorbis;
    case PP_AUDIOCODEC_AAC:
      return cdm::AudioDecoderConfig::kCodecAac;
    default:
      return cdm::AudioDecoderConfig::kUnknownAudioCodec;
  }
}

cdm::VideoDecoderConfig::VideoCodec PpVideoCodecToCdmVideoCodec(
    PP_VideoCodec codec) {
  switch (codec) {
    case PP_VIDEOCODEC_VP8:
      return cdm::VideoDecoderConfig::kCodecVp8;
    case PP_VIDEOCODEC_H264:
      return cdm::VideoDecoderConfig::kCodecH264;
    case PP_VIDEOCODEC_VP9:
      return cdm::VideoDecoderConfig::kCodecVp9;
    default:
      return cdm::VideoDecoderConfig::kUnknownVideoCodec;
  }
}

cdm::VideoDecoderConfig::VideoCodecProfile PpVCProfileToCdmVCProfile(
    PP_VideoCodecProfile profile) {
  switch (profile) {
    case PP_VIDEOCODECPROFILE_NOT_NEEDED:
      return cdm::VideoDecoderConfig::kProfileNotNeeded;
    case PP_VIDEOCODECPROFILE_H264_BASELINE:
      return cdm::VideoDecoderConfig::kH264ProfileBaseline;
    case PP_VIDEOCODECPROFILE_H264_MAIN:
      return cdm::VideoDecoderConfig::kH264ProfileMain;
    case PP_VIDEOCODECPROFILE_H264_EXTENDED:
      return cdm::VideoDecoderConfig::kH264ProfileExtended;
    case PP_VIDEOCODECPROFILE_H264_HIGH:
      return cdm::VideoDecoderConfig::kH264ProfileHigh;
    case PP_VIDEOCODECPROFILE_H264_HIGH_10:
      return cdm::VideoDecoderConfig::kH264ProfileHigh10;
    case PP_VIDEOCODECPROFILE_H264_HIGH_422:
      return cdm::VideoDecoderConfig::kH264ProfileHigh422;
    case PP_VIDEOCODECPROFILE_H264_HIGH_444_PREDICTIVE:
      return cdm::VideoDecoderConfig::kH264ProfileHigh444Predictive;
    default:
      return cdm::VideoDecoderConfig::kUnknownVideoCodecProfile;
  }
}

cdm::VideoFormat PpDecryptedFrameFormatToCdmVideoFormat(
    PP_DecryptedFrameFormat format) {
  switch (format) {
    case PP_DECRYPTEDFRAMEFORMAT_YV12:
      return cdm::kYv12;
    case PP_DECRYPTEDFRAMEFORMAT_I420:
      return cdm::kI420;
    default:
      return cdm::kUnknownVideoFormat;
  }
}

cdm::StreamType PpDecryptorStreamTypeToCdmStreamType(
    PP_DecryptorStreamType stream_type) {
  switch (stream_type) {
    case PP_DECRYPTORSTREAMTYPE_AUDIO:
      return cdm::kStreamTypeAudio;
    case PP_DECRYPTORSTREAMTYPE_VIDEO:
      return cdm::kStreamTypeVideo;
  }

  PP_NOTREACHED();
  return cdm::kStreamTypeVideo;
}

cdm::SessionType PpSessionTypeToCdmSessionType(PP_SessionType session_type) {
  switch (session_type) {
    case PP_SESSIONTYPE_TEMPORARY:
      return cdm::kTemporary;
    case PP_SESSIONTYPE_PERSISTENT_LICENSE:
      return cdm::kPersistentLicense;
    case PP_SESSIONTYPE_PERSISTENT_RELEASE:
      return cdm::kPersistentKeyRelease;
  }

  PP_NOTREACHED();
  return cdm::kTemporary;
}

cdm::InitDataType PpInitDataTypeToCdmInitDataType(
    PP_InitDataType init_data_type) {
  switch (init_data_type) {
    case PP_INITDATATYPE_CENC:
      return cdm::kCenc;
    case PP_INITDATATYPE_KEYIDS:
      return cdm::kKeyIds;
    case PP_INITDATATYPE_WEBM:
      return cdm::kWebM;
  }

  PP_NOTREACHED();
  return cdm::kKeyIds;
}

PP_CdmExceptionCode CdmExceptionTypeToPpCdmExceptionType(cdm::Error error) {
  switch (error) {
    case cdm::kNotSupportedError:
      return PP_CDMEXCEPTIONCODE_NOTSUPPORTEDERROR;
    case cdm::kInvalidStateError:
      return PP_CDMEXCEPTIONCODE_INVALIDSTATEERROR;
    case cdm::kInvalidAccessError:
      return PP_CDMEXCEPTIONCODE_INVALIDACCESSERROR;
    case cdm::kQuotaExceededError:
      return PP_CDMEXCEPTIONCODE_QUOTAEXCEEDEDERROR;
    case cdm::kUnknownError:
      return PP_CDMEXCEPTIONCODE_UNKNOWNERROR;
    case cdm::kClientError:
      return PP_CDMEXCEPTIONCODE_CLIENTERROR;
    case cdm::kOutputError:
      return PP_CDMEXCEPTIONCODE_OUTPUTERROR;
  }

  PP_NOTREACHED();
  return PP_CDMEXCEPTIONCODE_UNKNOWNERROR;
}

PP_CdmMessageType CdmMessageTypeToPpMessageType(cdm::MessageType message) {
  switch (message) {
    case cdm::kLicenseRequest:
      return PP_CDMMESSAGETYPE_LICENSE_REQUEST;
    case cdm::kLicenseRenewal:
      return PP_CDMMESSAGETYPE_LICENSE_RENEWAL;
    case cdm::kLicenseRelease:
      return PP_CDMMESSAGETYPE_LICENSE_RELEASE;
  }

  PP_NOTREACHED();
  return PP_CDMMESSAGETYPE_LICENSE_REQUEST;
}

PP_CdmKeyStatus CdmKeyStatusToPpKeyStatus(cdm::KeyStatus status) {
  switch (status) {
    case cdm::kUsable:
      return PP_CDMKEYSTATUS_USABLE;
    case cdm::kInternalError:
      return PP_CDMKEYSTATUS_INVALID;
    case cdm::kExpired:
      return PP_CDMKEYSTATUS_EXPIRED;
    case cdm::kOutputRestricted:
      return PP_CDMKEYSTATUS_OUTPUTRESTRICTED;
    case cdm::kOutputDownscaled:
      return PP_CDMKEYSTATUS_OUTPUTDOWNSCALED;
    case cdm::kStatusPending:
      return PP_CDMKEYSTATUS_STATUSPENDING;
    case cdm::kReleased:
      return PP_CDMKEYSTATUS_RELEASED;
  }

  PP_NOTREACHED();
  return PP_CDMKEYSTATUS_INVALID;
}

}  // namespace

namespace media {

PpapiCdmAdapter::PpapiCdmAdapter(PP_Instance instance, pp::Module* module)
    : pp::Instance(instance),
      pp::ContentDecryptor_Private(this),
      output_protection_(this),
      output_link_mask_(0),
      output_protection_mask_(0),
      query_output_protection_in_progress_(false),
      uma_for_output_protection_query_reported_(false),
      uma_for_output_protection_positive_result_reported_(false),
      platform_verification_(this),
      allocator_(this),
      cdm_(NULL),
      allow_distinctive_identifier_(false),
      allow_persistent_state_(false),
      deferred_initialize_audio_decoder_(false),
      deferred_audio_decoder_config_id_(0),
      deferred_initialize_video_decoder_(false),
      deferred_video_decoder_config_id_(0),
      last_read_file_size_kb_(0),
      file_size_uma_reported_(false) {
  callback_factory_.Initialize(this);
}

PpapiCdmAdapter::~PpapiCdmAdapter() {}

CdmWrapper* PpapiCdmAdapter::CreateCdmInstance(const std::string& key_system) {
  // The Pepper plugin will be staticly linked to the CDM, so pass the plugin's
  // CreateCdmInstance() to CdmWrapper.
  CdmWrapper* cdm = CdmWrapper::Create(::CreateCdmInstance, key_system.data(),
                                       key_system.size(), GetCdmHost, this);

  const std::string message = "CDM instance for " + key_system +
                              (cdm ? "" : " could not be") + " created.";
  DLOG_TO_CONSOLE(message);
  CDM_DLOG() << message;

  if (cdm) {
    pp::UMAPrivate uma_interface(this);

    // The interface version is relatively small. So using normal histogram
    // instead of a sparse histogram is okay. The following DCHECK asserts this.
    PP_DCHECK(cdm->GetInterfaceVersion() <= 30);
    uma_interface.HistogramEnumeration(
        "Media.EME.CdmInterfaceVersion", cdm->GetInterfaceVersion(),
        // Sample value should always be less than the boundary. Hence use "+1".
        // See the comment on HistogramEnumeration in ppb_uma_private.idl.
        cdm::ContentDecryptionModule::kVersion + 1);
  }

  return cdm;
}

void PpapiCdmAdapter::Initialize(uint32_t promise_id,
                                 const std::string& key_system,
                                 bool allow_distinctive_identifier,
                                 bool allow_persistent_state) {
  PP_DCHECK(!key_system.empty());
  PP_DCHECK(!cdm_);

#if defined(CHECK_DOCUMENT_URL)
  PP_URLComponents_Dev url_components = {};
  const pp::URLUtil_Dev* url_util = pp::URLUtil_Dev::Get();
  if (!url_util) {
    RejectPromise(promise_id, cdm::kUnknownError, 0,
                  "Unable to determine origin.");
    return;
  }

  pp::Var href = url_util->GetDocumentURL(pp::InstanceHandle(pp_instance()),
                                          &url_components);
  PP_DCHECK(href.is_string());
  std::string url = href.AsString();
  PP_DCHECK(!url.empty());
  std::string url_scheme =
      url.substr(url_components.scheme.begin, url_components.scheme.len);
  if (url_scheme != "file") {
    // Skip this check for file:// URLs as they don't have a host component.
    PP_DCHECK(url_components.host.begin);
    PP_DCHECK(0 < url_components.host.len);
  }
#endif  // defined(CHECK_DOCUMENT_URL)

  cdm_ = make_linked_ptr(CreateCdmInstance(key_system));
  if (!cdm_) {
    RejectPromise(promise_id, cdm::kInvalidAccessError, 0,
                  "Unable to create CDM.");
    return;
  }

  key_system_ = key_system;
  allow_distinctive_identifier_ = allow_distinctive_identifier;
  allow_persistent_state_ = allow_persistent_state;
  cdm_->Initialize(allow_distinctive_identifier, allow_persistent_state);
  OnResolvePromise(promise_id);
}

void PpapiCdmAdapter::SetServerCertificate(
    uint32_t promise_id,
    pp::VarArrayBuffer server_certificate) {
  const uint8_t* server_certificate_ptr =
      static_cast<const uint8_t*>(server_certificate.Map());
  const uint32_t server_certificate_size = server_certificate.ByteLength();

  if (!server_certificate_ptr ||
      server_certificate_size < media::limits::kMinCertificateLength ||
      server_certificate_size > media::limits::kMaxCertificateLength) {
    RejectPromise(promise_id, cdm::kInvalidAccessError, 0,
                  "Incorrect certificate.");
    return;
  }

  cdm_->SetServerCertificate(promise_id, server_certificate_ptr,
                             server_certificate_size);
}

void PpapiCdmAdapter::CreateSessionAndGenerateRequest(
    uint32_t promise_id,
    PP_SessionType session_type,
    PP_InitDataType init_data_type,
    pp::VarArrayBuffer init_data) {
  cdm_->CreateSessionAndGenerateRequest(
      promise_id, PpSessionTypeToCdmSessionType(session_type),
      PpInitDataTypeToCdmInitDataType(init_data_type),
      static_cast<const uint8_t*>(init_data.Map()), init_data.ByteLength());
}

void PpapiCdmAdapter::LoadSession(uint32_t promise_id,
                                  PP_SessionType session_type,
                                  const std::string& session_id) {
  cdm_->LoadSession(promise_id, PpSessionTypeToCdmSessionType(session_type),
                    session_id.data(), session_id.size());
}

void PpapiCdmAdapter::UpdateSession(uint32_t promise_id,
                                    const std::string& session_id,
                                    pp::VarArrayBuffer response) {
  const uint8_t* response_ptr = static_cast<const uint8_t*>(response.Map());
  const uint32_t response_size = response.ByteLength();

  PP_DCHECK(!session_id.empty());
  PP_DCHECK(response_ptr);
  PP_DCHECK(response_size > 0);

  cdm_->UpdateSession(promise_id, session_id.data(), session_id.length(),
                      response_ptr, response_size);
}

void PpapiCdmAdapter::CloseSession(uint32_t promise_id,
                                   const std::string& session_id) {
  cdm_->CloseSession(promise_id, session_id.data(), session_id.length());
}

void PpapiCdmAdapter::RemoveSession(uint32_t promise_id,
                                    const std::string& session_id) {
  cdm_->RemoveSession(promise_id, session_id.data(), session_id.length());
}

// Note: In the following decryption/decoding related functions, errors are NOT
// reported via KeyError, but are reported via corresponding PPB calls.

void PpapiCdmAdapter::Decrypt(
    pp::Buffer_Dev encrypted_buffer,
    const PP_EncryptedBlockInfo& encrypted_block_info) {
  PP_DCHECK(!encrypted_buffer.is_null());

  // Release a buffer that the caller indicated it is finished with.
  allocator_.Release(encrypted_block_info.tracking_info.buffer_id);

  cdm::Status status = cdm::kDecryptError;
  LinkedDecryptedBlock decrypted_block(new DecryptedBlockImpl());

  if (cdm_) {
    cdm::InputBuffer input_buffer;
    std::vector<cdm::SubsampleEntry> subsamples;
    ConfigureInputBuffer(encrypted_buffer, encrypted_block_info, &subsamples,
                         &input_buffer);
    status = cdm_->Decrypt(input_buffer, decrypted_block.get());
    PP_DCHECK(status != cdm::kSuccess ||
              (decrypted_block->DecryptedBuffer() &&
               decrypted_block->DecryptedBuffer()->Size()));
  }

  CallOnMain(callback_factory_.NewCallback(&PpapiCdmAdapter::DeliverBlock,
                                           status, decrypted_block,
                                           encrypted_block_info.tracking_info));
}

void PpapiCdmAdapter::InitializeAudioDecoder(
    const PP_AudioDecoderConfig& decoder_config,
    pp::Buffer_Dev extra_data_buffer) {
  PP_DCHECK(!deferred_initialize_audio_decoder_);
  PP_DCHECK(deferred_audio_decoder_config_id_ == 0);
  cdm::Status status = cdm::kSessionError;
  if (cdm_) {
    cdm::AudioDecoderConfig cdm_decoder_config;
    cdm_decoder_config.codec =
        PpAudioCodecToCdmAudioCodec(decoder_config.codec);
    cdm_decoder_config.channel_count = decoder_config.channel_count;
    cdm_decoder_config.bits_per_channel = decoder_config.bits_per_channel;
    cdm_decoder_config.samples_per_second = decoder_config.samples_per_second;
    cdm_decoder_config.extra_data =
        static_cast<uint8_t*>(extra_data_buffer.data());
    cdm_decoder_config.extra_data_size = extra_data_buffer.size();
    status = cdm_->InitializeAudioDecoder(cdm_decoder_config);
  }

  if (status == cdm::kDeferredInitialization) {
    deferred_initialize_audio_decoder_ = true;
    deferred_audio_decoder_config_id_ = decoder_config.request_id;
    return;
  }

  CallOnMain(callback_factory_.NewCallback(
      &PpapiCdmAdapter::DecoderInitializeDone, PP_DECRYPTORSTREAMTYPE_AUDIO,
      decoder_config.request_id, status == cdm::kSuccess));
}

void PpapiCdmAdapter::InitializeVideoDecoder(
    const PP_VideoDecoderConfig& decoder_config,
    pp::Buffer_Dev extra_data_buffer) {
  PP_DCHECK(!deferred_initialize_video_decoder_);
  PP_DCHECK(deferred_video_decoder_config_id_ == 0);
  cdm::Status status = cdm::kSessionError;
  if (cdm_) {
    cdm::VideoDecoderConfig cdm_decoder_config;
    cdm_decoder_config.codec =
        PpVideoCodecToCdmVideoCodec(decoder_config.codec);
    cdm_decoder_config.profile =
        PpVCProfileToCdmVCProfile(decoder_config.profile);
    cdm_decoder_config.format =
        PpDecryptedFrameFormatToCdmVideoFormat(decoder_config.format);
    cdm_decoder_config.coded_size.width = decoder_config.width;
    cdm_decoder_config.coded_size.height = decoder_config.height;
    cdm_decoder_config.extra_data =
        static_cast<uint8_t*>(extra_data_buffer.data());
    cdm_decoder_config.extra_data_size = extra_data_buffer.size();
    status = cdm_->InitializeVideoDecoder(cdm_decoder_config);
  }

  if (status == cdm::kDeferredInitialization) {
    deferred_initialize_video_decoder_ = true;
    deferred_video_decoder_config_id_ = decoder_config.request_id;
    return;
  }

  CallOnMain(callback_factory_.NewCallback(
      &PpapiCdmAdapter::DecoderInitializeDone, PP_DECRYPTORSTREAMTYPE_VIDEO,
      decoder_config.request_id, status == cdm::kSuccess));
}

void PpapiCdmAdapter::DeinitializeDecoder(PP_DecryptorStreamType decoder_type,
                                          uint32_t request_id) {
  PP_DCHECK(cdm_);  // InitializeXxxxxDecoder should have succeeded.
  if (cdm_) {
    cdm_->DeinitializeDecoder(
        PpDecryptorStreamTypeToCdmStreamType(decoder_type));
  }

  CallOnMain(callback_factory_.NewCallback(
      &PpapiCdmAdapter::DecoderDeinitializeDone, decoder_type, request_id));
}

void PpapiCdmAdapter::ResetDecoder(PP_DecryptorStreamType decoder_type,
                                   uint32_t request_id) {
  PP_DCHECK(cdm_);  // InitializeXxxxxDecoder should have succeeded.
  if (cdm_)
    cdm_->ResetDecoder(PpDecryptorStreamTypeToCdmStreamType(decoder_type));

  CallOnMain(callback_factory_.NewCallback(&PpapiCdmAdapter::DecoderResetDone,
                                           decoder_type, request_id));
}

void PpapiCdmAdapter::DecryptAndDecode(
    PP_DecryptorStreamType decoder_type,
    pp::Buffer_Dev encrypted_buffer,
    const PP_EncryptedBlockInfo& encrypted_block_info) {
  PP_DCHECK(cdm_);  // InitializeXxxxxDecoder should have succeeded.
  // Release a buffer that the caller indicated it is finished with.
  allocator_.Release(encrypted_block_info.tracking_info.buffer_id);

  cdm::InputBuffer input_buffer;
  std::vector<cdm::SubsampleEntry> subsamples;
  if (cdm_ && !encrypted_buffer.is_null()) {
    ConfigureInputBuffer(encrypted_buffer, encrypted_block_info, &subsamples,
                         &input_buffer);
  }

  cdm::Status status = cdm::kDecodeError;

  switch (decoder_type) {
    case PP_DECRYPTORSTREAMTYPE_VIDEO: {
      LinkedVideoFrame video_frame(new VideoFrameImpl());
      if (cdm_)
        status = cdm_->DecryptAndDecodeFrame(input_buffer, video_frame.get());
      CallOnMain(callback_factory_.NewCallback(
          &PpapiCdmAdapter::DeliverFrame, status, video_frame,
          encrypted_block_info.tracking_info));
      return;
    }

    case PP_DECRYPTORSTREAMTYPE_AUDIO: {
      LinkedAudioFrames audio_frames(new AudioFramesImpl());
      if (cdm_) {
        status =
            cdm_->DecryptAndDecodeSamples(input_buffer, audio_frames.get());
      }
      CallOnMain(callback_factory_.NewCallback(
          &PpapiCdmAdapter::DeliverSamples, status, audio_frames,
          encrypted_block_info.tracking_info));
      return;
    }

    default:
      PP_NOTREACHED();
      return;
  }
}

cdm::Buffer* PpapiCdmAdapter::Allocate(uint32_t capacity) {
  return allocator_.Allocate(capacity);
}

void PpapiCdmAdapter::SetTimer(int64_t delay_ms, void* context) {
  // NOTE: doesn't really need to run on the main thread; could just as well run
  // on a helper thread if |cdm_| were thread-friendly and care was taken.  We
  // only use CallOnMainThread() here to get delayed-execution behavior.
  pp::Module::Get()->core()->CallOnMainThread(
      delay_ms,
      callback_factory_.NewCallback(&PpapiCdmAdapter::TimerExpired, context),
      PP_OK);
}

void PpapiCdmAdapter::TimerExpired(int32_t result, void* context) {
  PP_DCHECK(result == PP_OK);
  cdm_->TimerExpired(context);
}

cdm::Time PpapiCdmAdapter::GetCurrentWallTime() {
  return pp::Module::Get()->core()->GetTime();
}

void PpapiCdmAdapter::OnResolveNewSessionPromise(uint32_t promise_id,
                                                 const char* session_id,
                                                 uint32_t session_id_size) {
  PostOnMain(callback_factory_.NewCallback(
      &PpapiCdmAdapter::SendPromiseResolvedWithSessionInternal, promise_id,
      std::string(session_id, session_id_size)));
}

void PpapiCdmAdapter::OnResolvePromise(uint32_t promise_id) {
  PostOnMain(callback_factory_.NewCallback(
      &PpapiCdmAdapter::SendPromiseResolvedInternal, promise_id));
}

void PpapiCdmAdapter::OnRejectPromise(uint32_t promise_id,
                                      cdm::Error error,
                                      uint32_t system_code,
                                      const char* error_message,
                                      uint32_t error_message_size) {
  // UMA to investigate http://crbug.com/410630
  // TODO(xhwang): Remove after bug is fixed.
  if (system_code == 0x27) {
    pp::UMAPrivate uma_interface(this);
    uma_interface.HistogramCustomCounts("Media.EME.CdmFileIO.FileSizeKBOnError",
                                        last_read_file_size_kb_, kSizeKBMin,
                                        kSizeKBMax, kSizeKBBuckets);
  }

  RejectPromise(promise_id, error, system_code,
                std::string(error_message, error_message_size));
}

void PpapiCdmAdapter::RejectPromise(uint32_t promise_id,
                                    cdm::Error error,
                                    uint32_t system_code,
                                    const std::string& error_message) {
  PostOnMain(callback_factory_.NewCallback(
      &PpapiCdmAdapter::SendPromiseRejectedInternal, promise_id,
      SessionError(error, system_code, error_message)));
}

void PpapiCdmAdapter::OnSessionMessage(const char* session_id,
                                       uint32_t session_id_size,
                                       cdm::MessageType message_type,
                                       const char* message,
                                       uint32_t message_size,
                                       const char* legacy_destination_url,
                                       uint32_t legacy_destination_url_size) {
  // |legacy_destination_url| is obsolete and will be removed as part of
  // https://crbug.com/570216.
  // License requests should not specify |legacy_destination_url|.
  PP_DCHECK(legacy_destination_url_size == 0 ||
            message_type != cdm::MessageType::kLicenseRequest);

  PostOnMain(callback_factory_.NewCallback(
      &PpapiCdmAdapter::SendSessionMessageInternal,
      SessionMessage(std::string(session_id, session_id_size), message_type,
                     message, message_size)));
}

void PpapiCdmAdapter::OnSessionKeysChange(const char* session_id,
                                          uint32_t session_id_size,
                                          bool has_additional_usable_key,
                                          const cdm::KeyInformation* keys_info,
                                          uint32_t keys_info_count) {
  std::vector<PP_KeyInformation> key_information;
  for (uint32_t i = 0; i < keys_info_count; ++i) {
    const auto& key_info = keys_info[i];
    PP_KeyInformation next_key = {};

    if (key_info.key_id_size > sizeof(next_key.key_id)) {
      PP_NOTREACHED();
      continue;
    }

    // Copy key_id into |next_key|.
    memcpy(next_key.key_id, key_info.key_id, key_info.key_id_size);

    // Set remaining fields on |next_key|.
    next_key.key_id_size = key_info.key_id_size;
    next_key.key_status = CdmKeyStatusToPpKeyStatus(key_info.status);
    next_key.system_code = key_info.system_code;
    key_information.push_back(next_key);
  }

  PostOnMain(callback_factory_.NewCallback(
      &PpapiCdmAdapter::SendSessionKeysChangeInternal,
      std::string(session_id, session_id_size), has_additional_usable_key,
      key_information));
}

void PpapiCdmAdapter::OnExpirationChange(const char* session_id,
                                         uint32_t session_id_size,
                                         cdm::Time new_expiry_time) {
  PostOnMain(callback_factory_.NewCallback(
      &PpapiCdmAdapter::SendExpirationChangeInternal,
      std::string(session_id, session_id_size), new_expiry_time));
}

void PpapiCdmAdapter::OnSessionClosed(const char* session_id,
                                      uint32_t session_id_size) {
  PostOnMain(
      callback_factory_.NewCallback(&PpapiCdmAdapter::SendSessionClosedInternal,
                                    std::string(session_id, session_id_size)));
}

void PpapiCdmAdapter::OnLegacySessionError(const char* session_id,
                                           uint32_t session_id_size,
                                           cdm::Error error,
                                           uint32_t system_code,
                                           const char* error_message,
                                           uint32_t error_message_size) {
  // Obsolete and will be removed as part of https://crbug.com/570216.
}

// Helpers to pass the event to Pepper.

void PpapiCdmAdapter::SendPromiseResolvedInternal(int32_t result,
                                                  uint32_t promise_id) {
  PP_DCHECK(result == PP_OK);
  pp::ContentDecryptor_Private::PromiseResolved(promise_id);
}

void PpapiCdmAdapter::SendPromiseResolvedWithSessionInternal(
    int32_t result,
    uint32_t promise_id,
    const std::string& session_id) {
  PP_DCHECK(result == PP_OK);
  pp::ContentDecryptor_Private::PromiseResolvedWithSession(promise_id,
                                                           session_id);
}

void PpapiCdmAdapter::SendPromiseRejectedInternal(int32_t result,
                                                  uint32_t promise_id,
                                                  const SessionError& error) {
  PP_DCHECK(result == PP_OK);
  pp::ContentDecryptor_Private::PromiseRejected(
      promise_id, CdmExceptionTypeToPpCdmExceptionType(error.error),
      error.system_code, error.error_description);
}

void PpapiCdmAdapter::SendSessionMessageInternal(
    int32_t result,
    const SessionMessage& message) {
  PP_DCHECK(result == PP_OK);

  pp::VarArrayBuffer message_array_buffer(message.message.size());
  if (message.message.size() > 0) {
    memcpy(message_array_buffer.Map(), message.message.data(),
           message.message.size());
  }

  pp::ContentDecryptor_Private::SessionMessage(
      message.session_id, CdmMessageTypeToPpMessageType(message.message_type),
      message_array_buffer, std::string());
}

void PpapiCdmAdapter::SendSessionClosedInternal(int32_t result,
                                                const std::string& session_id) {
  PP_DCHECK(result == PP_OK);
  pp::ContentDecryptor_Private::SessionClosed(session_id);
}

void PpapiCdmAdapter::SendSessionKeysChangeInternal(
    int32_t result,
    const std::string& session_id,
    bool has_additional_usable_key,
    const std::vector<PP_KeyInformation>& key_info) {
  PP_DCHECK(result == PP_OK);
  pp::ContentDecryptor_Private::SessionKeysChange(
      session_id, has_additional_usable_key, key_info);
}

void PpapiCdmAdapter::SendExpirationChangeInternal(
    int32_t result,
    const std::string& session_id,
    cdm::Time new_expiry_time) {
  PP_DCHECK(result == PP_OK);
  pp::ContentDecryptor_Private::SessionExpirationChange(session_id,
                                                        new_expiry_time);
}

void PpapiCdmAdapter::DeliverBlock(
    int32_t result,
    const cdm::Status& status,
    const LinkedDecryptedBlock& decrypted_block,
    const PP_DecryptTrackingInfo& tracking_info) {
  PP_DCHECK(result == PP_OK);
  PP_DecryptedBlockInfo decrypted_block_info = {};
  decrypted_block_info.tracking_info = tracking_info;
  decrypted_block_info.tracking_info.timestamp = decrypted_block->Timestamp();
  decrypted_block_info.tracking_info.buffer_id = 0;
  decrypted_block_info.data_size = 0;
  decrypted_block_info.result = CdmStatusToPpDecryptResult(status);

  pp::Buffer_Dev buffer;

  if (decrypted_block_info.result == PP_DECRYPTRESULT_SUCCESS) {
    PP_DCHECK(decrypted_block.get() && decrypted_block->DecryptedBuffer());
    if (!decrypted_block.get() || !decrypted_block->DecryptedBuffer()) {
      PP_NOTREACHED();
      decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR;
    } else {
      PpbBuffer* ppb_buffer =
          static_cast<PpbBuffer*>(decrypted_block->DecryptedBuffer());
      decrypted_block_info.tracking_info.buffer_id = ppb_buffer->buffer_id();
      decrypted_block_info.data_size = ppb_buffer->Size();

      buffer = ppb_buffer->TakeBuffer();
    }
  }

  pp::ContentDecryptor_Private::DeliverBlock(buffer, decrypted_block_info);
}

void PpapiCdmAdapter::DecoderInitializeDone(int32_t result,
                                            PP_DecryptorStreamType decoder_type,
                                            uint32_t request_id,
                                            bool success) {
  PP_DCHECK(result == PP_OK);
  pp::ContentDecryptor_Private::DecoderInitializeDone(decoder_type, request_id,
                                                      success);
}

void PpapiCdmAdapter::DecoderDeinitializeDone(
    int32_t result,
    PP_DecryptorStreamType decoder_type,
    uint32_t request_id) {
  pp::ContentDecryptor_Private::DecoderDeinitializeDone(decoder_type,
                                                        request_id);
}

void PpapiCdmAdapter::DecoderResetDone(int32_t result,
                                       PP_DecryptorStreamType decoder_type,
                                       uint32_t request_id) {
  pp::ContentDecryptor_Private::DecoderResetDone(decoder_type, request_id);
}

void PpapiCdmAdapter::DeliverFrame(
    int32_t result,
    const cdm::Status& status,
    const LinkedVideoFrame& video_frame,
    const PP_DecryptTrackingInfo& tracking_info) {
  PP_DCHECK(result == PP_OK);
  PP_DecryptedFrameInfo decrypted_frame_info = {};
  decrypted_frame_info.tracking_info.request_id = tracking_info.request_id;
  decrypted_frame_info.tracking_info.buffer_id = 0;
  decrypted_frame_info.result = CdmStatusToPpDecryptResult(status);

  pp::Buffer_Dev buffer;

  if (decrypted_frame_info.result == PP_DECRYPTRESULT_SUCCESS) {
    if (!IsValidVideoFrame(video_frame)) {
      PP_NOTREACHED();
      decrypted_frame_info.result = PP_DECRYPTRESULT_DECODE_ERROR;
    } else {
      PpbBuffer* ppb_buffer =
          static_cast<PpbBuffer*>(video_frame->FrameBuffer());

      decrypted_frame_info.tracking_info.timestamp = video_frame->Timestamp();
      decrypted_frame_info.tracking_info.buffer_id = ppb_buffer->buffer_id();
      decrypted_frame_info.format =
          CdmVideoFormatToPpDecryptedFrameFormat(video_frame->Format());
      decrypted_frame_info.width = video_frame->Size().width;
      decrypted_frame_info.height = video_frame->Size().height;
      decrypted_frame_info.plane_offsets[PP_DECRYPTEDFRAMEPLANES_Y] =
          video_frame->PlaneOffset(cdm::VideoFrame::kYPlane);
      decrypted_frame_info.plane_offsets[PP_DECRYPTEDFRAMEPLANES_U] =
          video_frame->PlaneOffset(cdm::VideoFrame::kUPlane);
      decrypted_frame_info.plane_offsets[PP_DECRYPTEDFRAMEPLANES_V] =
          video_frame->PlaneOffset(cdm::VideoFrame::kVPlane);
      decrypted_frame_info.strides[PP_DECRYPTEDFRAMEPLANES_Y] =
          video_frame->Stride(cdm::VideoFrame::kYPlane);
      decrypted_frame_info.strides[PP_DECRYPTEDFRAMEPLANES_U] =
          video_frame->Stride(cdm::VideoFrame::kUPlane);
      decrypted_frame_info.strides[PP_DECRYPTEDFRAMEPLANES_V] =
          video_frame->Stride(cdm::VideoFrame::kVPlane);

      buffer = ppb_buffer->TakeBuffer();
    }
  }

  pp::ContentDecryptor_Private::DeliverFrame(buffer, decrypted_frame_info);
}

void PpapiCdmAdapter::DeliverSamples(
    int32_t result,
    const cdm::Status& status,
    const LinkedAudioFrames& audio_frames,
    const PP_DecryptTrackingInfo& tracking_info) {
  PP_DCHECK(result == PP_OK);

  PP_DecryptedSampleInfo decrypted_sample_info = {};
  decrypted_sample_info.tracking_info = tracking_info;
  decrypted_sample_info.tracking_info.timestamp = 0;
  decrypted_sample_info.tracking_info.buffer_id = 0;
  decrypted_sample_info.data_size = 0;
  decrypted_sample_info.result = CdmStatusToPpDecryptResult(status);

  pp::Buffer_Dev buffer;

  if (decrypted_sample_info.result == PP_DECRYPTRESULT_SUCCESS) {
    PP_DCHECK(audio_frames.get() && audio_frames->FrameBuffer());
    if (!audio_frames.get() || !audio_frames->FrameBuffer()) {
      PP_NOTREACHED();
      decrypted_sample_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR;
    } else {
      PpbBuffer* ppb_buffer =
          static_cast<PpbBuffer*>(audio_frames->FrameBuffer());

      decrypted_sample_info.tracking_info.buffer_id = ppb_buffer->buffer_id();
      decrypted_sample_info.data_size = ppb_buffer->Size();
      decrypted_sample_info.format =
          CdmAudioFormatToPpDecryptedSampleFormat(audio_frames->Format());

      buffer = ppb_buffer->TakeBuffer();
    }
  }

  pp::ContentDecryptor_Private::DeliverSamples(buffer, decrypted_sample_info);
}

bool PpapiCdmAdapter::IsValidVideoFrame(const LinkedVideoFrame& video_frame) {
  if (!video_frame.get() || !video_frame->FrameBuffer() ||
      (video_frame->Format() != cdm::kI420 &&
       video_frame->Format() != cdm::kYv12)) {
    CDM_DLOG() << "Invalid video frame!";
    return false;
  }

  PpbBuffer* ppb_buffer = static_cast<PpbBuffer*>(video_frame->FrameBuffer());

  for (uint32_t i = 0; i < cdm::VideoFrame::kMaxPlanes; ++i) {
    int plane_height = (i == cdm::VideoFrame::kYPlane)
                           ? video_frame->Size().height
                           : (video_frame->Size().height + 1) / 2;
    cdm::VideoFrame::VideoPlane plane =
        static_cast<cdm::VideoFrame::VideoPlane>(i);
    if (ppb_buffer->Size() < video_frame->PlaneOffset(plane) +
                                 plane_height * video_frame->Stride(plane)) {
      return false;
    }
  }

  return true;
}

void PpapiCdmAdapter::OnFirstFileRead(int32_t file_size_bytes) {
  PP_DCHECK(IsMainThread());
  PP_DCHECK(file_size_bytes >= 0);

  last_read_file_size_kb_ = file_size_bytes / 1024;

  if (file_size_uma_reported_)
    return;

  pp::UMAPrivate uma_interface(this);
  uma_interface.HistogramCustomCounts(
      "Media.EME.CdmFileIO.FileSizeKBOnFirstRead", last_read_file_size_kb_,
      kSizeKBMin, kSizeKBMax, kSizeKBBuckets);
  file_size_uma_reported_ = true;
}

#if !defined(NDEBUG)
void PpapiCdmAdapter::LogToConsole(const pp::Var& value) {
  PP_DCHECK(IsMainThread());
  const PPB_Console* console = reinterpret_cast<const PPB_Console*>(
      pp::Module::Get()->GetBrowserInterface(PPB_CONSOLE_INTERFACE));
  console->Log(pp_instance(), PP_LOGLEVEL_LOG, value.pp_var());
}
#endif  // !defined(NDEBUG)

void PpapiCdmAdapter::SendPlatformChallenge(const char* service_id,
                                            uint32_t service_id_size,
                                            const char* challenge,
                                            uint32_t challenge_size) {
#if defined(OS_CHROMEOS)
  // If access to a distinctive identifier is not allowed, block platform
  // verification to prevent access to such an identifier.
  if (allow_distinctive_identifier_) {
    pp::VarArrayBuffer challenge_var(challenge_size);
    uint8_t* var_data = static_cast<uint8_t*>(challenge_var.Map());
    memcpy(var_data, challenge, challenge_size);

    std::string service_id_str(service_id, service_id_size);

    linked_ptr<PepperPlatformChallengeResponse> response(
        new PepperPlatformChallengeResponse());

    int32_t result = platform_verification_.ChallengePlatform(
        pp::Var(service_id_str), challenge_var, &response->signed_data,
        &response->signed_data_signature, &response->platform_key_certificate,
        callback_factory_.NewCallback(
            &PpapiCdmAdapter::SendPlatformChallengeDone, response));
    challenge_var.Unmap();
    if (result == PP_OK_COMPLETIONPENDING)
      return;

    // Fall through on error and issue an empty OnPlatformChallengeResponse().
    PP_DCHECK(result != PP_OK);
  }
#endif

  cdm::PlatformChallengeResponse platform_challenge_response = {};
  cdm_->OnPlatformChallengeResponse(platform_challenge_response);
}

void PpapiCdmAdapter::EnableOutputProtection(uint32_t desired_protection_mask) {
  int32_t result = output_protection_.EnableProtection(
      desired_protection_mask,
      callback_factory_.NewCallback(&PpapiCdmAdapter::EnableProtectionDone));

  // Errors are ignored since clients must call QueryOutputProtectionStatus() to
  // inspect the protection status on a regular basis.

  if (result != PP_OK && result != PP_OK_COMPLETIONPENDING)
    CDM_DLOG() << __func__ << " failed!";
}

void PpapiCdmAdapter::QueryOutputProtectionStatus() {
  PP_DCHECK(!query_output_protection_in_progress_);

  output_link_mask_ = output_protection_mask_ = 0;
  const int32_t result = output_protection_.QueryStatus(
      &output_link_mask_, &output_protection_mask_,
      callback_factory_.NewCallback(
          &PpapiCdmAdapter::QueryOutputProtectionStatusDone));
  if (result == PP_OK_COMPLETIONPENDING) {
    query_output_protection_in_progress_ = true;
    ReportOutputProtectionQuery();
    return;
  }

  // Fall through on error and issue an empty OnQueryOutputProtectionStatus().
  PP_DCHECK(result != PP_OK);
  CDM_DLOG() << __func__ << " failed, result = " << result;
}

void PpapiCdmAdapter::OnDeferredInitializationDone(cdm::StreamType stream_type,
                                                   cdm::Status decoder_status) {
  switch (stream_type) {
    case cdm::kStreamTypeAudio:
      PP_DCHECK(deferred_initialize_audio_decoder_);
      CallOnMain(callback_factory_.NewCallback(
          &PpapiCdmAdapter::DecoderInitializeDone, PP_DECRYPTORSTREAMTYPE_AUDIO,
          deferred_audio_decoder_config_id_, decoder_status == cdm::kSuccess));
      deferred_initialize_audio_decoder_ = false;
      deferred_audio_decoder_config_id_ = 0;
      break;
    case cdm::kStreamTypeVideo:
      PP_DCHECK(deferred_initialize_video_decoder_);
      CallOnMain(callback_factory_.NewCallback(
          &PpapiCdmAdapter::DecoderInitializeDone, PP_DECRYPTORSTREAMTYPE_VIDEO,
          deferred_video_decoder_config_id_, decoder_status == cdm::kSuccess));
      deferred_initialize_video_decoder_ = false;
      deferred_video_decoder_config_id_ = 0;
      break;
  }
}

// The CDM owns the returned object and must call FileIO::Close() to release it.
cdm::FileIO* PpapiCdmAdapter::CreateFileIO(cdm::FileIOClient* client) {
  if (!allow_persistent_state_) {
    CDM_DLOG()
        << "Cannot create FileIO because persistent state is not allowed.";
    return nullptr;
  }

  return new CdmFileIOImpl(
      client, pp_instance(),
      callback_factory_.NewCallback(&PpapiCdmAdapter::OnFirstFileRead));
}

void PpapiCdmAdapter::ReportOutputProtectionUMA(OutputProtectionStatus status) {
  pp::UMAPrivate uma_interface(this);
  uma_interface.HistogramEnumeration("Media.EME.OutputProtection", status,
                                     OUTPUT_PROTECTION_MAX);
}

void PpapiCdmAdapter::ReportOutputProtectionQuery() {
  if (uma_for_output_protection_query_reported_)
    return;

  ReportOutputProtectionUMA(OUTPUT_PROTECTION_QUERIED);
  uma_for_output_protection_query_reported_ = true;
}

void PpapiCdmAdapter::ReportOutputProtectionQueryResult() {
  if (uma_for_output_protection_positive_result_reported_)
    return;

  // Report UMAs for output protection query result.
  uint32_t external_links = (output_link_mask_ & ~cdm::kLinkTypeInternal);

  if (!external_links) {
    ReportOutputProtectionUMA(OUTPUT_PROTECTION_NO_EXTERNAL_LINK);
    uma_for_output_protection_positive_result_reported_ = true;
    return;
  }

  const uint32_t kProtectableLinks =
      cdm::kLinkTypeHDMI | cdm::kLinkTypeDVI | cdm::kLinkTypeDisplayPort;
  bool is_unprotectable_link_connected =
      (external_links & ~kProtectableLinks) != 0;
  bool is_hdcp_enabled_on_all_protectable_links =
      (output_protection_mask_ & cdm::kProtectionHDCP) != 0;

  if (!is_unprotectable_link_connected &&
      is_hdcp_enabled_on_all_protectable_links) {
    ReportOutputProtectionUMA(OUTPUT_PROTECTION_ALL_EXTERNAL_LINKS_PROTECTED);
    uma_for_output_protection_positive_result_reported_ = true;
    return;
  }

  // Do not report a negative result because it could be a false negative.
  // Instead, we will calculate number of negatives using the total number of
  // queries and success results.
}

#if defined(OS_CHROMEOS)
void PpapiCdmAdapter::SendPlatformChallengeDone(
    int32_t result,
    const linked_ptr<PepperPlatformChallengeResponse>& response) {
  if (result != PP_OK) {
    CDM_DLOG() << __func__ << ": Platform challenge failed!";
    cdm::PlatformChallengeResponse platform_challenge_response = {};
    cdm_->OnPlatformChallengeResponse(platform_challenge_response);
    return;
  }

  pp::VarArrayBuffer signed_data_var(response->signed_data);
  pp::VarArrayBuffer signed_data_signature_var(response->signed_data_signature);
  std::string platform_key_certificate_string =
      response->platform_key_certificate.AsString();

  cdm::PlatformChallengeResponse platform_challenge_response = {
      static_cast<uint8_t*>(signed_data_var.Map()),
      signed_data_var.ByteLength(),
      static_cast<uint8_t*>(signed_data_signature_var.Map()),
      signed_data_signature_var.ByteLength(),
      reinterpret_cast<const uint8_t*>(platform_key_certificate_string.data()),
      static_cast<uint32_t>(platform_key_certificate_string.length())};
  cdm_->OnPlatformChallengeResponse(platform_challenge_response);

  signed_data_var.Unmap();
  signed_data_signature_var.Unmap();
}
#endif

void PpapiCdmAdapter::EnableProtectionDone(int32_t result) {
  // Does nothing since clients must call QueryOutputProtectionStatus() to
  // inspect the protection status on a regular basis.
  CDM_DLOG() << __func__ << " : " << result;
}

void PpapiCdmAdapter::QueryOutputProtectionStatusDone(int32_t result) {
  PP_DCHECK(query_output_protection_in_progress_);
  query_output_protection_in_progress_ = false;

  // Return a query status of failed on error.
  cdm::QueryResult query_result;
  if (result != PP_OK) {
    CDM_DLOG() << __func__ << " failed, result = " << result;
    output_link_mask_ = output_protection_mask_ = 0;
    query_result = cdm::kQueryFailed;
  } else {
    query_result = cdm::kQuerySucceeded;
    ReportOutputProtectionQueryResult();
  }

  cdm_->OnQueryOutputProtectionStatus(query_result, output_link_mask_,
                                      output_protection_mask_);
}

PpapiCdmAdapter::SessionError::SessionError(
    cdm::Error error,
    uint32_t system_code,
    const std::string& error_description)
    : error(error),
      system_code(system_code),
      error_description(error_description) {}

PpapiCdmAdapter::SessionMessage::SessionMessage(const std::string& session_id,
                                                cdm::MessageType message_type,
                                                const char* message,
                                                uint32_t message_size)
    : session_id(session_id),
      message_type(message_type),
      message(message, message + message_size) {}

void* GetCdmHost(int host_interface_version, void* user_data) {
  if (!host_interface_version || !user_data)
    return NULL;

  static_assert(
      cdm::ContentDecryptionModule::Host::kVersion == cdm::Host_8::kVersion,
      "update the code below");

  // Ensure IsSupportedCdmHostVersion matches implementation of this function.
  // Always update this DCHECK when updating this function.
  // If this check fails, update this function and DCHECK or update
  // IsSupportedCdmHostVersion.

  PP_DCHECK(
      // Future version is not supported.
      !IsSupportedCdmHostVersion(cdm::Host_8::kVersion + 1) &&
      // Current version is supported.
      IsSupportedCdmHostVersion(cdm::Host_8::kVersion) &&
      // Include all previous supported versions (if any) here.
      // One older than the oldest supported version is not supported.
      !IsSupportedCdmHostVersion(cdm::Host_8::kVersion - 1));
  PP_DCHECK(IsSupportedCdmHostVersion(host_interface_version));

  PpapiCdmAdapter* cdm_adapter = static_cast<PpapiCdmAdapter*>(user_data);
  CDM_DLOG() << "Create CDM Host with version " << host_interface_version;
  switch (host_interface_version) {
    case cdm::Host_8::kVersion:
      return static_cast<cdm::Host_8*>(cdm_adapter);
    default:
      PP_NOTREACHED();
      return NULL;
  }
}

// This object is the global object representing this plugin library as long
// as it is loaded.
class PpapiCdmAdapterModule : public pp::Module {
 public:
  PpapiCdmAdapterModule() : pp::Module() {
    // This function blocks the renderer thread (PluginInstance::Initialize()).
    // Move this call to other places if this may be a concern in the future.
    INITIALIZE_CDM_MODULE();
  }
  virtual ~PpapiCdmAdapterModule() { DeinitializeCdmModule(); }

  virtual pp::Instance* CreateInstance(PP_Instance instance) {
    return new PpapiCdmAdapter(instance, this);
  }

 private:
  CdmFileIOImpl::ResourceTracker cdm_file_io_impl_resource_tracker;
};

}  // namespace media

namespace pp {

// Factory function for your specialization of the Module object.
Module* CreateModule() {
  return new media::PpapiCdmAdapterModule();
}

}  // namespace pp
