From 1d9a16c3b9c05b872fad2921666c5c81bc90470c Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Thu, 8 Mar 2018 14:27:59 -0800 Subject: [PATCH 1/2] Rename ReleaseAllUsageInfo to RemoveAllUsageInfo [ Merge of http://go/wvgerrit/44920 ] Bug: 69674645 Test: WV unit and integration tests Change-Id: Iee6e60b9dd20a8ed087c5e44924aa1c05f640920 --- libwvdrmengine/cdm/core/include/cdm_engine.h | 10 +++---- .../cdm/core/include/wv_cdm_types.h | 15 ++++++---- libwvdrmengine/cdm/core/src/cdm_engine.cpp | 28 ++++++++--------- .../cdm/core/test/test_printers.cpp | 30 +++++++++++-------- .../include/wv_content_decryption_module.h | 4 +-- .../cdm/metrics/include/metrics_collections.h | 4 ++- .../cdm/metrics/src/metrics_collections.cpp | 14 +++++++-- .../cdm/src/wv_content_decryption_module.cpp | 6 ++-- .../cdm/test/request_license_test.cpp | 6 ++-- libwvdrmengine/include/WVErrors.h | 17 ++++++----- libwvdrmengine/include/mapErrors-inl.h | 30 +++++++++++-------- libwvdrmengine/include_hidl/mapErrors-inl.h | 15 ++++++---- libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp | 4 +-- .../mediadrm/src_hidl/WVDrmPlugin.cpp | 4 +-- .../mediadrm/test/WVDrmPlugin_test.cpp | 6 ++-- .../test/legacy_src/WVDrmPlugin_test.cpp | 6 ++-- 16 files changed, 115 insertions(+), 84 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/cdm_engine.h b/libwvdrmengine/cdm/core/include/cdm_engine.h index 739de8d4..c1d485ba 100644 --- a/libwvdrmengine/cdm/core/include/cdm_engine.h +++ b/libwvdrmengine/cdm/core/include/cdm_engine.h @@ -212,13 +212,13 @@ class CdmEngine { const CdmSecureStopId& ssid, CdmUsageInfo* usage_info); - // Release all usage records for the current origin. - virtual CdmResponseType ReleaseAllUsageInfo(const std::string& app_id, - CdmSecurityLevel security_level); + // Remove all usage records for the current origin. + virtual CdmResponseType RemoveAllUsageInfo(const std::string& app_id, + CdmSecurityLevel security_level); - // Release all usage records for the current origin. Span all + // Remove all usage records for the current origin. Span all // security levels. - virtual CdmResponseType ReleaseAllUsageInfo(const std::string& app_id); + virtual CdmResponseType RemoveAllUsageInfo(const std::string& app_id); virtual CdmResponseType ReleaseUsageInfo( const CdmUsageInfoReleaseMessage& message); diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index 5e3f2958..5685878e 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -140,8 +140,8 @@ enum CdmResponseType { LOAD_KEY_ERROR = 99, NO_CONTENT_KEY = 100, REFRESH_KEYS_ERROR = 101, - RELEASE_ALL_USAGE_INFO_ERROR_1 = 102, - RELEASE_ALL_USAGE_INFO_ERROR_2 = 103, + REMOVE_ALL_USAGE_INFO_ERROR_1 = 102, + REMOVE_ALL_USAGE_INFO_ERROR_2 = 103, RELEASE_KEY_ERROR = 104, RELEASE_KEY_REQUEST_ERROR = 105, RELEASE_LICENSE_ERROR_1 = 106, @@ -289,8 +289,8 @@ enum CdmResponseType { USAGE_STORE_LICENSE_FAILED = 247, USAGE_STORE_USAGE_INFO_FAILED = 248, USAGE_INVALID_LOAD_ENTRY = 249, - RELEASE_ALL_USAGE_INFO_ERROR_4 = 250, - RELEASE_ALL_USAGE_INFO_ERROR_5 = 251, + REMOVE_ALL_USAGE_INFO_ERROR_4 = 250, + REMOVE_ALL_USAGE_INFO_ERROR_5 = 251, RELEASE_USAGE_INFO_FAILED = 252, INCORRECT_USAGE_SUPPORT_TYPE_1 = 253, INCORRECT_USAGE_SUPPORT_TYPE_2 = 254, @@ -314,13 +314,16 @@ enum CdmResponseType { USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED = 272, USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED = 273, USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE = 274, - RELEASE_ALL_USAGE_INFO_ERROR_6 = 275, - RELEASE_ALL_USAGE_INFO_ERROR_7 = 276, + REMOVE_ALL_USAGE_INFO_ERROR_6 = 275, + REMOVE_ALL_USAGE_INFO_ERROR_7 = 276, LICENSE_REQUEST_INVALID_SUBLICENSE = 277, CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE = 278, LOAD_SYSTEM_ID_ERROR = 279, INSUFFICIENT_CRYPTO_RESOURCES_4 = 280, INSUFFICIENT_CRYPTO_RESOURCES_5 = 281, + REMOVE_USAGE_INFO_ERROR_1 = 282, + REMOVE_USAGE_INFO_ERROR_2 = 283, + REMOVE_USAGE_INFO_ERROR_3 = 284, }; enum CdmKeyStatus { diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 9c0b1305..5a214b0a 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -1156,17 +1156,17 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, return status; } -CdmResponseType CdmEngine::ReleaseAllUsageInfo( +CdmResponseType CdmEngine::RemoveAllUsageInfo( const std::string& app_id, CdmSecurityLevel security_level) { DeviceFiles handle(file_system_); if (!handle.Init(security_level)) { - LOGE("CdmEngine::ReleaseAllUsageInfo: unable to initialize device files"); - return RELEASE_ALL_USAGE_INFO_ERROR_6; + LOGE("CdmEngine::RemoveAllUsageInfo: unable to initialize device files"); + return REMOVE_ALL_USAGE_INFO_ERROR_6; } std::vector provider_session_tokens; if (!handle.DeleteAllUsageInfoForApp(app_id, &provider_session_tokens)) { - LOGE("CdmEngine::ReleaseAllUsageInfo: failed to delete usage records"); - return RELEASE_ALL_USAGE_INFO_ERROR_7; + LOGE("CdmEngine::RemoveAllUsageInfo: failed to delete usage records"); + return REMOVE_ALL_USAGE_INFO_ERROR_7; } if (provider_session_tokens.size() == 0UL) { @@ -1183,12 +1183,12 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo( DeleteMultipleUsageInformation(provider_session_tokens); } if (status != NO_ERROR) { - LOGE("CdmEngine::ReleaseAllUsageInfo: CryptoSession failure"); + LOGE("CdmEngine::RemoveAllUsageInfo: CryptoSession failure"); } return status; } -CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) { +CdmResponseType CdmEngine::RemoveAllUsageInfo(const std::string& app_id) { if (NULL == usage_property_set_.get()) { usage_property_set_.reset(new UsagePropertySet()); } @@ -1216,7 +1216,7 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) { if (!handle.RetrieveUsageInfo( DeviceFiles::GetUsageInfoFileName(app_id), &usage_data)) { - status = RELEASE_ALL_USAGE_INFO_ERROR_4; + status = REMOVE_ALL_USAGE_INFO_ERROR_4; break; } @@ -1230,7 +1230,7 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) { if (!handle.DeleteUsageInfo( DeviceFiles::GetUsageInfoFileName(app_id), usage_data[0].provider_session_token)) { - status = RELEASE_ALL_USAGE_INFO_ERROR_6; + status = REMOVE_ALL_USAGE_INFO_ERROR_6; break; } } while (status == NO_ERROR && !usage_data.empty()); @@ -1239,7 +1239,7 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) { if (!handle.DeleteAllUsageInfoForApp( DeviceFiles::GetUsageInfoFileName(app_id), &provider_session_tokens)) { - status = RELEASE_ALL_USAGE_INFO_ERROR_5; + status = REMOVE_ALL_USAGE_INFO_ERROR_5; } break; } @@ -1248,9 +1248,9 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) { if (!handle.DeleteAllUsageInfoForApp( DeviceFiles::GetUsageInfoFileName(app_id), &provider_session_tokens)) { - LOGE("CdmEngine::ReleaseAllUsageInfo: failed to delete %d secure" + LOGE("CdmEngine::RemoveAllUsageInfo: failed to delete %d secure" "stops", j); - status = RELEASE_ALL_USAGE_INFO_ERROR_1; + status = REMOVE_ALL_USAGE_INFO_ERROR_1; } else { CdmResponseType status2 = usage_session_-> DeleteMultipleUsageInformation(provider_session_tokens); @@ -1263,9 +1263,9 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) { break; } } else { - LOGE("CdmEngine::ReleaseAllUsageInfo: failed to initialize L%d device" + LOGE("CdmEngine::RemoveAllUsageInfo: failed to initialize L%d device" "files", j); - status = RELEASE_ALL_USAGE_INFO_ERROR_2; + status = REMOVE_ALL_USAGE_INFO_ERROR_2; } } usage_session_.reset(NULL); diff --git a/libwvdrmengine/cdm/core/test/test_printers.cpp b/libwvdrmengine/cdm/core/test/test_printers.cpp index 8c26bf3a..7da8bbf5 100644 --- a/libwvdrmengine/cdm/core/test/test_printers.cpp +++ b/libwvdrmengine/cdm/core/test/test_printers.cpp @@ -221,23 +221,23 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { break; case REFRESH_KEYS_ERROR: *os << "REFRESH_KEYS_ERROR"; break; - case RELEASE_ALL_USAGE_INFO_ERROR_1: - *os << "RELEASE_ALL_USAGE_INFO_ERROR_1"; + case REMOVE_ALL_USAGE_INFO_ERROR_1: + *os << "REMOVE_ALL_USAGE_INFO_ERROR_1"; break; - case RELEASE_ALL_USAGE_INFO_ERROR_2: - *os << "RELEASE_ALL_USAGE_INFO_ERROR_2"; + case REMOVE_ALL_USAGE_INFO_ERROR_2: + *os << "REMOVE_ALL_USAGE_INFO_ERROR_2"; break; - case RELEASE_ALL_USAGE_INFO_ERROR_4: - *os << "RELEASE_ALL_USAGE_INFO_ERROR_4"; + case REMOVE_ALL_USAGE_INFO_ERROR_4: + *os << "REMOVE_ALL_USAGE_INFO_ERROR_4"; break; - case RELEASE_ALL_USAGE_INFO_ERROR_5: - *os << "RELEASE_ALL_USAGE_INFO_ERROR_5"; + case REMOVE_ALL_USAGE_INFO_ERROR_5: + *os << "REMOVE_ALL_USAGE_INFO_ERROR_5"; break; - case RELEASE_ALL_USAGE_INFO_ERROR_6: - *os << "RELEASE_ALL_USAGE_INFO_ERROR_6"; + case REMOVE_ALL_USAGE_INFO_ERROR_6: + *os << "REMOVE_ALL_USAGE_INFO_ERROR_6"; break; - case RELEASE_ALL_USAGE_INFO_ERROR_7: - *os << "RELEASE_ALL_USAGE_INFO_ERROR_7"; + case REMOVE_ALL_USAGE_INFO_ERROR_7: + *os << "REMOVE_ALL_USAGE_INFO_ERROR_7"; break; case RELEASE_KEY_ERROR: *os << "RELEASE_KEY_ERROR"; break; @@ -578,6 +578,12 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { case INSUFFICIENT_CRYPTO_RESOURCES_5: *os << "INSUFFICIENT_CRYPTO_RESOURCES_5"; break; + case REMOVE_USAGE_INFO_ERROR_1: *os << "REMOVE_USAGE_INFO_ERROR_1"; + break; + case REMOVE_USAGE_INFO_ERROR_2: *os << "REMOVE_USAGE_INFO_ERROR_2"; + break; + case REMOVE_USAGE_INFO_ERROR_3: *os << "REMOVE_USAGE_INFO_ERROR_3"; + break; default: *os << "Unknown CdmResponseType"; break; diff --git a/libwvdrmengine/cdm/include/wv_content_decryption_module.h b/libwvdrmengine/cdm/include/wv_content_decryption_module.h index 472e418b..4c5fe843 100644 --- a/libwvdrmengine/cdm/include/wv_content_decryption_module.h +++ b/libwvdrmengine/cdm/include/wv_content_decryption_module.h @@ -105,8 +105,8 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler { const CdmSecureStopId& ssid, const CdmIdentifier& identifier, CdmUsageInfo* usage_info); - virtual CdmResponseType ReleaseAllUsageInfo(const std::string& app_id, - const CdmIdentifier& identifier); + virtual CdmResponseType RemoveAllUsageInfo(const std::string& app_id, + const CdmIdentifier& identifier); virtual CdmResponseType ReleaseUsageInfo( const CdmUsageInfoReleaseMessage& message, const CdmIdentifier& identifier); diff --git a/libwvdrmengine/cdm/metrics/include/metrics_collections.h b/libwvdrmengine/cdm/metrics/include/metrics_collections.h index ccde3ed2..4193024d 100644 --- a/libwvdrmengine/cdm/metrics/include/metrics_collections.h +++ b/libwvdrmengine/cdm/metrics/include/metrics_collections.h @@ -279,8 +279,10 @@ class EngineMetrics { CounterMetric cdm_engine_open_key_set_session_; CounterMetric cdm_engine_open_session_; EventMetric cdm_engine_query_key_status_; - CounterMetric cdm_engine_release_all_usage_info_; + CounterMetric cdm_engine_remove_all_usage_info_; + CounterMetric cdm_engine_remove_usage_info_; CounterMetric cdm_engine_release_usage_info_; + CounterMetric cdm_engine_get_secure_stop_ids_; CounterMetric cdm_engine_remove_keys_; EventMetric cdm_engine_restore_key_; CounterMetric cdm_engine_unprovision_; diff --git a/libwvdrmengine/cdm/metrics/src/metrics_collections.cpp b/libwvdrmengine/cdm/metrics/src/metrics_collections.cpp index 13e76ce8..4861f6d3 100644 --- a/libwvdrmengine/cdm/metrics/src/metrics_collections.cpp +++ b/libwvdrmengine/cdm/metrics/src/metrics_collections.cpp @@ -420,12 +420,18 @@ EngineMetrics::EngineMetrics() : cdm_engine_query_key_status_( "/drm/widevine/cdm_engine/query_key_status/time", "error"), - cdm_engine_release_all_usage_info_( - "/drm/widevine/cdm_engine/release_all_usage_info", + cdm_engine_remove_all_usage_info_( + "/drm/widevine/cdm_engine/remove_all_usage_info", + "error"), + cdm_engine_remove_usage_info_( + "/drm/widevine/cdm_engine/remove_usage_info", "error"), cdm_engine_release_usage_info_( "/drm/widevine/cdm_engine/release_usage_info", "error"), + cdm_engine_get_secure_stop_ids_( + "/drm/widevine/cdm_engine/get_secure_stop_ids", + "error"), cdm_engine_remove_keys_( "/drm/widevine/cdm_engine/remove_keys", "error"), @@ -524,8 +530,10 @@ void EngineMetrics::SerializeEngineMetrics(MetricsGroup* metric_group) { cdm_engine_open_key_set_session_.Serialize(&serializer); cdm_engine_open_session_.Serialize(&serializer); cdm_engine_query_key_status_.Serialize(&serializer); - cdm_engine_release_all_usage_info_.Serialize(&serializer); + cdm_engine_remove_all_usage_info_.Serialize(&serializer); + cdm_engine_remove_usage_info_.Serialize(&serializer); cdm_engine_release_usage_info_.Serialize(&serializer); + cdm_engine_get_secure_stop_ids_.Serialize(&serializer); cdm_engine_remove_keys_.Serialize(&serializer); cdm_engine_restore_key_.Serialize(&serializer); cdm_engine_unprovision_.Serialize(&serializer); diff --git a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp index b8aa08d5..4e5d18a0 100644 --- a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp +++ b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp @@ -297,11 +297,11 @@ CdmResponseType WvContentDecryptionModule::GetUsageInfo( return sts; } -CdmResponseType WvContentDecryptionModule::ReleaseAllUsageInfo( +CdmResponseType WvContentDecryptionModule::RemoveAllUsageInfo( const std::string& app_id, const CdmIdentifier& identifier) { CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); - CdmResponseType sts = cdm_engine->ReleaseAllUsageInfo(app_id); - cdm_engine->GetMetrics()->cdm_engine_release_all_usage_info_.Increment(sts); + CdmResponseType sts = cdm_engine->RemoveAllUsageInfo(app_id); + cdm_engine->GetMetrics()->cdm_engine_remove_all_usage_info_.Increment(sts); return sts; } diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index fa9f07e6..ddae4bdc 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -2956,7 +2956,7 @@ INSTANTIATE_TEST_CASE_P(Cdm, WvCdmUsageInfoTest, &usage_info_sub_sample_info[6], &usage_info_sub_sample_info[7])); -TEST_F(WvCdmRequestLicenseTest, UsageReleaseAllTest) { +TEST_F(WvCdmRequestLicenseTest, UsageRemoveAllTest) { Unprovision(); std::string app_id_empty = ""; @@ -3025,7 +3025,7 @@ TEST_F(WvCdmRequestLicenseTest, UsageReleaseAllTest) { EXPECT_EQ( NO_ERROR, - decryptor_.ReleaseAllUsageInfo(app_id_not_empty, kDefaultCdmIdentifier)); + decryptor_.RemoveAllUsageInfo(app_id_not_empty, kDefaultCdmIdentifier)); EXPECT_EQ( NO_ERROR, @@ -3040,7 +3040,7 @@ TEST_F(WvCdmRequestLicenseTest, UsageReleaseAllTest) { EXPECT_EQ( NO_ERROR, - decryptor_.ReleaseAllUsageInfo(app_id_empty, kDefaultCdmIdentifier)); + decryptor_.RemoveAllUsageInfo(app_id_empty, kDefaultCdmIdentifier)); EXPECT_EQ( NO_ERROR, diff --git a/libwvdrmengine/include/WVErrors.h b/libwvdrmengine/include/WVErrors.h index 7128f31a..0e373979 100644 --- a/libwvdrmengine/include/WVErrors.h +++ b/libwvdrmengine/include/WVErrors.h @@ -99,8 +99,8 @@ enum { kNoContentKey = ERROR_DRM_VENDOR_MIN + 98, kProvisioningGetKeyboxError = ERROR_DRM_VENDOR_MIN + 99, kRefreshKeysError = ERROR_DRM_VENDOR_MIN + 100, - kReleaseAllUsageInfoError1 = ERROR_DRM_VENDOR_MIN + 101, - kReleaseAllUsageInfoError2 = ERROR_DRM_VENDOR_MIN + 102, + kRemoveAllUsageInfoError1 = ERROR_DRM_VENDOR_MIN + 101, + kRemoveAllUsageInfoError2 = ERROR_DRM_VENDOR_MIN + 102, kReleaseKeyError = ERROR_DRM_VENDOR_MIN + 103, kReleaseKeyRequestError = ERROR_DRM_VENDOR_MIN + 104, kReleaseLicenseError1 = ERROR_DRM_VENDOR_MIN + 105, @@ -231,8 +231,8 @@ enum { kUsageStoreLicenseFailed = ERROR_DRM_VENDOR_MIN + 241, kUsageStoreUsageInfoFailed = ERROR_DRM_VENDOR_MIN + 242, kUsageInvalidLoadEntry = ERROR_DRM_VENDOR_MIN + 243, - kReleaseAllUsageInfoError4 = ERROR_DRM_VENDOR_MIN + 244, - kReleaseAllUsageInfoError5 = ERROR_DRM_VENDOR_MIN + 245, + kRemoveAllUsageInfoError4 = ERROR_DRM_VENDOR_MIN + 244, + kRemoveAllUsageInfoError5 = ERROR_DRM_VENDOR_MIN + 245, kReleaseUsageInfoFailed = ERROR_DRM_VENDOR_MIN + 246, kIncorrectUsageSupportType1 = ERROR_DRM_VENDOR_MIN + 247, kIncorrectUsageSupportType2 = ERROR_DRM_VENDOR_MIN + 248, @@ -254,17 +254,20 @@ enum { kUsageStoreEntryRetrieveLicenseFailed = ERROR_DRM_VENDOR_MIN + 264, kUsageStoreEntryRetrieveUsageInfoFailed = ERROR_DRM_VENDOR_MIN + 265, kUsageStoreEntryRetrieveInvalidStorageType = ERROR_DRM_VENDOR_MIN + 266, - kReleaseAllUsageInfoError6 = ERROR_DRM_VENDOR_MIN + 267, - kReleaseAllUsageInfoError7 = ERROR_DRM_VENDOR_MIN + 268, + kRemoveAllUsageInfoError6 = ERROR_DRM_VENDOR_MIN + 267, + kRemoveAllUsageInfoError7 = ERROR_DRM_VENDOR_MIN + 268, kLicenseRequestInvalidSublicense = ERROR_DRM_VENDOR_MIN + 269, kCertProvisioningEmptyServiceCertificate = ERROR_DRM_VENDOR_MIN + 270, kLoadSystemIdError = ERROR_DRM_VENDOR_MIN + 271, kInsufficientCryptoResources4 = ERROR_DRM_VENDOR_MIN + 272, kInsufficientCryptoResources5 = ERROR_DRM_VENDOR_MIN + 273, + kRemoveUsageInfoError1 = ERROR_DRM_VENDOR_MIN + 274, + kRemoveUsageInfoError2 = ERROR_DRM_VENDOR_MIN + 275, + kRemoveUsageInfoError3 = ERROR_DRM_VENDOR_MIN + 276, // This should always follow the last error code. // The offset value should be updated each time a new error code is added. - kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 273, + kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 276, // Used by crypto test mode kErrorTestMode = ERROR_DRM_VENDOR_MAX, diff --git a/libwvdrmengine/include/mapErrors-inl.h b/libwvdrmengine/include/mapErrors-inl.h index 752555c3..e9d82b20 100644 --- a/libwvdrmengine/include/mapErrors-inl.h +++ b/libwvdrmengine/include/mapErrors-inl.h @@ -189,10 +189,10 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kNoContentKey; case wvcdm::REFRESH_KEYS_ERROR: return kRefreshKeysError; - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_1: - return kReleaseAllUsageInfoError1; - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_2: - return kReleaseAllUsageInfoError2; + case wvcdm::REMOVE_ALL_USAGE_INFO_ERROR_1: + return kRemoveAllUsageInfoError1; + case wvcdm::REMOVE_ALL_USAGE_INFO_ERROR_2: + return kRemoveAllUsageInfoError2; case wvcdm::RELEASE_KEY_ERROR: return kReleaseKeyError; case wvcdm::RELEASE_KEY_REQUEST_ERROR: @@ -447,10 +447,10 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kIncorrectUsageSupportType1; case wvcdm::INCORRECT_USAGE_SUPPORT_TYPE_2: return kIncorrectUsageSupportType2; - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_4: - return kReleaseAllUsageInfoError4; - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_5: - return kReleaseAllUsageInfoError5; + case wvcdm::REMOVE_ALL_USAGE_INFO_ERROR_4: + return kRemoveAllUsageInfoError4; + case wvcdm::REMOVE_ALL_USAGE_INFO_ERROR_5: + return kRemoveAllUsageInfoError5; case wvcdm::NO_USAGE_ENTRIES: return kNoUsageEntries; case wvcdm::LIST_LICENSE_ERROR_1: @@ -489,10 +489,10 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kUsageStoreEntryRetrieveUsageInfoFailed; case wvcdm::USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE: return kUsageStoreEntryRetrieveInvalidStorageType; - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_6: - return kReleaseAllUsageInfoError6; - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_7: - return kReleaseAllUsageInfoError7; + case wvcdm::REMOVE_ALL_USAGE_INFO_ERROR_6: + return kRemoveAllUsageInfoError6; + case wvcdm::REMOVE_ALL_USAGE_INFO_ERROR_7: + return kRemoveAllUsageInfoError7; case wvcdm::LICENSE_REQUEST_INVALID_SUBLICENSE: return kLicenseRequestInvalidSublicense; case wvcdm::CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE: @@ -503,6 +503,12 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kInsufficientCryptoResources4; case wvcdm::INSUFFICIENT_CRYPTO_RESOURCES_5: return kInsufficientCryptoResources5; + case wvcdm::REMOVE_USAGE_INFO_ERROR_1: + return kRemoveUsageInfoError1; + case wvcdm::REMOVE_USAGE_INFO_ERROR_2: + return kRemoveUsageInfoError2; + case wvcdm::REMOVE_USAGE_INFO_ERROR_3: + return kRemoveUsageInfoError3; } // Return here instead of as a default case so that the compiler will warn diff --git a/libwvdrmengine/include_hidl/mapErrors-inl.h b/libwvdrmengine/include_hidl/mapErrors-inl.h index 6229f10a..e64601c7 100644 --- a/libwvdrmengine/include_hidl/mapErrors-inl.h +++ b/libwvdrmengine/include_hidl/mapErrors-inl.h @@ -145,8 +145,8 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) { case wvcdm::LOAD_KEY_ERROR: case wvcdm::NO_CONTENT_KEY: case wvcdm::REFRESH_KEYS_ERROR: - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_1: - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_2: + case wvcdm::REMOVE_ALL_USAGE_INFO_ERROR_1: + case wvcdm::REMOVE_ALL_USAGE_INFO_ERROR_2: case wvcdm::RELEASE_KEY_ERROR: case wvcdm::RELEASE_KEY_REQUEST_ERROR: case wvcdm::RELEASE_LICENSE_ERROR_1: @@ -264,10 +264,10 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) { case wvcdm::USAGE_STORE_LICENSE_FAILED: case wvcdm::USAGE_STORE_USAGE_INFO_FAILED: case wvcdm::USAGE_INVALID_LOAD_ENTRY: - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_4: - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_5: - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_6: - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_7: + case wvcdm::REMOVE_ALL_USAGE_INFO_ERROR_4: + case wvcdm::REMOVE_ALL_USAGE_INFO_ERROR_5: + case wvcdm::REMOVE_ALL_USAGE_INFO_ERROR_6: + case wvcdm::REMOVE_ALL_USAGE_INFO_ERROR_7: case wvcdm::INCORRECT_USAGE_SUPPORT_TYPE_1: case wvcdm::INCORRECT_USAGE_SUPPORT_TYPE_2: case wvcdm::NO_USAGE_ENTRIES: @@ -288,6 +288,9 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) { case wvcdm::PARSE_RESPONSE_ERROR_3: case wvcdm::PARSE_RESPONSE_ERROR_4: case wvcdm::LOAD_SYSTEM_ID_ERROR: + case wvcdm::REMOVE_USAGE_INFO_ERROR_1: + case wvcdm::REMOVE_USAGE_INFO_ERROR_2: + case wvcdm::REMOVE_USAGE_INFO_ERROR_3: ALOGW("Returns UNKNOWN error for legacy status: %d", res); return Status::ERROR_DRM_UNKNOWN; diff --git a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp index 169e7949..6782fdd1 100644 --- a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp @@ -457,8 +457,8 @@ status_t WVDrmPlugin::getSecureStops(List >& secureStops) { } status_t WVDrmPlugin::releaseAllSecureStops() { - CdmResponseType res = mCDM->ReleaseAllUsageInfo(mPropertySet.app_id(), - mCdmIdentifier); + CdmResponseType res = mCDM->RemoveAllUsageInfo(mPropertySet.app_id(), + mCdmIdentifier); return mapCdmResponseType(res); } diff --git a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp index cc9003d6..58d08b7c 100644 --- a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp @@ -609,8 +609,8 @@ Return WVDrmPlugin::releaseAllSecureStops() { return status; } - CdmResponseType res = mCDM->ReleaseAllUsageInfo(mPropertySet.app_id(), - identifier); + CdmResponseType res = mCDM->RemoveAllUsageInfo(mPropertySet.app_id(), + identifier); return mapCdmResponseType(res); } diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp index 14f20c51..b20edf2d 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp @@ -190,8 +190,8 @@ class MockCDM : public WvContentDecryptionModule { const CdmIdentifier&, CdmUsageInfo*)); - MOCK_METHOD2(ReleaseAllUsageInfo, CdmResponseType(const std::string&, - const CdmIdentifier&)); + MOCK_METHOD2(RemoveAllUsageInfo, CdmResponseType(const std::string&, + const CdmIdentifier&)); MOCK_METHOD2(ReleaseUsageInfo, CdmResponseType(const CdmUsageInfoReleaseMessage&, const CdmIdentifier&)); @@ -1026,7 +1026,7 @@ TEST_F(WVDrmPluginTest, ReleasesAllSecureStops) { StrictMock crypto; std::string appPackageName; - EXPECT_CALL(*cdm, ReleaseAllUsageInfo(StrEq(""), _)) + EXPECT_CALL(*cdm, RemoveAllUsageInfo(StrEq(""), _)) .Times(1); WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); diff --git a/libwvdrmengine/mediadrm/test/legacy_src/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/legacy_src/WVDrmPlugin_test.cpp index c496291b..50fddc43 100644 --- a/libwvdrmengine/mediadrm/test/legacy_src/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/legacy_src/WVDrmPlugin_test.cpp @@ -100,8 +100,8 @@ class MockCDM : public WvContentDecryptionModule { const CdmIdentifier&, CdmUsageInfo*)); - MOCK_METHOD2(ReleaseAllUsageInfo, CdmResponseType(const std::string&, - const CdmIdentifier&)); + MOCK_METHOD2(RemoveAllUsageInfo, CdmResponseType(const std::string&, + const CdmIdentifier&)); MOCK_METHOD2(ReleaseUsageInfo, CdmResponseType(const CdmUsageInfoReleaseMessage&, const CdmIdentifier&)); @@ -800,7 +800,7 @@ TEST_F(WVDrmPluginTest, ReleasesAllSecureStops) { status_t res = plugin.setPropertyString(String8("appId"), String8("")); ASSERT_EQ(OK, res); - EXPECT_CALL(*cdm, ReleaseAllUsageInfo(StrEq(""), _)) + EXPECT_CALL(*cdm, RemoveAllUsageInfo(StrEq(""), _)) .Times(1); res = plugin.releaseAllSecureStops(); From 4ba82e458595b303e59d721549808667be82aafe Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Fri, 9 Mar 2018 00:04:30 -0800 Subject: [PATCH 2/2] Secure stop API related changes [ Merge of http://go/wvgerrit/44921 ] * Added the ability to remove a single usage information record. * Added a method to retrieve all secure stop Ids. Bug: 69674645 Test: WV unit, integration tests Change-Id: I04ac8224b4bdda69541e61ff1103af3836138228 --- libwvdrmengine/cdm/core/include/cdm_engine.h | 14 +- .../cdm/core/include/device_files.h | 10 +- libwvdrmengine/cdm/core/src/cdm_engine.cpp | 97 ++++- libwvdrmengine/cdm/core/src/cdm_session.cpp | 20 +- libwvdrmengine/cdm/core/src/device_files.cpp | 25 +- .../cdm/core/test/device_files_unittest.cpp | 174 +++++++++ .../include/wv_content_decryption_module.h | 8 + .../cdm/src/wv_content_decryption_module.cpp | 31 ++ .../cdm/test/request_license_test.cpp | 349 +++++++++++++++++- 9 files changed, 700 insertions(+), 28 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/cdm_engine.h b/libwvdrmengine/cdm/core/include/cdm_engine.h index c1d485ba..754960e4 100644 --- a/libwvdrmengine/cdm/core/include/cdm_engine.h +++ b/libwvdrmengine/cdm/core/include/cdm_engine.h @@ -188,11 +188,13 @@ class CdmEngine { virtual CdmResponseType ListStoredLicenses( CdmSecurityLevel security_level, std::vector* key_set_ids); - // Return the list of key_set_ids stored as usage records on the - // current (origin-specific) file system. - virtual CdmResponseType ListUsageRecords( + // Return the list of IDs associated with usage records for the + // current (origin-specific) file system. At least one parameter + // |ksids| or |provider_session_tokens| needs to be supplied. + virtual CdmResponseType ListUsageIds( const std::string& app_id, CdmSecurityLevel security_level, - std::vector* ksids); + std::vector* ksids, + std::vector* provider_session_tokens); // Delete the usage record for the given key_set_id. This removes the // usage record in the file system and the OEMCrypto usage record. @@ -220,6 +222,10 @@ class CdmEngine { // security levels. virtual CdmResponseType RemoveAllUsageInfo(const std::string& app_id); + virtual CdmResponseType RemoveUsageInfo( + const std::string& app_id, + const CdmSecureStopId& secure_stop_id); + virtual CdmResponseType ReleaseUsageInfo( const CdmUsageInfoReleaseMessage& message); virtual CdmResponseType LoadUsageSession(const CdmKeySetId& key_set_id, diff --git a/libwvdrmengine/cdm/core/include/device_files.h b/libwvdrmengine/cdm/core/include/device_files.h index 13aad015..a08a7c2b 100644 --- a/libwvdrmengine/cdm/core/include/device_files.h +++ b/libwvdrmengine/cdm/core/include/device_files.h @@ -105,9 +105,13 @@ class DeviceFiles { const CdmUsageEntry& usage_entry, uint32_t usage_entry_number); - // Extract KSIDs from usage information on the file system. - virtual bool ListUsageRecords(const std::string& app_id, - std::vector* ksids); + // Retrieve usage identifying information stored on the file system. + // The caller needs to specify at least one of |ksids| or + // |provider_session_tokens| + virtual bool ListUsageIds( + const std::string& app_id, + std::vector* ksids, + std::vector* provider_session_tokens); // Get the provider session token for the given key_set_id. virtual bool GetProviderSessionToken(const std::string& app_id, diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 5a214b0a..8027f0bb 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -929,20 +929,22 @@ CdmResponseType CdmEngine::ListStoredLicenses( return NO_ERROR; } -CdmResponseType CdmEngine::ListUsageRecords(const std::string& app_id, - CdmSecurityLevel security_level, - std::vector* ksids) { +CdmResponseType CdmEngine::ListUsageIds( + const std::string& app_id, + CdmSecurityLevel security_level, + std::vector* ksids, + std::vector* provider_session_tokens) { DeviceFiles handle(file_system_); - if (!ksids) { - LOGE("CdmEngine::ListUsageRecords: no response destination"); + if (!ksids && !provider_session_tokens) { + LOGE("CdmEngine::ListUsageIds: no response destination"); return INVALID_PARAMETERS_ENG_23; } if (!handle.Init(security_level)) { - LOGE("CdmEngine::ListUsageRecords: unable to initialize device files"); + LOGE("CdmEngine::ListUsageIds: unable to initialize device files"); return LIST_USAGE_ERROR_1; } - if (!handle.ListUsageRecords(app_id, ksids)) { - LOGE("CdmEngine::ListUsageRecords: ListUsageRecords call failed"); + if (!handle.ListUsageIds(app_id, ksids, provider_session_tokens)) { + LOGE("CdmEngine::ListUsageIds: ListUsageIds call failed"); return LIST_USAGE_ERROR_2; } return NO_ERROR; @@ -1272,6 +1274,85 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo(const std::string& app_id) { return status; } +CdmResponseType CdmEngine::RemoveUsageInfo( + const std::string& app_id, + const CdmSecureStopId& provider_session_token) { + if (NULL == usage_property_set_.get()) { + usage_property_set_.reset(new UsagePropertySet()); + } + usage_property_set_->set_app_id(app_id); + + CdmResponseType status = NO_ERROR; + for (int j = kSecurityLevelL1; j < kSecurityLevelUnknown; ++j) { + DeviceFiles handle(file_system_); + if (handle.Init(static_cast(j))) { + SecurityLevel security_level = + static_cast(j) == kSecurityLevelL3 + ? kLevel3 + : kLevelDefault; + usage_property_set_->set_security_level(security_level); + usage_session_.reset(new CdmSession(file_system_, metrics_.AddSession())); + usage_session_->Init(usage_property_set_.get()); + + std::vector usage_data; + CdmKeyMessage license_request; + CdmKeyResponse license_response; + CdmUsageEntry usage_entry; + uint32_t usage_entry_number; + + if (!handle.RetrieveUsageInfo( + DeviceFiles::GetUsageInfoFileName(app_id), provider_session_token, + &license_request, &license_response, &usage_entry, + &usage_entry_number)) { + // Try other security level + continue; + } + + switch (usage_session_->get_usage_support_type()) { + case kUsageEntrySupport: { + status = usage_session_->DeleteUsageEntry( + usage_data[0].usage_entry_number); + + if (!handle.DeleteUsageInfo( + DeviceFiles::GetUsageInfoFileName(app_id), + provider_session_token)) { + status = REMOVE_USAGE_INFO_ERROR_1; + } + usage_session_.reset(NULL); + return status; + } + case kUsageTableSupport: { + std::vector provider_session_tokens; + handle.DeleteUsageInfo( + DeviceFiles::GetUsageInfoFileName(app_id), + provider_session_token); + scoped_ptr crypto_session( + new CryptoSession(metrics_.GetCryptoMetrics())); + status = crypto_session->Open( + static_cast(j) == kSecurityLevelL3 + ? kLevel3 : kLevelDefault); + if (status == NO_ERROR) { + crypto_session->UpdateUsageInformation(); + status = + crypto_session->DeleteUsageInformation(provider_session_token); + crypto_session->UpdateUsageInformation(); + } + return status; + } + default: + // Ignore + break; + } + } else { + LOGE("CdmEngine::RemoveUsageInfo: failed to initialize L%d devicefiles", + j); + status = REMOVE_USAGE_INFO_ERROR_2; + } + } + usage_session_.reset(NULL); + return REMOVE_USAGE_INFO_ERROR_3; +} + CdmResponseType CdmEngine::ReleaseUsageInfo( const CdmUsageInfoReleaseMessage& message) { if (NULL == usage_session_.get()) { diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index bc7876b0..3de40213 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -868,10 +868,22 @@ void CdmSession::GetApplicationId(std::string* app_id) { CdmResponseType CdmSession::DeleteMultipleUsageInformation( const std::vector& provider_session_tokens) { - CdmResponseType sts = crypto_session_->DeleteMultipleUsageInformation( - provider_session_tokens); - crypto_metrics_->crypto_session_delete_multiple_usage_information_ - .Increment(sts); + CdmUsageSupportType usage_support_type; + CdmResponseType sts = + crypto_session_->GetUsageSupportType(&usage_support_type); + if (sts == NO_ERROR && usage_support_type == kUsageTableSupport) { + for (size_t i = 0; i < provider_session_tokens.size(); ++i) { + crypto_session_->DeactivateUsageInformation(provider_session_tokens[i]); + UpdateUsageTableInformation(); + } + } + + if (sts == NO_ERROR) { + sts = crypto_session_->DeleteMultipleUsageInformation( + provider_session_tokens); + crypto_metrics_->crypto_session_delete_multiple_usage_information_ + .Increment(sts); + } return sts; } diff --git a/libwvdrmengine/cdm/core/src/device_files.cpp b/libwvdrmengine/cdm/core/src/device_files.cpp index 4db8d3de..8ae95fc5 100644 --- a/libwvdrmengine/cdm/core/src/device_files.cpp +++ b/libwvdrmengine/cdm/core/src/device_files.cpp @@ -464,22 +464,25 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token, return StoreFileWithHash(usage_info_file_name, serialized_file); } -bool DeviceFiles::ListUsageRecords(const std::string& app_id, - std::vector* ksids) { +bool DeviceFiles::ListUsageIds( + const std::string& app_id, + std::vector* ksids, + std::vector* provider_session_tokens) { if (!initialized_) { - LOGW("DeviceFiles::ListUsageRecords: not initialized"); + LOGW("DeviceFiles::ListUsageIds: not initialized"); return false; } - if (ksids == NULL) { - LOGW("DeviceFiles::ListUsageRecords: return parameter not provided"); + if (ksids == NULL && provider_session_tokens == NULL) { + LOGW("DeviceFiles::ListUsageIds: ksids or pst parameter not provided"); return false; } // Empty or non-existent file == no usage records. std::string file_name = GetUsageInfoFileName(app_id); if (!FileExists(file_name) || GetFileSize(file_name) == 0) { - ksids->clear(); + if (ksids != NULL) ksids->clear(); + if (provider_session_tokens != NULL) provider_session_tokens->clear(); return true; } @@ -489,13 +492,19 @@ bool DeviceFiles::ListUsageRecords(const std::string& app_id, return false; } - ksids->clear(); + if (ksids != NULL) ksids->clear(); + if (provider_session_tokens != NULL) provider_session_tokens->clear(); size_t num_records = file.usage_info().sessions_size(); for (size_t i = 0; i < num_records; ++i) { - if (!file.usage_info().sessions(i).key_set_id().empty()) { + if ((ksids != NULL) && + !file.usage_info().sessions(i).key_set_id().empty()) { ksids->push_back(file.usage_info().sessions(i).key_set_id()); } + if ((provider_session_tokens != NULL) && + !file.usage_info().sessions(i).token().empty()) { + provider_session_tokens->push_back(file.usage_info().sessions(i).token()); + } } return true; } diff --git a/libwvdrmengine/cdm/core/test/device_files_unittest.cpp b/libwvdrmengine/cdm/core/test/device_files_unittest.cpp index 1fe4632b..87c1f8e8 100644 --- a/libwvdrmengine/cdm/core/test/device_files_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/device_files_unittest.cpp @@ -2629,6 +2629,73 @@ TEST_F(DeviceFilesUsageInfoTest, ListNullParam) { EXPECT_FALSE(device_files.ListUsageInfoFiles(NULL)); } +TEST_F(DeviceFilesUsageInfoTest, ListIdsNull) { + MockFileSystem file_system; + MockFile file; + + std::string app_id = kUsageInfoTestData[0].app_id; + + DeviceFiles device_files(&file_system); + EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); + EXPECT_FALSE(device_files.ListUsageIds(app_id, NULL, NULL)); +} + +TEST_F(DeviceFilesUsageInfoTest, ListUsageIds) { + MockFileSystem file_system; + MockFile file; + + int index = 8; + std::string app_id = kUsageInfoTestData[index].app_id; + + std::string file_name = DeviceFiles::GetUsageInfoFileName(app_id); + std::string path = device_base_path_ + file_name; + std::string file_data = (index < 0) ? kEmptyUsageInfoFileData + : kUsageInfoTestData[index].file_data; + if (index >= 0) { + EXPECT_CALL(file_system, Exists(StrEq(path))) + .Times(2) + .WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, FileSize(StrEq(path))) + .Times(2) + .WillRepeatedly(Return(kUsageInfoTestData[index].file_data.size())); + EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file)); + EXPECT_CALL(file, + Read(NotNull(), Eq(kUsageInfoTestData[index].file_data.size()))) + .WillOnce(DoAll(SetArrayArgument<0>(file_data.begin(), file_data.end()), + Return(file_data.size()))); + EXPECT_CALL(file, Close()); + } + else { + EXPECT_CALL(file_system, Exists(StrEq(path))) + .WillOnce(Return(false)); + } + + DeviceFiles device_files(&file_system); + EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); + + std::vector key_set_ids; + std::vector provider_session_tokens; + EXPECT_TRUE(device_files.ListUsageIds( + app_id, &key_set_ids, &provider_session_tokens)); + + EXPECT_EQ(key_set_ids.size(), provider_session_tokens.size()); + if (index >= 0) { + for (size_t i = 0; i < provider_session_tokens.size(); ++i) { + bool found = false; + for (int j = 0; !found && j <= index; ++j) { + if (app_id == kUsageInfoTestData[j].app_id && + kUsageInfoTestData[j].usage_data.provider_session_token == + provider_session_tokens[i] && + kUsageInfoTestData[j].usage_data.key_set_id == + key_set_ids[i]) { + found = true; + } + } + EXPECT_TRUE(found); + } + } +} + TEST_P(DeviceFilesUsageInfoListTest, UsageInfoList) { MockFileSystem file_system; MockFile file; @@ -2767,6 +2834,113 @@ TEST_P(DeviceFilesUsageInfoTest, Retrieve) { } } +TEST_P(DeviceFilesUsageInfoTest, ListKeySetIds) { + MockFileSystem file_system; + MockFile file; + + int index = GetParam(); + + std::string app_id; + if (index >= 0) app_id = kUsageInfoTestData[index].app_id; + + std::string file_name = DeviceFiles::GetUsageInfoFileName(app_id); + std::string path = device_base_path_ + file_name; + std::string file_data = (index < 0) ? kEmptyUsageInfoFileData + : kUsageInfoTestData[index].file_data; + if (index >= 0) { + EXPECT_CALL(file_system, Exists(StrEq(path))) + .Times(2) + .WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, FileSize(StrEq(path))) + .Times(2) + .WillRepeatedly(Return(kUsageInfoTestData[index].file_data.size())); + EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file)); + EXPECT_CALL(file, + Read(NotNull(), Eq(kUsageInfoTestData[index].file_data.size()))) + .WillOnce(DoAll(SetArrayArgument<0>(file_data.begin(), file_data.end()), + Return(file_data.size()))); + EXPECT_CALL(file, Close()); + } + else { + EXPECT_CALL(file_system, Exists(StrEq(path))) + .WillOnce(Return(false)); + } + + DeviceFiles device_files(&file_system); + EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); + + std::vector key_set_ids; + EXPECT_TRUE(device_files.ListUsageIds(app_id, &key_set_ids, NULL)); + + if (index >= 0) { + for (size_t i = 0; i < key_set_ids.size(); ++i) { + bool found = false; + for (int j = 0; !found && j <= index; ++j) { + if (app_id == kUsageInfoTestData[j].app_id && + kUsageInfoTestData[j].usage_data.key_set_id == + key_set_ids[i]) { + found = true; + } + } + EXPECT_TRUE(found); + } + } +} + +TEST_P(DeviceFilesUsageInfoTest, ListProviderSessionTokenIds) { + MockFileSystem file_system; + MockFile file; + + int index = GetParam(); + + std::string app_id; + if (index >= 0) app_id = kUsageInfoTestData[index].app_id; + + std::string file_name = DeviceFiles::GetUsageInfoFileName(app_id); + std::string path = device_base_path_ + file_name; + std::string file_data = (index < 0) ? kEmptyUsageInfoFileData + : kUsageInfoTestData[index].file_data; + if (index >= 0) { + EXPECT_CALL(file_system, Exists(StrEq(path))) + .Times(2) + .WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, FileSize(StrEq(path))) + .Times(2) + .WillRepeatedly(Return(kUsageInfoTestData[index].file_data.size())); + EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file)); + EXPECT_CALL(file, + Read(NotNull(), Eq(kUsageInfoTestData[index].file_data.size()))) + .WillOnce(DoAll(SetArrayArgument<0>(file_data.begin(), file_data.end()), + Return(file_data.size()))); + EXPECT_CALL(file, Close()); + } + else { + EXPECT_CALL(file_system, Exists(StrEq(path))) + .WillOnce(Return(false)); + } + + DeviceFiles device_files(&file_system); + EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); + + std::vector provider_session_tokens; + EXPECT_TRUE( + device_files.ListUsageIds(app_id, NULL, &provider_session_tokens)); + + if (index >= 0) { + for (size_t i = 0; i < provider_session_tokens.size(); ++i) { + bool found = false; + for (int j = 0; !found && j <= index; ++j) { + if (app_id == kUsageInfoTestData[j].app_id && + kUsageInfoTestData[j].usage_data.provider_session_token == + provider_session_tokens[i]) { + found = true; + } + } + EXPECT_TRUE(found); + } + } +} + TEST_P(DeviceFilesUsageInfoTest, RetrieveByProviderSessionToken) { MockFileSystem file_system; MockFile file; diff --git a/libwvdrmengine/cdm/include/wv_content_decryption_module.h b/libwvdrmengine/cdm/include/wv_content_decryption_module.h index 4c5fe843..52957731 100644 --- a/libwvdrmengine/cdm/include/wv_content_decryption_module.h +++ b/libwvdrmengine/cdm/include/wv_content_decryption_module.h @@ -107,10 +107,18 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler { CdmUsageInfo* usage_info); virtual CdmResponseType RemoveAllUsageInfo(const std::string& app_id, const CdmIdentifier& identifier); + virtual CdmResponseType RemoveUsageInfo( + const std::string& app_id, + const CdmIdentifier& identifier, + const CdmSecureStopId& secure_stop_id); virtual CdmResponseType ReleaseUsageInfo( const CdmUsageInfoReleaseMessage& message, const CdmIdentifier& identifier); + virtual CdmResponseType GetSecureStopIds(const std::string& app_id, + const CdmIdentifier& identifier, + std::vector* ssids); + // Accept encrypted buffer and decrypt data. // Decryption parameters that need to be specified are // is_encrypted, is_secure, key_id, encrypt_buffer, encrypt_length, diff --git a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp index 4e5d18a0..666fe7f2 100644 --- a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp +++ b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp @@ -305,6 +305,16 @@ CdmResponseType WvContentDecryptionModule::RemoveAllUsageInfo( return sts; } +CdmResponseType WvContentDecryptionModule::RemoveUsageInfo( + const std::string& app_id, + const CdmIdentifier& identifier, + const CdmSecureStopId& secure_stop_id) { + CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); + CdmResponseType sts = cdm_engine->RemoveUsageInfo(app_id, secure_stop_id); + cdm_engine->GetMetrics()->cdm_engine_remove_usage_info_.Increment(sts); + return sts; +} + CdmResponseType WvContentDecryptionModule::ReleaseUsageInfo( const CdmUsageInfoReleaseMessage& message, const CdmIdentifier& identifier) { @@ -314,6 +324,27 @@ CdmResponseType WvContentDecryptionModule::ReleaseUsageInfo( return sts; } +CdmResponseType WvContentDecryptionModule::GetSecureStopIds( + const std::string& app_id, + const CdmIdentifier& identifier, + std::vector* ssids) { + if (ssids == NULL) { + LOGE("WvContentDecryptionModule::Decrypt: ssid destination not provided"); + return PARAMETER_NULL; + } + + CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); + CdmResponseType sts = cdm_engine->ListUsageIds(app_id, kSecurityLevelL1, + NULL, ssids); + std::vector secure_stop_ids; + CdmResponseType sts_l3 = cdm_engine->ListUsageIds(app_id, kSecurityLevelL3, + NULL, &secure_stop_ids); + ssids->insert(ssids->end(), secure_stop_ids.begin(), secure_stop_ids.end()); + if (sts_l3 != NO_ERROR) sts = sts_l3; + cdm_engine->GetMetrics()->cdm_engine_get_secure_stop_ids_.Increment(sts); + return sts; +} + CdmResponseType WvContentDecryptionModule::Decrypt( const CdmSessionId& session_id, bool validate_key_id, diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index ddae4bdc..25549269 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -37,6 +37,7 @@ using ::testing::IsEmpty; using ::testing::Not; using ::testing::Pair; using ::testing::StrictMock; +using ::testing::UnorderedElementsAreArray; namespace { @@ -418,6 +419,55 @@ UsageInfoSubSampleInfo usage_info_sub_sample_info[] = { {&usage_info_sub_samples_icp[0], 5, wvcdm::kLevel3, ""}, {&usage_info_sub_samples_icp[0], 3, wvcdm::kLevel3, "other app id"}}; +struct UsageLicenseAndSubSampleInfo { + std::string pssh; + SubSampleInfo* sub_sample; + std::string provider_session_token; +}; + +std::string kPsshStreamingClip3 = wvcdm::a2bs_hex( + "000000427073736800000000" // blob size and pssh + "EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id + "08011a0d7769646576696e655f74657374220f73" // pssh data + "747265616d696e675f636c697033"); +std::string kPsshStreamingClip4 = wvcdm::a2bs_hex( + "000000427073736800000000" // blob size and pssh + "EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id + "08011a0d7769646576696e655f74657374220f73" // pssh data + "747265616d696e675f636c697034"); +std::string kPsshStreamingClip5 = wvcdm::a2bs_hex( + "000000427073736800000000" // blob size and pssh + "EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id + "08011a0d7769646576696e655f74657374220f73" // pssh data + "747265616d696e675f636c697035"); +std::string kPsshStreamingClip7 = wvcdm::a2bs_hex( + "000000427073736800000000" // blob size and pssh + "EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id + "08011a0d7769646576696e655f74657374220f73" // pssh data + "747265616d696e675f636c697037"); + +std::string kProviderSessionTokenStreamingClip3 = wvcdm::a2bs_hex( + "4851305A4A4156485A554936444E4931"); +std::string kProviderSessionTokenStreamingClip4 = wvcdm::a2bs_hex( + "4942524F4355544E5557553145463243"); +std::string kProviderSessionTokenStreamingClip7 = wvcdm::a2bs_hex( + "44434C53524F4E30394C4E5535544B4C"); + +UsageLicenseAndSubSampleInfo kUsageLicenseTestVector1[] = { + { kPsshStreamingClip3, &usage_info_sub_samples_icp[0], + kProviderSessionTokenStreamingClip3 }, + { kPsshStreamingClip4, &usage_info_sub_samples_icp[1], + kProviderSessionTokenStreamingClip4 }, +}; + +UsageLicenseAndSubSampleInfo kUsageLicenseTestVector2[] = { + { kPsshStreamingClip7, &usage_info_sub_samples_icp[4], + kProviderSessionTokenStreamingClip7 }, + // TODO(rfrias): Add another streaming usage license. Streaming + // clip 5 has includes a randomly generated PST, while + // streaming clip 6 does not include a PST. +}; + struct RenewWithClientIdTestConfiguration { bool always_include_client_id; bool specify_app_parameters; @@ -1273,6 +1323,18 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { CdmAppParameterMap& app_parameters, CdmLicenseType license_type, CdmClientPropertySet* property_set) { + GenerateKeyRequest(expected_response, init_data_type, init_data, + app_parameters, license_type, kDefaultCdmIdentifier, + property_set); + } + + void GenerateKeyRequest(CdmResponseType expected_response, + const std::string& init_data_type, + const std::string& init_data, + CdmAppParameterMap& app_parameters, + CdmLicenseType license_type, + const CdmIdentifier& cdm_identifier, + CdmClientPropertySet* property_set) { CdmKeyRequest key_request; std::string key_set_id; license_type_ = license_type; @@ -1280,7 +1342,7 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { decryptor_.GenerateKeyRequest( session_id_, key_set_id, init_data_type, init_data, license_type, app_parameters, property_set, - kDefaultCdmIdentifier, &key_request)); + cdm_identifier, &key_request)); key_msg_ = key_request.message; EXPECT_EQ(0u, key_request.url.size()); } @@ -3054,6 +3116,291 @@ TEST_F(WvCdmRequestLicenseTest, UsageRemoveAllTest) { EXPECT_TRUE(usage_info.empty()); } +TEST_F(WvCdmRequestLicenseTest, GetSecureStopIdsTest) { + Unprovision(); + + std::string app_id_empty = ""; + + TestWvCdmClientPropertySet property_set; + Provision(kLevelDefault); + + CdmSecurityLevel security_level = GetDefaultSecurityLevel(); + FileSystem file_system; + DeviceFiles handle(&file_system); + EXPECT_TRUE(handle.Init(security_level)); + std::vector psts; + EXPECT_TRUE(handle.DeleteAllUsageInfoForApp( + DeviceFiles::GetUsageInfoFileName(""), &psts)); + + std::vector retrieved_secure_stop_ids; + EXPECT_EQ( + NO_ERROR, + decryptor_.GetSecureStopIds(app_id_empty, kDefaultCdmIdentifier, + &retrieved_secure_stop_ids)); + EXPECT_TRUE(retrieved_secure_stop_ids.empty()); + + // First fetch licenses for the default app + for (size_t i = 0; i < N_ELEM(kUsageLicenseTestVector1); ++i) { + SubSampleInfo* data = kUsageLicenseTestVector1[i].sub_sample; + + property_set.set_app_id(app_id_empty); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); + GenerateKeyRequest(kUsageLicenseTestVector1[i].pssh, kLicenseTypeStreaming, + &property_set); + + VerifyUsageKeyRequestResponse(g_license_server, g_client_auth); + + std::vector decrypt_buffer(data->encrypt_data.size()); + CdmDecryptionParameters decryption_parameters( + &data->key_id, &data->encrypt_data.front(), data->encrypt_data.size(), + &data->iv, data->block_offset, &decrypt_buffer[0]); + decryption_parameters.is_encrypted = data->is_encrypted; + decryption_parameters.is_secure = data->is_secure; + decryption_parameters.subsample_flags = data->subsample_flags; + EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_, data->validate_key_id, + decryption_parameters)); + + EXPECT_TRUE(std::equal(data->decrypt_data.begin(), data->decrypt_data.end(), + decrypt_buffer.begin())); + decryptor_.CloseSession(session_id_); + } + + // Provision the other identifier + Provision(kExampleIdentifier, kLevelDefault); + + // Verify that there are usage records for the default identifier but + // none yet for the non-default one + std::vector expected_provider_session_tokens; + for (size_t i = 0; i < N_ELEM(kUsageLicenseTestVector1); ++i) { + expected_provider_session_tokens.push_back( + kUsageLicenseTestVector1[i].provider_session_token); + } + + EXPECT_EQ( + NO_ERROR, + decryptor_.GetSecureStopIds(app_id_empty, kDefaultCdmIdentifier, + &retrieved_secure_stop_ids)); + EXPECT_EQ(N_ELEM(kUsageLicenseTestVector1), retrieved_secure_stop_ids.size()); + EXPECT_THAT(retrieved_secure_stop_ids, + UnorderedElementsAreArray(expected_provider_session_tokens)); + + EXPECT_EQ( + NO_ERROR, + decryptor_.GetSecureStopIds(kExampleIdentifier.app_package_name, + kDefaultCdmIdentifier, + &retrieved_secure_stop_ids)); + EXPECT_TRUE(retrieved_secure_stop_ids.empty()); + + // Now fetch licenses for the other identifier + for (size_t i = 0; i < N_ELEM(kUsageLicenseTestVector2); ++i) { + SubSampleInfo* data = kUsageLicenseTestVector2[i].sub_sample; + + property_set.set_app_id(kExampleIdentifier.app_package_name); + EXPECT_EQ(NO_ERROR, + decryptor_.OpenSession(g_key_system, &property_set, + kExampleIdentifier, NULL, + &session_id_)); + std::string init_data_type = "video/mp4"; + CdmAppParameterMap app_parameters; + GenerateKeyRequest(wvcdm::KEY_MESSAGE, init_data_type, + kUsageLicenseTestVector2[i].pssh, app_parameters, + kLicenseTypeStreaming, kExampleIdentifier, + &property_set); + + VerifyUsageKeyRequestResponse(g_license_server, g_client_auth); + + std::vector decrypt_buffer(data->encrypt_data.size()); + CdmDecryptionParameters decryption_parameters( + &data->key_id, &data->encrypt_data.front(), data->encrypt_data.size(), + &data->iv, data->block_offset, &decrypt_buffer[0]); + decryption_parameters.is_encrypted = data->is_encrypted; + decryption_parameters.is_secure = data->is_secure; + decryption_parameters.subsample_flags = data->subsample_flags; + EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_, data->validate_key_id, + decryption_parameters)); + + EXPECT_TRUE(std::equal(data->decrypt_data.begin(), data->decrypt_data.end(), + decrypt_buffer.begin())); + decryptor_.CloseSession(session_id_); + } + + // Verify that there are usage records for both the default and + // non-default identifier. + EXPECT_EQ( + NO_ERROR, + decryptor_.GetSecureStopIds(kDefaultCdmIdentifier.app_package_name, + kDefaultCdmIdentifier, + &retrieved_secure_stop_ids)); + EXPECT_EQ(N_ELEM(kUsageLicenseTestVector1), retrieved_secure_stop_ids.size()); + EXPECT_THAT(retrieved_secure_stop_ids, + UnorderedElementsAreArray(expected_provider_session_tokens)); + + retrieved_secure_stop_ids.clear(); + expected_provider_session_tokens.clear(); + + for (size_t i = 0; i < N_ELEM(kUsageLicenseTestVector2); ++i) { + expected_provider_session_tokens.push_back( + kUsageLicenseTestVector2[i].provider_session_token); + } + + EXPECT_EQ( + NO_ERROR, + decryptor_.GetSecureStopIds(kExampleIdentifier.app_package_name, + kExampleIdentifier, + &retrieved_secure_stop_ids)); + EXPECT_EQ(N_ELEM(kUsageLicenseTestVector2), retrieved_secure_stop_ids.size()); + EXPECT_THAT(retrieved_secure_stop_ids, + UnorderedElementsAreArray(expected_provider_session_tokens)); + + EXPECT_EQ( + NO_ERROR, + decryptor_.RemoveAllUsageInfo(kDefaultCdmIdentifier.app_package_name, + kDefaultCdmIdentifier)); + EXPECT_EQ( + NO_ERROR, + decryptor_.RemoveAllUsageInfo(kExampleIdentifier.app_package_name, + kExampleIdentifier)); + + EXPECT_EQ( + NO_ERROR, + decryptor_.GetSecureStopIds(kDefaultCdmIdentifier.app_package_name, + kDefaultCdmIdentifier, + &retrieved_secure_stop_ids)); + EXPECT_TRUE(retrieved_secure_stop_ids.empty()); + EXPECT_EQ( + NO_ERROR, + decryptor_.GetSecureStopIds(kExampleIdentifier.app_package_name, + kExampleIdentifier, + &retrieved_secure_stop_ids)); + EXPECT_TRUE(retrieved_secure_stop_ids.empty()); +} + +TEST_F(WvCdmRequestLicenseTest, UsageRemoveSecureStopTest) { + Unprovision(); + + std::string app_id_empty = ""; + + TestWvCdmClientPropertySet property_set; + Provision(kLevelDefault); + + CdmSecurityLevel security_level = GetDefaultSecurityLevel(); + FileSystem file_system; + DeviceFiles handle(&file_system); + EXPECT_TRUE(handle.Init(security_level)); + std::vector psts; + EXPECT_TRUE(handle.DeleteAllUsageInfoForApp( + DeviceFiles::GetUsageInfoFileName(""), &psts)); + + // First fetch licenses for the default app + for (size_t i = 0; i < N_ELEM(kUsageLicenseTestVector1); ++i) { + SubSampleInfo* data = kUsageLicenseTestVector1[i].sub_sample; + + property_set.set_app_id(app_id_empty); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); + GenerateKeyRequest(kUsageLicenseTestVector1[i].pssh, kLicenseTypeStreaming, + &property_set); + + VerifyUsageKeyRequestResponse(g_license_server, g_client_auth); + + std::vector decrypt_buffer(data->encrypt_data.size()); + CdmDecryptionParameters decryption_parameters( + &data->key_id, &data->encrypt_data.front(), data->encrypt_data.size(), + &data->iv, data->block_offset, &decrypt_buffer[0]); + decryption_parameters.is_encrypted = data->is_encrypted; + decryption_parameters.is_secure = data->is_secure; + decryption_parameters.subsample_flags = data->subsample_flags; + EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_, data->validate_key_id, + decryption_parameters)); + + EXPECT_TRUE(std::equal(data->decrypt_data.begin(), data->decrypt_data.end(), + decrypt_buffer.begin())); + decryptor_.CloseSession(session_id_); + } + + // Provision and fetch licenses for the other identifier + Provision(kExampleIdentifier, kLevelDefault); + + for (size_t i = 0; i < N_ELEM(kUsageLicenseTestVector2); ++i) { + SubSampleInfo* data = kUsageLicenseTestVector2[i].sub_sample; + + property_set.set_app_id(kExampleIdentifier.app_package_name); + EXPECT_EQ(NO_ERROR, + decryptor_.OpenSession(g_key_system, &property_set, + kExampleIdentifier, NULL, + &session_id_)); + std::string init_data_type = "video/mp4"; + CdmAppParameterMap app_parameters; + GenerateKeyRequest(wvcdm::KEY_MESSAGE, init_data_type, + kUsageLicenseTestVector2[i].pssh, app_parameters, + kLicenseTypeStreaming, kExampleIdentifier, + &property_set); + + VerifyUsageKeyRequestResponse(g_license_server, g_client_auth); + + std::vector decrypt_buffer(data->encrypt_data.size()); + CdmDecryptionParameters decryption_parameters( + &data->key_id, &data->encrypt_data.front(), data->encrypt_data.size(), + &data->iv, data->block_offset, &decrypt_buffer[0]); + decryption_parameters.is_encrypted = data->is_encrypted; + decryption_parameters.is_secure = data->is_secure; + decryption_parameters.subsample_flags = data->subsample_flags; + EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_, data->validate_key_id, + decryption_parameters)); + + EXPECT_TRUE(std::equal(data->decrypt_data.begin(), data->decrypt_data.end(), + decrypt_buffer.begin())); + decryptor_.CloseSession(session_id_); + } + + // Release usage records for both the default and non-default identifier. + std::vector secure_stop_ids; + EXPECT_EQ( + NO_ERROR, + decryptor_.GetSecureStopIds(kDefaultCdmIdentifier.app_package_name, + kDefaultCdmIdentifier, + &secure_stop_ids)); + EXPECT_EQ(N_ELEM(kUsageLicenseTestVector1), secure_stop_ids.size()); + + for (size_t i = 0; i < N_ELEM(kUsageLicenseTestVector1); ++i) { + EXPECT_EQ( + NO_ERROR, + decryptor_.RemoveUsageInfo(kDefaultCdmIdentifier.app_package_name, + kDefaultCdmIdentifier, + secure_stop_ids[i])); + } + + EXPECT_EQ( + NO_ERROR, + decryptor_.GetSecureStopIds(kDefaultCdmIdentifier.app_package_name, + kDefaultCdmIdentifier, + &secure_stop_ids)); + EXPECT_TRUE(secure_stop_ids.empty()); + + EXPECT_EQ( + NO_ERROR, + decryptor_.GetSecureStopIds(kExampleIdentifier.app_package_name, + kExampleIdentifier, + &secure_stop_ids)); + EXPECT_EQ(N_ELEM(kUsageLicenseTestVector2), secure_stop_ids.size()); + + for (size_t i = 0; i < N_ELEM(kUsageLicenseTestVector2); ++i) { + EXPECT_EQ( + NO_ERROR, + decryptor_.RemoveUsageInfo(kExampleIdentifier.app_package_name, + kExampleIdentifier, + secure_stop_ids[i])); + } + + EXPECT_EQ( + NO_ERROR, + decryptor_.GetSecureStopIds(kExampleIdentifier.app_package_name, + kExampleIdentifier, + &secure_stop_ids)); + EXPECT_TRUE(secure_stop_ids.empty()); +} + TEST_F(WvCdmRequestLicenseTest, QueryUnmodifiedSessionStatus) { // Test that the global value is returned when no properties are modifying it. std::string security_level;