Builds libwvmdrmengine.so, which is loaded by the new MediaDrm APIs to support playback of Widevine/CENC protected content. Change-Id: I6f57dd37083dfd96c402cb9dd137c7d74edc8f1c
145 lines
4.1 KiB
C++
145 lines
4.1 KiB
C++
// Copyright 2012 Google Inc. All Rights Reserved.
|
|
// Author: jfore@google.com (Jeff Fore), rkuroiwa@google.com (Rintaro Kuroiwa)
|
|
|
|
#include "cdm_session.h"
|
|
|
|
#include <iostream>
|
|
|
|
#include "crypto_engine.h"
|
|
#include "log.h"
|
|
#include "string_conversions.h"
|
|
#include "clock.h"
|
|
#include "wv_cdm_constants.h"
|
|
|
|
namespace wvcdm {
|
|
|
|
typedef std::set<WvCdmEventListener*>::iterator CdmEventListenerIter;
|
|
|
|
bool CdmSession::Init() {
|
|
CryptoEngine* crypto_engine = CryptoEngine::GetInstance();
|
|
if (!crypto_engine) {
|
|
LOGE("CdmSession::Init failed to get CryptoEngine instance.");
|
|
return false;
|
|
}
|
|
|
|
crypto_session_ = crypto_engine->CreateSession(session_id_);
|
|
if (!crypto_session_) {
|
|
return false;
|
|
}
|
|
|
|
std::string token;
|
|
if (!crypto_engine->GetToken(&token)) return false;
|
|
|
|
return license_parser_.Init(token, crypto_session_);
|
|
}
|
|
|
|
bool CdmSession::DestroySession() {
|
|
if (crypto_session_) {
|
|
delete crypto_session_;
|
|
crypto_session_ = NULL;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool CdmSession::VerifySession(const CdmKeySystem& key_system,
|
|
const CdmInitData& init_data) {
|
|
// TODO(gmorgan): Compare key_system and init_data with value received
|
|
// during session startup - they should be the same.
|
|
return true;
|
|
}
|
|
|
|
CdmResponseType CdmSession::GenerateKeyRequest(const CdmInitData& init_data,
|
|
CdmKeyMessage* key_request) {
|
|
crypto_session_->Open();
|
|
if(!license_parser_.PrepareKeyRequest(init_data, key_request)) {
|
|
return KEY_ERROR;
|
|
} else {
|
|
return KEY_MESSAGE;
|
|
}
|
|
}
|
|
|
|
// AddKey() - Accept license response and extract key info.
|
|
CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) {
|
|
if (!license_parser_.HandleKeyResponse(key_response)) {
|
|
return KEY_ERROR;
|
|
} else {
|
|
return KEY_ADDED;
|
|
}
|
|
}
|
|
|
|
// CancelKeyRequest() - Cancel session.
|
|
CdmResponseType CdmSession::CancelKeyRequest() {
|
|
// TODO(gmorgan): cancel and clean up session
|
|
crypto_session_->Close();
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Decrypt() - Accept encrypted buffer and return decrypted data.
|
|
CdmResponseType CdmSession::Decrypt(const uint8_t* encrypted_buffer,
|
|
size_t encrypted_size,
|
|
size_t block_offset,
|
|
const std::string& iv,
|
|
const KeyId& key_id,
|
|
uint8_t* decrypted_buffer) {
|
|
return UNKNOWN_ERROR;
|
|
}
|
|
|
|
// License renewal
|
|
// GenerateRenewalRequest() - Construct valid renewal request for the current
|
|
// session keys.
|
|
CdmResponseType CdmSession::GenerateRenewalRequest(CdmKeyMessage* key_request) {
|
|
if(!license_parser_.PrepareKeyRenewalRequest(key_request)) {
|
|
return KEY_ERROR;
|
|
} else {
|
|
return KEY_MESSAGE;
|
|
}
|
|
}
|
|
|
|
// RenewKey() - Accept renewal response and update key info.
|
|
CdmResponseType CdmSession::RenewKey(const CdmKeyResponse& key_response) {
|
|
if (!license_parser_.HandleKeyRenewalResponse(key_response)) {
|
|
return KEY_ERROR;
|
|
} else {
|
|
return KEY_ADDED;
|
|
}
|
|
}
|
|
|
|
bool CdmSession::IsKeyValid(const KeyId& key_id) {
|
|
// TODO(gmorgan): lookup key and determine if valid.
|
|
// return (session_keys_.find(key_id) != session_keys_.end());
|
|
return true;
|
|
}
|
|
|
|
CdmSessionId CdmSession::GenerateSessionId() {
|
|
static const std::string kSessionPrefix("Session");
|
|
static int session_num = 1;
|
|
// TODO(rkuroiwa): Want this to be unique. Probably doing Hash(time+init_data)
|
|
// to get something that is reasonably unique.
|
|
return kSessionPrefix + IntToString(++session_num);
|
|
}
|
|
|
|
bool CdmSession::AttachEventListener(WvCdmEventListener* listener) {
|
|
std::pair<CdmEventListenerIter, bool> result = listeners_.insert(listener);
|
|
return result.second;
|
|
}
|
|
|
|
bool CdmSession::DetachEventListener(WvCdmEventListener* listener) {
|
|
return (listeners_.erase(listener) == 1);
|
|
}
|
|
|
|
void CdmSession::OnTimerEvent() {
|
|
bool event_occurred = false;
|
|
CdmEventType event;
|
|
|
|
policy_engine_.OnTimerEvent(GetCurrentTime(), event_occurred, event);
|
|
|
|
if (event_occurred) {
|
|
for (CdmEventListenerIter iter = listeners_.begin();
|
|
iter != listeners_.end(); ++iter) {
|
|
(*iter)->onEvent(session_id(), event);
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace wvcdm
|