diff --git a/libwvdrmengine/Android.bp b/libwvdrmengine/Android.bp index 4e21fc5f..1b7fb375 100644 --- a/libwvdrmengine/Android.bp +++ b/libwvdrmengine/Android.bp @@ -99,6 +99,7 @@ cc_defaults { relative_install_path: "hw", include_dirs: [ "vendor/widevine/libwvdrmengine/cdm/core/include/", + "vendor/widevine/libwvdrmengine/cdm/util/include/", "vendor/widevine/libwvdrmengine/include", "vendor/widevine/libwvdrmengine/mediadrm/include", "vendor/widevine/libwvdrmengine/oemcrypto/include", diff --git a/libwvdrmengine/include/Utils.h b/libwvdrmengine/include/Utils.h index c18f2365..0c1a2b6b 100644 --- a/libwvdrmengine/include/Utils.h +++ b/libwvdrmengine/include/Utils.h @@ -42,6 +42,8 @@ inline ::ndk::ScopedAStatus toNdkScopedAStatus( return toNdkScopedAStatus(::wvdrm::WvStatus(status), msg); } +bool checkIfEnableMultiThreadBinder(); + } // namespace wvdrm #endif // WV_UTILS_H_ diff --git a/libwvdrmengine/src/Utils.cpp b/libwvdrmengine/src/Utils.cpp index 754f802e..f517518e 100644 --- a/libwvdrmengine/src/Utils.cpp +++ b/libwvdrmengine/src/Utils.cpp @@ -7,6 +7,8 @@ #include "Utils.h" #include +#include "WVCDMSingleton.h" +#include "log.h" #include @@ -163,4 +165,97 @@ CryptoSessionApi getCryptoSessionMethodEnum(const std::string& method) { err, writer.write(jsonMsg).c_str()); } +constexpr const char* kJsonKeySocVendor = "soc_vendor"; +constexpr const char* kJsonKeySocModel = "soc_model"; +constexpr const char* kJsonKeyFormFactor = "form_factor"; + +struct DeviceInfo { + std::string soc_vendor; + std::string soc_model; + std::string form_factor; +}; + +static std::vector const kMultiThreadBinderEnabledDevices = { + {"MediaTek", "mt*_multi_thread", "TV"}, +}; + +bool matchesSocModelPattern(const std::string& socModel) { + const std::string prefix = "mt"; + const std::string suffix = "_multi_thread"; + const size_t minLength = prefix.length() + suffix.length(); + + if (socModel.length() < minLength) { + return false; + } + + if (socModel.compare(0, prefix.length(), prefix) != 0) { + return false; + } + + if (socModel.compare(socModel.length() - suffix.length(), suffix.length(), suffix) != 0) { + return false; + } + + return true; +} + +bool checkIfEnableMultiThreadBinder() { + android::sp cdm = wvdrm::getCDM(); + if (cdm == nullptr) { + LOGW("Failed to get CDM when checking if multi-thread binder is enabled."); + return false; + } + std::string buildInfoValue; + cdm->QueryStatus(wvcdm::RequestedSecurityLevel::kLevelDefault, + wvcdm::QUERY_KEY_OEMCRYPTO_BUILD_INFORMATION, &buildInfoValue); + + Json::Reader reader; + Json::Value buildInfoJson; + if (!reader.parse(buildInfoValue, buildInfoJson)) { + LOGW("Failed to parse build info to JSON: %s", buildInfoValue.c_str()); + return false; + } + + if (!buildInfoJson.isMember(kJsonKeySocVendor) || + !buildInfoJson.isMember(kJsonKeySocModel) || + !buildInfoJson.isMember(kJsonKeyFormFactor)) { + return false; + } + + std::string currentSocVendor = buildInfoJson[kJsonKeySocVendor].asString(); + std::string currentSocModel = buildInfoJson[kJsonKeySocModel].asString(); + std::string currentFormFactor = buildInfoJson[kJsonKeyFormFactor].asString(); + + for (const auto& allowedDevice : kMultiThreadBinderEnabledDevices) { + if (allowedDevice.soc_vendor == currentSocVendor && + allowedDevice.form_factor == currentFormFactor) { + + if (allowedDevice.soc_vendor == "MediaTek" && + allowedDevice.soc_model == "mt*_multi_thread" && + allowedDevice.form_factor == "TV") + { + if (matchesSocModelPattern(currentSocModel)) { + LOGI("Multi-thread binder enabled for device via MediaTek TV pattern: " + "Model=%s matches pattern=%s", + currentSocModel.c_str(), + allowedDevice.soc_model.c_str()); + return true; + } + } else { + // For all other rules, perform an exact match on soc_model + if (allowedDevice.soc_model == currentSocModel) { + LOGI("Multi-thread binder enabled for device via exact match rule: " + "Vendor=%s, Model=%s, FormFactor=%s", + allowedDevice.soc_vendor.c_str(), + allowedDevice.soc_model.c_str(), + allowedDevice.form_factor.c_str()); + return true; + } + } + } + } + + return false; +} + } // namespace wvdrm diff --git a/libwvdrmengine/src/service.cpp b/libwvdrmengine/src/service.cpp index d30ad182..e3b2af6a 100644 --- a/libwvdrmengine/src/service.cpp +++ b/libwvdrmengine/src/service.cpp @@ -22,6 +22,7 @@ #include "WVCreatePluginFactories.h" #include "WVDrmFactory.h" +#include "Utils.h" using ::wvdrm::hardware::drm::widevine::createDrmFactory; using ::wvdrm::hardware::drm::widevine::WVDrmFactory; @@ -29,6 +30,9 @@ using ::wvdrm::hardware::drm::widevine::WVDrmFactory; int main(int /* argc */, char** /* argv */) { ABinderProcess_setThreadPoolMaxThreadCount(8); + if (wvdrm::checkIfEnableMultiThreadBinder()) { + ABinderProcess_startThreadPool(); + } std::shared_ptr drmFactory = createDrmFactory(); const std::string drmInstance = diff --git a/libwvdrmengine/src/serviceLazy.cpp b/libwvdrmengine/src/serviceLazy.cpp index 53312dab..c511314d 100644 --- a/libwvdrmengine/src/serviceLazy.cpp +++ b/libwvdrmengine/src/serviceLazy.cpp @@ -22,6 +22,7 @@ #include "WVCreatePluginFactories.h" #include "WVDrmFactory.h" +#include "Utils.h" using ::wvdrm::hardware::drm::widevine::createDrmFactory; using ::wvdrm::hardware::drm::widevine::WVDrmFactory; @@ -29,6 +30,9 @@ using ::wvdrm::hardware::drm::widevine::WVDrmFactory; int main(int /* argc */, char** /* argv */) { ABinderProcess_setThreadPoolMaxThreadCount(8); + if (wvdrm::checkIfEnableMultiThreadBinder()) { + ABinderProcess_startThreadPool(); + } std::shared_ptr drmFactory = createDrmFactory(); const std::string drmInstance =