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:
Jeff Tinker
2013-03-21 17:39:02 -07:00
parent 38334efbe7
commit 1a8aa0dd05
211 changed files with 51913 additions and 144 deletions

View File

@@ -0,0 +1,257 @@
//
// Copyright 2013 Google Inc. All Rights Reserved.
//
//#define LOG_NDEBUG 0
#define LOG_TAG "WVCdm"
#include <utils/Log.h>
#include "WVDrmPlugin.h"
#include <string>
#include <vector>
#include "utils/Errors.h"
#include "wv_cdm_constants.h"
namespace wvdrm {
using namespace android;
using namespace std;
using namespace wvcdm;
WVDrmPlugin::WVDrmPlugin(WvContentDecryptionModule* cdm) : mCDM(cdm) {}
status_t WVDrmPlugin::openSession(Vector<uint8_t>& sessionId) {
CdmSessionId cdmSessionId;
CdmResponseType res = mCDM->OpenSession("com.widevine", &cdmSessionId);
if (res != wvcdm::NO_ERROR) {
return android::UNKNOWN_ERROR;
}
sessionId.clear();
sessionId.appendArray(reinterpret_cast<const uint8_t*>(cdmSessionId.data()),
cdmSessionId.size());
return android::OK;
}
status_t WVDrmPlugin::closeSession(const Vector<uint8_t>& sessionId) {
CdmSessionId cdmSessionId(sessionId.begin(), sessionId.end());
CdmResponseType res = mCDM->CloseSession(cdmSessionId);
if (res == wvcdm::NO_ERROR) {
return android::OK;
} else {
return android::UNKNOWN_ERROR;
}
}
status_t WVDrmPlugin::getLicenseRequest(
const Vector<uint8_t>& sessionId,
const Vector<uint8_t>& initData,
const String8& mimeType,
LicenseType licenseType,
const KeyedVector<String8, String8>& optionalParameters,
Vector<uint8_t>& request,
String8& defaultUrl) {
CdmLicenseType cdmLicenseType;
if (licenseType == kLicenseType_Offline) {
cdmLicenseType = kLicenseTypeOffline;
} else if (licenseType == kLicenseType_Streaming) {
cdmLicenseType = kLicenseTypeStreaming;
} else {
return BAD_TYPE;
}
CdmSessionId cdmSessionId(sessionId.begin(), sessionId.end());
CdmInitData cdmInitData(initData.begin(), initData.end());
// TODO: Do something with mimeType?
CdmNameValueMap cdmParameters;
for (size_t i = 0; i < optionalParameters.size(); ++i) {
const String8& key = optionalParameters.keyAt(i);
const String8& value = optionalParameters.valueAt(i);
string cdmKey(key.string(), key.size());
string cdmValue(value.string(), value.size());
cdmParameters[cdmKey] = cdmValue;
}
CdmKeyMessage keyRequest;
CdmResponseType res = mCDM->GenerateKeyRequest(cdmSessionId, cdmInitData,
cdmLicenseType,
cdmParameters, &keyRequest);
if (res != wvcdm::KEY_MESSAGE) {
return android::UNKNOWN_ERROR;
}
// TODO: Do something more with defaultUrl?
defaultUrl.clear();
request.clear();
request.appendArray(reinterpret_cast<const uint8_t*>(keyRequest.data()),
keyRequest.size());
return android::OK;
}
status_t WVDrmPlugin::provideLicenseResponse(
const Vector<uint8_t>& sessionId,
const Vector<uint8_t>& response) {
CdmSessionId cdmSessionId(sessionId.begin(), sessionId.end());
CdmKeyResponse cdmResponse(response.begin(), response.end());
CdmResponseType res = mCDM->AddKey(cdmSessionId, cdmResponse);
if (res == wvcdm::KEY_ADDED || res == wvcdm::NO_ERROR) {
return android::OK;
} else {
return android::UNKNOWN_ERROR;
}
}
status_t WVDrmPlugin::removeLicense(const Vector<uint8_t>& sessionId) {
CdmSessionId cdmSessionId(sessionId.begin(), sessionId.end());
CdmResponseType res = mCDM->CancelKeyRequest(cdmSessionId);
if (res == wvcdm::NO_ERROR) {
return android::OK;
} else {
return android::UNKNOWN_ERROR;
}
}
status_t WVDrmPlugin::queryLicenseStatus(
const Vector<uint8_t>& sessionId,
KeyedVector<String8, String8>& infoMap) const {
CdmSessionId cdmSessionId(sessionId.begin(), sessionId.end());
CdmNameValueMap cdmLicenseInfo;
CdmResponseType res = mCDM->QueryKeyStatus(cdmSessionId, &cdmLicenseInfo);
if (res != wvcdm::NO_ERROR) {
return android::UNKNOWN_ERROR;
}
infoMap.clear();
for (CdmNameValueMap::const_iterator iter = cdmLicenseInfo.begin();
iter != cdmLicenseInfo.end();
++iter) {
const string& cdmKey = iter->first;
const string& cdmValue = iter->second;
String8 key(cdmKey.data(), cdmKey.size());
String8 value(cdmValue.data(), cdmValue.size());
infoMap.add(key, value);
}
return android::OK;
}
status_t WVDrmPlugin::getProvisionRequest(Vector<uint8_t>& request,
String8& defaultUrl) {
CdmProvisioningRequest cdmProvisionRequest;
string cdmDefaultUrl;
CdmResponseType res = mCDM->GetProvisioningRequest(&cdmProvisionRequest,
&cdmDefaultUrl);
if (res != wvcdm::NO_ERROR) {
return android::UNKNOWN_ERROR;
}
request.clear();
request.appendArray(reinterpret_cast<const uint8_t*>(
cdmProvisionRequest.data()),
cdmProvisionRequest.size());
defaultUrl.clear();
defaultUrl.setTo(cdmDefaultUrl.data(), cdmDefaultUrl.size());
return android::OK;
}
status_t WVDrmPlugin::provideProvisionResponse(
const Vector<uint8_t>& response) {
CdmProvisioningResponse cdmResponse(response.begin(), response.end());
CdmResponseType res = mCDM->HandleProvisioningResponse(cdmResponse);
if (res == wvcdm::NO_ERROR) {
return android::OK;
} else {
return android::UNKNOWN_ERROR;
}
}
status_t WVDrmPlugin::getSecureStops(List<Vector<uint8_t> >& secureStops) {
CdmSecureStops cdmSecureStops;
CdmResponseType res = mCDM->GetSecureStops(&cdmSecureStops);
if (res != wvcdm::NO_ERROR) {
return android::UNKNOWN_ERROR;
}
secureStops.clear();
for (CdmSecureStops::const_iterator iter = cdmSecureStops.begin();
iter != cdmSecureStops.end();
++iter) {
const string& cdmStop = *iter;
Vector<uint8_t> stop;
stop.appendArray(reinterpret_cast<const uint8_t*>(cdmStop.data()),
cdmStop.size());
secureStops.push_back(stop);
}
return android::OK;
}
status_t WVDrmPlugin::releaseSecureStops(const Vector<uint8_t>& ssRelease) {
CdmSecureStopReleaseMessage cdmMessage(ssRelease.begin(), ssRelease.end());
CdmResponseType res = mCDM->ReleaseSecureStops(cdmMessage);
if (res == wvcdm::NO_ERROR) {
return android::OK;
} else {
return android::UNKNOWN_ERROR;
}
}
status_t WVDrmPlugin::getPropertyString(const String8& name,
String8& value) const {
// TODO: Implement this function once the CDM query API is finalized.
return -EPERM;
}
status_t WVDrmPlugin::getPropertyByteArray(const String8& name,
Vector<uint8_t>& value) const {
// TODO: Implement this function once the CDM query API is finalized.
return -EPERM;
}
status_t WVDrmPlugin::setPropertyString(const String8& name,
const String8& value) {
// TODO: Implement this function once the CDM query API is finalized.
return -EPERM;
}
status_t WVDrmPlugin::setPropertyByteArray(const String8& name,
const Vector<uint8_t>& value) {
// TODO: Implement this function once the CDM query API is finalized.
return -EPERM;
}
// TODO: Hook up to event listener methods on CDM once Android API for
// eventing is finalized.
} // namespace wvdrm