Initial import of Widevine Common Encryption DRM engine
Builds libwvmdrmengine.so, which is loaded by the new MediaDrm APIs to support playback of Widevine/CENC protected content. Change-Id: I6f57dd37083dfd96c402cb9dd137c7d74edc8f1c
This commit is contained in:
178
libwvdrmengine/cdm/core/src/crypto_engine.cpp
Normal file
178
libwvdrmengine/cdm/core/src/crypto_engine.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
// Copyright 2012 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Crypto - wrapper classes for OEMCrypto interface
|
||||
//
|
||||
|
||||
#include "crypto_engine.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "log.h"
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
CryptoEngine* CryptoEngine::crypto_engine_ = NULL;
|
||||
Lock CryptoEngine::crypto_engine_lock_;
|
||||
|
||||
// wrapper classes for OEMCrypto interface
|
||||
// CryptoEngine -- top-level interface
|
||||
// CryptoSession -- session-specific interface
|
||||
// CryptoKey -- key interface
|
||||
|
||||
// CryptoEngine methods
|
||||
|
||||
CryptoEngine::CryptoEngine() : initialized_(false) {}
|
||||
|
||||
CryptoEngine::~CryptoEngine() {
|
||||
if (initialized_) {
|
||||
Terminate();
|
||||
}
|
||||
|
||||
CryptoSessionMap::iterator i(sessions_.begin());
|
||||
for (; i != sessions_.end(); ++i)
|
||||
delete i->second;
|
||||
sessions_.clear();
|
||||
}
|
||||
|
||||
// get the instance of OEMCrypto Client
|
||||
CryptoEngine* CryptoEngine::GetInstance() {
|
||||
if (NULL == crypto_engine_) {
|
||||
crypto_engine_ = CreateSingleton();
|
||||
}
|
||||
return crypto_engine_;
|
||||
}
|
||||
|
||||
CryptoEngine* CryptoEngine::CreateSingleton() {
|
||||
AutoLock auto_lock(crypto_engine_lock_);
|
||||
if (NULL == crypto_engine_) {
|
||||
crypto_engine_ = new CryptoEngine;
|
||||
}
|
||||
return crypto_engine_;
|
||||
}
|
||||
|
||||
void CryptoEngine::DeleteInstance() {
|
||||
if (NULL != crypto_engine_) {
|
||||
delete crypto_engine_;
|
||||
LOGV("CryptoEngine::DeleteInstance");
|
||||
crypto_engine_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool CryptoEngine::Init() {
|
||||
LOGV("CryptoEngine::Init: Lock");
|
||||
AutoLock auto_lock(crypto_lock_);
|
||||
if (!initialized_) {
|
||||
OEMCryptoResult result = OEMCrypto_Initialize();
|
||||
initialized_ = (OEMCrypto_SUCCESS == result);
|
||||
}
|
||||
return initialized_;
|
||||
}
|
||||
|
||||
bool CryptoEngine::Terminate() {
|
||||
DestroySessions();
|
||||
LOGV("CryptoEngine::Terminate: Lock");
|
||||
AutoLock auto_lock(crypto_lock_);
|
||||
OEMCryptoResult result = OEMCrypto_Terminate();
|
||||
if (OEMCrypto_SUCCESS == result) {
|
||||
initialized_ = false;
|
||||
}
|
||||
return !initialized_;
|
||||
}
|
||||
|
||||
bool CryptoEngine::ValidateKeybox() {
|
||||
LOGV("CryptoEngine::ValidateKeybox: Lock");
|
||||
AutoLock auto_lock(crypto_lock_);
|
||||
OEMCryptoResult result = OEMCrypto_IsKeyboxValid();
|
||||
return (OEMCrypto_SUCCESS == result);
|
||||
}
|
||||
|
||||
CryptoSession* CryptoEngine::CreateSession(const CdmSessionId& session_id) {
|
||||
LOGV("CryptoEngine::CreateSession: SLock");
|
||||
AutoLock auto_lock(sessions_lock_);
|
||||
if (0 == sessions_.size()) {
|
||||
if (!Init()) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CryptoSessionMap::iterator it = sessions_.find(session_id);
|
||||
if (it != sessions_.end()) {
|
||||
LOGE("CryptoEngine::CreateSession : Duplicate session ID.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CryptoSession* new_session = new CryptoSession(session_id);
|
||||
if (!new_session) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!new_session->Open()) {
|
||||
delete new_session;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sessions_[session_id] = new_session;
|
||||
return new_session;
|
||||
}
|
||||
|
||||
CryptoSession* CryptoEngine::FindSessionInternal(
|
||||
const CdmSessionId& session_id) {
|
||||
// must hold sessions_lock_
|
||||
CryptoSessionMap::iterator it = sessions_.find(session_id);
|
||||
if (it != sessions_.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CryptoSession* CryptoEngine::FindSession(const CdmSessionId& session_id) {
|
||||
LOGV("CryptoEngine::FindSession: SLock");
|
||||
AutoLock auto_lock(sessions_lock_);
|
||||
return FindSessionInternal(session_id);
|
||||
}
|
||||
|
||||
bool CryptoEngine::DestroySession(const CdmSessionId& session_id) {
|
||||
LOGV("CryptoEngine::DestroySession: SLock");
|
||||
AutoLock auto_lock(sessions_lock_);
|
||||
if (0 == sessions_.size()) {
|
||||
return false;
|
||||
}
|
||||
CryptoSession* session = FindSessionInternal(session_id);
|
||||
if (session) {
|
||||
delete session;
|
||||
sessions_.erase(session_id);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CryptoEngine::DestroySessions() {
|
||||
for (CryptoSessionMap::iterator it = sessions_.begin();
|
||||
it != sessions_.end(); ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
sessions_.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CryptoEngine::GetToken(std::string* token) {
|
||||
LOGV("CryptoEngine::GetToken: Lock");
|
||||
AutoLock auto_lock(crypto_lock_);
|
||||
if (!token) {
|
||||
LOGE("CryptoEngine::GetToken : No token passed to method.");
|
||||
return false;
|
||||
}
|
||||
uint8_t buf[72];
|
||||
size_t buflen = 72;
|
||||
OEMCryptoResult sts = OEMCrypto_GetKeyData(buf, &buflen);
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
return false;
|
||||
}
|
||||
token->assign((const char*)buf, (size_t)buflen);
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // namespace wvcdm
|
||||
Reference in New Issue
Block a user