diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h index 3db2a051..9724011e 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h @@ -48,7 +48,14 @@ static const char KEY_SET_ID_PREFIX[] = "ksid"; static const char KEY_SYSTEM[] = "com.widevine"; static const char ATSC_APP_PACKAGE_NAME[] = "org.atsc"; -// define query keys, values here +// Define query keys, values here. +// To expose these query items to Android update: +// android/mediadrm/src/WVDrmPlugin.cpp +// android/mediadrm/src_hidl/WVDrmPlugin.cpp +// Update test QueryStatus and QueryStatusL3 test for all possible outputs: +// android/cdm/test/request_license_test.cpp +// Update HIDL debug output: +// android/src_hidl/WVDrmFactory.cpp static const std::string QUERY_KEY_LICENSE_TYPE = "LicenseType"; // "Streaming", "Offline" static const std::string QUERY_KEY_PLAY_ALLOWED = @@ -96,10 +103,16 @@ static const std::string QUERY_KEY_MAX_USAGE_TABLE_ENTRIES = "MaxNumberOfUsageTableEntries"; static const std::string QUERY_KEY_OEMCRYPTO_API_MINOR_VERSION = "OemCryptoApiMinorVersion"; +static const std::string QUERY_KEY_ANALOG_OUTPUT_CAPABILITIES = + "AnalogOutputCapabilities"; +static const std::string QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT = + "CanDisableAnalogOutput"; static const std::string QUERY_VALUE_TRUE = "True"; static const std::string QUERY_VALUE_FALSE = "False"; static const std::string QUERY_VALUE_NONE = "None"; +static const std::string QUERY_VALUE_SUPPORTED = "Supported"; +static const std::string QUERY_VALUE_UNKNOWN = "Unknown"; static const std::string QUERY_VALUE_STREAMING = "Streaming"; static const std::string QUERY_VALUE_OFFLINE = "Offline"; static const std::string QUERY_VALUE_SECURITY_LEVEL_L1 = "L1"; @@ -118,6 +131,7 @@ static const std::string QUERY_VALUE_HDCP_LEVEL_UNKNOWN = "HDCP-LevelUnknown"; static const std::string QUERY_VALUE_DRM_CERTIFICATE = "DrmCertificate"; static const std::string QUERY_VALUE_KEYBOX = "Keybox"; static const std::string QUERY_VALUE_OEM_CERTIFICATE = "OEMCertificate"; +static const std::string QUERY_VALUE_CGMS_A = "CGMS-A"; static const std::string ISO_BMFF_VIDEO_MIME_TYPE = "video/mp4"; static const std::string ISO_BMFF_AUDIO_MIME_TYPE = "audio/mp4"; diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index ec6fdc78..0d7745cb 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -720,6 +720,32 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, *query_response = std::to_string(api_minor_version); return NO_ERROR; + } else if (query_token == QUERY_KEY_ANALOG_OUTPUT_CAPABILITIES) { + bool supported = false, can_disable = false, cgms_a = false; + if (crypto_session->GetAnalogOutputCapabilities(&supported, &can_disable, + &cgms_a)) { + if (supported) { + if (cgms_a) { + *query_response = QUERY_VALUE_CGMS_A; + } else { + *query_response = QUERY_VALUE_SUPPORTED; + } + } else { + *query_response = QUERY_VALUE_NONE; + } + } else { + *query_response = QUERY_VALUE_UNKNOWN; + } + return NO_ERROR; + } else if (query_token == QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT) { + bool supported = false, can_disable = false, cgms_a = false; + if (crypto_session->GetAnalogOutputCapabilities(&supported, &can_disable, + &cgms_a)) { + *query_response = can_disable ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; + } else { + *query_response = QUERY_VALUE_UNKNOWN; + } + return NO_ERROR; } M_TIME(status = crypto_session->Open(security_level), diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index ba939545..c2f186d9 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -2648,9 +2648,9 @@ bool CryptoSession::GetAnalogOutputCapabilities(bool* can_support_output, bool* can_disable_output, bool* can_support_cgms_a) { LOGV("Getting analog output capabilities: id = %u", oec_session_id_); - uint32_t flags; - WithOecReadLock("GetAnalogOutputCapabilities", [&] { - flags = OEMCrypto_GetAnalogOutputFlags(requested_security_level_); + RETURN_IF_UNINITIALIZED(false); + const uint32_t flags = WithOecReadLock("GetAnalogOutputCapabilities", [&] { + return OEMCrypto_GetAnalogOutputFlags(requested_security_level_); }); if ((flags & OEMCrypto_Unknown_Analog_Output) != 0) return false; diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index 6d612707..83a130a7 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -63,6 +63,14 @@ const wvcdm::CdmIdentifier kAlternateCdmIdentifier2 = { const std::string kEmptyServiceCertificate; const std::string kComma = ","; +// Analog output capabilities constants. +const std::vector kAnalogOutputCapabilities = { + wvcdm::QUERY_VALUE_NONE, wvcdm::QUERY_VALUE_SUPPORTED, + wvcdm::QUERY_VALUE_CGMS_A, wvcdm::QUERY_VALUE_UNKNOWN}; +const std::vector kCanDisableAnalogOutput = { + wvcdm::QUERY_VALUE_TRUE, wvcdm::QUERY_VALUE_FALSE, + wvcdm::QUERY_VALUE_UNKNOWN}; + // Protobuf generated classes using video_widevine::LicenseIdentification; using video_widevine::LicenseRequest_ContentIdentification; @@ -4985,6 +4993,18 @@ TEST_F(WvCdmRequestLicenseTest, QueryStatus) { ASSERT_FALSE(ss.fail()); EXPECT_TRUE(ss.eof()); EXPECT_LE(0u, api_minor_version); + + EXPECT_EQ( + wvcdm::NO_ERROR, + decryptor_->QueryStatus( + kLevelDefault, wvcdm::QUERY_KEY_ANALOG_OUTPUT_CAPABILITIES, &value)); + EXPECT_THAT(kAnalogOutputCapabilities, Contains(value)); + + EXPECT_EQ( + wvcdm::NO_ERROR, + decryptor_->QueryStatus( + kLevelDefault, wvcdm::QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT, &value)); + EXPECT_THAT(kCanDisableAnalogOutput, Contains(value)); } TEST_F(WvCdmRequestLicenseTest, QueryStatusL3) { @@ -5115,6 +5135,16 @@ TEST_F(WvCdmRequestLicenseTest, QueryStatusL3) { ASSERT_FALSE(ss.fail()); EXPECT_TRUE(ss.eof()); EXPECT_LE(200u, max_usage_table_entries); + + EXPECT_EQ(wvcdm::NO_ERROR, + decryptor_->QueryStatus( + kLevel3, wvcdm::QUERY_KEY_ANALOG_OUTPUT_CAPABILITIES, &value)); + EXPECT_THAT(kAnalogOutputCapabilities, Contains(value)); + + EXPECT_EQ(wvcdm::NO_ERROR, + decryptor_->QueryStatus( + kLevel3, wvcdm::QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT, &value)); + EXPECT_THAT(kCanDisableAnalogOutput, Contains(value)); } TEST_F(WvCdmRequestLicenseTest, QueryOemCryptoSessionId) { diff --git a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp index 70164ae4..7641e83a 100644 --- a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp @@ -555,6 +555,10 @@ status_t WVDrmPlugin::getPropertyString(const String8& name, return queryProperty(QUERY_KEY_MAX_USAGE_TABLE_ENTRIES, value); } else if (name == "oemCryptoApiMinorVersion") { return queryProperty(QUERY_KEY_OEMCRYPTO_API_MINOR_VERSION, value); + } else if (name == "analogOutputCapabilities") { + return queryProperty(QUERY_KEY_ANALOG_OUTPUT_CAPABILITIES, value); + } else if (name == "canDisableAnalogOutput") { + return queryProperty(QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT, value); } else if (name == "atscMode") { if (mPropertySet.use_atsc_mode()) { value = kEnable; diff --git a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp index 0bbb2dc9..78393f6d 100644 --- a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp @@ -1267,6 +1267,10 @@ Return WVDrmPlugin::getPropertyString(const hidl_string& propertyName, status = queryProperty(wvcdm::QUERY_KEY_MAX_USAGE_TABLE_ENTRIES, value); } else if (name == "oemCryptoApiMinorVersion") { status = queryProperty(wvcdm::QUERY_KEY_OEMCRYPTO_API_MINOR_VERSION, value); + } else if (name == "analogOutputCapabilities") { + status = queryProperty(wvcdm::QUERY_KEY_ANALOG_OUTPUT_CAPABILITIES, value); + } else if (name == "canDisableAnalogOutput") { + status = queryProperty(wvcdm::QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT, value); } else if (name == "atscMode") { if (mPropertySet.use_atsc_mode()) { value = kEnable; diff --git a/libwvdrmengine/src_hidl/WVDrmFactory.cpp b/libwvdrmengine/src_hidl/WVDrmFactory.cpp index b4ecfacd..3b9e7704 100644 --- a/libwvdrmengine/src_hidl/WVDrmFactory.cpp +++ b/libwvdrmengine/src_hidl/WVDrmFactory.cpp @@ -191,7 +191,7 @@ void WVDrmFactory::printCdmProperties(FILE* out) { cdm->IsSecurityLevelSupported(wvcdm::CdmSecurityLevel::kSecurityLevelL1); fprintf(out, "default security level: [%s]\n", isLevel1 ? "L1" : "L3"); - std::map cdmProperties = { + const std::map cdmProperties = { {"version- Widevine CDM:", wvcdm::QUERY_KEY_WVCDM_VERSION}, {"version- current SRM:", wvcdm::QUERY_KEY_CURRENT_SRM_VERSION}, {"version(major)- OEM Crypto API:", @@ -213,6 +213,9 @@ void WVDrmFactory::printCdmProperties(FILE* out) { {"OEM Crypto build info:", wvcdm::QUERY_KEY_OEMCRYPTO_BUILD_INFORMATION}, {"provisioning id:", wvcdm::QUERY_KEY_PROVISIONING_ID}, {"provisioning model:", wvcdm::QUERY_KEY_PROVISIONING_MODEL}, + {"analog capabilities:", wvcdm::QUERY_KEY_ANALOG_OUTPUT_CAPABILITIES}, + {"can disable analog output:", + wvcdm::QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT}, }; std::string value;