diff --git a/libwvdrmengine/include_hidl/WVDrmFactory.h b/libwvdrmengine/include_hidl/WVDrmFactory.h index 86894f51..ddb5530f 100644 --- a/libwvdrmengine/include_hidl/WVDrmFactory.h +++ b/libwvdrmengine/include_hidl/WVDrmFactory.h @@ -41,6 +41,10 @@ struct WVDrmFactory : public IDrmFactory { WVDRM_DISALLOW_COPY_AND_ASSIGN(WVDrmFactory); static WVGenericCryptoInterface sOemCryptoInterface; + + static bool areSpoidsEnabled(); + + friend class WVDrmFactoryTest_CalculatesSpoidUseCorrectly_Test; }; extern "C" IDrmFactory* HIDL_FETCH_IDrmFactory(const char* name); diff --git a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h index c827c4fe..11237ead 100644 --- a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h +++ b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h @@ -55,7 +55,8 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener, WVDrmPlugin(const sp& cdm, const std::string& appPackageName, - WVGenericCryptoInterface* crypto); + WVGenericCryptoInterface* crypto, + bool useSpoid); virtual ~WVDrmPlugin(); @@ -307,16 +308,13 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener, class CdmIdentifierBuilder { public: - CdmIdentifierBuilder(); + CdmIdentifierBuilder(bool useSpoid, const std::string& appPackageName); 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); diff --git a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp index f8a28dff..116383ed 100644 --- a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp @@ -11,7 +11,6 @@ #include "WVDrmPlugin.h" #include "TypeConvert.h" -#include "cutils/properties.h" #include "mapErrors-inl.h" #include "media/stagefright/MediaErrors.h" #include "openssl/sha.h" @@ -103,12 +102,12 @@ KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) { WVDrmPlugin::WVDrmPlugin(const sp& cdm, const std::string& appPackageName, - WVGenericCryptoInterface* crypto) - : mCDM(cdm), + WVGenericCryptoInterface* crypto, + bool useSpoid) + : mCdmIdentifierBuilder(useSpoid, appPackageName), + mCDM(cdm), mCrypto(crypto), mCryptoSessions() { - mCdmIdentifierBuilder.set_app_package_name(appPackageName); - std::string deviceId; queryProperty(wvcdm::QUERY_KEY_DEVICE_ID, deviceId); mCdmIdentifierBuilder.set_device_id(deviceId); @@ -1285,21 +1284,13 @@ status_t WVDrmPlugin::unprovision(const CdmIdentifier& identifier) { } // Implementation for the CdmIdentifierBuilder inner class -WVDrmPlugin::CdmIdentifierBuilder::CdmIdentifierBuilder() +WVDrmPlugin::CdmIdentifierBuilder::CdmIdentifierBuilder( + bool useSpoid, const std::string& appPackageName) : mCdmIdentifier(), mIsIdentifierSealed(false), + mUseSpoid(useSpoid), 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 -} + mAppPackageName(appPackageName) {} const CdmIdentifier& WVDrmPlugin::CdmIdentifierBuilder::get_identifier() { if (!mIsIdentifierSealed) calculateSpoid(); @@ -1321,12 +1312,6 @@ bool WVDrmPlugin::CdmIdentifierBuilder::set_device_id(const std::string& 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; diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp index 4e46e43b..ea8cb105 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp @@ -15,7 +15,6 @@ #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" @@ -300,7 +299,7 @@ TEST_F(WVDrmPluginTest, OpensSessions) { EXPECT_CALL(*cdm, CloseSession(_)) .Times(AtLeast(0)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.openSession([&](Status status, hidl_vec hSessionId) { ASSERT_EQ(Status::OK, status); @@ -322,7 +321,7 @@ TEST_F(WVDrmPluginTest, ClosesSessions) { EXPECT_CALL(*cdm, CloseSession(cdmSessionId)) .Times(1); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); Status status = plugin.closeSession(toHidlVec(sessionId)); ASSERT_EQ(Status::OK, status); } @@ -338,7 +337,7 @@ TEST_F(WVDrmPluginTest, ClosesSessionWithoutReturningError) { EXPECT_CALL(*cdm, CloseSession(cdmSessionId)) .WillOnce(testing::Return(wvcdm::SESSION_NOT_FOUND_1)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); Status status = plugin.closeSession(toHidlVec(sessionId)); ASSERT_EQ(Status::OK, status); } @@ -485,7 +484,7 @@ TEST_F(WVDrmPluginTest, DISABLED_GeneratesKeyRequests) { } // Performs the actual tests - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); for (size_t i = 0; i < testSetCount; ++i) { const std::string mimeType(testSets[i].mimeType); @@ -567,7 +566,7 @@ TEST_F(WVDrmPluginTest, AddsKeys) { Pointee(cdmKeySetId))) .Times(1); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.provideKeyResponse( toHidlVec(sessionId), toHidlVec(response), @@ -632,7 +631,7 @@ TEST_F(WVDrmPluginTest, HandlesPrivacyCertCaseOfAddKey) { EXPECT_CALL(*cdm, AddKey(_, _, _)) .WillRepeatedly(testing::Return(wvcdm::NEED_KEY)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.openSession([&](Status status, hidl_vec hSessionId) { ASSERT_EQ(Status::OK, status); @@ -670,7 +669,7 @@ TEST_F(WVDrmPluginTest, RemovesKeys) { EXPECT_CALL(*cdm, RemoveKeys(cdmSessionId)) .Times(1); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); Status status = plugin.removeKeys(toHidlVec(sessionId)); ASSERT_EQ(Status::OK, status); } @@ -696,7 +695,7 @@ TEST_F(WVDrmPluginTest, RestoresKeys) { ElementsAreArray(keySetIdRaw, kKeySetIdSize))) .Times(1); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); Status status = plugin.restoreKeys(toHidlVec(sessionId), toHidlVec(keySetId)); ASSERT_EQ(Status::OK, status); } @@ -726,7 +725,7 @@ TEST_F(WVDrmPluginTest, QueriesKeyStatus) { .WillOnce(DoAll(SetArgPointee<1>(cdmLicenseStatus), testing::Return(wvcdm::NO_ERROR))); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.queryKeyStatus(toHidlVec(sessionId), [&](Status status, hidl_vec(hLicenseStatus)) { ASSERT_EQ(Status::OK, status); @@ -768,7 +767,7 @@ TEST_F(WVDrmPluginTest, GetsProvisioningRequests) { SetArgPointee<4>(kDefaultUrl), testing::Return(wvcdm::NO_ERROR))); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.getProvisionRequest( hidl_string(""), hidl_string(""), [&](Status status, hidl_vec hRequest, hidl_string defaultUrl) { @@ -806,7 +805,7 @@ TEST_F(WVDrmPluginTest, HandlesProvisioningResponses) { std::vector cert; std::vector key; - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.provideProvisionResponse( toHidlVec(response), [&](Status status, hidl_vec /* cert */, @@ -828,7 +827,7 @@ TEST_F(WVDrmPluginTest, UnprovisionsDevice) { EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, HasOrigin(EMPTY_ORIGIN))) .Times(1); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); status_t res = plugin.unprovisionDevice(); ASSERT_EQ(android::OK, res); } @@ -852,7 +851,7 @@ TEST_F(WVDrmPluginTest, MuxesUnprovisioningErrors) { .WillOnce(testing::Return(wvcdm::UNKNOWN_ERROR)) .WillOnce(testing::Return(wvcdm::UNKNOWN_ERROR)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); status_t res = plugin.unprovisionDevice(); ASSERT_NE(android::OK, res); res = plugin.unprovisionDevice(); @@ -880,7 +879,7 @@ TEST_F(WVDrmPluginTest, UnprovisionsOrigin) { EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, HasOrigin(kOrigin.c_str()))) .Times(1); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); Status status = plugin.setPropertyString(hidl_string("origin"), hidl_string(kOrigin)); @@ -898,37 +897,29 @@ TEST_F(WVDrmPluginTest, WillNotUnprovisionWithoutOrigin) { // 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); - } + 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))); - // 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))); + std::vector cert; + std::vector key; + std::vector specialResponse; + specialResponse.assign( + kUnprovisionResponse, kUnprovisionResponse + kUnprovisionResponseSize); - std::vector cert; - std::vector key; - std::vector specialResponse; - specialResponse.assign( - kUnprovisionResponse, kUnprovisionResponse + kUnprovisionResponseSize); + EXPECT_CALL(*cdm, Unprovision(_, _)) + .Times(0); - 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); - }); - } + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); + plugin.provideProvisionResponse( + toHidlVec(specialResponse), + [&](Status status, hidl_vec /* cert */, + hidl_vec /* key */) { + EXPECT_NE(Status::OK, status); + }); } TEST_F(WVDrmPluginTest, MuxesOriginUnprovisioningErrors) { @@ -956,7 +947,7 @@ TEST_F(WVDrmPluginTest, MuxesOriginUnprovisioningErrors) { .WillOnce(testing::Return(wvcdm::UNKNOWN_ERROR)) .WillOnce(testing::Return(wvcdm::UNKNOWN_ERROR)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); Status status = plugin.setPropertyString(hidl_string("origin"), hidl_string(kOrigin)); @@ -1013,7 +1004,7 @@ TEST_F(WVDrmPluginTest, GetsSecureStops) { std::list > stops; - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); Status status = plugin.setPropertyString(hidl_string("appId"), hidl_string(app_id)); ASSERT_EQ(Status::OK, status); @@ -1054,7 +1045,7 @@ TEST_F(WVDrmPluginTest, ReleasesAllSecureStops) { EXPECT_CALL(*cdm, ReleaseAllUsageInfo(StrEq(""))) .Times(1); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); Status status = plugin.setPropertyString(hidl_string("appId"), hidl_string("")); @@ -1085,7 +1076,7 @@ TEST_F(WVDrmPluginTest, ReleasesSecureStop) { kMessageSize))) .Times(1); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); Status status = plugin.releaseSecureStop(toHidlVec(message)); ASSERT_EQ(Status::OK, status); } @@ -1136,7 +1127,7 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { .WillOnce(DoAll(SetArgPointee<2>(oemCryptoApiVersion), testing::Return(wvcdm::NO_ERROR))); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); std::string stringResult; std::vector vectorResult; @@ -1178,6 +1169,14 @@ 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(kDeviceId.data(), kDeviceId.size())); + }); + plugin.getPropertyString( hidl_string("systemId"), [&](Status status, hidl_string stringResult) { @@ -1224,7 +1223,7 @@ TEST_F(WVDrmPluginTest, DoesNotGetUnknownProperties) { .WillOnce(DoAll(SetArgPointee<2>(kDeviceId), testing::Return(wvcdm::NO_ERROR))); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); std::string stringResult; std::vector vectorResult; @@ -1257,7 +1256,7 @@ TEST_F(WVDrmPluginTest, DoesNotSetUnknownProperties) { fread(valueRaw, sizeof(uint8_t), kValueSize, fp); fclose(fp); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); std::vector value; value.assign(valueRaw, valueRaw + kValueSize); @@ -1297,7 +1296,7 @@ TEST_F(WVDrmPluginTest, FailsGenericMethodsWithoutAnAlgorithmSet) { EXPECT_CALL(*cdm, CloseSession(_)) .Times(AtLeast(0)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.openSession([&](Status status, hidl_vec hSessionId) { ASSERT_EQ(Status::OK, status); @@ -1393,7 +1392,7 @@ TEST_F(WVDrmPluginTest, CallsGenericEncrypt) { EXPECT_CALL(*cdm, CloseSession(_)) .Times(AtLeast(0)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.openSession([&](Status status, hidl_vec hSessionId) { ASSERT_EQ(Status::OK, status); @@ -1464,7 +1463,7 @@ TEST_F(WVDrmPluginTest, CallsGenericDecrypt) { EXPECT_CALL(*cdm, CloseSession(_)) .Times(AtLeast(0)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.openSession([&](Status status, hidl_vec hSessionId) { ASSERT_EQ(Status::OK, status); @@ -1537,7 +1536,7 @@ TEST_F(WVDrmPluginTest, CallsGenericSign) { EXPECT_CALL(*cdm, CloseSession(_)) .Times(AtLeast(0)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.openSession([&](Status status, hidl_vec hSessionId) { ASSERT_EQ(Status::OK, status); @@ -1621,7 +1620,7 @@ TEST_F(WVDrmPluginTest, CallsGenericVerify) { EXPECT_CALL(*cdm, CloseSession(_)) .Times(AtLeast(0)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.openSession([&](Status status, hidl_vec hSessionId) { ASSERT_EQ(Status::OK, status); @@ -1667,7 +1666,7 @@ TEST_F(WVDrmPluginTest, RegistersForEvents) { EXPECT_CALL(*cdm, CloseSession(_)) .Times(AtLeast(0)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.openSession([&](Status status, hidl_vec /* hSessionId */) { ASSERT_EQ(Status::OK, status); }); @@ -1707,7 +1706,7 @@ TEST_F(WVDrmPluginTest, UnregistersForAllEventsOnDestruction) { .Times(AtLeast(0)); { - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.openSession([&](Status status, hidl_vec /* hSessionId */) { ASSERT_EQ(Status::OK, status); @@ -1788,7 +1787,7 @@ TEST_F(WVDrmPluginTest, DISABLED_MarshalsEvents) { EXPECT_CALL(*listener, sendKeysChange(hSessionId, hKeyStatusList2, false)); } - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.setListener(listener); CdmKeyStatusMap cdmKeysStatus; @@ -1834,7 +1833,7 @@ TEST_F(WVDrmPluginTest, DISABLED_GeneratesProvisioningNeededEvent) { EXPECT_CALL(*cdm, CloseSession(_)) .Times(AtLeast(0)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.setListener(listener); plugin.openSession([&](Status status, hidl_vec /* hSessionId */) { @@ -1869,7 +1868,7 @@ TEST_F(WVDrmPluginTest, ProvidesExpectedDefaultPropertiesToCdm) { .Times(AtLeast(0)); } - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.openSession([&](Status status, hidl_vec /* hSessionId */) { ASSERT_EQ(Status::OK, status); @@ -1916,7 +1915,7 @@ TEST_F(WVDrmPluginTest, CanSetAppId) { .Times(AtLeast(0)); } - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); // Test setting an empty string Status status = plugin.setPropertyString(hidl_string("appId"), @@ -1969,7 +1968,7 @@ TEST_P(WVDrmPluginOriginTest, CanSetOrigin) { testing::Return(wvcdm::NO_ERROR))); // Set the properties & run the test - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); if (!params.origin.empty()) { ASSERT_EQ(Status::OK, @@ -2024,7 +2023,7 @@ TEST_F(WVDrmPluginTest, CanSetSecurityLevel) { .Times(AtLeast(0)); } - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); // Test forcing L3 Status status = plugin.setPropertyString(hidl_string("securityLevel"), @@ -2151,7 +2150,7 @@ TEST_F(WVDrmPluginTest, CanSetPrivacyMode) { .Times(AtLeast(0)); } - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.openSession([&](Status status, hidl_vec hSessionId) { ASSERT_EQ(Status::OK, status); @@ -2225,7 +2224,7 @@ TEST_F(WVDrmPluginTest, CanSetServiceCertificate) { .WillOnce(testing::Return(true)) .WillOnce(testing::Return(false)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.openSession([&](Status status, hidl_vec hSessionId) { ASSERT_EQ(Status::OK, status); @@ -2281,7 +2280,7 @@ TEST_F(WVDrmPluginTest, CanSetSessionSharing) { .Times(AtLeast(0)); } - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); status_t res; // Test turning on session sharing @@ -2365,7 +2364,7 @@ TEST_F(WVDrmPluginTest, AllowsStoringOfSessionSharingId) { .Times(AtLeast(0)); } - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto); + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); plugin.openSession([&](Status status, hidl_vec hSessionId) { ASSERT_EQ(Status::OK, status); sessionId.clear(); diff --git a/libwvdrmengine/src_hidl/WVDrmFactory.cpp b/libwvdrmengine/src_hidl/WVDrmFactory.cpp index da934128..be688053 100644 --- a/libwvdrmengine/src_hidl/WVDrmFactory.cpp +++ b/libwvdrmengine/src_hidl/WVDrmFactory.cpp @@ -8,6 +8,7 @@ #include "WVDrmFactory.h" +#include "cutils/properties.h" #include "wv_cdm_constants.h" #include "WVCDMSingleton.h" #include "wv_content_decryption_module.h" @@ -49,11 +50,24 @@ Return WVDrmFactory::createPlugin( } plugin = new WVDrmPlugin(getCDM(), appPackageName.c_str(), - &sOemCryptoInterface); + &sOemCryptoInterface, areSpoidsEnabled()); _hidl_cb(Status::OK, plugin); return Void(); } +bool WVDrmFactory::areSpoidsEnabled() { + // Check what this device's first API level was. + 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. + return firstApiLevel >= 26; // Android O +} + + } // namespace widevine } // namespace V1_0 } // namespace drm diff --git a/libwvdrmengine/test/unit/Android.mk b/libwvdrmengine/test/unit/Android.mk index c0d87689..47f50056 100644 --- a/libwvdrmengine/test/unit/Android.mk +++ b/libwvdrmengine/test/unit/Android.mk @@ -68,6 +68,7 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ + libcutils \ libdl \ libhidlbase \ libhidlmemory \ diff --git a/libwvdrmengine/test/unit/WVDrmFactory_test.cpp b/libwvdrmengine/test/unit/WVDrmFactory_test.cpp index 44afde83..4336d979 100644 --- a/libwvdrmengine/test/unit/WVDrmFactory_test.cpp +++ b/libwvdrmengine/test/unit/WVDrmFactory_test.cpp @@ -5,6 +5,8 @@ #include "gtest/gtest.h" #include "WVDrmFactory.h" +#include "cutils/properties.h" + namespace wvdrm { namespace hardware { namespace drm { @@ -93,6 +95,22 @@ TEST(WVDrmFactoryTest, DoesNotSupportUnsupportedContainerFormats) { "WVPluginFactory incorrectly claims to support WMV"; } +TEST(WVDrmFactoryTest, CalculatesSpoidUseCorrectly) { + WVDrmFactory factory; + + 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. + bool shouldUseSpoids = (firstApiLevel >= 26); // Android O + + EXPECT_EQ(shouldUseSpoids, factory.areSpoidsEnabled()) << + "WVDrmFactory calculated a different SPOID state than expected."; +} + } // namespace widevine } // namespace V1_0 } // namespace drm