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

#ifndef MEDIA_CDM_PPAPI_CDM_WRAPPER_H_
#define MEDIA_CDM_PPAPI_CDM_WRAPPER_H_

#include <map>
#include <queue>
#include <string>

#include "base/basictypes.h"
#include "media/cdm/ppapi/api/content_decryption_module.h"
#include "media/cdm/ppapi/cdm_helpers.h"
#include "media/cdm/ppapi/supported_cdm_versions.h"
#include "ppapi/cpp/logging.h"

namespace media {

// CdmWrapper wraps different versions of ContentDecryptionModule interfaces and
// exposes a common interface to the caller.
//
// The caller should call CdmWrapper::Create() to create a CDM instance.
// CdmWrapper will first try to create a CDM instance that supports the latest
// CDM interface (ContentDecryptionModule). If such an instance cannot be
// created (e.g. an older CDM was loaded), CdmWrapper will try to create a CDM
// that supports an older version of CDM interface (e.g.
// ContentDecryptionModule_*). Internally CdmWrapper converts the CdmWrapper
// calls to corresponding ContentDecryptionModule calls.
//
// Note that CdmWrapper interface always reflects the latest state of content
// decryption related PPAPI APIs (e.g. pp::ContentDecryptor_Private).
//
// Since this file is highly templated and default implementations are short
// (just a shim layer in most cases), everything is done in this header file.
class CdmWrapper {
 public:
  static CdmWrapper* Create(const char* key_system,
                            uint32_t key_system_size,
                            GetCdmHostFunc get_cdm_host_func,
                            void* user_data);

  virtual ~CdmWrapper() {};

  virtual void CreateSession(uint32_t promise_id,
                             const char* init_data_type,
                             uint32_t init_data_type_size,
                             const uint8_t* init_data,
                             uint32_t init_data_size,
                             cdm::SessionType session_type) = 0;
  virtual void LoadSession(uint32_t promise_id,
                           const char* web_session_id,
                           uint32_t web_session_id_size) = 0;
  virtual void UpdateSession(uint32_t promise_id,
                             const char* web_session_id,
                             uint32_t web_session_id_size,
                             const uint8_t* response,
                             uint32_t response_size) = 0;
  // TODO(jrummell): Remove return value when CDM4/5 are removed.
  virtual bool CloseSession(uint32_t promise_id,
                            const char* web_session_id,
                            uint32_t web_session_id_size) = 0;
  virtual void RemoveSession(uint32_t promise_id,
                             const char* web_session_id,
                             uint32_t web_session_id_size) = 0;
  // TODO(jrummell): Remove return value when CDM4/5 are removed.
  virtual bool GetUsableKeyIds(uint32_t promise_id,
                               const char* web_session_id,
                               uint32_t web_session_id_size) = 0;
  virtual void TimerExpired(void* context) = 0;
  virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer,
                              cdm::DecryptedBlock* decrypted_buffer) = 0;
  virtual cdm::Status InitializeAudioDecoder(
      const cdm::AudioDecoderConfig& audio_decoder_config) = 0;
  virtual cdm::Status InitializeVideoDecoder(
      const cdm::VideoDecoderConfig& video_decoder_config) = 0;
  virtual void DeinitializeDecoder(cdm::StreamType decoder_type) = 0;
  virtual void ResetDecoder(cdm::StreamType decoder_type) = 0;
  virtual cdm::Status DecryptAndDecodeFrame(
      const cdm::InputBuffer& encrypted_buffer,
      cdm::VideoFrame* video_frame) = 0;
  virtual cdm::Status DecryptAndDecodeSamples(
      const cdm::InputBuffer& encrypted_buffer,
      cdm::AudioFrames* audio_frames) = 0;
  virtual void OnPlatformChallengeResponse(
      const cdm::PlatformChallengeResponse& response) = 0;
  virtual void OnQueryOutputProtectionStatus(
      uint32_t link_mask,
      uint32_t output_protection_mask) = 0;

  // Helper function for the cdm::Host_4 methods. Calls to CreateSession(),
  // LoadSession(), UpdateSession(), and ReleaseSession() pass in promise ids,
  // but the CDM interface needs session ids. For create and load, we need to
  // create a new session_id to pass to the CDM. For update and release, we need
  // to look up |web_session_id| and convert it into the existing |session_id|.
  // Since the callbacks don't come through this interface, cdm_adapter needs to
  // create the mapping (and delete it on release).
  // TODO(jrummell): Remove these once Host_4 interface is removed.
  virtual uint32_t LookupPromiseId(uint32_t session_id) = 0;
  virtual void AssignWebSessionId(uint32_t session_id,
                                  const char* web_session_id,
                                  uint32_t web_session_id_size) = 0;
  virtual std::string LookupWebSessionId(uint32_t session_id) = 0;
  virtual void DropWebSessionId(std::string web_session_id) = 0;

  // Helper functions for the cdm::Host_4 and cdm::Host_5 methods.
  // CDMs using cdm::Host_6 will call OnSessionUsableKeys() as necessary when
  // resolving LoadSession() and UpdateSession(). This needs to be simulated
  // for the older CDMs. These must not be called for cdm::Host_6 and later.
  // TODO(jrummell): Remove these once Host_4 and Host_5 interfaces are removed.

  // Query whether a SessionUsableKeys event is necessary for the specified
  // |promise_id|. Returns true if needed and |web_session_id| is updated,
  // otherwise returns false.
  virtual bool SessionUsableKeysEventNeeded(uint32_t promise_id,
                                            std::string* web_session_id) = 0;

  // Used to indicate that a SessionUsableKeys event is required for the
  // specified |promise_id| and associated |web_session_id|.
  virtual void SetSessionUsableKeysEventNeeded(
      uint32_t promise_id,
      const char* web_session_id,
      uint32_t web_session_id_size) = 0;

  // cdm::Host_6 introduces InputBuffer_2 (aka InputBuffer). cdm::Host_4 and
  // cdm::Host_5 methods still use InputBuffer_1, so this helper function
  // converts InputBuffer_2 to InputBuffer_1.
  // TODO(jrummell): Remove these once Host_4 and Host_5 interfaces are removed.
  virtual void ConvertInputBuffer(const cdm::InputBuffer& v2,
                                  cdm::InputBuffer_1* v1) = 0;

  // Prior to CDM_6, |init_data_type| was a content type. This helper convererts
  // an |init_data_type| to a content type.
  // TODO(sandersd): Remove once Host_4 and Host_5 interfaces are removed.
  virtual std::string ConvertInitDataTypeToContentType(
      const std::string& init_data_type) const = 0;

 protected:
  CdmWrapper() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(CdmWrapper);
};

// Template class that does the CdmWrapper -> CdmInterface conversion. Default
// implementations are provided. Any methods that need special treatment should
// be specialized.
template <class CdmInterface>
class CdmWrapperImpl : public CdmWrapper {
 public:
  static CdmWrapper* Create(const char* key_system,
                            uint32_t key_system_size,
                            GetCdmHostFunc get_cdm_host_func,
                            void* user_data) {
    void* cdm_instance = ::CreateCdmInstance(
        CdmInterface::kVersion, key_system, key_system_size, get_cdm_host_func,
        user_data);
    if (!cdm_instance)
      return NULL;

    return new CdmWrapperImpl<CdmInterface>(
        static_cast<CdmInterface*>(cdm_instance));
  }

  virtual ~CdmWrapperImpl() {
    cdm_->Destroy();
  }

  // Returns true if |data| is prefixed with |header| and has data after the
  // |header|.
  bool HasHeader(const uint8* data,
                 int data_length,
                 const std::string& header) {
    return static_cast<size_t>(data_length) > header.length() &&
           std::equal(data, data + header.length(), header.begin());
  }

  virtual void CreateSession(uint32_t promise_id,
                             const char* init_data_type,
                             uint32_t init_data_type_size,
                             const uint8_t* init_data,
                             uint32_t init_data_size,
                             cdm::SessionType session_type) OVERRIDE {
    // TODO(jrummell): Remove this code once |session_type| is passed through
    // Pepper. When removing, add the header back in for CDM4.
    PP_DCHECK(session_type == cdm::kTemporary);
    const char kPersistentSessionHeader[] = "PERSISTENT|";
    if (HasHeader(init_data, init_data_size, kPersistentSessionHeader)) {
      cdm_->CreateSession(promise_id,
                          init_data_type,
                          init_data_type_size,
                          init_data + strlen(kPersistentSessionHeader),
                          init_data_size - strlen(kPersistentSessionHeader),
                          cdm::kPersistent);
      return;
    }

    cdm_->CreateSession(promise_id,
                        init_data_type,
                        init_data_type_size,
                        init_data,
                        init_data_size,
                        session_type);
  }

  virtual void LoadSession(uint32_t promise_id,
                           const char* web_session_id,
                           uint32_t web_session_id_size) OVERRIDE {
    cdm_->LoadSession(promise_id, web_session_id, web_session_id_size);
  }

  virtual void UpdateSession(uint32_t promise_id,
                             const char* web_session_id,
                             uint32_t web_session_id_size,
                             const uint8_t* response,
                             uint32_t response_size) OVERRIDE {
    cdm_->UpdateSession(promise_id,
                        web_session_id,
                        web_session_id_size,
                        response,
                        response_size);
  }

  virtual bool GetUsableKeyIds(uint32_t promise_id,
                               const char* web_session_id,
                               uint32_t web_session_id_size) OVERRIDE {
    cdm_->GetUsableKeyIds(promise_id, web_session_id, web_session_id_size);
    return true;
  }

  virtual bool CloseSession(uint32_t promise_id,
                            const char* web_session_id,
                            uint32_t web_session_id_size) OVERRIDE {
    cdm_->CloseSession(promise_id, web_session_id, web_session_id_size);
    return true;
  }

  virtual void RemoveSession(uint32_t promise_id,
                             const char* web_session_id,
                             uint32_t web_session_id_size) OVERRIDE {
    cdm_->RemoveSession(promise_id, web_session_id, web_session_id_size);
  }

  virtual void TimerExpired(void* context) OVERRIDE {
    cdm_->TimerExpired(context);
  }

  virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer,
                              cdm::DecryptedBlock* decrypted_buffer) OVERRIDE {
    return cdm_->Decrypt(encrypted_buffer, decrypted_buffer);
  }

  virtual cdm::Status InitializeAudioDecoder(
      const cdm::AudioDecoderConfig& audio_decoder_config) OVERRIDE {
    return cdm_->InitializeAudioDecoder(audio_decoder_config);
  }

  virtual cdm::Status InitializeVideoDecoder(
      const cdm::VideoDecoderConfig& video_decoder_config) OVERRIDE {
    return cdm_->InitializeVideoDecoder(video_decoder_config);
  }

  virtual void DeinitializeDecoder(cdm::StreamType decoder_type) OVERRIDE {
    cdm_->DeinitializeDecoder(decoder_type);
  }

  virtual void ResetDecoder(cdm::StreamType decoder_type) OVERRIDE {
    cdm_->ResetDecoder(decoder_type);
  }

  virtual cdm::Status DecryptAndDecodeFrame(
      const cdm::InputBuffer& encrypted_buffer,
      cdm::VideoFrame* video_frame) OVERRIDE {
    return cdm_->DecryptAndDecodeFrame(encrypted_buffer, video_frame);
  }

  virtual cdm::Status DecryptAndDecodeSamples(
      const cdm::InputBuffer& encrypted_buffer,
      cdm::AudioFrames* audio_frames) OVERRIDE {
    return cdm_->DecryptAndDecodeSamples(encrypted_buffer, audio_frames);
  }

  virtual void OnPlatformChallengeResponse(
      const cdm::PlatformChallengeResponse& response) OVERRIDE {
    cdm_->OnPlatformChallengeResponse(response);
  }

  virtual void OnQueryOutputProtectionStatus(
      uint32_t link_mask,
      uint32_t output_protection_mask) OVERRIDE {
    cdm_->OnQueryOutputProtectionStatus(link_mask, output_protection_mask);
  }

  uint32_t CreateSessionId() {
    return next_session_id_++;
  }

  void RegisterPromise(uint32_t session_id, uint32_t promise_id) {
    PP_DCHECK(promise_to_session_id_map_.find(session_id) ==
              promise_to_session_id_map_.end());
    promise_to_session_id_map_.insert(std::make_pair(session_id, promise_id));
  }

  virtual uint32_t LookupPromiseId(uint32_t session_id) {
    std::map<uint32_t, uint32_t>::iterator it =
        promise_to_session_id_map_.find(session_id);
    if (it == promise_to_session_id_map_.end())
      return 0;
    uint32_t promise_id = it->second;
    promise_to_session_id_map_.erase(it);
    return promise_id;
  }

  virtual void AssignWebSessionId(uint32_t session_id,
                                  const char* web_session_id,
                                  uint32_t web_session_id_size) {
    web_session_to_session_id_map_.insert(std::make_pair(
        std::string(web_session_id, web_session_id_size), session_id));
  }

  uint32_t LookupSessionId(std::string web_session_id) {
    return web_session_to_session_id_map_.find(web_session_id)->second;
  }

  virtual std::string LookupWebSessionId(uint32_t session_id) {
    std::map<std::string, uint32_t>::iterator it;
    for (it = web_session_to_session_id_map_.begin();
         it != web_session_to_session_id_map_.end();
         ++it) {
      if (it->second == session_id)
        return it->first;
    }
    PP_NOTREACHED();
    return std::string();
  }

  virtual void DropWebSessionId(std::string web_session_id) {
    web_session_to_session_id_map_.erase(web_session_id);
  }

  virtual bool SessionUsableKeysEventNeeded(uint32_t promise_id,
                                            std::string* web_session_id) {
    std::map<uint32_t, std::string>::iterator it =
        promises_needing_usable_keys_event_.find(promise_id);
    if (it == promises_needing_usable_keys_event_.end())
      return false;
    web_session_id->swap(it->second);
    promises_needing_usable_keys_event_.erase(it);
    return true;
  }

  virtual void SetSessionUsableKeysEventNeeded(uint32_t promise_id,
                                               const char* web_session_id,
                                               uint32_t web_session_id_size) {
    promises_needing_usable_keys_event_.insert(std::make_pair(
        promise_id, std::string(web_session_id, web_session_id_size)));
  }

  virtual void ConvertInputBuffer(const cdm::InputBuffer& v2,
                                  cdm::InputBuffer_1* v1) {
    v1->data = v2.data;
    v1->data_size = v2.data_size;
    v1->data_offset = 0;
    v1->key_id = v2.key_id;
    v1->key_id_size = v2.key_id_size;
    v1->iv = v2.iv;
    v1->iv_size = v2.iv_size;
    v1->subsamples = v2.subsamples;
    v1->num_subsamples = v2.num_subsamples;
    v1->timestamp = v2.timestamp;
  }

  virtual std::string ConvertInitDataTypeToContentType(
      const std::string& init_data_type) const {
    if (init_data_type == "cenc")
      return "video/mp4";
    if (init_data_type == "webm")
      return "video/webm";
    return init_data_type;
  }

 private:
  CdmWrapperImpl(CdmInterface* cdm) : cdm_(cdm), next_session_id_(100) {
    PP_DCHECK(cdm_);
  }

  CdmInterface* cdm_;

  std::map<uint32_t, uint32_t> promise_to_session_id_map_;
  uint32_t next_session_id_;
  std::map<std::string, uint32_t> web_session_to_session_id_map_;

  std::map<uint32_t, std::string> promises_needing_usable_keys_event_;

  DISALLOW_COPY_AND_ASSIGN(CdmWrapperImpl);
};

// Overrides for the cdm::Host_4 methods. Calls to CreateSession(),
// LoadSession(), UpdateSession(), and ReleaseSession() pass in promise ids,
// but the CDM interface needs session ids. For create and load, we need to
// create a new session_id to pass to the CDM. For update and release, we need
// to look up |web_session_id| and convert it into the existing |session_id|.
// Since the callbacks don't come through this interface, cdm_adapter needs to
// create the mapping (and delete it on release). Finally, for create, we need
// to translate |init_data_type| to a MIME type.
// TODO(jrummell): Remove these once Host_4 interface is removed.

template <>
void CdmWrapperImpl<cdm::ContentDecryptionModule_4>::CreateSession(
    uint32_t promise_id,
    const char* init_data_type,
    uint32_t init_data_type_size,
    const uint8_t* init_data,
    uint32_t init_data_size,
    cdm::SessionType session_type) {
  uint32_t session_id = CreateSessionId();
  RegisterPromise(session_id, promise_id);
  std::string converted_init_data_type = ConvertInitDataTypeToContentType(
      std::string(init_data_type, init_data_type_size));
  cdm_->CreateSession(session_id,
                      converted_init_data_type.data(),
                      converted_init_data_type.length(),
                      init_data,
                      init_data_size);
}

template <>
void CdmWrapperImpl<cdm::ContentDecryptionModule_4>::LoadSession(
    uint32_t promise_id,
    const char* web_session_id,
    uint32_t web_session_id_size) {
  uint32_t session_id = CreateSessionId();
  RegisterPromise(session_id, promise_id);
  // As CDM_4 doesn't support OnSessionUsableKeysChange(), make sure to generate
  // one when the promise is resolved. This may be overly aggressive.
  SetSessionUsableKeysEventNeeded(
      promise_id, web_session_id, web_session_id_size);
  cdm_->LoadSession(session_id, web_session_id, web_session_id_size);
}

template <>
void CdmWrapperImpl<cdm::ContentDecryptionModule_4>::UpdateSession(
    uint32_t promise_id,
    const char* web_session_id,
    uint32_t web_session_id_size,
    const uint8_t* response,
    uint32_t response_size) {
  std::string web_session_str(web_session_id, web_session_id_size);
  uint32_t session_id = LookupSessionId(web_session_str);
  RegisterPromise(session_id, promise_id);
  // As CDM_4 doesn't support OnSessionUsableKeysChange(), make sure to generate
  // one when the promise is resolved. This may be overly aggressive.
  SetSessionUsableKeysEventNeeded(
      promise_id, web_session_id, web_session_id_size);
  cdm_->UpdateSession(session_id, response, response_size);
}

template <>
bool CdmWrapperImpl<cdm::ContentDecryptionModule_4>::CloseSession(
    uint32_t promise_id,
    const char* web_session_id,
    uint32_t web_session_id_size) {
  return false;
}

template <>
void CdmWrapperImpl<cdm::ContentDecryptionModule_4>::RemoveSession(
    uint32_t promise_id,
    const char* web_session_id,
    uint32_t web_session_id_size) {
  std::string web_session_str(web_session_id, web_session_id_size);
  uint32_t session_id = LookupSessionId(web_session_str);
  RegisterPromise(session_id, promise_id);
  cdm_->ReleaseSession(session_id);
}

template <>
bool CdmWrapperImpl<cdm::ContentDecryptionModule_4>::GetUsableKeyIds(
    uint32_t promise_id,
    const char* web_session_id,
    uint32_t web_session_id_size) {
  return false;
}

template <>
cdm::Status CdmWrapperImpl<cdm::ContentDecryptionModule_4>::Decrypt(
    const cdm::InputBuffer& encrypted_buffer,
    cdm::DecryptedBlock* decrypted_buffer) {
  cdm::InputBuffer_1 buffer;
  ConvertInputBuffer(encrypted_buffer, &buffer);
  return cdm_->Decrypt(buffer, decrypted_buffer);
}

template <>
cdm::Status
CdmWrapperImpl<cdm::ContentDecryptionModule_4>::DecryptAndDecodeFrame(
    const cdm::InputBuffer& encrypted_buffer,
    cdm::VideoFrame* video_frame) {
  cdm::InputBuffer_1 buffer;
  ConvertInputBuffer(encrypted_buffer, &buffer);
  return cdm_->DecryptAndDecodeFrame(buffer, video_frame);
}

template <>
cdm::Status
CdmWrapperImpl<cdm::ContentDecryptionModule_4>::DecryptAndDecodeSamples(
    const cdm::InputBuffer& encrypted_buffer,
    cdm::AudioFrames* audio_frames) {
  cdm::InputBuffer_1 buffer;
  ConvertInputBuffer(encrypted_buffer, &buffer);
  return cdm_->DecryptAndDecodeSamples(buffer, audio_frames);
}

// Overrides for the cdm::Host_5 methods.
// TODO(jrummell): Remove these once Host_5 interface is removed.

template <>
void CdmWrapperImpl<cdm::ContentDecryptionModule_5>::CreateSession(
    uint32_t promise_id,
    const char* init_data_type,
    uint32_t init_data_type_size,
    const uint8_t* init_data,
    uint32_t init_data_size,
    cdm::SessionType session_type) {
  std::string converted_init_data_type = ConvertInitDataTypeToContentType(
      std::string(init_data_type, init_data_type_size));
  // TODO(jrummell): Remove this code once |session_type| is passed through
  // Pepper. When removing, add the header back in for CDM4.
  PP_DCHECK(session_type == cdm::kTemporary);
  const char kPersistentSessionHeader[] = "PERSISTENT|";
  if (HasHeader(init_data, init_data_size, kPersistentSessionHeader)) {
    cdm_->CreateSession(promise_id,
                        converted_init_data_type.data(),
                        converted_init_data_type.length(),
                        init_data + strlen(kPersistentSessionHeader),
                        init_data_size - strlen(kPersistentSessionHeader),
                        cdm::kPersistent);
    return;
  }

  cdm_->CreateSession(promise_id,
                      converted_init_data_type.data(),
                      converted_init_data_type.length(),
                      init_data,
                      init_data_size,
                      session_type);
}

template <>
void CdmWrapperImpl<cdm::ContentDecryptionModule_5>::LoadSession(
    uint32_t promise_id,
    const char* web_session_id,
    uint32_t web_session_id_size) {
  // As CDM_5 doesn't support OnSessionUsableKeysChange(), make sure to generate
  // one when the promise is resolved. This may be overly aggressive.
  SetSessionUsableKeysEventNeeded(
      promise_id, web_session_id, web_session_id_size);
  cdm_->LoadSession(promise_id, web_session_id, web_session_id_size);
}

template <>
void CdmWrapperImpl<cdm::ContentDecryptionModule_5>::UpdateSession(
    uint32_t promise_id,
    const char* web_session_id,
    uint32_t web_session_id_size,
    const uint8_t* response,
    uint32_t response_size) {
  // As CDM_5 doesn't support OnSessionUsableKeysChange(), make sure to generate
  // one when the promise is resolved. This may be overly aggressive.
  SetSessionUsableKeysEventNeeded(
      promise_id, web_session_id, web_session_id_size);
  cdm_->UpdateSession(
      promise_id, web_session_id, web_session_id_size, response, response_size);
}

template <>
bool CdmWrapperImpl<cdm::ContentDecryptionModule_5>::CloseSession(
    uint32_t promise_id,
    const char* web_session_id,
    uint32_t web_session_id_size) {
  return false;
}

template <>
void CdmWrapperImpl<cdm::ContentDecryptionModule_5>::RemoveSession(
    uint32_t promise_id,
    const char* web_session_id,
    uint32_t web_session_id_size) {
  cdm_->ReleaseSession(promise_id, web_session_id, web_session_id_size);
}

template <>
bool CdmWrapperImpl<cdm::ContentDecryptionModule_5>::GetUsableKeyIds(
    uint32_t promise_id,
    const char* web_session_id,
    uint32_t web_session_id_size) {
  return false;
}

template <>
cdm::Status CdmWrapperImpl<cdm::ContentDecryptionModule_5>::Decrypt(
    const cdm::InputBuffer& encrypted_buffer,
    cdm::DecryptedBlock* decrypted_buffer) {
  cdm::InputBuffer_1 buffer;
  ConvertInputBuffer(encrypted_buffer, &buffer);
  return cdm_->Decrypt(buffer, decrypted_buffer);
}

template <>
cdm::Status
CdmWrapperImpl<cdm::ContentDecryptionModule_5>::DecryptAndDecodeFrame(
    const cdm::InputBuffer& encrypted_buffer,
    cdm::VideoFrame* video_frame) {
  cdm::InputBuffer_1 buffer;
  ConvertInputBuffer(encrypted_buffer, &buffer);
  return cdm_->DecryptAndDecodeFrame(buffer, video_frame);
}

template <>
cdm::Status
CdmWrapperImpl<cdm::ContentDecryptionModule_5>::DecryptAndDecodeSamples(
    const cdm::InputBuffer& encrypted_buffer,
    cdm::AudioFrames* audio_frames) {
  cdm::InputBuffer_1 buffer;
  ConvertInputBuffer(encrypted_buffer, &buffer);
  return cdm_->DecryptAndDecodeSamples(buffer, audio_frames);
}

CdmWrapper* CdmWrapper::Create(const char* key_system,
                               uint32_t key_system_size,
                               GetCdmHostFunc get_cdm_host_func,
                               void* user_data) {
  COMPILE_ASSERT(cdm::ContentDecryptionModule::kVersion ==
                     cdm::ContentDecryptionModule_6::kVersion,
                 update_code_below);

  // Ensure IsSupportedCdmInterfaceVersion() matches this implementation.
  // Always update this DCHECK when updating this function.
  // If this check fails, update this function and DCHECK or update
  // IsSupportedCdmInterfaceVersion().
  PP_DCHECK(
      !IsSupportedCdmInterfaceVersion(cdm::ContentDecryptionModule::kVersion +
                                      1) &&
      IsSupportedCdmInterfaceVersion(cdm::ContentDecryptionModule::kVersion) &&
      IsSupportedCdmInterfaceVersion(
          cdm::ContentDecryptionModule_4::kVersion) &&
      !IsSupportedCdmInterfaceVersion(cdm::ContentDecryptionModule_4::kVersion -
                                      1));

  // Try to create the CDM using the latest CDM interface version.
  CdmWrapper* cdm_wrapper =
      CdmWrapperImpl<cdm::ContentDecryptionModule>::Create(
          key_system, key_system_size, get_cdm_host_func, user_data);
  if (cdm_wrapper)
    return cdm_wrapper;

  // If |cdm_wrapper| is NULL, try to create the CDM using older supported
  // versions of the CDM interface.
  cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_5>::Create(
      key_system, key_system_size, get_cdm_host_func, user_data);
  if (cdm_wrapper)
    return cdm_wrapper;

  cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_4>::Create(
      key_system, key_system_size, get_cdm_host_func, user_data);
  return cdm_wrapper;
}

// When updating the CdmAdapter, ensure you've updated the CdmWrapper to contain
// stub implementations for new or modified methods that the older CDM interface
// does not have.
// Also update supported_cdm_versions.h.
COMPILE_ASSERT(cdm::ContentDecryptionModule::kVersion ==
                   cdm::ContentDecryptionModule_6::kVersion,
               ensure_cdm_wrapper_templates_have_old_version_support);

}  // namespace media

#endif  // MEDIA_CDM_PPAPI_CDM_WRAPPER_H_
