Enable SPOIDs in Treble Widevine Glue Layer

Adds code to the Widevine Glue Layer that drives the generation and use
of SPOIDs on platforms that support SPOIDs. (All devices whose first
release is Android O or later.) Note that this only applies to the new,
Treble-ized API. If the Widevine DRM Plugin is accessed through the old
API, it will not use SPOIDs. This is by design because the old API does
not provide an application package name, so SPOID generation is no
better than the existing, origin-based solution.

Bug: 27101531
Test: Unit tests
Test: GTS tests
Test: Google Play
Change-Id: I80f79fca84065105e218e9070a1d5299c8e33500
This commit is contained in:
John W. Bruce
2017-01-25 18:40:40 -08:00
parent 2dc53442e7
commit d9b90be205
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/mediadrm/include \
vendor/widevine/libwvdrmengine/oemcrypto/include \ vendor/widevine/libwvdrmengine/oemcrypto/include \
LOCAL_STATIC_LIBRARIES := libcrypto_static
LOCAL_SHARED_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \
android.hardware.drm@1.0 \ android.hardware.drm@1.0 \
android.hidl.memory@1.0 \ android.hidl.memory@1.0 \

View File

@@ -309,17 +309,39 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
const std::string mEmptyString; const std::string mEmptyString;
} mPropertySet; } 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; sp<wvcdm::WvContentDecryptionModule> const mCDM;
CdmIdentifier mCdmIdentifier;
WVGenericCryptoInterface* mCrypto; WVGenericCryptoInterface* mCrypto;
map<CdmSessionId, CryptoSession> mCryptoSessions; map<CdmSessionId, CryptoSession> mCryptoSessions;
sp<IDrmPluginListener> mListener; sp<IDrmPluginListener> mListener;
const std::string& appPackageName() const {
return mAppPackageName;
}
status_t queryProperty(const std::string& property, status_t queryProperty(const std::string& property,
std::string& stringValue) const; std::string& stringValue) const;

View File

@@ -9,18 +9,22 @@
#include "WVDrmPlugin.h" #include "WVDrmPlugin.h"
#include "TypeConvert.h" #include "TypeConvert.h"
#include "cutils/properties.h"
#include "mapErrors-inl.h" #include "mapErrors-inl.h"
#include "media/stagefright/MediaErrors.h" #include "media/stagefright/MediaErrors.h"
#include "openssl/sha.h"
#include "utils/List.h" #include "utils/List.h"
#include "wv_cdm_constants.h" #include "wv_cdm_constants.h"
namespace { namespace {
static const char* const kResetSecurityLevel = "";
static const char* const kEnable = "enable"; static const char* const kResetSecurityLevel = "";
static const char* const kDisable = "disable"; static const char* const kEnable = "enable";
static const std::string kPsshTag = "pssh"; static const char* const kDisable = "disable";
static const char* const kSpecialUnprovisionResponse = "unprovision"; static const std::string kPsshTag = "pssh";
} static const char* const kSpecialUnprovisionResponse = "unprovision";
} // namespace
namespace wvdrm { namespace wvdrm {
namespace hardware { namespace hardware {
@@ -102,11 +106,15 @@ KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) {
WVDrmPlugin::WVDrmPlugin(const sp<WvContentDecryptionModule>& cdm, WVDrmPlugin::WVDrmPlugin(const sp<WvContentDecryptionModule>& cdm,
const std::string& appPackageName, const std::string& appPackageName,
WVGenericCryptoInterface* crypto) WVGenericCryptoInterface* crypto)
: mAppPackageName(appPackageName), : mCDM(cdm),
mCDM(cdm),
mCdmIdentifier(kDefaultCdmIdentifier),
mCrypto(crypto), 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() { WVDrmPlugin::~WVDrmPlugin() {
typedef map<CdmSessionId, CryptoSession>::iterator mapIterator; typedef map<CdmSessionId, CryptoSession>::iterator mapIterator;
@@ -127,7 +135,8 @@ Return<void> WVDrmPlugin::openSession(openSession_cb _hidl_cb) {
CdmSessionId cdmSessionId; CdmSessionId cdmSessionId;
CdmResponseType res = CdmResponseType res =
mCDM->OpenSession("com.widevine", &mPropertySet, mCdmIdentifier, this, mCDM->OpenSession("com.widevine", &mPropertySet,
mCdmIdentifierBuilder.get_identifier(), this,
&cdmSessionId); &cdmSessionId);
if (!isCdmResponseTypeSuccess(res)) { if (!isCdmResponseTypeSuccess(res)) {
@@ -269,8 +278,8 @@ Return<void> WVDrmPlugin::getKeyRequest(
CdmKeyRequest keyRequest; CdmKeyRequest keyRequest;
CdmResponseType res = mCDM->GenerateKeyRequest( CdmResponseType res = mCDM->GenerateKeyRequest(
cdmSessionId, cdmKeySetId, cdmInitDataType, processedInitData, cdmSessionId, cdmKeySetId, cdmInitDataType, processedInitData,
cdmLicenseType, cdmParameters, &mPropertySet, mCdmIdentifier, cdmLicenseType, cdmParameters, &mPropertySet,
&keyRequest); mCdmIdentifierBuilder.get_identifier(), &keyRequest);
requestType = ConvertFromCdmKeyRequestType(keyRequest.type); requestType = ConvertFromCdmKeyRequestType(keyRequest.type);
@@ -412,11 +421,9 @@ Return<Status> WVDrmPlugin::restoreKeys(const hidl_vec<uint8_t>& sessionId,
std::string cdmCertAuthority = certificateAuthority; std::string cdmCertAuthority = certificateAuthority;
CdmResponseType res = mCDM->GetProvisioningRequest(cdmCertType, CdmResponseType res = mCDM->GetProvisioningRequest(
cdmCertAuthority, cdmCertType, cdmCertAuthority, mCdmIdentifierBuilder.get_identifier(),
mCdmIdentifier, &cdmProvisionRequest, &cdmDefaultUrl);
&cdmProvisionRequest,
&cdmDefaultUrl);
String8 defaultUrl; String8 defaultUrl;
Vector<uint8_t> request; Vector<uint8_t> request;
if (isCdmResponseTypeSuccess(res)) { if (isCdmResponseTypeSuccess(res)) {
@@ -440,21 +447,21 @@ Return<void> WVDrmPlugin::provideProvisionResponse(
CdmProvisioningResponse cdmResponse(resp.begin(), resp.end()); CdmProvisioningResponse cdmResponse(resp.begin(), resp.end());
if (cdmResponse == kSpecialUnprovisionResponse) { if (cdmResponse == kSpecialUnprovisionResponse) {
if (mCdmIdentifier == kDefaultCdmIdentifier) { if (mCdmIdentifierBuilder.get_identifier() == kDefaultCdmIdentifier) {
_hidl_cb(toStatus(kErrorNoOriginSpecified), toHidlVec(certificate), _hidl_cb(toStatus(kErrorNoOriginSpecified), toHidlVec(certificate),
toHidlVec(wrappedKey)); toHidlVec(wrappedKey));
return Void(); return Void();
} }
_hidl_cb(toStatus(unprovision(mCdmIdentifier)), toHidlVec(certificate), _hidl_cb(toStatus(unprovision(mCdmIdentifierBuilder.get_identifier())),
toHidlVec(certificate),
toHidlVec(wrappedKey)); toHidlVec(wrappedKey));
return Void(); return Void();
} else { } else {
std::string cdmCertificate; std::string cdmCertificate;
std::string cdmWrappedKey; std::string cdmWrappedKey;
CdmResponseType res = mCDM->HandleProvisioningResponse(mCdmIdentifier, CdmResponseType res = mCDM->HandleProvisioningResponse(
cdmResponse, mCdmIdentifierBuilder.get_identifier(), cdmResponse, &cdmCertificate,
&cdmCertificate, &cdmWrappedKey);
&cdmWrappedKey);
if (isCdmResponseTypeSuccess(res)) { if (isCdmResponseTypeSuccess(res)) {
certificate = StrToVector(cdmCertificate); certificate = StrToVector(cdmCertificate);
wrappedKey = StrToVector(cdmWrappedKey); wrappedKey = StrToVector(cdmWrappedKey);
@@ -594,7 +601,7 @@ Return<void> WVDrmPlugin::getPropertyString(const hidl_string& propertyName,
} else if (name == "appId") { } else if (name == "appId") {
value = mPropertySet.app_id().c_str(); value = mPropertySet.app_id().c_str();
} else if (name == "origin") { } else if (name == "origin") {
value = mCdmIdentifier.origin.c_str(); value = mCdmIdentifierBuilder.origin().c_str();
} else { } else {
ALOGE("App requested unknown string property %s", name.string()); ALOGE("App requested unknown string property %s", name.string());
status = android::ERROR_DRM_CANNOT_HANDLE; status = android::ERROR_DRM_CANNOT_HANDLE;
@@ -613,7 +620,7 @@ Return<void> WVDrmPlugin::getPropertyByteArray(
Vector<uint8_t> value; Vector<uint8_t> value;
if (name == "deviceUniqueId") { if (name == "deviceUniqueId") {
status = queryProperty(wvcdm::QUERY_KEY_DEVICE_ID, value); value = StrToVector(mCdmIdentifierBuilder.get_device_unique_id());
} else if (name == "provisioningUniqueId") { } else if (name == "provisioningUniqueId") {
status = queryProperty(wvcdm::QUERY_KEY_PROVISIONING_ID, value); status = queryProperty(wvcdm::QUERY_KEY_PROVISIONING_ID, value);
} else if (name == "serviceCertificate") { } 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."); ALOGE("App tried to set the origin while sessions are opened.");
return toStatus(kErrorSessionIsOpen); return toStatus(kErrorSessionIsOpen);
} else { } else {
mCdmIdentifier.origin = _value.string(); if (!mCdmIdentifierBuilder.set_origin(_value.string())) {
return Status::BAD_VALUE;
}
} }
} else { } else {
ALOGE("App set unknown string property %s", name.string()); 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 widevine
} // namespace V1_0 } // namespace V1_0
} // namespace drm } // namespace drm

View File

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