diff options
Diffstat (limited to 'drm/1.4/vts/functional/drm_hal_test.cpp')
-rw-r--r-- | drm/1.4/vts/functional/drm_hal_test.cpp | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/drm/1.4/vts/functional/drm_hal_test.cpp b/drm/1.4/vts/functional/drm_hal_test.cpp new file mode 100644 index 0000000000..f9fa0bde3b --- /dev/null +++ b/drm/1.4/vts/functional/drm_hal_test.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "drm_hal_test@1.4" + +#include "android/hardware/drm/1.4/vts/drm_hal_test.h" + +namespace android { +namespace hardware { +namespace drm { +namespace V1_4 { +namespace vts { + +const char* const DrmHalTest::kVideoMp4 = "video/mp4"; +const char* const DrmHalTest::kAudioMp4 = "audio/mp4"; +const uint32_t DrmHalTest::kSecLevelDefault = DrmHalTest::kSecLevelMax + 1; + +sp<drm::V1_4::IDrmPlugin> DrmHalTest::DrmPluginV1_4() const { + sp<drm::V1_4::IDrmPlugin> plugin(drm::V1_4::IDrmPlugin::castFrom(drmPlugin)); + EXPECT_NE(nullptr, plugin.get()); + return plugin; +} + +sp<V1_0::ICryptoPlugin> DrmHalTest::CryptoPlugin(const SessionId& sid) { + sp<V1_0::ICryptoPlugin> crypto; + auto res = cryptoFactory->createPlugin( + getUUID(), sid, + [&](V1_0::Status status, const sp<V1_0::ICryptoPlugin>& plugin) { + EXPECT_EQ(V1_0::Status::OK, status); + EXPECT_NE(nullptr, plugin.get()); + crypto = plugin; + }); + EXPECT_OK(res); + return crypto; +} + +SessionId DrmHalTest::OpenSession(uint32_t level = kSecLevelDefault) { + V1_0::Status err; + SessionId sessionId; + bool attemptedProvision = false; + + V1_0::IDrmPlugin::openSession_cb cb = [&]( + V1_0::Status status, + const hidl_vec<unsigned char> &id) { + err = status; + sessionId = id; + }; + + while (true) { + Return<void> res; + if (level > kSecLevelMax) { + res = drmPlugin->openSession(cb); + } else if (level >= kSecLevelMin) { + auto securityLevel = static_cast<SecurityLevel>(level); + res = drmPlugin->openSession_1_1(securityLevel, cb); + } + EXPECT_OK(res); + if (V1_0::Status::ERROR_DRM_NOT_PROVISIONED == err + && !attemptedProvision) { + // provision once if necessary + provision(); + attemptedProvision = true; + continue; + } else if (V1_0::Status::ERROR_DRM_CANNOT_HANDLE == err) { + // must be able to handle default level + EXPECT_NE(kSecLevelDefault, level); + sessionId = {}; + } else { + EXPECT_EQ(V1_0::Status::OK, err); + EXPECT_NE(sessionId.size(), 0u); + } + break; + } + + return sessionId; +} + +TEST_P(DrmHalTest, RequiresSecureDecoder) { + for (uint32_t level : {kSecLevelMin, kSecLevelMax, kSecLevelDefault}) { + for (auto mime : {kVideoMp4, kAudioMp4}) { + auto sid = OpenSession(level); + if (sid.size() == 0u) { + continue; + } + auto drm = DrmPluginV1_4(); + sp<V1_0::ICryptoPlugin> crypto(CryptoPlugin(sid)); + if (drm == nullptr || crypto == nullptr) { + continue; + } + bool r1 = crypto->requiresSecureDecoderComponent(mime); + bool r2; + if (level == kSecLevelDefault) { + r2 = drm->requiresSecureDecoderDefault(mime); + } else { + auto sL = static_cast<SecurityLevel>(level); + r2 = drm->requiresSecureDecoder(mime, sL); + } + EXPECT_EQ(r1, r2); + closeSession(sid); + } + } +} + +TEST_P(DrmHalTest, SetPlaybackId) { + auto testInfo = ::testing::UnitTest::GetInstance()->current_test_info(); + auto testName = testInfo->name(); + const hidl_string& pbId{testName}; + auto sid = OpenSession(); + auto drm = DrmPluginV1_4(); + if (drm == nullptr) { + return; + } + V1_0::Status err = drm->setPlaybackId(sid, pbId); + EXPECT_EQ(V1_0::Status::OK, err); + closeSession(sid); + + // search for playback id among metric attributes/values + bool foundPbId = false; + auto res = drmPlugin->getMetrics([&]( + V1_0::Status status, + hidl_vec<V1_1::DrmMetricGroup> metricGroups) { + EXPECT_EQ(V1_0::Status::OK, status); + for (const auto& group : metricGroups) { + for (const auto& metric : group.metrics) { + for (const auto& value : metric.values) { + if (value.stringValue == pbId) { + foundPbId = true; + break; + } + } + for (const auto& attr : metric.attributes) { + if (attr.stringValue == pbId) { + foundPbId = true; + break; + } + } + } + } + }); + EXPECT_OK(res); + EXPECT_TRUE(foundPbId); +} + +TEST_P(DrmHalTest, GetLogMessages) { + auto drm = DrmPluginV1_4(); + auto sid = OpenSession(); + auto crypto_1_0 = CryptoPlugin(sid); + sp<V1_4::ICryptoPlugin> crypto(V1_4::ICryptoPlugin::castFrom(crypto_1_0)); + + hidl_vec<uint8_t> initData; + hidl_string mime{"text/plain"}; + V1_0::KeyedVector optionalParameters; + auto res = drmPlugin->getKeyRequest_1_2( + sid, initData, mime, V1_0::KeyType::STREAMING, + optionalParameters, [&](V1_2::Status status, const hidl_vec<uint8_t>&, + V1_1::KeyRequestType, const hidl_string&) { + EXPECT_NE(V1_2::Status::OK, status); + }); + EXPECT_OK(res); + + V1_4::IDrmPlugin::getLogMessages_cb cb = [&]( + V1_4::Status status, + hidl_vec<V1_4::LogMessage> logs) { + EXPECT_EQ(V1_4::Status::OK, status); + EXPECT_NE(0, logs.size()); + for (auto log: logs) { + ALOGI("priority=[%u] message='%s'", log.priority, log.message.c_str()); + } + }; + + auto res2 = drm->getLogMessages(cb); + EXPECT_OK(res2); + + auto res3 = crypto->getLogMessages(cb); + EXPECT_OK(res3); + + closeSession(sid); +} + +} // namespace vts +} // namespace V1_4 +} // namespace drm +} // namespace hardware +} // namespace android |