diff --git a/libwvdrmengine/mediadrm/Android.mk b/libwvdrmengine/mediadrm/Android.mk index 7f62ba5d..a598a349 100644 --- a/libwvdrmengine/mediadrm/Android.mk +++ b/libwvdrmengine/mediadrm/Android.mk @@ -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 \ diff --git a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h index 3206a95d..40601cd2 100644 --- a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h +++ b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h @@ -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 const mCDM; - CdmIdentifier mCdmIdentifier; WVGenericCryptoInterface* mCrypto; map mCryptoSessions; sp mListener; - const std::string& appPackageName() const { - return mAppPackageName; - } - status_t queryProperty(const std::string& property, std::string& stringValue) const; diff --git a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp index bd439c29..616b4188 100644 --- a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp @@ -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& 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::iterator mapIterator; @@ -127,7 +135,8 @@ Return 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 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 WVDrmPlugin::restoreKeys(const hidl_vec& 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 request; if (isCdmResponseTypeSuccess(res)) { @@ -440,21 +447,21 @@ Return 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 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 WVDrmPlugin::getPropertyByteArray( Vector 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 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(hash), SHA256_DIGEST_LENGTH); + } +} + } // namespace widevine } // namespace V1_0 } // namespace drm diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp index 17a12013..d4de9f1c 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp @@ -18,6 +18,7 @@ #include #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("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> cdm = new StrictMock(); StrictMock 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 hSessionId) { ASSERT_EQ(Status::OK, status); sessionId.clear(); @@ -315,11 +321,14 @@ TEST_F(WVDrmPluginTest, ClosesSessions) { android::sp> cdm = new StrictMock(); StrictMock 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> cdm = new StrictMock(); StrictMock 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> cdm = new StrictMock(); StrictMock 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> cdm = new StrictMock(); StrictMock 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 hKeySetId) { @@ -575,7 +594,9 @@ TEST_F(WVDrmPluginTest, HandlesPrivacyCertCaseOfAddKey) { android::sp> cdm = new StrictMock(); StrictMock 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 > listener = new StrictMock(); @@ -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 hSessionId) { ASSERT_EQ(Status::OK, status); sessionId.clear(); @@ -642,11 +665,14 @@ TEST_F(WVDrmPluginTest, RemovesKeys) { android::sp> cdm = new StrictMock(); StrictMock 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> cdm = new StrictMock(); StrictMock 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> cdm = new StrictMock(); StrictMock 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 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(hLicenseStatus)) { ASSERT_EQ(Status::OK, status); @@ -713,7 +745,9 @@ TEST_F(WVDrmPluginTest, GetsProvisioningRequests) { android::sp> cdm = new StrictMock(); StrictMock 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 hRequest, hidl_string defaultUrl) { @@ -746,7 +781,9 @@ TEST_F(WVDrmPluginTest, HandlesProvisioningResponses) { android::sp> cdm = new StrictMock(); StrictMock 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 cert; Vector key; + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); plugin.provideProvisionResponse( toHidlVec(response), [&](Status status, hidl_vec /* cert */, @@ -778,13 +816,16 @@ TEST_F(WVDrmPluginTest, UnprovisionsDevice) { android::sp> cdm = new StrictMock(); StrictMock 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> cdm = new StrictMock(); StrictMock 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> cdm = new StrictMock(); StrictMock 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 cert; Vector 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> cdm = new StrictMock(); - StrictMock 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 cert; - Vector key; - Vector specialResponse; - specialResponse.appendArray(kUnprovisionResponse, kUnprovisionResponseSize); + // TODO(juce): b/34548395 Make sure this API version is correct. + if (firstApiLevel >= 26) { + android::sp> cdm = new StrictMock(); + StrictMock 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 cert; + Vector key; + Vector specialResponse; + specialResponse.appendArray(kUnprovisionResponse, kUnprovisionResponseSize); - plugin.provideProvisionResponse( - toHidlVec(specialResponse), - [&](Status status, hidl_vec /* cert */, - hidl_vec /* 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 /* cert */, + hidl_vec /* key */) { + EXPECT_NE(Status::OK, status); + }); + } } TEST_F(WVDrmPluginTest, MuxesOriginUnprovisioningErrors) { android::sp> cdm = new StrictMock(); StrictMock 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 cert; Vector 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> cdm = new StrictMock(); StrictMock 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 > 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 hSecureStops) { ASSERT_EQ(Status::OK, status); @@ -972,15 +1041,19 @@ TEST_F(WVDrmPluginTest, ReleasesAllSecureStops) { android::sp> cdm = new StrictMock(); StrictMock 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> cdm = new StrictMock(); StrictMock 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> cdm = new StrictMock(); StrictMock 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 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 vectorResult) { - ASSERT_EQ(Status::OK, status); - std::vector 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> cdm = new StrictMock(); StrictMock 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 vectorResult; @@ -1172,7 +1241,9 @@ TEST_F(WVDrmPluginTest, DoesNotSetUnknownProperties) { android::sp> cdm = new StrictMock(); StrictMock 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 value; value.appendArray(valueRaw, kValueSize); @@ -1196,7 +1268,9 @@ TEST_F(WVDrmPluginTest, FailsGenericMethodsWithoutAnAlgorithmSet) { android::sp> cdm = new StrictMock(); StrictMock 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 keyId; Vector 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 hSessionId) { ASSERT_EQ(Status::OK, status); sessionId.clear(); @@ -1262,7 +1338,9 @@ TEST_F(WVDrmPluginTest, CallsGenericEncrypt) { android::sp> cdm = new StrictMock(); StrictMock 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 hSessionId) { ASSERT_EQ(Status::OK, status); sessionId.clear(); @@ -1329,7 +1409,9 @@ TEST_F(WVDrmPluginTest, CallsGenericDecrypt) { android::sp> cdm = new StrictMock(); StrictMock 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 hSessionId) { ASSERT_EQ(Status::OK, status); sessionId.clear(); @@ -1396,7 +1480,9 @@ TEST_F(WVDrmPluginTest, CallsGenericSign) { android::sp> cdm = new StrictMock(); StrictMock 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 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 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> cdm = new StrictMock(); StrictMock 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 hSessionId) { ASSERT_EQ(Status::OK, status); sessionId.clear(); @@ -1552,10 +1644,12 @@ TEST_F(WVDrmPluginTest, RegistersForEvents) { android::sp> cdm = new StrictMock(); StrictMock 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 /* hSessionId */) { ASSERT_EQ(Status::OK, status); }); @@ -1575,36 +1670,39 @@ TEST_F(WVDrmPluginTest, RegistersForEvents) { TEST_F(WVDrmPluginTest, UnregistersForAllEventsOnDestruction) { android::sp> cdm = new StrictMock(); StrictMock 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 /* hSessionId */) { ASSERT_EQ(Status::OK, status); }); @@ -1620,7 +1718,9 @@ TEST_F(WVDrmPluginTest, DISABLED_MarshalsEvents) { android::sp> cdm = new StrictMock(); StrictMock 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 > listener = new StrictMock(); @@ -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> cdm = new StrictMock(); StrictMock 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 > listener = new StrictMock(); @@ -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 /* hSessionId */) { @@ -1736,7 +1840,9 @@ TEST_F(WVDrmPluginTest, ProvidesExpectedDefaultPropertiesToCdm) { android::sp> cdm = new StrictMock(); StrictMock 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 /* hSessionId */) { ASSERT_EQ(Status::OK, status); }); @@ -1774,7 +1882,9 @@ TEST_F(WVDrmPluginTest, CanSetAppId) { android::sp> cdm = new StrictMock(); StrictMock 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> cdm = new StrictMock(); StrictMock 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> cdm = new StrictMock(); StrictMock 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> cdm = new StrictMock(); StrictMock 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 hSessionId) { ASSERT_EQ(Status::OK, status); sessionId.clear(); @@ -2052,7 +2176,9 @@ TEST_F(WVDrmPluginTest, CanSetServiceCertificate) { android::sp> cdm = new StrictMock(); StrictMock 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 hSessionId) { ASSERT_EQ(Status::OK, status); sessionId.clear(); @@ -2124,7 +2252,9 @@ TEST_F(WVDrmPluginTest, CanSetSessionSharing) { android::sp> cdm = new StrictMock(); StrictMock 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> cdm = new StrictMock(); StrictMock 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 hSessionId) { ASSERT_EQ(Status::OK, status); sessionId.clear();