From 69c8f488ca61a06c45f0ab3794541e0569df820c Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Fri, 10 May 2019 13:29:54 -0700 Subject: [PATCH] Add CdmKeyStatus kKeyStatusUsableInFuture Bug: 116738851 Test: unit tests Change-Id: I49728788e57905806b72e891f3654fbf0c8b1bc0 --- .../cdm/core/include/wv_cdm_types.h | 1 + libwvdrmengine/cdm/core/src/policy_engine.cpp | 2 +- .../cdm/core/test/license_keys_unittest.cpp | 16 +++--- .../cdm/core/test/policy_engine_unittest.cpp | 4 +- libwvdrmengine/include_hidl/HidlTypes.h | 1 + .../mediadrm/include_hidl/WVDrmPlugin.h | 12 +++++ libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp | 1 + .../mediadrm/src_hidl/WVDrmPlugin.cpp | 54 +++++++++++++++++-- .../mediadrm/test/WVDrmPlugin_test.cpp | 35 +++++++----- .../test/legacy_src/WVDrmPlugin_test.cpp | 8 ++- 10 files changed, 105 insertions(+), 29 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index d4b20a49..fdad2308 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -406,6 +406,7 @@ enum CdmKeyStatus { kKeyStatusOutputNotAllowed, kKeyStatusPending, kKeyStatusInternalError, + kKeyStatusUsableInFuture, }; typedef std::map CdmKeyStatusMap; diff --git a/libwvdrmengine/cdm/core/src/policy_engine.cpp b/libwvdrmengine/cdm/core/src/policy_engine.cpp index 8a6ff8f5..661cb1e5 100644 --- a/libwvdrmengine/cdm/core/src/policy_engine.cpp +++ b/libwvdrmengine/cdm/core/src/policy_engine.cpp @@ -226,7 +226,7 @@ void PolicyEngine::UpdateLicense(const License& license) { NotifyKeysChange(kKeyStatusUsable); } else { license_state_ = kLicenseStatePending; - NotifyKeysChange(kKeyStatusPending); + NotifyKeysChange(kKeyStatusUsableInFuture); } NotifyExpirationUpdate(current_time); } diff --git a/libwvdrmengine/cdm/core/test/license_keys_unittest.cpp b/libwvdrmengine/cdm/core/test/license_keys_unittest.cpp index 1718b036..cbfa77d8 100644 --- a/libwvdrmengine/cdm/core/test/license_keys_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/license_keys_unittest.cpp @@ -619,17 +619,17 @@ TEST_F(LicenseKeysTest, KeyStatusChanges) { EXPECT_EQ(content_key_count_, key_status_map.size()); ExpectKeyStatusesEqual(key_status_map, kKeyStatusPending); - // change to pending (again) - any_change = license_keys_->ApplyStatusChange(kKeyStatusPending, + // change to usable in future + any_change = license_keys_->ApplyStatusChange(kKeyStatusUsableInFuture, &new_usable_keys); - EXPECT_FALSE(any_change); + EXPECT_TRUE(any_change); EXPECT_FALSE(new_usable_keys); EXPECT_FALSE(license_keys_->CanDecryptContent(ck_sw_crypto)); EXPECT_FALSE(license_keys_->CanDecryptContent(ck_hw_secure)); license_keys_->ExtractKeyStatuses(&key_status_map); EXPECT_EQ(content_key_count_, key_status_map.size()); - ExpectKeyStatusesEqual(key_status_map, kKeyStatusPending); + ExpectKeyStatusesEqual(key_status_map, kKeyStatusUsableInFuture); // change to usable any_change = license_keys_->ApplyStatusChange(kKeyStatusUsable, @@ -1353,10 +1353,10 @@ TEST_P(LicenseKeysSecurityLevelConstraintsTest, KeyStatusChange) { EXPECT_EQ(content_key_count_, key_status_map.size()); ExpectKeyStatusesEqual(key_status_map, kKeyStatusPending); - // change to pending (again) - any_change = license_keys_->ApplyStatusChange(kKeyStatusPending, + // change to usable in future + any_change = license_keys_->ApplyStatusChange(kKeyStatusUsableInFuture, &new_usable_keys); - EXPECT_FALSE(any_change); + EXPECT_TRUE(any_change); EXPECT_FALSE(new_usable_keys); EXPECT_FALSE(license_keys_->CanDecryptContent(ck_sw_crypto)); EXPECT_FALSE(license_keys_->CanDecryptContent(ck_sw_decode)); @@ -1366,7 +1366,7 @@ TEST_P(LicenseKeysSecurityLevelConstraintsTest, KeyStatusChange) { license_keys_->ExtractKeyStatuses(&key_status_map); EXPECT_EQ(content_key_count_, key_status_map.size()); - ExpectKeyStatusesEqual(key_status_map, kKeyStatusPending); + ExpectKeyStatusesEqual(key_status_map, kKeyStatusUsableInFuture); // change to usable any_change = license_keys_->ApplyStatusChange(kKeyStatusUsable, diff --git a/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp b/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp index 3ce75e51..6fc297c1 100644 --- a/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp @@ -906,7 +906,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_LicenseWithFutureStartTime) { Return(GET_HDCP_CAPABILITY_FAILED))); InSequence s; - ExpectSessionKeysChange(kKeyStatusPending, false); + ExpectSessionKeysChange(kKeyStatusUsableInFuture, false); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -1054,7 +1054,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccess_WithFutureStartTime) { EXPECT_CALL(check_, Call(1)); EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); EXPECT_CALL(check_, Call(2)); - ExpectSessionKeysChange(kKeyStatusPending, false); + ExpectSessionKeysChange(kKeyStatusUsableInFuture, false); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, new_license_start_time + kLowDuration)); EXPECT_CALL(check_, Call(3)); diff --git a/libwvdrmengine/include_hidl/HidlTypes.h b/libwvdrmengine/include_hidl/HidlTypes.h index 2c29749a..c84423b7 100644 --- a/libwvdrmengine/include_hidl/HidlTypes.h +++ b/libwvdrmengine/include_hidl/HidlTypes.h @@ -57,6 +57,7 @@ using drm::V1_2::OfflineLicenseState; typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1; typedef drm::V1_2::KeyStatus KeyStatus_V1_2; +typedef drm::V1_2::KeyStatusType KeyStatusType_V1_2; typedef drm::V1_2::IDrmPluginListener IDrmPluginListener_V1_2; typedef drm::V1_2::Status Status_V1_2; typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2; diff --git a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h index 2714cbfa..e5aaba3e 100644 --- a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h +++ b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h @@ -225,6 +225,18 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener, virtual void OnSessionRenewalNeeded(const CdmSessionId& cdmSessionId); + template + void _sendKeysChange( + const hidl_vec& sessionId, + const hidl_vec& keyStatusList, + bool hasNewUsableKey); + + template + void _OnSessionKeysChange( + const CdmSessionId&, + const CdmKeyStatusMap&, + bool hasNewUsableKey); + virtual void OnSessionKeysChange( const CdmSessionId& cdmSessionId, const CdmKeyStatusMap& cdmKeysStatus, diff --git a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp index 9a7a091c..d0a06fb0 100644 --- a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp @@ -67,6 +67,7 @@ DrmPlugin::KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) { case kKeyStatusOutputNotAllowed: return DrmPlugin::kKeyStatusType_OutputNotAllowed; case kKeyStatusPending: + case kKeyStatusUsableInFuture: return DrmPlugin::kKeyStatusType_StatusPending; case kKeyStatusInternalError: default: diff --git a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp index 249d14db..32b4e13e 100644 --- a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp @@ -117,7 +117,11 @@ Status toStatus_1_0(Status_V1_2 status) { } } -KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) { +template +KST ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus); + +template<> +KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) { switch (keyStatus) { case wvcdm::kKeyStatusUsable: return KeyStatusType::USABLE; @@ -126,6 +130,7 @@ KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) { case wvcdm::kKeyStatusOutputNotAllowed: return KeyStatusType::OUTPUTNOTALLOWED; case wvcdm::kKeyStatusPending: + case wvcdm::kKeyStatusUsableInFuture: return KeyStatusType::STATUSPENDING; case wvcdm::kKeyStatusInternalError: default: @@ -133,6 +138,16 @@ KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) { } } +template<> +KeyStatusType_V1_2 ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) { + switch (keyStatus) { + case wvcdm::kKeyStatusUsableInFuture: + return KeyStatusType_V1_2::USABLEINFUTURE; + default: + return static_cast(ConvertFromCdmKeyStatus(keyStatus)); + } +} + HdcpLevel mapHdcpLevel(const std::string& level) { if (level == wvcdm::QUERY_VALUE_HDCP_V1) return HdcpLevel::HDCP_V1; @@ -1773,6 +1788,22 @@ Return WVDrmPlugin::sendExpirationUpdate( return Void(); } +template<> +void WVDrmPlugin::_sendKeysChange( + const hidl_vec& sessionId, + const hidl_vec& keyStatusList, + bool hasNewUsableKey) { + mListener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey); +} + +template<> +void WVDrmPlugin::_sendKeysChange( + const hidl_vec& sessionId, + const hidl_vec& keyStatusList, + bool hasNewUsableKey) { + mListenerV1_2->sendKeysChange_1_2(sessionId, keyStatusList, hasNewUsableKey); +} + Return WVDrmPlugin::sendKeysChange( const hidl_vec& sessionId, const hidl_vec& keyStatusList, bool hasNewUsableKey) { @@ -1817,24 +1848,37 @@ void WVDrmPlugin::OnSessionRenewalNeeded(const CdmSessionId& cdmSessionId) { void WVDrmPlugin::OnSessionKeysChange(const CdmSessionId& cdmSessionId, const CdmKeyStatusMap& cdmKeysStatus, bool hasNewUsableKey) { + if (mListenerV1_2 != NULL) { + _OnSessionKeysChange(cdmSessionId, cdmKeysStatus, hasNewUsableKey); + } else if (mListener != NULL) { + _OnSessionKeysChange(cdmSessionId, cdmKeysStatus, hasNewUsableKey); + } else { + ALOGE("Null event listener, event not sent"); + } +} + +template +void WVDrmPlugin::_OnSessionKeysChange(const CdmSessionId& cdmSessionId, + const CdmKeyStatusMap& cdmKeysStatus, + bool hasNewUsableKey) { bool expired = false; - std::vector keyStatusList; + std::vector keyStatusList; for (CdmKeyStatusMap::const_iterator it = cdmKeysStatus.begin(); it != cdmKeysStatus.end(); ++it) { const KeyId& keyId = it->first; const CdmKeyStatus cdmKeyStatus = it->second; if (cdmKeyStatus == wvcdm::kKeyStatusExpired) expired = true; - KeyStatus keyStatus; + KS keyStatus; keyStatus.keyId = toHidlVec(StrToVector(keyId)); - keyStatus.type = ConvertFromCdmKeyStatus(cdmKeyStatus); + keyStatus.type = ConvertFromCdmKeyStatus(cdmKeyStatus); keyStatusList.push_back(keyStatus); } const std::vector sessionId = StrToVector(cdmSessionId); const hidl_vec data; // data is ignored const hidl_vec sid = toHidlVec(sessionId); - sendKeysChange(sid, toHidlVec(keyStatusList), hasNewUsableKey); + _sendKeysChange(sid, toHidlVec(keyStatusList), hasNewUsableKey); // For backward compatibility. if (expired) { sendEvent(EventType::KEY_EXPIRED, sid, data); diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp index 197a4bda..f900d592 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp @@ -253,7 +253,7 @@ class MockCrypto : public WVGenericCryptoInterface { RSA_Padding_Scheme)); }; -class MockDrmPluginListener : public IDrmPluginListener { +class MockDrmPluginListener : public IDrmPluginListener_V1_2 { public: MOCK_METHOD3(sendEvent, Return(EventType, const hidl_vec&, const hidl_vec&)); @@ -264,6 +264,12 @@ class MockDrmPluginListener : public IDrmPluginListener { MOCK_METHOD3(sendKeysChange, Return(const hidl_vec&, const hidl_vec&, bool)); + MOCK_METHOD1(sendSessionLostState, + Return(const hidl_vec&)); + + MOCK_METHOD3(sendKeysChange_1_2, Return(const hidl_vec&, + const hidl_vec&, bool)); + }; template @@ -1996,6 +2002,7 @@ TEST_F(WVDrmPluginTest, DISABLED_MarshalsEvents) { std::string kKeyId2 = "Testing Key2 Id "; std::string kKeyId3 = "Testing Key3 Id "; std::string kKeyId4 = "Testing Key4 Id "; + std::string kKeyId5 = "Testing Key5 Id "; { InSequence calls; @@ -2005,17 +2012,17 @@ TEST_F(WVDrmPluginTest, DISABLED_MarshalsEvents) { hSessionId.setToExternal(sessionIdRaw, kSessionIdSize); std::vector keyId; - std::vector keyStatusList; + std::vector keyStatusList; - KeyStatus keyStatus; + KeyStatus_V1_2 keyStatus; keyId.assign(kKeyId1.begin(), kKeyId1.end()); keyStatus.keyId = toHidlVec(keyId); - keyStatus.type = KeyStatusType::EXPIRED; + keyStatus.type = KeyStatusType_V1_2::EXPIRED; keyStatusList.push_back(keyStatus); - hidl_vec hKeyStatusList = toHidlVec(keyStatusList); + hidl_vec hKeyStatusList = toHidlVec(keyStatusList); EXPECT_CALL(*listener, - sendKeysChange(hSessionId, hKeyStatusList, false)); + sendKeysChange_1_2(hSessionId, hKeyStatusList, false)); EXPECT_CALL( *listener, @@ -2032,20 +2039,23 @@ TEST_F(WVDrmPluginTest, DISABLED_MarshalsEvents) { keyStatusList.clear(); keyId.clear(); keyId.assign(kKeyId1.begin(), kKeyId1.end()); - keyStatus.type = KeyStatusType::USABLE; + keyStatus.type = KeyStatusType_V1_2::USABLE; keyStatusList.push_back(keyStatus); keyId.assign(kKeyId2.begin(), kKeyId2.end()); - keyStatus.type = KeyStatusType::OUTPUTNOTALLOWED; + keyStatus.type = KeyStatusType_V1_2::OUTPUTNOTALLOWED; keyStatusList.push_back(keyStatus); keyId.assign(kKeyId3.begin(), kKeyId3.end()); - keyStatus.type = KeyStatusType::INTERNALERROR; + keyStatus.type = KeyStatusType_V1_2::INTERNALERROR; keyStatusList.push_back(keyStatus); keyId.assign(kKeyId4.begin(), kKeyId4.end()); - keyStatus.type = KeyStatusType::STATUSPENDING; + keyStatus.type = KeyStatusType_V1_2::STATUSPENDING; + keyStatusList.push_back(keyStatus); + keyId.assign(kKeyId5.begin(), kKeyId5.end()); + keyStatus.type = KeyStatusType_V1_2::USABLEINFUTURE; keyStatusList.push_back(keyStatus); - hidl_vec hKeyStatusList2 = toHidlVec(keyStatusList); - EXPECT_CALL(*listener, sendKeysChange(hSessionId, hKeyStatusList2, false)); + hidl_vec hKeyStatusList2 = toHidlVec(keyStatusList); + EXPECT_CALL(*listener, sendKeysChange_1_2(hSessionId, hKeyStatusList2, false)); } WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); @@ -2063,6 +2073,7 @@ TEST_F(WVDrmPluginTest, DISABLED_MarshalsEvents) { cdmKeysStatus[kKeyId2] = wvcdm::kKeyStatusOutputNotAllowed; cdmKeysStatus[kKeyId3] = wvcdm::kKeyStatusInternalError; cdmKeysStatus[kKeyId4] = wvcdm::kKeyStatusPending; + cdmKeysStatus[kKeyId5] = wvcdm::kKeyStatusUsableInFuture; plugin.OnSessionKeysChange(cdmSessionId, cdmKeysStatus, true); } diff --git a/libwvdrmengine/mediadrm/test/legacy_src/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/legacy_src/WVDrmPlugin_test.cpp index 0970d182..33553147 100644 --- a/libwvdrmengine/mediadrm/test/legacy_src/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/legacy_src/WVDrmPlugin_test.cpp @@ -1407,6 +1407,7 @@ TEST_F(WVDrmPluginTest, MarshalsEvents) { const char kKeyId2[] = "Testing Key2 Id "; const char kKeyId3[] = "Testing Key3 Id "; const char kKeyId4[] = "Testing Key4 Id "; + const char kKeyId5[] = "Testing Key5 Id "; { InSequence calls; @@ -1459,7 +1460,11 @@ TEST_F(WVDrmPluginTest, MarshalsEvents) { AllOf(Field(&DrmPlugin::KeyStatus::mKeyId, ElementsAreArray(kKeyId4, sizeof(kKeyId4) - 1)), Field(&DrmPlugin::KeyStatus::mType, - DrmPlugin::kKeyStatusType_StatusPending)))), + DrmPlugin::kKeyStatusType_StatusPending)), + AllOf(Field(&DrmPlugin::KeyStatus::mKeyId, + ElementsAreArray(kKeyId5, sizeof(kKeyId5) - 1)), + Field(&DrmPlugin::KeyStatus::mType, + DrmPlugin::kKeyStatusType_UsableInFuture)))), true)); } @@ -1478,6 +1483,7 @@ TEST_F(WVDrmPluginTest, MarshalsEvents) { cdmKeysStatus[kKeyId2] = kKeyStatusOutputNotAllowed; cdmKeysStatus[kKeyId3] = kKeyStatusInternalError; cdmKeysStatus[kKeyId4] = kKeyStatusPending; + cdmKeysStatus[kKeyId5] = kKeyStatusUsableInFuture; plugin.OnSessionKeysChange(cdmSessionId, cdmKeysStatus, true); }