// 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/cdm_adapter.h"

#include "media/cdm/ppapi/cdm_file_io_impl.h"
#include "media/cdm/ppapi/cdm_helpers.h"
#include "media/cdm/ppapi/cdm_logging.h"
#include "media/cdm/ppapi/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;
    default:
      PP_NOTREACHED();
      return PP_DECRYPTRESULT_DECODE_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:
      return cdm::kPersistent;
    default:
      PP_NOTREACHED();
      return cdm::kTemporary;
  }
}

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;
    default:
      PP_NOTREACHED();
      return PP_CDMEXCEPTIONCODE_UNKNOWNERROR;
  }
}

}  // namespace

namespace media {

CdmAdapter::CdmAdapter(PP_Instance instance, pp::Module* module)
    : pp::Instance(instance),
      pp::ContentDecryptor_Private(this),
#if defined(OS_CHROMEOS)
      output_protection_(this),
      platform_verification_(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),
#endif
      allocator_(this),
      cdm_(NULL),
      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);
}

CdmAdapter::~CdmAdapter() {}

bool CdmAdapter::CreateCdmInstance(const std::string& key_system) {
  PP_DCHECK(!cdm_);
  cdm_ = make_linked_ptr(CdmWrapper::Create(
      key_system.data(), key_system.size(), GetCdmHost, this));
  bool success = cdm_ != NULL;

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

  return success;
}

// No errors should be reported in this function because the spec says:
// "Store this new error object internally with the MediaKeys instance being
// created. This will be used to fire an error against any session created for
// this instance." These errors will be reported during session creation
// (CreateSession()) or session loading (LoadSession()).
// TODO(xhwang): If necessary, we need to store the error here if we want to
// support more specific error reporting (other than "Unknown").
void CdmAdapter::Initialize(const std::string& key_system) {
  PP_DCHECK(!key_system.empty());
  PP_DCHECK(key_system_.empty() || (key_system_ == key_system && cdm_));

#if defined(CHECK_DOCUMENT_URL)
  PP_URLComponents_Dev url_components = {};
  const pp::URLUtil_Dev* url_util = pp::URLUtil_Dev::Get();
  if (!url_util)
    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)

  if (!cdm_ && !CreateCdmInstance(key_system))
    return;

  PP_DCHECK(cdm_);
  key_system_ = key_system;
}

void CdmAdapter::CreateSession(uint32_t promise_id,
                               const std::string& init_data_type,
                               pp::VarArrayBuffer init_data,
                               PP_SessionType session_type) {
  // Initialize() doesn't report an error, so CreateSession() can be called
  // even if Initialize() failed.
  // TODO(jrummell): Remove this code when prefixed EME gets removed.
  // TODO(jrummell): Verify that Initialize() failing does not resolve the
  // MediaKeys.create() promise.
  if (!cdm_) {
    RejectPromise(promise_id,
                  cdm::kInvalidStateError,
                  0,
                  "CDM has not been initialized.");
    return;
  }

  cdm_->CreateSession(promise_id,
                      init_data_type.data(),
                      init_data_type.size(),
                      static_cast<const uint8_t*>(init_data.Map()),
                      init_data.ByteLength(),
                      PpSessionTypeToCdmSessionType(session_type));
}

void CdmAdapter::LoadSession(uint32_t promise_id,
                             const std::string& web_session_id) {
  // Initialize() doesn't report an error, so LoadSession() can be called
  // even if Initialize() failed.
  // TODO(jrummell): Remove this code when prefixed EME gets removed.
  // TODO(jrummell): Verify that Initialize() failing does not resolve the
  // MediaKeys.create() promise.
  if (!cdm_) {
    RejectPromise(promise_id,
                  cdm::kInvalidStateError,
                  0,
                  "CDM has not been initialized.");
    return;
  }

  cdm_->LoadSession(promise_id, web_session_id.data(), web_session_id.size());
}

void CdmAdapter::UpdateSession(uint32_t promise_id,
                               const std::string& web_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(!web_session_id.empty());
  PP_DCHECK(response_ptr);
  PP_DCHECK(response_size > 0);

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

void CdmAdapter::CloseSession(uint32_t promise_id,
                              const std::string& web_session_id) {
  if (!cdm_->CloseSession(
          promise_id, web_session_id.data(), web_session_id.length())) {
    // CDM_4 and CDM_5 don't support this method, so reject the promise.
    RejectPromise(promise_id, cdm::kNotSupportedError, 0, "Not implemented.");
  }
}

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

void CdmAdapter::GetUsableKeyIds(uint32_t promise_id,
                                 const std::string& web_session_id) {
  if (!cdm_->GetUsableKeyIds(
          promise_id, web_session_id.data(), web_session_id.length())) {
    // CDM_4 and CDM_5 don't support this method, so reject the promise.
    RejectPromise(promise_id, cdm::kNotSupportedError, 0, "Not implemented.");
  }
}

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

void CdmAdapter::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(
      &CdmAdapter::DeliverBlock,
      status,
      decrypted_block,
      encrypted_block_info.tracking_info));
}

void CdmAdapter::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(
      &CdmAdapter::DecoderInitializeDone,
      PP_DECRYPTORSTREAMTYPE_AUDIO,
      decoder_config.request_id,
      status == cdm::kSuccess));
}

void CdmAdapter::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(
      &CdmAdapter::DecoderInitializeDone,
      PP_DECRYPTORSTREAMTYPE_VIDEO,
      decoder_config.request_id,
      status == cdm::kSuccess));
}

void CdmAdapter::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(
      &CdmAdapter::DecoderDeinitializeDone,
      decoder_type,
      request_id));
}

void CdmAdapter::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(&CdmAdapter::DecoderResetDone,
                                           decoder_type,
                                           request_id));
}

void CdmAdapter::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(
          &CdmAdapter::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(
          &CdmAdapter::DeliverSamples,
          status,
          audio_frames,
          encrypted_block_info.tracking_info));
      return;
    }

    default:
      PP_NOTREACHED();
      return;
  }
}

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

void CdmAdapter::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(&CdmAdapter::TimerExpired, context),
      PP_OK);
}

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

// cdm::Host_4 methods

double CdmAdapter::GetCurrentWallTimeInSeconds() {
  return GetCurrentTime();
}

void CdmAdapter::OnSessionCreated(uint32_t session_id,
                                  const char* web_session_id,
                                  uint32_t web_session_id_length) {
  uint32_t promise_id = cdm_->LookupPromiseId(session_id);
  cdm_->AssignWebSessionId(session_id, web_session_id, web_session_id_length);
  OnResolveNewSessionPromise(promise_id, web_session_id, web_session_id_length);
}

void CdmAdapter::OnSessionMessage(uint32_t session_id,
                                  const char* message,
                                  uint32_t message_length,
                                  const char* destination_url,
                                  uint32_t destination_url_length) {
  std::string web_session_id = cdm_->LookupWebSessionId(session_id);
  OnSessionMessage(web_session_id.data(),
                   web_session_id.length(),
                   message,
                   message_length,
                   destination_url,
                   destination_url_length);
}

void CdmAdapter::OnSessionReady(uint32_t session_id) {
  uint32_t promise_id = cdm_->LookupPromiseId(session_id);
  if (promise_id) {
    OnResolvePromise(promise_id);
  } else {
    std::string web_session_id = cdm_->LookupWebSessionId(session_id);
    OnSessionReady(web_session_id.data(), web_session_id.length());
  }
}

void CdmAdapter::OnSessionClosed(uint32_t session_id) {
  uint32_t promise_id = cdm_->LookupPromiseId(session_id);
  std::string web_session_id = cdm_->LookupWebSessionId(session_id);
  cdm_->DropWebSessionId(web_session_id);
  if (promise_id) {
    OnResolvePromise(promise_id);
  } else {
    OnSessionClosed(web_session_id.data(), web_session_id.length());
  }
}

void CdmAdapter::OnSessionError(uint32_t session_id,
                                cdm::MediaKeyError error_code,
                                uint32_t system_code) {
  uint32_t promise_id = cdm_->LookupPromiseId(session_id);

  // Existing cdm::MediaKeyError don't map to DOM error names. Convert them
  // into non-standard names so that the prefixed API can extract them.
  // TODO(jrummell): Remove this conversion and the inverse when CDM4 is gone.
  cdm::Error error;
  switch (error_code) {
    case cdm::kPrefixedClientError:
      error = cdm::kClientError;
      break;
    case cdm::kPrefixedOutputError:
      error = cdm::kOutputError;
      break;
    case cdm::kPrefixedUnknownError:
    default:
      error = cdm::kUnknownError;
      break;
  }

  if (promise_id) {
    RejectPromise(promise_id, error, system_code, std::string());
  } else {
    std::string web_session_id = cdm_->LookupWebSessionId(session_id);
    OnSessionError(web_session_id.data(),
                   web_session_id.length(),
                   error,
                   system_code,
                   NULL,
                   0);
  }
}

// cdm::Host_5 and cdm::Host_6 methods

cdm::Time CdmAdapter::GetCurrentTime() {
  return GetCurrentWallTime();
}

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

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

  // CDM_5 doesn't support OnSessionKeysChange(), so simulate one if requested.
  // Passing "true" which may result in false positives for retrying.
  std::string session_id;
  if (cdm_->SessionUsableKeysEventNeeded(promise_id, &session_id))
    OnSessionKeysChange(session_id.data(), session_id.length(), true);
}

void CdmAdapter::OnResolveNewSessionPromise(uint32_t promise_id,
                                            const char* web_session_id,
                                            uint32_t web_session_id_length) {
  PostOnMain(callback_factory_.NewCallback(
      &CdmAdapter::SendPromiseResolvedWithSessionInternal,
      promise_id,
      std::string(web_session_id, web_session_id_length)));

  // CDM_5 doesn't support OnSessionKeysChange(), so simulate one if requested.
  // Passing "true" which may result in false positives for retrying.
  std::string session_id;
  if (cdm_->SessionUsableKeysEventNeeded(promise_id, &session_id))
    OnSessionKeysChange(web_session_id, web_session_id_length, true);
}

void CdmAdapter::OnResolveKeyIdsPromise(uint32_t promise_id,
                                        const cdm::BinaryData* usable_key_ids,
                                        uint32_t usable_key_ids_length) {
  std::vector<std::vector<uint8> > key_ids;
  for (uint32_t i = 0; i < usable_key_ids_length; ++i) {
    key_ids.push_back(
        std::vector<uint8>(usable_key_ids[i].data,
                           usable_key_ids[i].data + usable_key_ids[i].length));
  }
  PostOnMain(callback_factory_.NewCallback(
      &CdmAdapter::SendPromiseResolvedWithUsableKeyIdsInternal,
      promise_id,
      key_ids));
}

void CdmAdapter::OnRejectPromise(uint32_t promise_id,
                                 cdm::Error error,
                                 uint32_t system_code,
                                 const char* error_message,
                                 uint32_t error_message_length) {
  // 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_length));
}

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

void CdmAdapter::OnSessionMessage(const char* web_session_id,
                                  uint32_t web_session_id_length,
                                  const char* message,
                                  uint32_t message_length,
                                  const char* destination_url,
                                  uint32_t destination_url_length) {
  PostOnMain(callback_factory_.NewCallback(
      &CdmAdapter::SendSessionMessageInternal,
      std::string(web_session_id, web_session_id_length),
      std::vector<uint8>(message, message + message_length),
      std::string(destination_url, destination_url_length)));
}

void CdmAdapter::OnSessionKeysChange(const char* web_session_id,
                                     uint32_t web_session_id_length,
                                     bool has_additional_usable_key) {
  OnSessionUsableKeysChange(
      web_session_id, web_session_id_length, has_additional_usable_key);
}

void CdmAdapter::OnSessionUsableKeysChange(const char* web_session_id,
                                           uint32_t web_session_id_length,
                                           bool has_additional_usable_key) {
  PostOnMain(callback_factory_.NewCallback(
      &CdmAdapter::SendSessionUsableKeysChangeInternal,
      std::string(web_session_id, web_session_id_length),
      has_additional_usable_key));
}

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

void CdmAdapter::OnSessionReady(const char* web_session_id,
                                uint32_t web_session_id_length) {
  PostOnMain(callback_factory_.NewCallback(
      &CdmAdapter::SendSessionReadyInternal,
      std::string(web_session_id, web_session_id_length)));
}

void CdmAdapter::OnSessionClosed(const char* web_session_id,
                                 uint32_t web_session_id_length) {
  PostOnMain(callback_factory_.NewCallback(
      &CdmAdapter::SendSessionClosedInternal,
      std::string(web_session_id, web_session_id_length)));
}

void CdmAdapter::OnSessionError(const char* web_session_id,
                                uint32_t web_session_id_length,
                                cdm::Error error,
                                uint32_t system_code,
                                const char* error_message,
                                uint32_t error_message_length) {
  PostOnMain(callback_factory_.NewCallback(
      &CdmAdapter::SendSessionErrorInternal,
      std::string(web_session_id, web_session_id_length),
      SessionError(error,
                   system_code,
                   std::string(error_message, error_message_length))));
}

// Helpers to pass the event to Pepper.

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

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

void CdmAdapter::SendPromiseResolvedWithUsableKeyIdsInternal(
    int32_t result,
    uint32_t promise_id,
    std::vector<std::vector<uint8> > key_ids) {
  PP_DCHECK(result == PP_OK);
  // TODO(jrummell): Implement this event in subsequent CL.
  // (http://crbug.com/358271).
}

void CdmAdapter::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 CdmAdapter::SendSessionMessageInternal(
    int32_t result,
    const std::string& web_session_id,
    const std::vector<uint8>& message,
    const std::string& destination_url) {
  PP_DCHECK(result == PP_OK);

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

  pp::ContentDecryptor_Private::SessionMessage(
      web_session_id, message_array_buffer, destination_url);
}

void CdmAdapter::SendSessionReadyInternal(int32_t result,
                                          const std::string& web_session_id) {
  PP_DCHECK(result == PP_OK);
  pp::ContentDecryptor_Private::SessionReady(web_session_id);
}

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

void CdmAdapter::SendSessionErrorInternal(int32_t result,
                                          const std::string& web_session_id,
                                          const SessionError& error) {
  PP_DCHECK(result == PP_OK);
  pp::ContentDecryptor_Private::SessionError(
      web_session_id,
      CdmExceptionTypeToPpCdmExceptionType(error.error),
      error.system_code,
      error.error_description);
}

void CdmAdapter::SendSessionUsableKeysChangeInternal(
    int32_t result,
    const std::string& web_session_id,
    bool has_additional_usable_key) {
  PP_DCHECK(result == PP_OK);
  // TODO(jrummell): Implement this event in subsequent CL.
  // (http://crbug.com/358271).
}

void CdmAdapter::SendExpirationChangeInternal(int32_t result,
                                              const std::string& web_session_id,
                                              cdm::Time new_expiry_time) {
  PP_DCHECK(result == PP_OK);
  // TODO(jrummell): Implement this event in subsequent CL.
  // (http://crbug.com/358271).
}

void CdmAdapter::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 CdmAdapter::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 CdmAdapter::DecoderDeinitializeDone(int32_t result,
                                         PP_DecryptorStreamType decoder_type,
                                         uint32_t request_id) {
  pp::ContentDecryptor_Private::DecoderDeinitializeDone(decoder_type,
                                                        request_id);
}

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

void CdmAdapter::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 CdmAdapter::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 CdmAdapter::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 CdmAdapter::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 CdmAdapter::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 CdmAdapter::SendPlatformChallenge(
    const char* service_id, uint32_t service_id_length,
    const char* challenge, uint32_t challenge_length) {
#if defined(OS_CHROMEOS)
  pp::VarArrayBuffer challenge_var(challenge_length);
  uint8_t* var_data = static_cast<uint8_t*>(challenge_var.Map());
  memcpy(var_data, challenge, challenge_length);

  std::string service_id_str(service_id, service_id_length);

  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(&CdmAdapter::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 CdmAdapter::EnableOutputProtection(uint32_t desired_protection_mask) {
#if defined(OS_CHROMEOS)
  int32_t result = output_protection_.EnableProtection(
      desired_protection_mask, callback_factory_.NewCallback(
          &CdmAdapter::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() << __FUNCTION__ << " failed!";
#endif
}

void CdmAdapter::QueryOutputProtectionStatus() {
#if defined(OS_CHROMEOS)
  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(
          &CdmAdapter::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);
#endif

  cdm_->OnQueryOutputProtectionStatus(0, 0);
}

void CdmAdapter::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(&CdmAdapter::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(&CdmAdapter::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* CdmAdapter::CreateFileIO(cdm::FileIOClient* client) {
  return new CdmFileIOImpl(
      client,
      pp_instance(),
      callback_factory_.NewCallback(&CdmAdapter::OnFirstFileRead));
}

#if defined(OS_CHROMEOS)
void CdmAdapter::ReportOutputProtectionUMA(OutputProtectionStatus status) {
  pp::UMAPrivate uma_interface(this);
  uma_interface.HistogramEnumeration(
      "Media.EME.OutputProtection", status, OUTPUT_PROTECTION_MAX);
}

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

  ReportOutputProtectionUMA(OUTPUT_PROTECTION_QUERIED);
  uma_for_output_protection_query_reported_ = true;
}

void CdmAdapter::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;
  bool is_hdcp_enabled_on_all_protectable_links =
      output_protection_mask_ & cdm::kProtectionHDCP;

  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.
}

void CdmAdapter::SendPlatformChallengeDone(
    int32_t result,
    const linked_ptr<PepperPlatformChallengeResponse>& response) {
  if (result != PP_OK) {
    CDM_DLOG() << __FUNCTION__ << ": 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();
}

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

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

  // Return a protection status of none on error.
  if (result != PP_OK)
    output_link_mask_ = output_protection_mask_ = 0;
  else
    ReportOutputProtectionQueryResult();

  cdm_->OnQueryOutputProtectionStatus(output_link_mask_,
                                      output_protection_mask_);
}
#endif

CdmAdapter::SessionError::SessionError(cdm::Error error,
                                       uint32_t system_code,
                                       std::string error_description)
    : error(error),
      system_code(system_code),
      error_description(error_description) {
}

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

  COMPILE_ASSERT(
      cdm::ContentDecryptionModule::Host::kVersion == cdm::Host_6::kVersion,
      update_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_6::kVersion + 1) &&
      // Current version is supported.
      IsSupportedCdmHostVersion(cdm::Host_6::kVersion) &&
      // Include all previous supported versions (if any) here.
      IsSupportedCdmHostVersion(cdm::Host_5::kVersion) &&
      IsSupportedCdmHostVersion(cdm::Host_4::kVersion) &&
      // One older than the oldest supported version is not supported.
      !IsSupportedCdmHostVersion(cdm::Host_4::kVersion - 1));
  PP_DCHECK(IsSupportedCdmHostVersion(host_interface_version));

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

// This object is the global object representing this plugin library as long
// as it is loaded.
class CdmAdapterModule : public pp::Module {
 public:
  CdmAdapterModule() : 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 ~CdmAdapterModule() {
    DeinitializeCdmModule();
  }

  virtual pp::Instance* CreateInstance(PP_Instance instance) {
    return new CdmAdapter(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::CdmAdapterModule();
}

}  // namespace pp
