cdm_wrapper.h revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file.
48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#ifndef MEDIA_CDM_PPAPI_CDM_WRAPPER_H_
68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#define MEDIA_CDM_PPAPI_CDM_WRAPPER_H_
78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <map>
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <queue>
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <string>
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/basictypes.h"
138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "media/cdm/ppapi/api/content_decryption_module.h"
148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "media/cdm/ppapi/cdm_helpers.h"
150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "media/cdm/ppapi/supported_cdm_versions.h"
168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ppapi/cpp/logging.h"
178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace media {
198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// CdmWrapper wraps different versions of ContentDecryptionModule interfaces and
218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// exposes a common interface to the caller.
228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)//
238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// The caller should call CdmWrapper::Create() to create a CDM instance.
248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// CdmWrapper will first try to create a CDM instance that supports the latest
258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// CDM interface (ContentDecryptionModule). If such an instance cannot be
268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// created (e.g. an older CDM was loaded), CdmWrapper will try to create a CDM
278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// that supports an older version of CDM interface (e.g.
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// ContentDecryptionModule_*). Internally CdmWrapper converts the CdmWrapper
298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// calls to corresponding ContentDecryptionModule calls.
308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)//
318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Note that CdmWrapper interface always reflects the latest state of content
328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// decryption related PPAPI APIs (e.g. pp::ContentDecryptor_Private).
338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)//
348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Since this file is highly templated and default implementations are short
358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// (just a shim layer in most cases), everything is done in this header file.
368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class CdmWrapper {
378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public:
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // CDM_1 and CDM_2 methods AddKey() and CancelKeyRequest() may require
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // callbacks to fire. Use this enum to indicate the additional calls required.
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(jrummell): Remove return value once CDM_1 and CDM_2 are no longer
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // supported.
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  enum Result {
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NO_ACTION,
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CALL_KEY_ADDED,
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CALL_KEY_ERROR
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  static CdmWrapper* Create(const char* key_system,
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                            uint32_t key_system_size,
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                            GetCdmHostFunc get_cdm_host_func,
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                            void* user_data);
528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual ~CdmWrapper() {};
548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void CreateSession(uint32_t session_id,
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             const char* type,
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             uint32_t type_size,
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             const uint8_t* init_data,
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             uint32_t init_data_size) = 0;
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual Result UpdateSession(uint32_t session_id,
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               const uint8_t* response,
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               uint32_t response_size) = 0;
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual Result ReleaseSession(uint32_t session_id) = 0;
648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void TimerExpired(void* context) = 0;
658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer,
668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                              cdm::DecryptedBlock* decrypted_buffer) = 0;
678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual cdm::Status InitializeAudioDecoder(
688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const cdm::AudioDecoderConfig& audio_decoder_config) = 0;
698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual cdm::Status InitializeVideoDecoder(
708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const cdm::VideoDecoderConfig& video_decoder_config) = 0;
718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void DeinitializeDecoder(cdm::StreamType decoder_type) = 0;
728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void ResetDecoder(cdm::StreamType decoder_type) = 0;
738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual cdm::Status DecryptAndDecodeFrame(
748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const cdm::InputBuffer& encrypted_buffer,
758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      cdm::VideoFrame* video_frame) = 0;
768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual cdm::Status DecryptAndDecodeSamples(
778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const cdm::InputBuffer& encrypted_buffer,
788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      cdm::AudioFrames* audio_frames) = 0;
798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void OnPlatformChallengeResponse(
808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const cdm::PlatformChallengeResponse& response) = 0;
818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void OnQueryOutputProtectionStatus(
828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      uint32_t link_mask,
838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      uint32_t output_protection_mask) = 0;
848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // ContentDecryptionModule_1 and ContentDecryptionModule_2 interface methods
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // AddKey() and CancelKeyRequest() (older versions of UpdateSession() and
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // ReleaseSession(), respectively) pass in the web_session_id rather than the
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // session_id. As well, Host_1 and Host_2 callbacks SendKeyMessage() and
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // SendKeyError() include the web_session_id, but the actual callbacks need
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // session_id.
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // The following functions maintain the session_id <-> web_session_id mapping.
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // These can be removed once _1 and _2 interfaces are no longer supported.
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Determine the corresponding session_id for |web_session_id|.
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual uint32_t LookupSessionId(const std::string& web_session_id) = 0;
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Determine the corresponding session_id for |session_id|.
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual const std::string LookupWebSessionId(uint32_t session_id) = 0;
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Map between session_id and web_session_id.
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // TODO(jrummell): The following can be removed once CDM_1 and CDM_2 are
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // no longer supported.
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  typedef std::map<uint32_t, std::string> SessionMap;
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SessionMap session_map_;
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static const uint32_t kInvalidSessionId = 0;
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // As the response from PrefixedGenerateKeyRequest() may be synchronous or
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // asynchronous, keep track of the current request during the call to handle
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // synchronous responses or errors. If no response received, add this request
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // to a queue and assume that the subsequent responses come back in the order
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // issued.
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(jrummell): Remove once all supported CDM host interfaces support
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // session_id.
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32_t current_key_request_session_id_;
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::queue<uint32_t> pending_key_request_session_ids_;
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CdmWrapper() : current_key_request_session_id_(kInvalidSessionId) {}
1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private:
1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CdmWrapper);
1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)};
1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Template class that does the CdmWrapper -> CdmInterface conversion. Default
1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// implementations are provided. Any methods that need special treatment should
1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// be specialized.
1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)template <class CdmInterface>
1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class CdmWrapperImpl : public CdmWrapper {
1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public:
1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  static CdmWrapper* Create(const char* key_system,
1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                            uint32_t key_system_size,
1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                            GetCdmHostFunc get_cdm_host_func,
1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                            void* user_data) {
1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    void* cdm_instance = ::CreateCdmInstance(
1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        CdmInterface::kVersion, key_system, key_system_size, get_cdm_host_func,
1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        user_data);
1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (!cdm_instance)
1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return NULL;
1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return new CdmWrapperImpl<CdmInterface>(
1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        static_cast<CdmInterface*>(cdm_instance));
1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual ~CdmWrapperImpl() {
1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    cdm_->Destroy();
1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void CreateSession(uint32_t session_id,
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             const char* type,
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             uint32_t type_size,
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             const uint8_t* init_data,
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             uint32_t init_data_size) OVERRIDE {
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    cdm_->CreateSession(session_id, type, type_size, init_data, init_data_size);
1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual Result UpdateSession(uint32_t session_id,
159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               const uint8_t* response,
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               uint32_t response_size) OVERRIDE {
161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    cdm_->UpdateSession(session_id, response, response_size);
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return NO_ACTION;
1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual Result ReleaseSession(uint32_t session_id) OVERRIDE {
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    cdm_->ReleaseSession(session_id);
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return NO_ACTION;
1688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void TimerExpired(void* context) OVERRIDE {
1718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    cdm_->TimerExpired(context);
1728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer,
1758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                              cdm::DecryptedBlock* decrypted_buffer) OVERRIDE {
1768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return cdm_->Decrypt(encrypted_buffer, decrypted_buffer);
1778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual cdm::Status InitializeAudioDecoder(
1808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const cdm::AudioDecoderConfig& audio_decoder_config) OVERRIDE {
1818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return cdm_->InitializeAudioDecoder(audio_decoder_config);
1828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual cdm::Status InitializeVideoDecoder(
1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const cdm::VideoDecoderConfig& video_decoder_config) OVERRIDE {
1868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return cdm_->InitializeVideoDecoder(video_decoder_config);
1878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void DeinitializeDecoder(cdm::StreamType decoder_type) OVERRIDE {
1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    cdm_->DeinitializeDecoder(decoder_type);
1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void ResetDecoder(cdm::StreamType decoder_type) OVERRIDE {
1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    cdm_->ResetDecoder(decoder_type);
1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual cdm::Status DecryptAndDecodeFrame(
1988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const cdm::InputBuffer& encrypted_buffer,
1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      cdm::VideoFrame* video_frame) OVERRIDE {
2008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return cdm_->DecryptAndDecodeFrame(encrypted_buffer, video_frame);
2018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual cdm::Status DecryptAndDecodeSamples(
2048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const cdm::InputBuffer& encrypted_buffer,
2058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      cdm::AudioFrames* audio_frames) OVERRIDE {
2068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return cdm_->DecryptAndDecodeSamples(encrypted_buffer, audio_frames);
2078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void OnPlatformChallengeResponse(
2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const cdm::PlatformChallengeResponse& response) OVERRIDE {
2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    cdm_->OnPlatformChallengeResponse(response);
2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void OnQueryOutputProtectionStatus(
2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      uint32_t link_mask,
2168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      uint32_t output_protection_mask) OVERRIDE {
2178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    cdm_->OnQueryOutputProtectionStatus(link_mask, output_protection_mask);
2188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32_t LookupSessionId(const std::string& web_session_id) {
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    for (SessionMap::iterator it = session_map_.begin();
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         it != session_map_.end();
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         ++it) {
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (it->second == web_session_id)
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return it->first;
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // There is no entry in the map; assume it came from the current
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // PrefixedGenerateKeyRequest() call (if possible). If no current request,
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // assume it came from the oldest PrefixedGenerateKeyRequest() call.
231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    uint32_t session_id = current_key_request_session_id_;
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (current_key_request_session_id_) {
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // Only 1 response is allowed for the current
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // PrefixedGenerateKeyRequest().
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      current_key_request_session_id_ = kInvalidSessionId;
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else {
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      PP_DCHECK(!pending_key_request_session_ids_.empty());
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      session_id = pending_key_request_session_ids_.front();
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      pending_key_request_session_ids_.pop();
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // If this is a valid |session_id|, add it to the list. Otherwise, avoid
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // adding empty string as a mapping to prevent future calls with an empty
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // string from using the wrong session_id.
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!web_session_id.empty()) {
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      PP_DCHECK(session_map_.find(session_id) == session_map_.end());
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      session_map_[session_id] = web_session_id;
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return session_id;
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string LookupWebSessionId(uint32_t session_id) {
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Session may not exist if error happens during CreateSession().
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SessionMap::iterator it = session_map_.find(session_id);
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return (it != session_map_.end()) ? it->second : std::string();
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private:
2608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CdmWrapperImpl(CdmInterface* cdm) : cdm_(cdm) {
2618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    PP_DCHECK(cdm_);
2628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CdmInterface* cdm_;
2658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CdmWrapperImpl);
2678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)};
2688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// For ContentDecryptionModule_1 and ContentDecryptionModule_2,
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// CreateSession(), UpdateSession(), and ReleaseSession() call methods
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// are incompatible with ContentDecryptionModule_3. Use the following
272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// templated functions to handle this.
273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <class CdmInterface>
275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PrefixedGenerateKeyRequest(CdmWrapper* wrapper,
276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                CdmInterface* cdm,
277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                uint32_t session_id,
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                const char* type,
279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                uint32_t type_size,
280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                const uint8_t* init_data,
281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                uint32_t init_data_size) {
282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // As it is possible for CDMs to reply synchronously during the call to
283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // GenerateKeyRequest(), keep track of |session_id|.
284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  wrapper->current_key_request_session_id_ = session_id;
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  cdm::Status status =
287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      cdm->GenerateKeyRequest(type, type_size, init_data, init_data_size);
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError);
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (status != cdm::kSuccess) {
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // If GenerateKeyRequest() failed, no subsequent asynchronous replies
291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // will be sent. Verify that a response was sent synchronously.
292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PP_DCHECK(wrapper->current_key_request_session_id_ ==
293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              CdmWrapper::kInvalidSessionId);
294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    wrapper->current_key_request_session_id_ = CdmWrapper::kInvalidSessionId;
295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (wrapper->current_key_request_session_id_) {
299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // If this request is still pending (SendKeyMessage() or SendKeyError()
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // not called synchronously), add |session_id| to the end of the queue.
301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Without CDM support, it is impossible to match SendKeyMessage()
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // (or SendKeyError()) responses to the |session_id|. Doing the best
303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // we can by keeping track of this in a queue, and assuming the responses
304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // come back in order.
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    wrapper->pending_key_request_session_ids_.push(session_id);
306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    wrapper->current_key_request_session_id_ = CdmWrapper::kInvalidSessionId;
307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <class CdmInterface>
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CdmWrapper::Result PrefixedAddKey(CdmWrapper* wrapper,
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  CdmInterface* cdm,
313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  uint32_t session_id,
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  const uint8_t* response,
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  uint32_t response_size) {
316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string web_session_id = wrapper->LookupWebSessionId(session_id);
317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (web_session_id.empty()) {
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Possible if UpdateSession() called before CreateSession().
319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return CdmWrapper::CALL_KEY_ERROR;
320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // CDM_1 and CDM_2 accept initdata, which is no longer needed.
323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // In it's place pass in NULL.
324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  cdm::Status status = cdm->AddKey(web_session_id.data(), web_session_id.size(),
325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   response, response_size,
326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   NULL, 0);
327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError);
328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (status != cdm::kSuccess) {
329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Some CDMs using Host_1/2 don't call keyerror, so send one.
330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return CdmWrapper::CALL_KEY_ERROR;
331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return CdmWrapper::CALL_KEY_ADDED;
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <class CdmInterface>
337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CdmWrapper::Result PrefixedCancelKeyRequest(CdmWrapper* wrapper,
338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                            CdmInterface* cdm,
339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                            uint32_t session_id) {
340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string web_session_id = wrapper->LookupWebSessionId(session_id);
341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (web_session_id.empty()) {
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Possible if ReleaseSession() called before CreateSession().
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return CdmWrapper::CALL_KEY_ERROR;
344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  wrapper->session_map_.erase(session_id);
347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  cdm::Status status =
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      cdm->CancelKeyRequest(web_session_id.data(), web_session_id.size());
349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError);
351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (status != cdm::kSuccess) {
352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Some CDMs using Host_1/2 don't call keyerror, so send one.
353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return CdmWrapper::CALL_KEY_ERROR;
354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return CdmWrapper::NO_ACTION;
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Specializations for ContentDecryptionModule_1.
3608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <>
362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CdmWrapperImpl<cdm::ContentDecryptionModule_1>::CreateSession(
363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    uint32_t session_id,
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const char* type,
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    uint32_t type_size,
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const uint8_t* init_data,
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    uint32_t init_data_size) {
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PrefixedGenerateKeyRequest(
369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      this, cdm_, session_id, type, type_size, init_data, init_data_size);
370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <>
373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CdmWrapper::Result CdmWrapperImpl<
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    cdm::ContentDecryptionModule_1>::UpdateSession(uint32_t session_id,
375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                   const uint8_t* response,
376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                   uint32_t response_size) {
377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return PrefixedAddKey(this, cdm_, session_id, response, response_size);
378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <>
381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CdmWrapper::Result CdmWrapperImpl<
382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    cdm::ContentDecryptionModule_1>::ReleaseSession(uint32_t session_id) {
383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return PrefixedCancelKeyRequest(this, cdm_, session_id);
384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)template <> void CdmWrapperImpl<cdm::ContentDecryptionModule_1>::
3878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    OnPlatformChallengeResponse(
3888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        const cdm::PlatformChallengeResponse& response) {
3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PP_NOTREACHED();
3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)template <> void CdmWrapperImpl<cdm::ContentDecryptionModule_1>::
3938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    OnQueryOutputProtectionStatus(uint32_t link_mask,
3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                  uint32_t output_protection_mask) {
3958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PP_NOTREACHED();
3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)template <> cdm::Status CdmWrapperImpl<cdm::ContentDecryptionModule_1>::
3998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    DecryptAndDecodeSamples(const cdm::InputBuffer& encrypted_buffer,
4008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                            cdm::AudioFrames* audio_frames) {
4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AudioFramesImpl audio_frames_1;
4028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  cdm::Status status =
4038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      cdm_->DecryptAndDecodeSamples(encrypted_buffer, &audio_frames_1);
4048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (status != cdm::kSuccess)
4058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return status;
4068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  audio_frames->SetFrameBuffer(audio_frames_1.PassFrameBuffer());
4088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  audio_frames->SetFormat(cdm::kAudioFormatS16);
4098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return cdm::kSuccess;
4108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Specializations for ContentDecryptionModule_2.
413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
414a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <>
415a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CdmWrapperImpl<cdm::ContentDecryptionModule_2>::CreateSession(
416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    uint32_t session_id,
417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const char* type,
418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    uint32_t type_size,
419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const uint8_t* init_data,
420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    uint32_t init_data_size) {
421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PrefixedGenerateKeyRequest(
422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      this, cdm_, session_id, type, type_size, init_data, init_data_size);
423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
424a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <>
426a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CdmWrapper::Result CdmWrapperImpl<
427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    cdm::ContentDecryptionModule_2>::UpdateSession(uint32_t session_id,
428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                   const uint8_t* response,
429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                   uint32_t response_size) {
430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return PrefixedAddKey(this, cdm_, session_id, response, response_size);
431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <>
434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CdmWrapper::Result CdmWrapperImpl<
435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    cdm::ContentDecryptionModule_2>::ReleaseSession(uint32_t session_id) {
436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return PrefixedCancelKeyRequest(this, cdm_, session_id);
437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)CdmWrapper* CdmWrapper::Create(const char* key_system,
4401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                               uint32_t key_system_size,
4418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                               GetCdmHostFunc get_cdm_host_func,
4428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                               void* user_data) {
4430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  COMPILE_ASSERT(cdm::ContentDecryptionModule::kVersion ==
444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 cdm::ContentDecryptionModule_3::kVersion,
4450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                 update_code_below);
4460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
4470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Ensure IsSupportedCdmInterfaceVersion matches this implementation.
4480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Always update this DCHECK when updating this function.
4490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // If this check fails, update this function and DCHECK or update
4500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // IsSupportedCdmInterfaceVersion.
4510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  PP_DCHECK(
4520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      !IsSupportedCdmInterfaceVersion(
4530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          cdm::ContentDecryptionModule::kVersion + 1) &&
4540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      IsSupportedCdmInterfaceVersion(cdm::ContentDecryptionModule::kVersion) &&
4550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      IsSupportedCdmInterfaceVersion(
456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          cdm::ContentDecryptionModule_2::kVersion) &&
457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      IsSupportedCdmInterfaceVersion(
4580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          cdm::ContentDecryptionModule_1::kVersion) &&
4590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      !IsSupportedCdmInterfaceVersion(
4600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          cdm::ContentDecryptionModule_1::kVersion - 1));
4610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
4628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Try to create the CDM using the latest CDM interface version.
4630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CdmWrapper* cdm_wrapper =
4648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      CdmWrapperImpl<cdm::ContentDecryptionModule>::Create(
4658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          key_system, key_system_size, get_cdm_host_func, user_data);
4660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (cdm_wrapper)
4670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return cdm_wrapper;
4688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Try to see if the CDM supports older version(s) of the CDM interface.
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_2>::Create(
471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      key_system, key_system_size, get_cdm_host_func, user_data);
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (cdm_wrapper)
473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return cdm_wrapper;
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_1>::Create(
4768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      key_system, key_system_size, get_cdm_host_func, user_data);
4770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return cdm_wrapper;
4788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// When updating the CdmAdapter, ensure you've updated the CdmWrapper to contain
4811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// stub implementations for new or modified methods that the older CDM interface
4821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// does not have.
4830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Also update supported_cdm_versions.h.
4841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)COMPILE_ASSERT(cdm::ContentDecryptionModule::kVersion ==
485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   cdm::ContentDecryptionModule_3::kVersion,
4868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               ensure_cdm_wrapper_templates_have_old_version_support);
4878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace media
4898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif  // MEDIA_CDM_PPAPI_CDM_WRAPPER_H_
491