diff --git a/libwvdrmengine/mediadrm/include/WVDrmPlugin.h b/libwvdrmengine/mediadrm/include/WVDrmPlugin.h index b5e14891..4d374ac1 100644 --- a/libwvdrmengine/mediadrm/include/WVDrmPlugin.h +++ b/libwvdrmengine/mediadrm/include/WVDrmPlugin.h @@ -82,7 +82,7 @@ class WVDrmPlugin : public ::aidl::android::hardware::drm::BnDrmPlugin, ::ndk::ScopedAStatus getNumberOfSessions( ::aidl::android::hardware::drm::NumberOfSessions* _aidl_return) override; ::ndk::ScopedAStatus getOfflineLicenseKeySetIds( - std::vector<::aidl::android::hardware::drm::KeySetId>* _aidl_return) + std::vector<::aidl::android::hardware::drm::KeySetId>* keySetIds) override; ::ndk::ScopedAStatus getOfflineLicenseState( const ::aidl::android::hardware::drm::KeySetId& in_keySetId, diff --git a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp index 5ad1bc7b..636694c7 100644 --- a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp @@ -965,21 +965,27 @@ Status WVDrmPlugin::unprovisionDevice() { } ::ndk::ScopedAStatus WVDrmPlugin::getOfflineLicenseKeySetIds( - vector<::aidl::android::hardware::drm::KeySetId>* _aidl_return) { - _aidl_return->clear(); + vector<::aidl::android::hardware::drm::KeySetId>* keySetIds) { + keySetIds->clear(); CdmIdentifier identifier; const auto status = mCdmIdentifierBuilder.getCdmIdentifier(&identifier); if (status != Status::OK) { return toNdkScopedAStatus(status); } - const std::vector levels = {wvcdm::kSecurityLevelL1, - wvcdm::kSecurityLevelL3}; + std::vector levelsToList; + if (mPropertySet.security_level() != wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3) { + // Do not list L1 offline licenses if the DRM plugin is in + // L3-only mode. + levelsToList.push_back(wvcdm::kSecurityLevelL1); + } + // Always list L3, as "default" may imply either. + levelsToList.push_back(wvcdm::kSecurityLevelL3); std::vector allKeySetIds; CdmResponseType res(wvcdm::UNKNOWN_ERROR); bool success = false; - for (auto level : levels) { + for (const auto& level : levelsToList) { std::vector levelKeySetIds; res = mCDM->ListStoredLicenses(level, identifier, &levelKeySetIds); @@ -1004,15 +1010,13 @@ Status WVDrmPlugin::unprovisionDevice() { // Filter out key sets based on ATSC mode. const auto isAllowedKeySetId = mPropertySet.use_atsc_mode() ? IsAtscKeySetId : IsNotAtscKeySetId; - std::vector keySetIds; + keySetIds->reserve(allKeySetIds.size()); for (const CdmKeySetId& keySetId : allKeySetIds) { if (isAllowedKeySetId(keySetId)) { - keySetIds.push_back(KeySetId{StrToVector(keySetId)}); + keySetIds->push_back(KeySetId{StrToVector(keySetId)}); } } - - *_aidl_return = std::move(keySetIds); - return toNdkScopedAStatus(mapCdmResponseType(wvcdm::NO_ERROR)); + return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus WVDrmPlugin::getOfflineLicenseState( diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_hal_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_hal_test.cpp index 226fc0d4..260f7c7f 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_hal_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_hal_test.cpp @@ -2884,6 +2884,8 @@ TEST_F(WVDrmPluginHalTest, GetOfflineLicenseKeySetIds_NonAtscMode) { std::vector offlineKeySetIds; const auto ret = mPlugin->getOfflineLicenseKeySetIds(&offlineKeySetIds); ASSERT_TRUE(ret.isOk()); + + // Transform back into CDM types. std::vector offlineCdmKeySetIds; for (const auto &keySetId : offlineKeySetIds) { offlineCdmKeySetIds.emplace_back(keySetId.keySetId.begin(), @@ -2929,6 +2931,8 @@ TEST_F(WVDrmPluginHalTest, GetOfflineLicenseKeySetIds_AtscMode) { std::vector offlineKeySetIds; const auto ret = mPlugin->getOfflineLicenseKeySetIds(&offlineKeySetIds); ASSERT_TRUE(ret.isOk()); + + // Transform back into CDM types. std::vector offlineCdmKeySetIds; for (const auto &keySetId : offlineKeySetIds) { offlineCdmKeySetIds.emplace_back(keySetId.keySetId.begin(), @@ -2939,6 +2943,72 @@ TEST_F(WVDrmPluginHalTest, GetOfflineLicenseKeySetIds_AtscMode) { EXPECT_EQ(expectedCdmKeySetIds, offlineCdmKeySetIds); } +TEST_F(WVDrmPluginHalTest, GetOfflineLicenseKeySetIds_L1AndL3) { + const std::vector cdmKeySetIdsL1 = {"ksid1111", "ksid2222", + "ksid3333", "ksid4444"}; + const std::vector cdmKeySetIdsL3 = {"ksid5555", "ksid6666", + "ksid7777", "ksid8888"}; + // Expected key set IDs are the combination of both L1 and L3. + std::vector cdmKeySetIds = cdmKeySetIdsL1; + cdmKeySetIds.insert(cdmKeySetIds.end(), cdmKeySetIdsL3.begin(), + cdmKeySetIdsL3.end()); + + EXPECT_CALL(*mCdm, ListStoredLicenses(kSecurityLevelL1, _, NotNull())) + .WillOnce(DoAll(SetArgPointee<2>(cdmKeySetIdsL1), + testing::Return(CdmResponseType(wvcdm::NO_ERROR)))); + EXPECT_CALL(*mCdm, ListStoredLicenses(kSecurityLevelL3, _, NotNull())) + .WillOnce(DoAll(SetArgPointee<2>(cdmKeySetIdsL3), + testing::Return(CdmResponseType(wvcdm::NO_ERROR)))); + + // In if security level is default, then both L1 and L3 + // offline licenses should be returned. + mPlugin->setPropertyString("securityLevel", + wvcdm::QUERY_VALUE_SECURITY_LEVEL_DEFAULT); + + std::vector offlineKeySetIds; + const auto ret = mPlugin->getOfflineLicenseKeySetIds(&offlineKeySetIds); + ASSERT_TRUE(ret.isOk()); + + // Transform back into CDM types. + std::vector offlineCdmKeySetIds; + for (const auto &keySetId : offlineKeySetIds) { + offlineCdmKeySetIds.emplace_back(keySetId.keySetId.begin(), + keySetId.keySetId.end()); + } + + EXPECT_EQ(cdmKeySetIds.size(), offlineCdmKeySetIds.size()); + EXPECT_EQ(cdmKeySetIds, offlineCdmKeySetIds); +} + +TEST_F(WVDrmPluginHalTest, GetOfflineLicenseKeySetIds_L3Only) { + const std::vector cdmKeySetIdsL3 = {"ksid1111", "ksid2222", + "ksid3333", "ksid4444"}; + + EXPECT_CALL(*mCdm, ListStoredLicenses(kSecurityLevelL1, _, NotNull())) + .Times(0); + EXPECT_CALL(*mCdm, ListStoredLicenses(kSecurityLevelL3, _, NotNull())) + .WillOnce(DoAll(SetArgPointee<2>(cdmKeySetIdsL3), + testing::Return(CdmResponseType(wvcdm::NO_ERROR)))); + + // After setting L3 mode, only L3 key set IDs should be returned. + mPlugin->setPropertyString("securityLevel", + wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3); + + std::vector offlineKeySetIds; + const auto ret = mPlugin->getOfflineLicenseKeySetIds(&offlineKeySetIds); + ASSERT_TRUE(ret.isOk()); + + // Transform back into CDM types. + std::vector offlineCdmKeySetIds; + for (const auto &keySetId : offlineKeySetIds) { + offlineCdmKeySetIds.emplace_back(keySetId.keySetId.begin(), + keySetId.keySetId.end()); + } + + EXPECT_EQ(cdmKeySetIdsL3.size(), offlineCdmKeySetIds.size()); + EXPECT_EQ(cdmKeySetIdsL3, offlineCdmKeySetIds); +} + TEST_F(WVDrmPluginHalTest, GetOfflineLicenseState) { EXPECT_CALL(*mCdm, QueryStatus(_, QUERY_KEY_SECURITY_LEVEL, _)) .WillRepeatedly(DoAll(SetArgPointee<2>(QUERY_VALUE_SECURITY_LEVEL_L1),