Merge "Enable SPOIDs in Treble Widevine Glue Layer"

This commit is contained in:
John Bruce
2017-03-10 03:17:51 +00:00
committed by Android (Google) Code Review
4 changed files with 369 additions and 138 deletions

View File

@@ -46,6 +46,8 @@ LOCAL_C_INCLUDES := \
vendor/widevine/libwvdrmengine/mediadrm/include \
vendor/widevine/libwvdrmengine/oemcrypto/include \
LOCAL_STATIC_LIBRARIES := libcrypto_static
LOCAL_SHARED_LIBRARIES := \
android.hardware.drm@1.0 \
android.hidl.memory@1.0 \

View File

@@ -309,17 +309,39 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
const std::string mEmptyString;
} mPropertySet;
std::string mAppPackageName;
class CdmIdentifierBuilder {
public:
CdmIdentifierBuilder();
const CdmIdentifier& get_identifier();
const std::string& get_device_unique_id();
bool set_device_id(const std::string& id);
const std::string& app_package_name() { return mAppPackageName; }
bool set_app_package_name(const std::string& id);
const std::string& origin() const { return mCdmIdentifier.origin; }
bool set_origin(const std::string& id);
private:
WVDRM_DISALLOW_COPY_AND_ASSIGN(CdmIdentifierBuilder);
CdmIdentifier mCdmIdentifier;
bool mIsIdentifierSealed;
bool mUseSpoid;
std::string mDeviceId;
std::string mAppPackageName;
void calculateSpoid();
} mCdmIdentifierBuilder;
sp<wvcdm::WvContentDecryptionModule> const mCDM;
CdmIdentifier mCdmIdentifier;
WVGenericCryptoInterface* mCrypto;
map<CdmSessionId, CryptoSession> mCryptoSessions;
sp<IDrmPluginListener> mListener;
const std::string& appPackageName() const {
return mAppPackageName;
}
status_t queryProperty(const std::string& property,
std::string& stringValue) const;

View File

@@ -9,18 +9,22 @@
#include "WVDrmPlugin.h"
#include "TypeConvert.h"
#include "cutils/properties.h"
#include "mapErrors-inl.h"
#include "media/stagefright/MediaErrors.h"
#include "openssl/sha.h"
#include "utils/List.h"
#include "wv_cdm_constants.h"
namespace {
static const char* const kResetSecurityLevel = "";
static const char* const kEnable = "enable";
static const char* const kDisable = "disable";
static const std::string kPsshTag = "pssh";
static const char* const kSpecialUnprovisionResponse = "unprovision";
}
static const char* const kResetSecurityLevel = "";
static const char* const kEnable = "enable";
static const char* const kDisable = "disable";
static const std::string kPsshTag = "pssh";
static const char* const kSpecialUnprovisionResponse = "unprovision";
} // namespace
namespace wvdrm {
namespace hardware {
@@ -102,11 +106,15 @@ KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) {
WVDrmPlugin::WVDrmPlugin(const sp<WvContentDecryptionModule>& cdm,
const std::string& appPackageName,
WVGenericCryptoInterface* crypto)
: mAppPackageName(appPackageName),
mCDM(cdm),
mCdmIdentifier(kDefaultCdmIdentifier),
: mCDM(cdm),
mCrypto(crypto),
mCryptoSessions() {}
mCryptoSessions() {
mCdmIdentifierBuilder.set_app_package_name(appPackageName);
std::string deviceId;
queryProperty(wvcdm::QUERY_KEY_DEVICE_ID, deviceId);
mCdmIdentifierBuilder.set_device_id(deviceId);
}
WVDrmPlugin::~WVDrmPlugin() {
typedef map<CdmSessionId, CryptoSession>::iterator mapIterator;
@@ -127,7 +135,8 @@ Return<void> WVDrmPlugin::openSession(openSession_cb _hidl_cb) {
CdmSessionId cdmSessionId;
CdmResponseType res =
mCDM->OpenSession("com.widevine", &mPropertySet, mCdmIdentifier, this,
mCDM->OpenSession("com.widevine", &mPropertySet,
mCdmIdentifierBuilder.get_identifier(), this,
&cdmSessionId);
if (!isCdmResponseTypeSuccess(res)) {
@@ -269,8 +278,8 @@ Return<void> WVDrmPlugin::getKeyRequest(
CdmKeyRequest keyRequest;
CdmResponseType res = mCDM->GenerateKeyRequest(
cdmSessionId, cdmKeySetId, cdmInitDataType, processedInitData,
cdmLicenseType, cdmParameters, &mPropertySet, mCdmIdentifier,
&keyRequest);
cdmLicenseType, cdmParameters, &mPropertySet,
mCdmIdentifierBuilder.get_identifier(), &keyRequest);
requestType = ConvertFromCdmKeyRequestType(keyRequest.type);
@@ -412,11 +421,9 @@ Return<Status> WVDrmPlugin::restoreKeys(const hidl_vec<uint8_t>& sessionId,
std::string cdmCertAuthority = certificateAuthority;
CdmResponseType res = mCDM->GetProvisioningRequest(cdmCertType,
cdmCertAuthority,
mCdmIdentifier,
&cdmProvisionRequest,
&cdmDefaultUrl);
CdmResponseType res = mCDM->GetProvisioningRequest(
cdmCertType, cdmCertAuthority, mCdmIdentifierBuilder.get_identifier(),
&cdmProvisionRequest, &cdmDefaultUrl);
String8 defaultUrl;
Vector<uint8_t> request;
if (isCdmResponseTypeSuccess(res)) {
@@ -440,21 +447,21 @@ Return<void> WVDrmPlugin::provideProvisionResponse(
CdmProvisioningResponse cdmResponse(resp.begin(), resp.end());
if (cdmResponse == kSpecialUnprovisionResponse) {
if (mCdmIdentifier == kDefaultCdmIdentifier) {
if (mCdmIdentifierBuilder.get_identifier() == kDefaultCdmIdentifier) {
_hidl_cb(toStatus(kErrorNoOriginSpecified), toHidlVec(certificate),
toHidlVec(wrappedKey));
return Void();
}
_hidl_cb(toStatus(unprovision(mCdmIdentifier)), toHidlVec(certificate),
_hidl_cb(toStatus(unprovision(mCdmIdentifierBuilder.get_identifier())),
toHidlVec(certificate),
toHidlVec(wrappedKey));
return Void();
} else {
std::string cdmCertificate;
std::string cdmWrappedKey;
CdmResponseType res = mCDM->HandleProvisioningResponse(mCdmIdentifier,
cdmResponse,
&cdmCertificate,
&cdmWrappedKey);
CdmResponseType res = mCDM->HandleProvisioningResponse(
mCdmIdentifierBuilder.get_identifier(), cdmResponse, &cdmCertificate,
&cdmWrappedKey);
if (isCdmResponseTypeSuccess(res)) {
certificate = StrToVector(cdmCertificate);
wrappedKey = StrToVector(cdmWrappedKey);
@@ -594,7 +601,7 @@ Return<void> WVDrmPlugin::getPropertyString(const hidl_string& propertyName,
} else if (name == "appId") {
value = mPropertySet.app_id().c_str();
} else if (name == "origin") {
value = mCdmIdentifier.origin.c_str();
value = mCdmIdentifierBuilder.origin().c_str();
} else {
ALOGE("App requested unknown string property %s", name.string());
status = android::ERROR_DRM_CANNOT_HANDLE;
@@ -613,7 +620,7 @@ Return<void> WVDrmPlugin::getPropertyByteArray(
Vector<uint8_t> value;
if (name == "deviceUniqueId") {
status = queryProperty(wvcdm::QUERY_KEY_DEVICE_ID, value);
value = StrToVector(mCdmIdentifierBuilder.get_device_unique_id());
} else if (name == "provisioningUniqueId") {
status = queryProperty(wvcdm::QUERY_KEY_PROVISIONING_ID, value);
} else if (name == "serviceCertificate") {
@@ -696,7 +703,9 @@ Return<Status> WVDrmPlugin::setPropertyString(const hidl_string& propertyName,
ALOGE("App tried to set the origin while sessions are opened.");
return toStatus(kErrorSessionIsOpen);
} else {
mCdmIdentifier.origin = _value.string();
if (!mCdmIdentifierBuilder.set_origin(_value.string())) {
return Status::BAD_VALUE;
}
}
} else {
ALOGE("App set unknown string property %s", name.string());
@@ -1242,6 +1251,70 @@ status_t WVDrmPlugin::unprovision(const CdmIdentifier& identifier) {
}
}
// Implementation for the CdmIdentifierBuilder inner class
WVDrmPlugin::CdmIdentifierBuilder::CdmIdentifierBuilder()
: mCdmIdentifier(),
mIsIdentifierSealed(false),
mDeviceId(),
mAppPackageName() {
// Determine if this device supports SPOIDs.
int32_t firstApiLevel = property_get_int32("ro.product.first_api_level", 0);
if (firstApiLevel == 0) {
// First API Level is 0 on factory ROMs, but we can assume the current SDK
// version is the first if it's a factory ROM.
firstApiLevel = property_get_int32("ro.build.version.sdk", 0);
}
// TODO(juce): b/34548395 Make sure this API version is correct.
mUseSpoid = firstApiLevel >= 26; // Android O
}
const CdmIdentifier& WVDrmPlugin::CdmIdentifierBuilder::get_identifier() {
if (!mIsIdentifierSealed) calculateSpoid();
mIsIdentifierSealed = true;
return mCdmIdentifier;
}
const std::string& WVDrmPlugin::CdmIdentifierBuilder::get_device_unique_id() {
if (mUseSpoid) {
return get_identifier().spoid;
} else {
return mDeviceId;
}
}
bool WVDrmPlugin::CdmIdentifierBuilder::set_device_id(const std::string& id) {
if (mIsIdentifierSealed) return false;
mDeviceId = id;
return true;
}
bool WVDrmPlugin::CdmIdentifierBuilder::set_app_package_name(const std::string& id) {
if (mIsIdentifierSealed) return false;
mAppPackageName = id;
return true;
}
bool WVDrmPlugin::CdmIdentifierBuilder::set_origin(const std::string& id) {
if (mIsIdentifierSealed) return false;
mCdmIdentifier.origin = id;
return true;
}
void WVDrmPlugin::CdmIdentifierBuilder::calculateSpoid() {
if (mUseSpoid) {
uint8_t hash[SHA256_DIGEST_LENGTH];
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, mDeviceId.data(), mDeviceId.length());
SHA256_Update(&ctx, mAppPackageName.data(), mAppPackageName.length());
SHA256_Update(&ctx, origin().data(), origin().length());
SHA256_Final(hash, &ctx);
mCdmIdentifier.spoid =
std::string(reinterpret_cast<char*>(hash), SHA256_DIGEST_LENGTH);
}
}
} // namespace widevine
} // namespace V1_0
} // namespace drm

View File

@@ -18,6 +18,7 @@
#include <string>
#include "cdm_client_property_set.h"
#include "cutils/properties.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "media/stagefright/foundation/ABase.h"
@@ -121,6 +122,7 @@ const String8 kAppId("com.unittest.mock.app.id");
const uint8_t* const kUnprovisionResponse =
reinterpret_cast<const uint8_t*>("unprovision");
const size_t kUnprovisionResponseSize = 11;
const std::string kDeviceId = "0123456789ABCDEF";
}
class MockCDM : public WvContentDecryptionModule {
@@ -287,7 +289,9 @@ TEST_F(WVDrmPluginTest, OpensSessions) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
EXPECT_CALL(*cdm,
OpenSession(StrEq("com.widevine"), _, HasOrigin(EMPTY_ORIGIN), _, _))
@@ -302,6 +306,8 @@ TEST_F(WVDrmPluginTest, OpensSessions) {
EXPECT_CALL(*cdm, CloseSession(_))
.Times(AtLeast(0));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.openSession([&](Status status, hidl_vec<uint8_t> hSessionId) {
ASSERT_EQ(Status::OK, status);
sessionId.clear();
@@ -315,11 +321,14 @@ TEST_F(WVDrmPluginTest, ClosesSessions) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
EXPECT_CALL(*cdm, CloseSession(cdmSessionId))
.Times(1);
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
Status status = plugin.closeSession(toHidlVec(sessionId));
ASSERT_EQ(Status::OK, status);
}
@@ -328,11 +337,14 @@ TEST_F(WVDrmPluginTest, ClosesSessionWithoutReturningError) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
EXPECT_CALL(*cdm, CloseSession(cdmSessionId))
.WillOnce(testing::Return(wvcdm::SESSION_NOT_FOUND_1));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
Status status = plugin.closeSession(toHidlVec(sessionId));
ASSERT_EQ(Status::OK, status);
}
@@ -342,7 +354,9 @@ TEST_F(WVDrmPluginTest, DISABLED_GeneratesKeyRequests) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
static const size_t kInitDataSize = 128;
uint8_t initDataRaw[kInitDataSize];
@@ -473,6 +487,7 @@ TEST_F(WVDrmPluginTest, DISABLED_GeneratesKeyRequests) {
}
// Performs the actual tests
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
for (size_t i = 0; i < testSetCount; ++i)
{
const String8 mimeType(testSets[i].mimeType);
@@ -523,7 +538,9 @@ TEST_F(WVDrmPluginTest, AddsKeys) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
static const uint32_t kResponseSize = 256;
uint8_t responseRaw[kResponseSize];
@@ -552,6 +569,8 @@ TEST_F(WVDrmPluginTest, AddsKeys) {
Pointee(cdmKeySetId)))
.Times(1);
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.provideKeyResponse(
toHidlVec(sessionId), toHidlVec(response),
[&](Status status, hidl_vec<uint8_t> hKeySetId) {
@@ -575,7 +594,9 @@ TEST_F(WVDrmPluginTest, HandlesPrivacyCertCaseOfAddKey) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
sp<StrictMock<MockDrmPluginListener> > listener =
new StrictMock<MockDrmPluginListener>();
@@ -613,6 +634,8 @@ TEST_F(WVDrmPluginTest, HandlesPrivacyCertCaseOfAddKey) {
EXPECT_CALL(*cdm, AddKey(_, _, _))
.WillRepeatedly(testing::Return(wvcdm::NEED_KEY));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.openSession([&](Status status, hidl_vec<uint8_t> hSessionId) {
ASSERT_EQ(Status::OK, status);
sessionId.clear();
@@ -642,11 +665,14 @@ TEST_F(WVDrmPluginTest, RemovesKeys) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
EXPECT_CALL(*cdm, RemoveKeys(cdmSessionId))
.Times(1);
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
Status status = plugin.removeKeys(toHidlVec(sessionId));
ASSERT_EQ(Status::OK, status);
}
@@ -655,7 +681,9 @@ TEST_F(WVDrmPluginTest, RestoresKeys) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
static const size_t kKeySetIdSize = 32;
uint8_t keySetIdRaw[kKeySetIdSize];
@@ -670,6 +698,7 @@ TEST_F(WVDrmPluginTest, RestoresKeys) {
ElementsAreArray(keySetIdRaw, kKeySetIdSize)))
.Times(1);
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
Status status = plugin.restoreKeys(toHidlVec(sessionId), toHidlVec(keySetId));
ASSERT_EQ(Status::OK, status);
}
@@ -678,7 +707,9 @@ TEST_F(WVDrmPluginTest, QueriesKeyStatus) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
KeyedVector<String8, String8> expectedLicenseStatus;
CdmQueryMap cdmLicenseStatus;
@@ -694,6 +725,7 @@ TEST_F(WVDrmPluginTest, QueriesKeyStatus) {
.WillOnce(DoAll(SetArgPointee<1>(cdmLicenseStatus),
testing::Return(wvcdm::NO_ERROR)));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.queryKeyStatus(toHidlVec(sessionId),
[&](Status status, hidl_vec<KeyValue>(hLicenseStatus)) {
ASSERT_EQ(Status::OK, status);
@@ -713,7 +745,9 @@ TEST_F(WVDrmPluginTest, GetsProvisioningRequests) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
static const uint32_t kRequestSize = 256;
uint8_t requestRaw[kRequestSize];
@@ -731,6 +765,7 @@ TEST_F(WVDrmPluginTest, GetsProvisioningRequests) {
SetArgPointee<4>(kDefaultUrl),
testing::Return(wvcdm::NO_ERROR)));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.getProvisionRequest(
hidl_string(""), hidl_string(""),
[&](Status status, hidl_vec<uint8_t> hRequest, hidl_string defaultUrl) {
@@ -746,7 +781,9 @@ TEST_F(WVDrmPluginTest, HandlesProvisioningResponses) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
static const uint32_t kResponseSize = 512;
uint8_t responseRaw[kResponseSize];
@@ -766,6 +803,7 @@ TEST_F(WVDrmPluginTest, HandlesProvisioningResponses) {
Vector<uint8_t> cert;
Vector<uint8_t> key;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.provideProvisionResponse(
toHidlVec(response),
[&](Status status, hidl_vec<uint8_t> /* cert */,
@@ -778,13 +816,16 @@ TEST_F(WVDrmPluginTest, UnprovisionsDevice) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL1, HasOrigin(EMPTY_ORIGIN)))
.Times(1);
EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, HasOrigin(EMPTY_ORIGIN)))
.Times(1);
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
status_t res = plugin.unprovisionDevice();
ASSERT_EQ(android::OK, res);
}
@@ -793,7 +834,9 @@ TEST_F(WVDrmPluginTest, MuxesUnprovisioningErrors) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
// Tests that both Unprovisions are called even if one fails. Also tests that
// no matter which fails, the function always propagates the error.
@@ -806,6 +849,7 @@ TEST_F(WVDrmPluginTest, MuxesUnprovisioningErrors) {
.WillOnce(testing::Return(wvcdm::UNKNOWN_ERROR))
.WillOnce(testing::Return(wvcdm::UNKNOWN_ERROR));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
status_t res = plugin.unprovisionDevice();
ASSERT_NE(android::OK, res);
res = plugin.unprovisionDevice();
@@ -818,7 +862,9 @@ TEST_F(WVDrmPluginTest, UnprovisionsOrigin) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
Vector<uint8_t> cert;
Vector<uint8_t> key;
@@ -830,6 +876,8 @@ TEST_F(WVDrmPluginTest, UnprovisionsOrigin) {
EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, HasOrigin(kOrigin.string())))
.Times(1);
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
Status status = plugin.setPropertyString(hidl_string("origin"),
hidl_string(kOrigin));
ASSERT_EQ(Status::OK, status);
@@ -843,32 +891,48 @@ TEST_F(WVDrmPluginTest, UnprovisionsOrigin) {
}
TEST_F(WVDrmPluginTest, WillNotUnprovisionWithoutOrigin) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
// This test is only valid on SPOID-free devices. SPOID devices can
// unprovision without an origin because the empty-origin provisioning is
// not global.
int32_t firstApiLevel = property_get_int32("ro.product.first_api_level", 0);
if (firstApiLevel == 0) {
firstApiLevel = property_get_int32("ro.build.version.sdk", 0);
}
Vector<uint8_t> cert;
Vector<uint8_t> key;
Vector<uint8_t> specialResponse;
specialResponse.appendArray(kUnprovisionResponse, kUnprovisionResponseSize);
// TODO(juce): b/34548395 Make sure this API version is correct.
if (firstApiLevel >= 26) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
EXPECT_CALL(*cdm, Unprovision(_, _))
.Times(0);
Vector<uint8_t> cert;
Vector<uint8_t> key;
Vector<uint8_t> specialResponse;
specialResponse.appendArray(kUnprovisionResponse, kUnprovisionResponseSize);
plugin.provideProvisionResponse(
toHidlVec(specialResponse),
[&](Status status, hidl_vec<uint8_t> /* cert */,
hidl_vec<uint8_t> /* key */) {
EXPECT_NE(Status::OK, status);
});
EXPECT_CALL(*cdm, Unprovision(_, _))
.Times(0);
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.provideProvisionResponse(
toHidlVec(specialResponse),
[&](Status status, hidl_vec<uint8_t> /* cert */,
hidl_vec<uint8_t> /* key */) {
EXPECT_NE(Status::OK, status);
});
}
}
TEST_F(WVDrmPluginTest, MuxesOriginUnprovisioningErrors) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
Vector<uint8_t> cert;
Vector<uint8_t> key;
@@ -886,6 +950,8 @@ TEST_F(WVDrmPluginTest, MuxesOriginUnprovisioningErrors) {
.WillOnce(testing::Return(wvcdm::UNKNOWN_ERROR))
.WillOnce(testing::Return(wvcdm::UNKNOWN_ERROR));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
Status status = plugin.setPropertyString(hidl_string("origin"),
hidl_string(kOrigin));
ASSERT_EQ(Status::OK, status);
@@ -916,12 +982,9 @@ TEST_F(WVDrmPluginTest, GetsSecureStops) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
const char* app_id = "my_app_id";
Status status = plugin.setPropertyString(hidl_string("appId"),
hidl_string(app_id));
ASSERT_EQ(Status::OK, status);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
static const uint32_t kStopSize = 53;
static const uint32_t kStopCount = 7;
@@ -937,12 +1000,18 @@ TEST_F(WVDrmPluginTest, GetsSecureStops) {
cdmStops.push_back(std::string(stopsRaw[i], stopsRaw[i] + kStopSize));
}
const char* app_id = "my_app_id";
EXPECT_CALL(*cdm, GetUsageInfo(StrEq(app_id), _))
.WillOnce(DoAll(SetArgPointee<1>(cdmStops),
testing::Return(wvcdm::NO_ERROR)));
List<std::vector<uint8_t> > stops;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
Status status = plugin.setPropertyString(hidl_string("appId"),
hidl_string(app_id));
ASSERT_EQ(Status::OK, status);
plugin.getSecureStops([&](Status status, hidl_vec<SecureStop> hSecureStops) {
ASSERT_EQ(Status::OK, status);
@@ -972,15 +1041,19 @@ TEST_F(WVDrmPluginTest, ReleasesAllSecureStops) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
EXPECT_CALL(*cdm, ReleaseAllUsageInfo(StrEq("")))
.Times(1);
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
Status status = plugin.setPropertyString(hidl_string("appId"),
hidl_string(""));
ASSERT_EQ(Status::OK, status);
EXPECT_CALL(*cdm, ReleaseAllUsageInfo(StrEq("")))
.Times(1);
status = plugin.releaseAllSecureStops();
ASSERT_EQ(Status::OK, status);
}
@@ -989,7 +1062,9 @@ TEST_F(WVDrmPluginTest, ReleasesSecureStop) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
static const uint32_t kMessageSize = 128;
uint8_t messageRaw[kMessageSize];
@@ -1004,6 +1079,7 @@ TEST_F(WVDrmPluginTest, ReleasesSecureStop) {
kMessageSize)))
.Times(1);
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
Status status = plugin.releaseSecureStop(toHidlVec(message));
ASSERT_EQ(Status::OK, status);
}
@@ -1012,7 +1088,9 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
CdmQueryMap l1Map;
l1Map[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_L1;
@@ -1020,12 +1098,11 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
CdmQueryMap l3Map;
l3Map[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_L3;
static const std::string uniqueId = "The Universe";
static const std::string systemId = "42";
static const std::string systemId = "The Universe";
static const std::string provisioningId("Life\0&Everything", 16);
static const std::string openSessions = "15";
static const std::string maxSessions = "18";
static const std::string oemCryptoApiVersion = "10";
static const std::string openSessions = "42";
static const std::string maxSessions = "54";
static const std::string oemCryptoApiVersion = "13";
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SECURITY_LEVEL, _))
.WillOnce(DoAll(SetArgPointee<2>(QUERY_VALUE_SECURITY_LEVEL_L1),
@@ -1033,10 +1110,6 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
.WillOnce(DoAll(SetArgPointee<2>(QUERY_VALUE_SECURITY_LEVEL_L3),
testing::Return(wvcdm::NO_ERROR)));
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(uniqueId),
testing::Return(wvcdm::NO_ERROR)));
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SYSTEM_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(systemId),
testing::Return(wvcdm::NO_ERROR)));
@@ -1057,6 +1130,7 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
.WillOnce(DoAll(SetArgPointee<2>(oemCryptoApiVersion),
testing::Return(wvcdm::NO_ERROR)));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
String8 stringResult;
Vector<uint8_t> vectorResult;
@@ -1098,14 +1172,6 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
EXPECT_STREQ(QUERY_VALUE_SECURITY_LEVEL_L3.c_str(), stringResult.c_str());
});
plugin.getPropertyByteArray(
hidl_string("deviceUniqueId"),
[&](Status status, hidl_vec<uint8_t> vectorResult) {
ASSERT_EQ(Status::OK, status);
std::vector<uint8_t> id(vectorResult);
EXPECT_THAT(id, ElementsAreArray(uniqueId.data(), uniqueId.size()));
});
plugin.getPropertyString(
hidl_string("systemId"),
[&](Status status, hidl_string stringResult) {
@@ -1148,8 +1214,11 @@ TEST_F(WVDrmPluginTest, DoesNotGetUnknownProperties) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
String8 stringResult;
Vector<uint8_t> vectorResult;
@@ -1172,7 +1241,9 @@ TEST_F(WVDrmPluginTest, DoesNotSetUnknownProperties) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
static const uint32_t kValueSize = 32;
uint8_t valueRaw[kValueSize];
@@ -1180,6 +1251,7 @@ TEST_F(WVDrmPluginTest, DoesNotSetUnknownProperties) {
fread(valueRaw, sizeof(uint8_t), kValueSize, fp);
fclose(fp);
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
Vector<uint8_t> value;
value.appendArray(valueRaw, kValueSize);
@@ -1196,7 +1268,9 @@ TEST_F(WVDrmPluginTest, FailsGenericMethodsWithoutAnAlgorithmSet) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
Vector<uint8_t> keyId;
Vector<uint8_t> input;
@@ -1217,6 +1291,8 @@ TEST_F(WVDrmPluginTest, FailsGenericMethodsWithoutAnAlgorithmSet) {
EXPECT_CALL(*cdm, CloseSession(_))
.Times(AtLeast(0));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.openSession([&](Status status, hidl_vec<uint8_t> hSessionId) {
ASSERT_EQ(Status::OK, status);
sessionId.clear();
@@ -1262,7 +1338,9 @@ TEST_F(WVDrmPluginTest, CallsGenericEncrypt) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
static const size_t kDataSize = 256;
uint8_t keyIdRaw[KEY_ID_SIZE];
@@ -1309,6 +1387,8 @@ TEST_F(WVDrmPluginTest, CallsGenericEncrypt) {
EXPECT_CALL(*cdm, CloseSession(_))
.Times(AtLeast(0));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.openSession([&](Status status, hidl_vec<uint8_t> hSessionId) {
ASSERT_EQ(Status::OK, status);
sessionId.clear();
@@ -1329,7 +1409,9 @@ TEST_F(WVDrmPluginTest, CallsGenericDecrypt) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
static const size_t kDataSize = 256;
uint8_t keyIdRaw[KEY_ID_SIZE];
@@ -1376,6 +1458,8 @@ TEST_F(WVDrmPluginTest, CallsGenericDecrypt) {
EXPECT_CALL(*cdm, CloseSession(_))
.Times(AtLeast(0));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.openSession([&](Status status, hidl_vec<uint8_t> hSessionId) {
ASSERT_EQ(Status::OK, status);
sessionId.clear();
@@ -1396,7 +1480,9 @@ TEST_F(WVDrmPluginTest, CallsGenericSign) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
static const size_t kDataSize = 256;
uint8_t keyIdRaw[KEY_ID_SIZE];
@@ -1445,6 +1531,8 @@ TEST_F(WVDrmPluginTest, CallsGenericSign) {
EXPECT_CALL(*cdm, CloseSession(_))
.Times(AtLeast(0));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.openSession([&](Status status, hidl_vec<uint8_t> hSessionId) {
ASSERT_EQ(Status::OK, status);
sessionId.clear();
@@ -1458,7 +1546,7 @@ TEST_F(WVDrmPluginTest, CallsGenericSign) {
plugin.sign(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(message),
[&](Status status, hidl_vec<uint8_t> signature) {
ASSERT_EQ(Status::OK, status);
ASSERT_NE(0u, signature.size());
ASSERT_NE(0u, signature.size());
});
}
@@ -1466,7 +1554,9 @@ TEST_F(WVDrmPluginTest, CallsGenericVerify) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
static const size_t kDataSize = 256;
static const size_t kSignatureSize = 16;
@@ -1525,6 +1615,8 @@ TEST_F(WVDrmPluginTest, CallsGenericVerify) {
EXPECT_CALL(*cdm, CloseSession(_))
.Times(AtLeast(0));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.openSession([&](Status status, hidl_vec<uint8_t> hSessionId) {
ASSERT_EQ(Status::OK, status);
sessionId.clear();
@@ -1552,10 +1644,12 @@ TEST_F(WVDrmPluginTest, RegistersForEvents) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
// Provide expected behavior to support session creation
EXPECT_CALL(*cdm, OpenSession(StrEq("com.widevine"), _, _, &plugin, _))
EXPECT_CALL(*cdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
.Times(AtLeast(1))
.WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId),
testing::Return(wvcdm::NO_ERROR)));
@@ -1567,6 +1661,7 @@ TEST_F(WVDrmPluginTest, RegistersForEvents) {
EXPECT_CALL(*cdm, CloseSession(_))
.Times(AtLeast(0));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.openSession([&](Status status, hidl_vec<uint8_t> /* hSessionId */) {
ASSERT_EQ(Status::OK, status);
});
@@ -1575,36 +1670,39 @@ TEST_F(WVDrmPluginTest, RegistersForEvents) {
TEST_F(WVDrmPluginTest, UnregistersForAllEventsOnDestruction) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
uint8_t sessionIdRaw1[kSessionIdSize];
uint8_t sessionIdRaw2[kSessionIdSize];
FILE* fp = fopen("/dev/urandom", "r");
fread(sessionIdRaw1, sizeof(uint8_t), kSessionIdSize, fp);
fread(sessionIdRaw2, sizeof(uint8_t), kSessionIdSize, fp);
fclose(fp);
CdmSessionId cdmSessionId1(sessionIdRaw1, sessionIdRaw1 + kSessionIdSize);
CdmSessionId cdmSessionId2(sessionIdRaw2, sessionIdRaw2 + kSessionIdSize);
EXPECT_CALL(*cdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
.WillOnce(DoAll(SetArgPointee<4>(cdmSessionId1),
testing::Return(wvcdm::NO_ERROR)))
.WillOnce(DoAll(SetArgPointee<4>(cdmSessionId2),
testing::Return(wvcdm::NO_ERROR)));
EXPECT_CALL(*cdm, QueryOemCryptoSessionId(cdmSessionId1, _))
.WillOnce(Invoke(setSessionIdOnMap<4>));
EXPECT_CALL(*cdm, QueryOemCryptoSessionId(cdmSessionId2, _))
.WillOnce(Invoke(setSessionIdOnMap<5>));
EXPECT_CALL(*cdm, CloseSession(_))
.Times(AtLeast(0));
{
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
uint8_t sessionIdRaw1[kSessionIdSize];
uint8_t sessionIdRaw2[kSessionIdSize];
FILE* fp = fopen("/dev/urandom", "r");
fread(sessionIdRaw1, sizeof(uint8_t), kSessionIdSize, fp);
fread(sessionIdRaw2, sizeof(uint8_t), kSessionIdSize, fp);
fclose(fp);
CdmSessionId cdmSessionId1(sessionIdRaw1, sessionIdRaw1 + kSessionIdSize);
CdmSessionId cdmSessionId2(sessionIdRaw2, sessionIdRaw2 + kSessionIdSize);
EXPECT_CALL(*cdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
.WillOnce(DoAll(SetArgPointee<4>(cdmSessionId1),
testing::Return(wvcdm::NO_ERROR)))
.WillOnce(DoAll(SetArgPointee<4>(cdmSessionId2),
testing::Return(wvcdm::NO_ERROR)));
EXPECT_CALL(*cdm, QueryOemCryptoSessionId(cdmSessionId1, _))
.WillOnce(Invoke(setSessionIdOnMap<4>));
EXPECT_CALL(*cdm, QueryOemCryptoSessionId(cdmSessionId2, _))
.WillOnce(Invoke(setSessionIdOnMap<5>));
EXPECT_CALL(*cdm, CloseSession(_))
.Times(AtLeast(0));
plugin.openSession([&](Status status, hidl_vec<uint8_t> /* hSessionId */) {
ASSERT_EQ(Status::OK, status);
});
@@ -1620,7 +1718,9 @@ TEST_F(WVDrmPluginTest, DISABLED_MarshalsEvents) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
sp<StrictMock<MockDrmPluginListener> > listener =
new StrictMock<MockDrmPluginListener>();
@@ -1682,6 +1782,7 @@ TEST_F(WVDrmPluginTest, DISABLED_MarshalsEvents) {
EXPECT_CALL(*listener, sendKeysChange(hSessionId, hKeyStatusList2, false));
}
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.setListener(listener);
CdmKeyStatusMap cdmKeysStatus;
@@ -1704,7 +1805,9 @@ TEST_F(WVDrmPluginTest, DISABLED_GeneratesProvisioningNeededEvent) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
sp<StrictMock<MockDrmPluginListener> > listener =
new StrictMock<MockDrmPluginListener>();
@@ -1725,6 +1828,7 @@ TEST_F(WVDrmPluginTest, DISABLED_GeneratesProvisioningNeededEvent) {
EXPECT_CALL(*cdm, CloseSession(_))
.Times(AtLeast(0));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.setListener(listener);
plugin.openSession([&](Status status, hidl_vec<uint8_t> /* hSessionId */) {
@@ -1736,7 +1840,9 @@ TEST_F(WVDrmPluginTest, ProvidesExpectedDefaultPropertiesToCdm) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
const CdmClientPropertySet* propertySet = NULL;
@@ -1757,6 +1863,8 @@ TEST_F(WVDrmPluginTest, ProvidesExpectedDefaultPropertiesToCdm) {
.Times(AtLeast(0));
}
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.openSession([&](Status status, hidl_vec<uint8_t> /* hSessionId */) {
ASSERT_EQ(Status::OK, status);
});
@@ -1774,7 +1882,9 @@ TEST_F(WVDrmPluginTest, CanSetAppId) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
const CdmClientPropertySet* propertySet = NULL;
@@ -1800,6 +1910,8 @@ TEST_F(WVDrmPluginTest, CanSetAppId) {
.Times(AtLeast(0));
}
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
// Test setting an empty string
Status status = plugin.setPropertyString(hidl_string("appId"),
hidl_string(""));
@@ -1828,7 +1940,9 @@ TEST_P(WVDrmPluginOriginTest, CanSetOrigin) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
OriginTestVariant params = GetParam();
@@ -1849,6 +1963,8 @@ TEST_P(WVDrmPluginOriginTest, CanSetOrigin) {
testing::Return(wvcdm::NO_ERROR)));
// Set the properties & run the test
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
if (!params.origin.isEmpty()) {
ASSERT_EQ(Status::OK,
plugin.setPropertyString(hidl_string("origin"),
@@ -1873,7 +1989,9 @@ TEST_F(WVDrmPluginTest, CanSetSecurityLevel) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
const CdmClientPropertySet* propertySet = NULL;
@@ -1900,6 +2018,8 @@ TEST_F(WVDrmPluginTest, CanSetSecurityLevel) {
.Times(AtLeast(0));
}
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
// Test forcing L3
Status status = plugin.setPropertyString(hidl_string("securityLevel"),
hidl_string("L3"));
@@ -2002,7 +2122,9 @@ TEST_F(WVDrmPluginTest, CanSetPrivacyMode) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
const CdmClientPropertySet* propertySet = NULL;
@@ -2023,6 +2145,8 @@ TEST_F(WVDrmPluginTest, CanSetPrivacyMode) {
.Times(AtLeast(0));
}
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.openSession([&](Status status, hidl_vec<uint8_t> hSessionId) {
ASSERT_EQ(Status::OK, status);
sessionId.clear();
@@ -2052,7 +2176,9 @@ TEST_F(WVDrmPluginTest, CanSetServiceCertificate) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
const CdmClientPropertySet* propertySet = NULL;
@@ -2093,6 +2219,8 @@ TEST_F(WVDrmPluginTest, CanSetServiceCertificate) {
.WillOnce(testing::Return(true))
.WillOnce(testing::Return(false));
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.openSession([&](Status status, hidl_vec<uint8_t> hSessionId) {
ASSERT_EQ(Status::OK, status);
sessionId.clear();
@@ -2124,7 +2252,9 @@ TEST_F(WVDrmPluginTest, CanSetSessionSharing) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
const CdmClientPropertySet* propertySet = NULL;
@@ -2145,6 +2275,7 @@ TEST_F(WVDrmPluginTest, CanSetSessionSharing) {
.Times(AtLeast(0));
}
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
status_t res;
// Test turning on session sharing
@@ -2200,7 +2331,9 @@ TEST_F(WVDrmPluginTest, AllowsStoringOfSessionSharingId) {
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> crypto;
std::string appPackageName;
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
testing::Return(wvcdm::NO_ERROR)));
CdmClientPropertySet* propertySet = NULL;
@@ -2226,6 +2359,7 @@ TEST_F(WVDrmPluginTest, AllowsStoringOfSessionSharingId) {
.Times(AtLeast(0));
}
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto);
plugin.openSession([&](Status status, hidl_vec<uint8_t> hSessionId) {
ASSERT_EQ(Status::OK, status);
sessionId.clear();