From 4f7e565dfaec3fafa1fb076a239447fb5d87f363 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Thu, 21 Jan 2021 02:49:22 -0800 Subject: [PATCH] android.hardware.drm@1.4 vts Bug: 177872328 Test: VtsHalDrmV1_4TargetTest Change-Id: I5586ab2bbf4eb0487c50f81758b6edb4e8eadd42 --- drm/1.4/vts/OWNERS | 9 + drm/1.4/vts/functional/Android.bp | 95 +++++++++++ drm/1.4/vts/functional/AndroidTest.xml | 38 +++++ drm/1.4/vts/functional/drm_hal_test.cpp | 161 ++++++++++++++++++ drm/1.4/vts/functional/drm_hal_test_main.cpp | 94 ++++++++++ .../hardware/drm/1.4/vts/drm_hal_test.h | 83 +++++++++ 6 files changed, 480 insertions(+) create mode 100644 drm/1.4/vts/OWNERS create mode 100644 drm/1.4/vts/functional/Android.bp create mode 100644 drm/1.4/vts/functional/AndroidTest.xml create mode 100644 drm/1.4/vts/functional/drm_hal_test.cpp create mode 100644 drm/1.4/vts/functional/drm_hal_test_main.cpp create mode 100644 drm/1.4/vts/functional/include/android/hardware/drm/1.4/vts/drm_hal_test.h diff --git a/drm/1.4/vts/OWNERS b/drm/1.4/vts/OWNERS new file mode 100644 index 0000000000..3a0672e5c6 --- /dev/null +++ b/drm/1.4/vts/OWNERS @@ -0,0 +1,9 @@ +conglin@google.com +edwinwong@google.com +fredgc@google.com +jtinker@google.com +juce@google.com +kylealexander@google.com +rfrias@google.com +robertshih@google.com +sigquit@google.com diff --git a/drm/1.4/vts/functional/Android.bp b/drm/1.4/vts/functional/Android.bp new file mode 100644 index 0000000000..80b1dd1825 --- /dev/null +++ b/drm/1.4/vts/functional/Android.bp @@ -0,0 +1,95 @@ +// +// 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. +// + +cc_library_static { + name: "android.hardware.drm@1.4-vts", + defaults: ["VtsHalTargetTestDefaults"], + local_include_dirs: [ + "include", + ], + srcs: [ + "drm_hal_test.cpp", + ], + shared_libs: [ + "android.hardware.drm@1.0", + "android.hardware.drm@1.1", + "android.hardware.drm@1.2", + "android.hardware.drm@1.3", + "android.hardware.drm@1.4", + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "libhidlmemory", + "libnativehelper", + ], + static_libs: [ + "android.hardware.drm@1.0-helper", + "android.hardware.drm@1.2-vts", + "libdrmvtshelper", + ], + export_static_lib_headers: [ + "android.hardware.drm@1.2-vts", + ], + export_include_dirs: [ + "include", + ], +} + +cc_test { + name: "VtsHalDrmV1_4TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + include_dirs: ["hardware/interfaces/drm/1.0/vts/functional"], + srcs: [ + "drm_hal_test_main.cpp", + ], + whole_static_libs: [ + "android.hardware.drm@1.4-vts", + ], + shared_libs: [ + "android.hardware.drm@1.0", + "android.hardware.drm@1.1", + "android.hardware.drm@1.2", + "android.hardware.drm@1.3", + "android.hardware.drm@1.4", + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "libcrypto", + "libhidlmemory", + "libnativehelper", + ], + static_libs: [ + "android.hardware.drm@1.0-helper", + "android.hardware.drm@1.2-vts", + "libdrmvtshelper", + ], + arch: { + arm: { + data: [":libvtswidevine-arm-prebuilts"], + }, + arm64: { + data: [":libvtswidevine-arm64-prebuilts"], + }, + x86: { + data: [":libvtswidevine-x86-prebuilts"], + }, + x86_64: { + data: [":libvtswidevine-x86_64-prebuilts"], + }, + }, + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/drm/1.4/vts/functional/AndroidTest.xml b/drm/1.4/vts/functional/AndroidTest.xml new file mode 100644 index 0000000000..b18da49a8c --- /dev/null +++ b/drm/1.4/vts/functional/AndroidTest.xml @@ -0,0 +1,38 @@ + + + + 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..ee6635b2ad --- /dev/null +++ b/drm/1.4/vts/functional/drm_hal_test.cpp @@ -0,0 +1,161 @@ +/* + * 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 DrmHalTest::DrmPluginV1_4() const { + sp plugin(drm::V1_4::IDrmPlugin::castFrom(drmPlugin)); + EXPECT_NE(nullptr, plugin.get()); + return plugin; +} + +sp DrmHalTest::CryptoPlugin(const SessionId& sid) { + sp crypto; + auto res = cryptoFactory->createPlugin( + getUUID(), sid, + [&](V1_0::Status status, const sp& 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 &id) { + err = status; + sessionId = id; + }; + + while (true) { + Return res; + if (level > kSecLevelMax) { + res = drmPlugin->openSession(cb); + } else if (level >= kSecLevelMin) { + auto securityLevel = static_cast(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 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(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 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); +} + +} // namespace vts +} // namespace V1_4 +} // namespace drm +} // namespace hardware +} // namespace android diff --git a/drm/1.4/vts/functional/drm_hal_test_main.cpp b/drm/1.4/vts/functional/drm_hal_test_main.cpp new file mode 100644 index 0000000000..65d1b76038 --- /dev/null +++ b/drm/1.4/vts/functional/drm_hal_test_main.cpp @@ -0,0 +1,94 @@ +/* + * 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. + */ + +/** + * Instantiate the set of test cases for each vendor module + */ + +#define LOG_TAG "drm_hal_test@1.4" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "android/hardware/drm/1.4/vts/drm_hal_test.h" + +using drm_vts::DrmHalTestParam; +using drm_vts::PrintParamInstanceToString; + +using android::hardware::drm::V1_4::vts::DrmHalTest; + +static const std::vector kAllInstances = [] { + using ::android::hardware::hidl_array; + using ::android::hardware::hidl_vec; + using ::android::hardware::drm::V1_4::ICryptoFactory; + using ::android::hardware::drm::V1_4::IDrmFactory; + + std::vector drmInstances = + android::hardware::getAllHalInstanceNames(IDrmFactory::descriptor); + std::vector cryptoInstances = + android::hardware::getAllHalInstanceNames(ICryptoFactory::descriptor); + std::set allInstances; + allInstances.insert(drmInstances.begin(), drmInstances.end()); + allInstances.insert(cryptoInstances.begin(), cryptoInstances.end()); + + std::vector firstInstanceUuidCombos; + for (const auto &instance : allInstances) { + auto drmFactory = IDrmFactory::getService(instance); + if (drmFactory == nullptr) { + continue; + } + drmFactory->getSupportedCryptoSchemes( + [&](const hidl_vec>& schemes) { + if (schemes.size() > 0) { + firstInstanceUuidCombos.push_back(DrmHalTestParam(instance, schemes[0])); + } + }); + } + return firstInstanceUuidCombos; +}(); + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalTest); +INSTANTIATE_TEST_SUITE_P(PerInstance, DrmHalTest, + testing::ValuesIn(kAllInstances), + PrintParamInstanceToString); + +int main(int argc, char** argv) { +#if defined(__LP64__) + const char* kModulePath = "/data/local/tmp/64/lib"; +#else + const char* kModulePath = "/data/local/tmp/32/lib"; +#endif + DrmHalTest::gVendorModules + = new drm_vts::VendorModules(kModulePath); + if (DrmHalTest::gVendorModules->getPathList().size() == 0) { + std::cerr << "WARNING: No vendor modules found in " << kModulePath << + ", all vendor tests will be skipped" << std::endl; + } + ::testing::InitGoogleTest(&argc, argv); + int status = RUN_ALL_TESTS(); + ALOGI("Test result = %d", status); + return status; +} diff --git a/drm/1.4/vts/functional/include/android/hardware/drm/1.4/vts/drm_hal_test.h b/drm/1.4/vts/functional/include/android/hardware/drm/1.4/vts/drm_hal_test.h new file mode 100644 index 0000000000..ed49a6141b --- /dev/null +++ b/drm/1.4/vts/functional/include/android/hardware/drm/1.4/vts/drm_hal_test.h @@ -0,0 +1,83 @@ +/* + * 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. + */ + +#ifndef DRM_HAL_TEST_V1_4_H +#define DRM_HAL_TEST_V1_4_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "drm_hal_vendor_module_api.h" +#include "drm_vts_helper.h" +#include "vendor_modules.h" +#include "VtsHalHidlTargetCallbackBase.h" + +#include "android/hardware/drm/1.2/vts/drm_hal_common.h" + +namespace android { +namespace hardware { +namespace drm { +namespace V1_4 { +namespace vts { + +namespace drm = ::android::hardware::drm; +using android::hardware::hidl_array; +using android::hardware::hidl_string; +using V1_0::SessionId; +using V1_1::SecurityLevel; + +using drm_vts::DrmHalTestParam; + +class DrmHalTest : public drm::V1_2::vts::DrmHalTest { +public: + using drm::V1_2::vts::DrmHalTest::DrmHalTest; + static const char* const kVideoMp4; + static const char* const kAudioMp4; + static const uint32_t kSecLevelMin = static_cast(SecurityLevel::SW_SECURE_CRYPTO); + static const uint32_t kSecLevelMax = static_cast(SecurityLevel::HW_SECURE_ALL); + static const uint32_t kSecLevelDefault; + +protected: + sp DrmPluginV1_4() const; + sp CryptoPlugin(const SessionId& sid); + SessionId OpenSession(uint32_t level); + +private: + void DoProvisioning(); +}; + +} // namespace vts +} // namespace V1_4 +} // namespace drm +} // namespace hardware +} // namespace android + +#endif // DRM_HAL_TEST_V1_4_H