From 19947dfe6fe2f3a66c68ab707d8321875eb0f161 Mon Sep 17 00:00:00 2001 From: "John W. Bruce" Date: Tue, 11 Apr 2017 11:55:37 -0700 Subject: [PATCH] Move SPOID Enable/Disable Logic Out of WVDrmPlugin (This is a merge of http://go/wvgerrit/25580) While writing fixes for b/36660726, b/34716264, and b/36065223, it became clear that having the logic that checks whether the device supports SPOIDs embedded inside WVDrmPlugin was complicating its code and inhibiting testing of the class. By moving this check into the code that instantiates WVDrmPlugin, the result of the calculation can be independently tested while the tests for WVDrmPlugin can put it in whatever state they need for the sake of unit testing. As a consequence of this, the check on retrieving the "deviceUniqueId" byte array property, which was removed when SPOIDs were implemented, can be reinstated. Bug: 36660726 Bug: 34716264 Bug: 36065223 Test: libwvdrmdrmplugin_hidl_test & libwvdrmengine_hidl_test Change-Id: I961d2ee42bbdc42f0c324e36d9a74ac92205a437 --- libwvdrmengine/include_hidl/WVDrmFactory.h | 4 + .../mediadrm/include_hidl/WVDrmPlugin.h | 8 +- .../mediadrm/src_hidl/WVDrmPlugin.cpp | 31 ++-- .../mediadrm/test/WVDrmPlugin_test.cpp | 133 +++++++++--------- libwvdrmengine/src_hidl/WVDrmFactory.cpp | 16 ++- libwvdrmengine/test/unit/Android.mk | 1 + .../test/unit/WVDrmFactory_test.cpp | 18 +++ 7 files changed, 115 insertions(+), 96 deletions(-) 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