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:
257
libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp
Normal file
257
libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp
Normal 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
|
||||
Reference in New Issue
Block a user