diff --git a/libwvdrmengine/mediadrm/include/WVDrmPlugin.h b/libwvdrmengine/mediadrm/include/WVDrmPlugin.h index 4d374ac1..63a428d4 100644 --- a/libwvdrmengine/mediadrm/include/WVDrmPlugin.h +++ b/libwvdrmengine/mediadrm/include/WVDrmPlugin.h @@ -134,7 +134,8 @@ class WVDrmPlugin : public ::aidl::android::hardware::drm::BnDrmPlugin, ::ndk::ScopedAStatus removeKeys( const std::vector& in_sessionId) override; ::ndk::ScopedAStatus removeOfflineLicense( - const ::aidl::android::hardware::drm::KeySetId& in_keySetId) override; + const ::aidl::android::hardware::drm::KeySetId& in_keySetIdPackage) + override; ::ndk::ScopedAStatus removeSecureStop( const ::aidl::android::hardware::drm::SecureStopId& in_secureStopId) override; diff --git a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp index 8e72ec0e..e222128d 100644 --- a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp @@ -1071,8 +1071,9 @@ Status WVDrmPlugin::unprovisionDevice() { } ::ndk::ScopedAStatus WVDrmPlugin::removeOfflineLicense( - const ::aidl::android::hardware::drm::KeySetId& in_keySetId) { - if (in_keySetId.keySetId.empty()) { + const ::aidl::android::hardware::drm::KeySetId& keySetIdPackage) { + const auto& keySetId = keySetIdPackage.keySetId; + if (keySetId.empty()) { return toNdkScopedAStatus(Status::BAD_VALUE); } @@ -1082,12 +1083,18 @@ Status WVDrmPlugin::unprovisionDevice() { return toNdkScopedAStatus(status); } - const std::vector levels = {wvcdm::kSecurityLevelL1, - wvcdm::kSecurityLevelL3}; - const CdmKeySetId cdmKeySetId(in_keySetId.keySetId.begin(), - in_keySetId.keySetId.end()); + std::vector levelsToCheck; + if (mPropertySet.security_level() != wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3) { + // Do not attempt to remove an L1 offline licenses if the DRM plugin + // is in L3-only mode. + levelsToCheck.push_back(wvcdm::kSecurityLevelL1); + } + // Always check L3, as "default" may imply either. + levelsToCheck.push_back(wvcdm::kSecurityLevelL3); - for (const CdmSecurityLevel level : levels) { + const CdmKeySetId cdmKeySetId(keySetId.begin(), keySetId.end()); + + for (const CdmSecurityLevel level : levelsToCheck) { std::vector keySetIds; const CdmResponseType res = mCDM->ListStoredLicenses(level, identifier, &keySetIds); diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_hal_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_hal_test.cpp index 260f7c7f..0e55641a 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_hal_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_hal_test.cpp @@ -3115,6 +3115,62 @@ TEST_F(WVDrmPluginHalTest, RemoveOfflineLicense_NotFound) { ASSERT_FALSE(status.isOk()); } +TEST_F(WVDrmPluginHalTest, RemoveOfflineLicense_L3_OnlyMode) { + // Key set to remove. + const CdmKeySetId cdmKeySetId = "ksidDEADBEAF"; + const KeySetId keySetId{ + std::vector(cdmKeySetId.begin(), cdmKeySetId.end())}; + + // Desired key set ID is found in L3. + const std::vector cdmKeySetIdsL3 = { + "ksidDEADC0DE", "ksid1337", cdmKeySetId, "ksidBAD", "ksidCAFEB0BA"}; + + // In L3 mode, there should be no call to L1. + EXPECT_CALL(*mCdm, ListStoredLicenses(kSecurityLevelL1, _, _)).Times(0); + EXPECT_CALL(*mCdm, ListStoredLicenses(kSecurityLevelL3, _, NotNull())) + .WillOnce(DoAll(SetArgPointee<2>(cdmKeySetIdsL3), + testing::Return(CdmResponseType(wvcdm::NO_ERROR)))); + + // Only call L3. + EXPECT_CALL(*mCdm, RemoveOfflineLicense(_, kSecurityLevelL1, _)).Times(0); + EXPECT_CALL(*mCdm, RemoveOfflineLicense(cdmKeySetId, kSecurityLevelL3, _)) + .WillOnce(testing::Return(CdmResponseType(wvcdm::NO_ERROR))); + + // After setting L3 mode, only L3 should be checked for removal. + mPlugin->setPropertyString("securityLevel", + wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3); + + const auto status = mPlugin->removeOfflineLicense(keySetId); + ASSERT_TRUE(status.isOk()); +} + +TEST_F(WVDrmPluginHalTest, RemoveOfflineLicense_L3_OnlyMode_NotFound) { + // Key set to remove. + const CdmKeySetId cdmKeySetId = "ksidDEADBEAF"; + const KeySetId keySetId{ + std::vector(cdmKeySetId.begin(), cdmKeySetId.end())}; + + // Desired key set ID is not found in L3. + const std::vector cdmKeySetIdsL3 = {"ksidDEADC0DE", "ksid1337", + "ksidBAD", "ksidCAFEB0BA"}; + + // In L3 mode, there should be no call to L1. + EXPECT_CALL(*mCdm, ListStoredLicenses(kSecurityLevelL1, _, _)).Times(0); + EXPECT_CALL(*mCdm, ListStoredLicenses(kSecurityLevelL3, _, NotNull())) + .WillOnce(DoAll(SetArgPointee<2>(cdmKeySetIdsL3), + testing::Return(CdmResponseType(wvcdm::NO_ERROR)))); + + // No call to RemoveOfflineLicense should be made. + EXPECT_CALL(*mCdm, RemoveOfflineLicense(_, _, _)).Times(0); + + // After setting L3 mode, only L3 should be checked for removal. + mPlugin->setPropertyString("securityLevel", + wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3); + + const auto status = mPlugin->removeOfflineLicense(keySetId); + ASSERT_FALSE(status.isOk()); +} + TEST_F(WVDrmPluginHalTest, CanStoreAtscLicense) { android::sp> cdm = new StrictMock(); StrictMock crypto;