Source release v2.2.0-0-903 + third_party libs

Change-Id: I03f670eaeb052bc741abb347be06f8ddc58418e7
This commit is contained in:
Joey Parrish
2014-12-15 10:35:08 -08:00
parent 5318232d46
commit 1955c9c2c9
85 changed files with 5594 additions and 2830 deletions

View File

@@ -37,13 +37,11 @@ typedef __int64 int64_t;
#endif // defined(WIN32)
// The version number must be rolled when the exported functions are updated!
// If the CDM and the adapter use different versions of these functions, the
// adapter will fail to load or crash!
#define INITIALIZE_CDM_MODULE InitializeCdmModule_1
// We maintain this macro for backward compatibility only.
#define INITIALIZE_CDM_MODULE InitializeCdmModule
extern "C" {
CDM_EXPORT void INITIALIZE_CDM_MODULE();
CDM_EXPORT void InitializeCdmModule();
CDM_EXPORT void DeinitializeCdmModule();
@@ -62,38 +60,47 @@ typedef void* (*GetCdmHostFunc)(int host_interface_version, void* user_data);
// object.
CDM_EXPORT void* CreateCdmInstance(
int cdm_interface_version,
const char* key_system, int key_system_size,
const char* key_system, uint32_t key_system_size,
GetCdmHostFunc get_cdm_host_func, void* user_data);
CDM_EXPORT int GetCdmVersion();
CDM_EXPORT const char* GetCdmVersion();
}
namespace cdm {
class AudioFrames;
class DecryptedBlock;
class VideoFrame;
class Host_1;
class Host_4;
enum Status {
kSuccess = 0,
kNeedMoreData, // Decoder needs more data to produce a decoded frame/sample.
kNoKey, // The required decryption key is not available.
kSessionError, // Session management error.
kDecryptError, // Decryption failed.
kDecodeError, // Error decoding audio or video.
kRetry, // Buffer temporarily cannot be accepted. Retry after a short delay.
kNeedsDeviceCertificate // Requires Device Certificate for content licensing
kNoKey = 2, // The required decryption key is not available.
kSessionError = 3, // Session management error.
kDecryptError = 4, // Decryption failed.
kDecodeError = 5, // Error decoding audio or video.
kRetry = 6, // Buffer temporarily cannot be accepted, delay and retry.
kNeedsDeviceCertificate = 7 // A certificate is required for licensing.
};
// This must be consistent with MediaKeyError defined in the
// Encrypted media Extensions (EME) specification: http://goo.gl/3Df8h
// Encrypted media Extensions (EME) specification: http://goo.gl/IBjNCP
enum MediaKeyError {
kUnknownError = 1,
kClientError,
kServiceError,
kOutputError,
kHardwareChangeError,
kDomainError
kClientError = 2,
kOutputError = 4,
};
// The type of session to create. The valid types are defined in the spec:
// http://goo.gl/vmc3pd
enum SessionType {
kTemporary = 0,
kPersistent = 1,
kProvisioning = 2,
};
// The type of stream. Used in DecryptDecodeAndRender.
enum StreamType {
kStreamTypeAudio = 0,
kStreamTypeVideo = 1
};
// An input buffer can be split into several continuous subsamples.
@@ -118,11 +125,11 @@ enum MediaKeyError {
// | clear1 | decrypted1| clear2 | decrypted2 | clear3 | decrypted3 |
//
struct SubsampleEntry {
SubsampleEntry(int32_t clear_bytes, int32_t cipher_bytes)
SubsampleEntry(uint32_t clear_bytes, uint32_t cipher_bytes)
: clear_bytes(clear_bytes), cipher_bytes(cipher_bytes) {}
int32_t clear_bytes;
int32_t cipher_bytes;
uint32_t clear_bytes;
uint32_t cipher_bytes;
};
// Represents an input buffer to be decrypted (and possibly decoded). It
@@ -141,116 +148,173 @@ struct InputBuffer {
timestamp(0) {}
const uint8_t* data; // Pointer to the beginning of the input data.
int32_t data_size; // Size (in bytes) of |data|.
uint32_t data_size; // Size (in bytes) of |data|.
int32_t data_offset; // Number of bytes to be discarded before decryption.
uint32_t data_offset; // Number of bytes to be discarded before decryption.
const uint8_t* key_id; // Key ID to identify the decryption key.
int32_t key_id_size; // Size (in bytes) of |key_id|.
uint32_t key_id_size; // Size (in bytes) of |key_id|.
const uint8_t* iv; // Initialization vector.
int32_t iv_size; // Size (in bytes) of |iv|.
uint32_t iv_size; // Size (in bytes) of |iv|.
const struct SubsampleEntry* subsamples;
int32_t num_subsamples; // Number of subsamples in |subsamples|.
uint32_t num_subsamples; // Number of subsamples in |subsamples|.
int64_t timestamp; // Presentation timestamp in microseconds.
};
struct AudioDecoderConfig {
enum AudioCodec {
kUnknownAudioCodec = 0,
kCodecVorbis,
kCodecAac
// Represents a buffer created by the Host.
class Buffer {
public:
// Destroys the buffer in the same context as it was created.
virtual void Destroy() = 0;
virtual int32_t Capacity() const = 0;
virtual uint8_t* Data() = 0;
virtual void SetSize(int32_t size) = 0;
virtual int32_t Size() const = 0;
protected:
Buffer() {}
virtual ~Buffer() {}
private:
Buffer(const Buffer&);
void operator=(const Buffer&);
};
// Represents a key-value map.
// Both created and destroyed by the Host.
// Data is filled in by the CDM.
// Need not be implemented if QueryKeyStatus() is not called.
class KeyValueMap {
public:
virtual void Set(const char* key, void* value, size_t value_size) = 0;
protected:
KeyValueMap() {}
virtual ~KeyValueMap() {}
private:
KeyValueMap(const KeyValueMap&);
void operator=(const KeyValueMap&);
};
// Represents a decrypted block that has not been decoded.
class DecryptedBlock {
public:
virtual void SetDecryptedBuffer(Buffer* buffer) = 0;
virtual Buffer* DecryptedBuffer() = 0;
virtual void SetTimestamp(int64_t timestamp) = 0;
virtual int64_t Timestamp() const = 0;
protected:
DecryptedBlock() {}
virtual ~DecryptedBlock() {}
};
// The FileIO interface provides a way for the CDM to store data in a file in
// persistent storage. This interface aims only at providing basic read/write
// capabilities and should not be used as a full fledged file IO API.
//
// All methods that report their result via calling a method on FileIOClient
// (currently, this is Open, Read, and Write) must call into FileIOClient on the
// same thread they were called on and must do so before returning. This
// restriction may be lifted in the future.
//
// Each domain (e.g. "example.com") and each CDM has it's own persistent
// storage. All instances of a given CDM associated with a given domain share
// the same persistent storage.
//
// Note to implementors of this interface:
// Per-origin storage and the ability for users to clear it are important.
// See http://www.w3.org/TR/encrypted-media/#privacy-storedinfo.
class FileIO {
public:
// Opens the file with |file_name| for read and write.
// FileIOClient::OnOpenComplete() will be called after the opening
// operation finishes.
// - When the file is opened by a CDM instance, it will be classified as "in
// use". In this case other CDM instances in the same domain may receive
// kInUse status when trying to open it.
// - |file_name| should not include path separators.
virtual void Open(const char* file_name, uint32_t file_name_size) = 0;
// Reads the contents of the file. FileIOClient::OnReadComplete() will be
// called with the read status. Read() should not be called if a previous
// Read() or Write() call is still pending; otherwise OnReadComplete() will
// be called with kInUse.
virtual void Read() = 0;
// Writes |data_size| bytes of |data| into the file.
// FileIOClient::OnWriteComplete() will be called with the write status.
// All existing contents in the file will be overwritten. Calling Write() with
// NULL |data| will clear all contents in the file. Write() should not be
// called if a previous Write() or Read() call is still pending; otherwise
// OnWriteComplete() will be called with kInUse.
virtual void Write(const uint8_t* data, uint32_t data_size) = 0;
// Closes the file if opened, destroys this FileIO object and releases any
// resources allocated. The CDM must call this method when it finished using
// this object. A FileIO object must not be used after Close() is called.
virtual void Close() = 0;
protected:
FileIO() {}
virtual ~FileIO() {}
};
// Responses to FileIO calls.
class FileIOClient {
public:
enum Status {
kSuccess = 0,
kInUse,
kError
};
AudioDecoderConfig()
: codec(kUnknownAudioCodec),
channel_count(0),
bits_per_channel(0),
samples_per_second(0),
extra_data(NULL),
extra_data_size(0) {}
// Response to a FileIO::Open() call with the open |status|.
virtual void OnOpenComplete(Status status) = 0;
AudioCodec codec;
int32_t channel_count;
int32_t bits_per_channel;
int32_t samples_per_second;
// Response to a FileIO::Read() call to provide |data_size| bytes of |data|
// read from the file.
// - kSuccess indicates that all contents of the file has been successfully
// read. In this case, 0 |data_size| means that the file is empty.
// - kInUse indicates that there are other read/write operations pending.
// - kError indicates read failure, e.g. the storage isn't open or cannot be
// fully read.
virtual void OnReadComplete(Status status,
const uint8_t* data, uint32_t data_size) = 0;
// Optional byte data required to initialize audio decoders, such as the
// vorbis setup header.
uint8_t* extra_data;
int32_t extra_data_size;
};
// Response to a FileIO::Write() call.
// - kSuccess indicates that all the data has been written into the file
// successfully.
// - kInUse indicates that there are other read/write operations pending.
// - kError indicates write failure, e.g. the storage isn't open or cannot be
// fully written. Upon write failure, the contents of the file should be
// regarded as corrupt and should not used.
virtual void OnWriteComplete(Status status) = 0;
// Surface formats based on FOURCC labels, see: http://www.fourcc.org/yuv.php
enum VideoFormat {
kUnknownVideoFormat = 0, // Unknown format value. Used for error reporting.
kYv12, // 12bpp YVU planar 1x1 Y, 2x2 VU samples.
kI420 // 12bpp YVU planar 1x1 Y, 2x2 UV samples.
};
struct Size {
Size() : width(0), height(0) {}
Size(int32_t width, int32_t height) : width(width), height(height) {}
int32_t width;
int32_t height;
};
struct VideoDecoderConfig {
enum VideoCodec {
kUnknownVideoCodec = 0,
kCodecVp8,
kCodecH264
};
enum VideoCodecProfile {
kUnknownVideoCodecProfile = 0,
kVp8ProfileMain,
kH264ProfileBaseline,
kH264ProfileMain,
kH264ProfileExtended,
kH264ProfileHigh,
kH264ProfileHigh10,
kH264ProfileHigh422,
kH264ProfileHigh444Predictive
};
VideoDecoderConfig()
: codec(kUnknownVideoCodec),
profile(kUnknownVideoCodecProfile),
format(kUnknownVideoFormat),
extra_data(NULL),
extra_data_size(0) {}
VideoCodec codec;
VideoCodecProfile profile;
VideoFormat format;
// Width and height of video frame immediately post-decode. Not all pixels
// in this region are valid.
Size coded_size;
// Optional byte data required to initialize video decoders, such as H.264
// AAVC data.
uint8_t* extra_data;
int32_t extra_data_size;
};
enum StreamType {
kStreamTypeAudio = 0,
kStreamTypeVideo = 1
protected:
FileIOClient() {}
virtual ~FileIOClient() {}
};
// ContentDecryptionModule interface that all CDMs need to implement.
// The interface is versioned for backward compatibility.
// Note: ContentDecryptionModule implementations must use the allocator
// provided in CreateCdmInstance() to allocate any Buffer that needs to
// be passed back to the caller. Implementations must call Buffer::Destroy()
// when a Buffer is created that will never be returned to the caller.
// CDM interfaces are versioned for backward compatibility.
// Note: ContentDecryptionModule implementations must use the Host
// to allocate any Buffer that needs to be passed back to the caller.
// Host implementations must call Buffer::Destroy() when a Buffer is created
// that will never be returned to the caller.
// Based on chromium's ContentDecryptionModule_1.
class ContentDecryptionModule_1 {
public:
static const int kVersion = 1002;
typedef Host_1 Host;
// Generates a |key_request| given |type| and |init_data|.
//
// Returns kSuccess if the key request was successfully generated, in which
@@ -296,9 +360,9 @@ class ContentDecryptionModule_1 {
virtual Status Decrypt(const InputBuffer& encrypted_buffer,
DecryptedBlock* decrypted_buffer) = 0;
// Decrypts the |encrypted_buffer|, decodes the decrypted buffer into a
// video frame, and passes the frame to the rendering FW/HW. No data
// is returned.
// Decrypts the |encrypted_buffer|, decodes the decrypted buffer, and passes
// the video frame or audio samples to the rendering FW/HW. No data is
// returned to the caller.
//
// Returns kSuccess if decryption, decoding, and rendering all succeeded.
// Returns kNoKey if the CDM did not have the necessary decryption key
@@ -312,9 +376,9 @@ class ContentDecryptionModule_1 {
virtual Status DecryptDecodeAndRenderFrame(
const InputBuffer& encrypted_buffer) = 0;
// Decrypts the |encrypted_buffer|, decodes the decrypted buffer into
// audio frames, and passes the samples to the rendering FW/HW. No
// data is returned.
// Decrypts the |encrypted_buffer|, decodes the decrypted buffer into a
// video frame, and passes the frame to the rendering FW/HW. No data
// is returned.
//
// Returns kSuccess if decryption, decoding, and rendering all succeeded.
// Returns kNoKey if the CDM did not have the necessary decryption key
@@ -331,11 +395,11 @@ class ContentDecryptionModule_1 {
// Destroys the object in the same context as it was created.
virtual void Destroy() = 0;
// Provisioning related methods
// Provisioning-related methods.
virtual Status GetProvisioningRequest(
std::string* request, std::string* default_url) = 0;
virtual cdm::Status HandleProvisioningResponse(
virtual Status HandleProvisioningResponse(
std::string& response) = 0;
protected:
@@ -343,36 +407,139 @@ class ContentDecryptionModule_1 {
virtual ~ContentDecryptionModule_1() {}
};
const int kWidevineCdmInterfaceVersion_1 = 1002;
typedef ContentDecryptionModule_1 ContentDecryptionModule;
const int kCdmInterfaceVersion = kWidevineCdmInterfaceVersion_1;
// Represents a buffer created by Allocator implementations.
class Buffer {
// Based on chromium's ContentDecryptionModule_4 and ContentDecryptionModule_5.
class ContentDecryptionModule_4 {
public:
// Destroys the buffer in the same context as it was created.
static const int kVersion = 1004;
typedef Host_4 Host;
// The non-decryption methods on this class, such as CreateSession(),
// get passed a |session_id| for a MediaKeySession object. It must be used in
// the reply via Host methods (e.g. Host::OnSessionMessage()).
// Note: |session_id| is different from MediaKeySession's sessionId attribute,
// which is referred to as |web_session_id| in this file.
// Creates a new session and generates a key request given |init_data| and
// |session_type|. OnSessionCreated() will be called with a web session ID
// once the session exists. OnSessionMessage() will subsequently be called
// with the key request. A session represents hardware crypto resources,
// (if any exist for the platform), which may be in limited supply.
// For sessions of type kProvisioning, |mime_type| and |init_data| will be
// ignored and may be NULL.
virtual void CreateSession(uint32_t session_id,
const char* mime_type, uint32_t mime_type_size,
const uint8_t* init_data, uint32_t init_data_size,
SessionType session_type) = 0;
// Creates a new session and loads a previous persistent session into it that
// has a web session ID of |web_session_id|. OnSessionCreated() will be
// called once the session is loaded.
virtual void LoadSession(
uint32_t session_id,
const char* web_session_id, uint32_t web_session_id_length) = 0;
// Updates the session with |response|.
virtual void UpdateSession(
uint32_t session_id,
const uint8_t* response, uint32_t response_size) = 0;
// Tests whether |key_id| is known to any current session.
virtual bool IsKeyValid(const uint8_t* key_id, int key_id_size) = 0;
// Releases the resources for the session |session_id|.
// After calling this, it is invalid to refer to this session any more.
// If any hardware crypto resources were being used by this session, they will
// be released.
// If this session was a persistent session, this will NOT delete the
// persisted data. The persisted data will be preserved so that the session
// can be reloaded later with LoadSession(). To delete the persisted session,
// use RemoveSession().
virtual void ReleaseSession(uint32_t session_id) = 0;
// Creates a new session and generates a key release request for the
// existing persistent session identified by |web_session_id|.
// OnSessionCreated() will be called once the session exists.
// OnSessionMessage() will subsequently be called with the key release
// request.
virtual void RemoveSession(
uint32_t session_id,
const char* web_session_id, uint32_t web_session_id_length) = 0;
// Signals to the CDM that it should use server certificates to protect the
// privacy of the user. The primary use of this is when the application
// driving the CDM is untrusted code, such as when a web browser allows a web
// page's JavaScript to access the CDM. By using server certificates to
// encrypt communication with the license server, device-identifying
// information cannot be extracted from the license exchange process by a
// malicious caller.
// Unless you also call SetServerCertificate() to set a pre-cached server
// certificate, the CDM will perform a certificate exchange with the server
// prior to any key exchanges.
// This method may not be called if any sessions are open. It is typically
// called before any sessions have been opened, but may also be called if all
// open sessions have been released.
// Note that calling SetServerCertificate() implicitly calls this method as
// well.
virtual Status UsePrivacyMode() = 0;
// Provides a server certificate to be used to encrypt messages to the
// license server. Calling this is like calling UsePrivacyMode(), except that
// because the certificate is provided up-front, the CDM does not have to
// perform a certificate exchange with the server.
// This method may not be called if any sessions are open. It is typically
// called before any sessions have been opened, but may also be called if all
// open sessions have been released.
// Note that calling this method also implicitly calls UsePrivacyMode().
virtual Status SetServerCertificate(
const uint8_t* server_certificate_data,
uint32_t server_certificate_data_size) = 0;
// Performs scheduled operation with |context| when the timer fires.
virtual void TimerExpired(void* context) = 0;
// Decrypts the |encrypted_buffer|.
//
// Returns kSuccess if decryption succeeded, in which case the callee
// should have filled the |decrypted_buffer| and passed the ownership of
// |data| in |decrypted_buffer| to the caller.
// Returns kNoKey if the CDM did not have the necessary decryption key
// to decrypt.
// Returns kDecryptError if any other error happened.
// If the return value is not kSuccess, |decrypted_buffer| should be ignored
// by the caller.
virtual Status Decrypt(const InputBuffer& encrypted_buffer,
DecryptedBlock* decrypted_buffer) = 0;
// Decrypts the |encrypted_buffer|, decodes the decrypted buffer, and passes
// the video or audio frames to the rendering FW/HW. No data is returned to
// the caller.
//
// Returns kSuccess if decryption, decoding, and rendering all succeeded.
// Returns kNoKey if the CDM did not have the necessary decryption key
// to decrypt.
// Returns kRetry if |encrypted_buffer| cannot be accepted (e.g, video
// pipeline is full). Caller should retry after a short delay.
// Returns kDecryptError if any decryption error happened.
// Returns kDecodeError if any decoding error happened.
virtual Status DecryptDecodeAndRender(const InputBuffer& encrypted_buffer,
StreamType stream_type) = 0;
// Destroys the object in the same context as it was created.
virtual void Destroy() = 0;
virtual int32_t Capacity() const = 0;
virtual uint8_t* Data() = 0;
virtual void SetSize(int32_t size) = 0;
virtual int32_t Size() const = 0;
protected:
Buffer() {}
virtual ~Buffer() {}
private:
Buffer(const Buffer&);
void operator=(const Buffer&);
ContentDecryptionModule_4() {}
virtual ~ContentDecryptionModule_4() {}
};
// Host interface that the CDM can call into to access browser side services.
// Host interfaces are versioned for backward compatibility. CDM should use
// HostFactory object to request a Host interface of a particular version.
// Host interfaces are versioned for backward compatibility.
// Based on chromium's Host_1.
class Host_1 {
public:
static const int kVersion = 1002;
// Returns a Buffer* containing non-zero members upon success, or NULL on
// failure. The caller owns the Buffer* after this call. The buffer is not
// guaranteed to be zero initialized. The capacity of the allocated Buffer
@@ -418,77 +585,69 @@ class Host_1 {
virtual ~Host_1() {}
};
const int kWidevineHostInterfaceVersion_1 = 1002;
typedef Host_1 Host;
const int kHostInterfaceVersion = kWidevineHostInterfaceVersion_1;
// Represents a decrypted block that has not been decoded.
class DecryptedBlock {
// Based on chromium's Host_4 and Host_5.
class Host_4 {
public:
virtual void SetDecryptedBuffer(Buffer* buffer) = 0;
virtual Buffer* DecryptedBuffer() = 0;
static const int kVersion = 1004;
virtual void SetTimestamp(int64_t timestamp) = 0;
virtual int64_t Timestamp() const = 0;
// Returns a Buffer* containing non-zero members upon success, or NULL on
// failure. The caller owns the Buffer* after this call. The buffer is not
// guaranteed to be zero initialized. The capacity of the allocated Buffer
// is guaranteed to be not less than |capacity|.
virtual Buffer* Allocate(uint32_t capacity) = 0;
// Requests the host to call ContentDecryptionModule::TimerFired() |delay_ms|
// from now with |context|.
virtual void SetTimer(int64_t delay_ms, void* context) = 0;
// Returns the current epoch wall time in seconds.
virtual double GetCurrentWallTimeInSeconds() = 0;
// Called by the CDM when a session is created or loaded and the value for the
// MediaKeySession's sessionId attribute is available (|web_session_id|).
// This must be called before OnSessionMessage() or OnSessionUpdated() is
// called for |session_id|. |web_session_id_length| should not include null
// termination.
// When called in response to LoadSession(), the |web_session_id| must be the
// same as the |web_session_id| passed in LoadSession().
virtual void OnSessionCreated(
uint32_t session_id,
const char* web_session_id, uint32_t web_session_id_length) = 0;
// Called by the CDM when it has a message for session |session_id|.
// Length parameters should not include null termination.
virtual void OnSessionMessage(
uint32_t session_id,
const char* message, uint32_t message_length,
const char* destination_url, uint32_t destination_url_length) = 0;
// Called by the CDM when session |session_id| has been updated.
virtual void OnSessionUpdated(uint32_t session_id) = 0;
// Called by the CDM when session |session_id| is closed.
virtual void OnSessionClosed(uint32_t session_id) = 0;
// Called by the CDM when an error occurs in session |session_id|.
virtual void OnSessionError(uint32_t session_id,
Status error_code,
uint32_t system_code) = 0;
// Creates a FileIO object from the host to do file IO operation. Returns NULL
// if a FileIO object cannot be obtained. Once a valid FileIO object is
// returned, |client| must be valid until FileIO::Close() is called. The
// CDM can call this method multiple times to operate on different files.
virtual FileIO* CreateFileIO(FileIOClient* client) = 0;
protected:
DecryptedBlock() {}
virtual ~DecryptedBlock() {}
Host_4() {}
virtual ~Host_4() {}
};
class VideoFrame {
public:
enum VideoPlane {
kYPlane = 0,
kUPlane = 1,
kVPlane = 2,
kMaxPlanes = 3,
};
typedef ContentDecryptionModule_1 ContentDecryptionModule;
const int kCdmInterfaceVersion = ContentDecryptionModule::kVersion;
virtual void SetFormat(VideoFormat format) = 0;
virtual VideoFormat Format() const = 0;
virtual void SetSize(cdm::Size size) = 0;
virtual cdm::Size Size() const = 0;
virtual void SetFrameBuffer(Buffer* frame_buffer) = 0;
virtual Buffer* FrameBuffer() = 0;
virtual void SetPlaneOffset(VideoPlane plane, int32_t offset) = 0;
virtual int32_t PlaneOffset(VideoPlane plane) = 0;
virtual void SetStride(VideoPlane plane, int32_t stride) = 0;
virtual int32_t Stride(VideoPlane plane) = 0;
virtual void SetTimestamp(int64_t timestamp) = 0;
virtual int64_t Timestamp() const = 0;
protected:
VideoFrame() {}
virtual ~VideoFrame() {}
};
// Represents decrypted and decoded audio frames. AudioFrames can contain
// multiple audio output buffers, which are serialized into this format:
//
// |<------------------- serialized audio buffer ------------------->|
// | int64_t timestamp | int64_t length | length bytes of audio data |
//
// For example, with three audio output buffers, the AudioFrames will look
// like this:
//
// |<----------------- AudioFrames ------------------>|
// | audio buffer 0 | audio buffer 1 | audio buffer 2 |
class AudioFrames {
public:
virtual void SetFrameBuffer(Buffer* buffer) = 0;
virtual Buffer* FrameBuffer() = 0;
protected:
AudioFrames() {}
virtual ~AudioFrames() {}
};
typedef ContentDecryptionModule::Host Host;
const int kHostInterfaceVersion = Host::kVersion;
} // namespace cdm