From ec5d8ab919d6d176aa142e1d9859d01ded5ef8c8 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Wed, 22 Jan 2020 15:09:33 -0800 Subject: [PATCH] drm vts 1.0 refactor * accept drm scheme as part of test parameter * extract test cases into separate library Bug: 142397658 Change-Id: I2f56d4e892b2fe45eabf37b351b5017a67828ee4 --- drm/1.0/vts/functional/Android.bp | 47 +++- .../vts/functional/drm_hal_clearkey_test.cpp | 201 +------------- drm/1.0/vts/functional/drm_hal_test_main.cpp | 71 +++++ .../functional/drm_hal_vendor_module_api.h | 235 +--------------- .../vts/functional/drm_hal_vendor_test.cpp | 262 +++--------------- .../drm/1.0/vts/drm_hal_clearkey_test.h | 201 ++++++++++++++ .../drm/1.0/vts/drm_hal_vendor_test.h | 209 ++++++++++++++ .../include/drm_hal_vendor_module_api.h | 234 ++++++++++++++++ 8 files changed, 801 insertions(+), 659 deletions(-) create mode 100644 drm/1.0/vts/functional/drm_hal_test_main.cpp mode change 100644 => 120000 drm/1.0/vts/functional/drm_hal_vendor_module_api.h create mode 100644 drm/1.0/vts/functional/include/android/hardware/drm/1.0/vts/drm_hal_clearkey_test.h create mode 100644 drm/1.0/vts/functional/include/android/hardware/drm/1.0/vts/drm_hal_vendor_test.h create mode 100644 drm/1.0/vts/functional/include/drm_hal_vendor_module_api.h diff --git a/drm/1.0/vts/functional/Android.bp b/drm/1.0/vts/functional/Android.bp index c7b022f59e..235bfb406f 100644 --- a/drm/1.0/vts/functional/Android.bp +++ b/drm/1.0/vts/functional/Android.bp @@ -29,21 +29,58 @@ cc_library_static { export_include_dirs: ["include"], } -cc_test { - name: "VtsHalDrmV1_0TargetTest", +cc_library_static { + name: "android.hardware.drm@1.0-vts", defaults: ["VtsHalTargetTestDefaults"], + local_include_dirs: [ + "include", + ], srcs: [ "drm_hal_clearkey_test.cpp", "drm_hal_vendor_test.cpp", ], - static_libs: [ + shared_libs: [ "android.hardware.drm@1.0", - "android.hardware.drm@1.0-helper", "android.hidl.allocator@1.0", "android.hidl.memory@1.0", "libhidlmemory", "libnativehelper", - "libssl", + ], + static_libs: [ + "android.hardware.drm@1.0-helper", + "libcrypto_static", + "libdrmvtshelper", + ], + export_shared_lib_headers: [ + "android.hardware.drm@1.0", + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "libhidlmemory", + "libnativehelper", + ], + export_include_dirs: [ + "include", + ], +} + +cc_test { + name: "VtsHalDrmV1_0TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "drm_hal_test_main.cpp", + ], + whole_static_libs: [ + "android.hardware.drm@1.0-vts", + ], + shared_libs: [ + "android.hardware.drm@1.0", + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "libhidlmemory", + "libnativehelper", + ], + static_libs: [ + "android.hardware.drm@1.0-helper", "libcrypto_static", "libdrmvtshelper", ], diff --git a/drm/1.0/vts/functional/drm_hal_clearkey_test.cpp b/drm/1.0/vts/functional/drm_hal_clearkey_test.cpp index 5713d2ef16..ebdc2d7350 100644 --- a/drm/1.0/vts/functional/drm_hal_clearkey_test.cpp +++ b/drm/1.0/vts/functional/drm_hal_clearkey_test.cpp @@ -16,127 +16,26 @@ #define LOG_TAG "drm_hal_clearkey_test@1.0" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include -using ::android::hardware::drm::V1_0::BufferType; -using ::android::hardware::drm::V1_0::DestinationBuffer; -using ::android::hardware::drm::V1_0::ICryptoFactory; -using ::android::hardware::drm::V1_0::ICryptoPlugin; -using ::android::hardware::drm::V1_0::IDrmFactory; -using ::android::hardware::drm::V1_0::IDrmPlugin; -using ::android::hardware::drm::V1_0::KeyedVector; -using ::android::hardware::drm::V1_0::KeyValue; -using ::android::hardware::drm::V1_0::KeyRequestType; -using ::android::hardware::drm::V1_0::KeyType; -using ::android::hardware::drm::V1_0::Mode; -using ::android::hardware::drm::V1_0::Pattern; -using ::android::hardware::drm::V1_0::SecureStop; -using ::android::hardware::drm::V1_0::SecureStopId; -using ::android::hardware::drm::V1_0::SessionId; -using ::android::hardware::drm::V1_0::SharedBuffer; -using ::android::hardware::drm::V1_0::Status; -using ::android::hardware::drm::V1_0::SubSample; - -using ::android::hardware::hidl_array; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_memory; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hidl::allocator::V1_0::IAllocator; -using ::android::hidl::memory::V1_0::IMemory; -using ::android::sp; +#include "android/hardware/drm/1.0/vts/drm_hal_clearkey_test.h" using std::string; -using std::unique_ptr; using std::random_device; using std::map; using std::mt19937; using std::vector; -/** - * These clearkey tests use white box knowledge of the legacy clearkey - * plugin to verify that the HIDL HAL services and interfaces are working. - * It is not intended to verify any vendor's HAL implementation. If you - * are looking for vendor HAL tests, see drm_hal_vendor_test.cpp - */ -#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) -#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk()) - -static const uint8_t kCommonPsshBoxUUID[16] = { - 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, - 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B}; - -// To be used in mpd to specify drm scheme for players -static const uint8_t kClearKeyUUID[16] = { - 0xE2, 0x71, 0x9D, 0x58, 0xA9, 0x85, 0xB3, 0xC9, - 0x78, 0x1A, 0xB0, 0x30, 0xAF, 0x78, 0xD3, 0x0E}; - static const uint8_t kInvalidUUID[16] = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}; -class DrmHalClearkeyFactoryTest : public ::testing::TestWithParam { - public: - void SetUp() override { - const ::testing::TestInfo* const test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - ALOGD("Running test %s.%s", test_info->test_case_name(), - test_info->name()); - - const std::string instanceName = GetParam(); - drmFactory = IDrmFactory::getService(instanceName); - ASSERT_NE(nullptr, drmFactory.get()); - cryptoFactory = ICryptoFactory::getService(instanceName); - ASSERT_NE(nullptr, cryptoFactory.get()); - - const bool drmClearKey = drmFactory->isCryptoSchemeSupported(kClearKeyUUID); - const bool cryptoClearKey = cryptoFactory->isCryptoSchemeSupported(kClearKeyUUID); - EXPECT_EQ(drmClearKey, cryptoClearKey); - const bool supportsClearKey = drmClearKey && cryptoClearKey; - - const bool drmCommonPsshBox = drmFactory->isCryptoSchemeSupported(kCommonPsshBoxUUID); - const bool cryptoCommonPsshBox = cryptoFactory->isCryptoSchemeSupported(kCommonPsshBoxUUID); - EXPECT_EQ(drmCommonPsshBox, cryptoCommonPsshBox); - const bool supportsCommonPsshBox = drmCommonPsshBox && cryptoCommonPsshBox; - - EXPECT_EQ(supportsClearKey, supportsCommonPsshBox); - correspondsToThisTest = supportsClearKey && supportsCommonPsshBox; - - if (instanceName == "clearkey") { - EXPECT_TRUE(correspondsToThisTest); - - // TODO(b/147449315) - // Only the clearkey plugged into the "default" instance supports - // this test. Currently the "clearkey" instance fails some tests - // here. - GTEST_SKIP() << "Clearkey tests don't work with 'clearkey' instance yet."; - } - - if (!correspondsToThisTest) { - GTEST_SKIP() << "Cannot test clearkey features on non-clearkey DRM modules"; - } - } - - protected: - sp drmFactory; - sp cryptoFactory; - - bool correspondsToThisTest; -}; +namespace android { +namespace hardware { +namespace drm { +namespace V1_0 { +namespace vts { /** * Ensure the factory doesn't support an invalid scheme UUID @@ -264,48 +163,6 @@ TEST_P(DrmHalClearkeyFactoryTest, CreateInvalidCryptoPlugin) { EXPECT_OK(res); } -class DrmHalClearkeyPluginTest : public DrmHalClearkeyFactoryTest { - public: - virtual void SetUp() override { - // Create factories - DrmHalClearkeyFactoryTest::SetUp(); - - if (!correspondsToThisTest) { - GTEST_SKIP() << "Cannot test clearkey features on non-clearkey DRM modules"; - } - - ASSERT_NE(nullptr, drmFactory.get()); - hidl_string packageName("android.hardware.drm.test"); - auto res = drmFactory->createPlugin( - kClearKeyUUID, packageName, - [this](Status status, const sp& plugin) { - EXPECT_EQ(Status::OK, status); - ASSERT_NE(nullptr, plugin.get()); - drmPlugin = plugin; - }); - ASSERT_OK(res); - - hidl_vec initVec; - res = cryptoFactory->createPlugin( - kClearKeyUUID, initVec, - [this](Status status, const sp& plugin) { - EXPECT_EQ(Status::OK, status); - ASSERT_NE(nullptr, plugin.get()); - cryptoPlugin = plugin; - }); - ASSERT_OK(res); - } - - SessionId openSession(); - void closeSession(const SessionId& sessionId); - hidl_vec loadKeys(const SessionId& sessionId, const KeyType& type); - sp getDecryptMemory(size_t size, size_t index); - - protected: - sp drmPlugin; - sp cryptoPlugin; -}; - /** * DrmPlugin tests */ @@ -966,30 +823,6 @@ TEST_P(DrmHalClearkeyPluginTest, SetMediaDrmSessionEmptySession) { * Decrypt tests */ -class DrmHalClearkeyDecryptTest : public DrmHalClearkeyPluginTest { - public: - void SetUp() override { - DrmHalClearkeyPluginTest::SetUp(); - - if (!correspondsToThisTest) { - GTEST_SKIP() << "Cannot test clearkey features on non-clearkey DRM modules"; - } - } - void fillRandom(const sp& memory); - hidl_array toHidlArray(const vector& vec) { - EXPECT_EQ(16u, vec.size()); - return hidl_array(&vec[0]); - } - uint32_t decrypt(Mode mode, uint8_t* iv, const hidl_vec& subSamples, - const Pattern& pattern, Status status); - void aes_ctr_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv, - const hidl_vec& subSamples, const vector& key); - void aes_cbc_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv, - const hidl_vec& subSamples, const vector& key); - void decryptWithInvalidKeys(hidl_vec& invalidResponse, - vector& iv, const Pattern& noPattern, const vector& subSamples); -}; - void DrmHalClearkeyDecryptTest::fillRandom(const sp& memory) { random_device rd; mt19937 rand(rd()); @@ -1300,20 +1133,8 @@ TEST_P(DrmHalClearkeyDecryptTest, DecryptWithKeyTooLong) { decryptWithInvalidKeys(invalidResponse, iv, noPattern, subSamples); } -static const std::set kAllInstances = [] { - 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()); - return allInstances; -}(); - -INSTANTIATE_TEST_SUITE_P(PerInstance, DrmHalClearkeyFactoryTest, testing::ValuesIn(kAllInstances), - android::hardware::PrintInstanceNameToString); -INSTANTIATE_TEST_SUITE_P(PerInstance, DrmHalClearkeyPluginTest, testing::ValuesIn(kAllInstances), - android::hardware::PrintInstanceNameToString); -INSTANTIATE_TEST_SUITE_P(PerInstance, DrmHalClearkeyDecryptTest, testing::ValuesIn(kAllInstances), - android::hardware::PrintInstanceNameToString); +} // namespace vts +} // namespace V1_0 +} // namespace drm +} // namespace hardware +} // namespace android diff --git a/drm/1.0/vts/functional/drm_hal_test_main.cpp b/drm/1.0/vts/functional/drm_hal_test_main.cpp new file mode 100644 index 0000000000..fd2538b051 --- /dev/null +++ b/drm/1.0/vts/functional/drm_hal_test_main.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2020 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_vendor_test@1.0" + +#include "vendor_modules.h" +#include "android/hardware/drm/1.0/vts/drm_hal_vendor_test.h" +#include "android/hardware/drm/1.0/vts/drm_hal_clearkey_test.h" + +using ::android::hardware::drm::V1_0::ICryptoFactory; +using ::android::hardware::drm::V1_0::IDrmFactory; + +using ::android::hardware::drm::V1_0::vts::DrmHalClearkeyFactoryTest; +using ::android::hardware::drm::V1_0::vts::DrmHalClearkeyPluginTest; +using ::android::hardware::drm::V1_0::vts::DrmHalClearkeyDecryptTest; + +using ::android::hardware::drm::V1_0::vts::DrmHalVendorFactoryTest; +using ::android::hardware::drm::V1_0::vts::DrmHalVendorPluginTest; +using ::android::hardware::drm::V1_0::vts::DrmHalVendorDecryptTest; + +/** + * Instantiate the set of test cases for each vendor module + */ + +static const std::vector kAllInstances = [] { + 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 allInstanceUuidCombos; + auto noUUID = [](std::string s) { return DrmHalTestParam(s); }; + std::transform(allInstances.begin(), allInstances.end(), + std::back_inserter(allInstanceUuidCombos), noUUID); + return allInstanceUuidCombos; +}(); + +INSTANTIATE_TEST_CASE_P(DrmHalVendorFactoryTestCases, DrmHalVendorFactoryTest, + testing::ValuesIn(kAllInstances), + drm_vts::PrintParamInstanceToString); + +INSTANTIATE_TEST_CASE_P(DrmHalVendorPluginTestCases, DrmHalVendorPluginTest, + testing::ValuesIn(kAllInstances), + drm_vts::PrintParamInstanceToString); + +INSTANTIATE_TEST_CASE_P(DrmHalVendorDecryptTestCases, DrmHalVendorDecryptTest, + testing::ValuesIn(kAllInstances), + drm_vts::PrintParamInstanceToString); + +INSTANTIATE_TEST_SUITE_P(PerInstance, DrmHalClearkeyFactoryTest, testing::ValuesIn(kAllInstances), + drm_vts::PrintParamInstanceToString); +INSTANTIATE_TEST_SUITE_P(PerInstance, DrmHalClearkeyPluginTest, testing::ValuesIn(kAllInstances), + drm_vts::PrintParamInstanceToString); +INSTANTIATE_TEST_SUITE_P(PerInstance, DrmHalClearkeyDecryptTest, testing::ValuesIn(kAllInstances), + drm_vts::PrintParamInstanceToString); diff --git a/drm/1.0/vts/functional/drm_hal_vendor_module_api.h b/drm/1.0/vts/functional/drm_hal_vendor_module_api.h deleted file mode 100644 index b8b205265d..0000000000 --- a/drm/1.0/vts/functional/drm_hal_vendor_module_api.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) 2017 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_VENDOR_MODULE_API_H -#define DRM_HAL_VENDOR_MODULE_API_H - -#include -#include -#include -#include - -/** - * The DRM and Crypto HALs interact with vendor-provided HAL implementations - * that have DRM-specific capabilities. Since the VTS tests cannot contain - * DRM-specific functionality, supporting modules are required to enable VTS - * to validate HAL implementations in a generic way. If the vendor-specific - * VTS module is not provided for a given drm HAL implementation, only very - * small subset of functionality can be verified. - * - * As an example, a DRM HAL implementation interacts with a DRM-specific - * license server to obtain licenses for decrypting content. The DRM HAL - * implementation generates a key request message, delivers it to the server - * and receives a key response message which is then loaded into the HAL. Once - * the keys are loaded, the Crypto HAL decryption functionality and performance - * and other associated APIs can be tested by the common VTS test suite. - * - * Vendor-specific VTS modules are shared libraries used by the DRM VTS test. - * They provide a set of functions to support VTS testing of the DRM HAL module. - * - * The modules are placed in a common location on the file system. The VTS test - * scans through all vendor-provided support libraries and runs the VTS test - * suite on each library that is found. - * - * The vendor-specific module exposes an extern ā€œCā€ vendorModuleFactory() - * function that returns a DrmHalVTSVendorModule instance. DrmHalVTSVendorModule - * instances are versioned, where each version is represented by subclass of - * DrmHalVTSVendorModule that corresponds to the API version. For example, a - * vendor-specific module that implements version 1 of the API would return a - * DrmHalVTSVendorModule_V1 from the vendorModuleFactory() function. - */ - -class DrmHalVTSVendorModule; - -extern "C" { -/** - * The factory method for creating DrmHalVTSVendorModule instances. The returned - * instance will be a subclass of DrmHalVTSVendorModule that corresponds to the - * supported API version. - */ -DrmHalVTSVendorModule* vendorModuleFactory(); -}; - -class DrmHalVTSVendorModule { - public: - DrmHalVTSVendorModule() : installed(true) {} - virtual ~DrmHalVTSVendorModule() {} - - /** - * Return the vendor-specific module API version. The version is an integer - * value with initial version 1. The API version indicates which subclass - * version DrmHalVTSVendorModule this instance is. - */ - virtual uint32_t getAPIVersion() const = 0; - - /** - * Return the UUID for the DRM HAL implementation. Protection System - * Specific - * UUID (see http://dashif.org/identifiers/protection/) - */ - virtual std::vector getUUID() const = 0; - - /** - * Return the service name for the DRM HAL implementation. If the hal is a - * legacy - * drm plugin, i.e. not running as a HIDL service, return the empty string. - */ - virtual std::string getServiceName() const = 0; - - /** - * Set a flag in the vendor module to indicate whether or not the drm - * scheme corresponding to this module is installed on the device. - */ - void setInstalled(bool flag) {installed = flag;} - bool isInstalled() const {return installed;} - - private: - bool installed; - DrmHalVTSVendorModule(const DrmHalVTSVendorModule&) = delete; - void operator=(const DrmHalVTSVendorModule&) = delete; -}; - -/** - * API Version 1. This is the baseline version that supports a minimal set - * of VTS tests. - */ -class DrmHalVTSVendorModule_V1 : public DrmHalVTSVendorModule { - public: - DrmHalVTSVendorModule_V1() {} - virtual ~DrmHalVTSVendorModule_V1() {} - - virtual uint32_t getAPIVersion() const { return 1; } - - /** - * Handle a provisioning request. This function will be called if the HAL - * module's getProvisionRequest returns a provision request. The vendor - * module should process the provisioning request, either by sending it - * to a provisioning server, or generating a mock response. The resulting - * provisioning response is returned to the VTS test. - * - * @param provisioningRequest the provisioning request recieved from - * the DRM HAL - * @param url the default url the HAL implementation provided with the - * provisioning request - * @return the generated provisioning response - */ - virtual std::vector handleProvisioningRequest( - const std::vector& provisioningRequest, - const std::string& url) = 0; - - /** - * Content configuration specifies content-specific parameters associated - * with a key request/response transaction. It allows the VTS test to - * request keys and use them to perform decryption. - */ - struct ContentConfiguration { - /** - * Assign a name for this configuration that will be referred to - * in log messages. - */ - const std::string name; - - /** - * Server to use when requesting a key response. This url will be - * passed as a parameter to the vendor vts module along with the - * key request to perform the key request transaction. - */ - const std::string serverUrl; - - /** - * Initialization data provided to getKeyRequest, e.g. PSSH for CENC - * content - */ - const std::vector initData; - - /** - * Mime type provided to getKeyRequest, e.g. "video/mp4", or "cenc" - */ - const std::string mimeType; - - /** - * Optional parameters to be associated with the key request - */ - const std::map optionalParameters; - - /** - * Define license policy attributes for the content configuration. - * These attributes can affect which tests are able to be applied. - */ - struct Policy { - /** - * Indicate if the license policy allows offline playback. - * Content configurated with this policy supports KeyType::OFFLINE - * key requests/responses. A vendor module should provide at least - * one content configuration where allowOffline is true if the drm - * scheme supports offline content. - */ - bool allowOffline; - } policy; - - /** - * The keys that will be available once the keys are loaded - */ - struct Key { - /** - * Indicate if the key content is configured to require secure - * buffers, where the output buffers are protected and cannot be - * accessed by the non-secure cpu. A vendor module should provide - * at least one content configurations where isSecure is false, to - * allow decrypt result verification tests to be run. - */ - bool isSecure; - - /** - * A key ID identifies a key to use for decryption - */ - const std::vector keyId; - - /** - * The clear content key is provided to generate expected values for - * validating decryption. - */ - const std::vector clearContentKey; - }; - std::vector keys; - }; - - /** - * Return a list of content configurations that can be exercised by the - * VTS test. - */ - virtual std::vector - getContentConfigurations() const = 0; - - /** - * Handle a key request. This function will be called if the HAL - * module's getKeyRequest returns a key request. The vendor - * module should process the key request, either by sending it - * to a license server, or by generating a mock response. The resulting - * key response is returned to the VTS test. - * - * @param keyRequest the key request recieved from the DRM HAL - * @param serverUrl the url of the key server that was supplied - * by the ContentConfiguration - * @return the generated key response - */ - virtual std::vector handleKeyRequest( - const std::vector& keyRequest, - const std::string& serverUrl) = 0; -}; - -#endif // DRM_HAL_VENDOR_MODULE_API_H diff --git a/drm/1.0/vts/functional/drm_hal_vendor_module_api.h b/drm/1.0/vts/functional/drm_hal_vendor_module_api.h new file mode 120000 index 0000000000..a8b5ade31c --- /dev/null +++ b/drm/1.0/vts/functional/drm_hal_vendor_module_api.h @@ -0,0 +1 @@ +include/drm_hal_vendor_module_api.h \ No newline at end of file diff --git a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp index 2259985712..5c6c98b32f 100644 --- a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp +++ b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp @@ -16,138 +16,46 @@ #define LOG_TAG "drm_hal_vendor_test@1.0" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include #include "drm_hal_vendor_module_api.h" #include "vendor_modules.h" #include -using ::android::hardware::drm::V1_0::BufferType; -using ::android::hardware::drm::V1_0::DestinationBuffer; -using ::android::hardware::drm::V1_0::EventType; -using ::android::hardware::drm::V1_0::ICryptoFactory; -using ::android::hardware::drm::V1_0::ICryptoPlugin; -using ::android::hardware::drm::V1_0::IDrmFactory; -using ::android::hardware::drm::V1_0::IDrmPlugin; -using ::android::hardware::drm::V1_0::IDrmPluginListener; -using ::android::hardware::drm::V1_0::KeyedVector; -using ::android::hardware::drm::V1_0::KeyRequestType; -using ::android::hardware::drm::V1_0::KeyStatus; -using ::android::hardware::drm::V1_0::KeyStatusType; -using ::android::hardware::drm::V1_0::KeyType; -using ::android::hardware::drm::V1_0::KeyValue; -using ::android::hardware::drm::V1_0::Mode; -using ::android::hardware::drm::V1_0::Pattern; -using ::android::hardware::drm::V1_0::SecureStop; -using ::android::hardware::drm::V1_0::SecureStopId; -using ::android::hardware::drm::V1_0::SessionId; -using ::android::hardware::drm::V1_0::SharedBuffer; -using ::android::hardware::drm::V1_0::Status; -using ::android::hardware::drm::V1_0::SubSample; +#include "android/hardware/drm/1.0/vts/drm_hal_vendor_test.h" -using ::android::hardware::hidl_array; -using ::android::hardware::hidl_memory; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; -using ::android::hidl::allocator::V1_0::IAllocator; -using ::android::hidl::memory::V1_0::IMemory; -using ::android::sp; - -using std::string; -using std::unique_ptr; using std::random_device; -using std::map; using std::mt19937; -using std::vector; - -using ContentConfiguration = ::DrmHalVTSVendorModule_V1::ContentConfiguration; -using Key = ::DrmHalVTSVendorModule_V1::ContentConfiguration::Key; - -#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) -#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk()) - -#define RETURN_IF_SKIPPED \ - if (vendorModule == nullptr || !vendorModule->isInstalled()) { \ - GTEST_SKIP() << "This drm scheme not supported." \ - << " library:" << GetParam() << " service-name:" \ - << (vendorModule == nullptr ? "N/A" : vendorModule->getServiceName()) \ - << std::endl; \ - return; \ - } static const uint8_t kInvalidUUID[16] = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, }; -static drm_vts::VendorModules* gVendorModules = nullptr; - -class DrmHalVendorFactoryTest : public testing::TestWithParam { - public: - DrmHalVendorFactoryTest() - : vendorModule( - static_cast(gVendorModules->getModule(GetParam()))) {} - - virtual ~DrmHalVendorFactoryTest() {} - - virtual void SetUp() { - const ::testing::TestInfo* const test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - ALOGD("Running test %s.%s from vendor module %s", test_info->test_case_name(), - test_info->name(), GetParam().c_str()); - - const std::string instance = GetParam(); - if (instance == "widevine") { - ASSERT_NE(nullptr, vendorModule.get()); - } - - if (vendorModule == nullptr) { - GTEST_SKIP() << "No vendor module available"; - } else { - ASSERT_EQ(instance, vendorModule->getServiceName()); - contentConfigurations = vendorModule->getContentConfigurations(); - } - - drmFactory = IDrmFactory::getService(instance); - ASSERT_NE(nullptr, drmFactory.get()); - cryptoFactory = ICryptoFactory::getService(instance); - ASSERT_NE(nullptr, cryptoFactory.get()); - - // If drm scheme not installed skip subsequent tests - if (!drmFactory->isCryptoSchemeSupported(getVendorUUID())) { - // no GTEST_SKIP since only some tests require the module - vendorModule->setInstalled(false); - } - } - - protected: - hidl_array getVendorUUID() { - if (vendorModule == nullptr) return {}; - vector uuid = vendorModule->getUUID(); - return hidl_array(&uuid[0]); +static drm_vts::VendorModules* gVendorModules = [] { +#if defined(__LP64__) + const char* kModulePath = "/data/local/tmp/64/lib"; +#else + const char* kModulePath = "/data/local/tmp/32/lib"; +#endif + auto modules = new drm_vts::VendorModules(kModulePath); + if (modules->getPathList().size() == 0) { + std::cerr << "WARNING: No vendor modules found in " << kModulePath << + ", all vendor tests will be skipped" << std::endl; } + return modules; +}(); - sp drmFactory; - sp cryptoFactory; - unique_ptr vendorModule; - vector contentConfigurations; -}; +namespace android { +namespace hardware { +namespace drm { +namespace V1_0 { +namespace vts { + +DrmHalVendorFactoryTest::DrmHalVendorFactoryTest() + : vendorModule(static_cast( + gVendorModules->getModuleByName(GetParam().instance_))) {} // getModuleByName TEST_P(DrmHalVendorFactoryTest, ValidateConfigurations) { const char* kVendorStr = "Vendor module "; @@ -195,8 +103,8 @@ TEST_P(DrmHalVendorFactoryTest, EmptyPluginUUIDNotSupported) { */ TEST_P(DrmHalVendorFactoryTest, PluginConfigUUIDSupported) { RETURN_IF_SKIPPED; - EXPECT_TRUE(drmFactory->isCryptoSchemeSupported(getVendorUUID())); - EXPECT_TRUE(cryptoFactory->isCryptoSchemeSupported(getVendorUUID())); + EXPECT_TRUE(drmFactory->isCryptoSchemeSupported(getUUID())); + EXPECT_TRUE(cryptoFactory->isCryptoSchemeSupported(getUUID())); } /** @@ -232,7 +140,7 @@ TEST_P(DrmHalVendorFactoryTest, CreateVendorDrmPlugin) { RETURN_IF_SKIPPED; hidl_string packageName("android.hardware.drm.test"); auto res = drmFactory->createPlugin( - getVendorUUID(), packageName, + getUUID(), packageName, [&](Status status, const sp& plugin) { EXPECT_EQ(Status::OK, status); EXPECT_NE(nullptr, plugin.get()); @@ -247,7 +155,7 @@ TEST_P(DrmHalVendorFactoryTest, CreateVendorCryptoPlugin) { RETURN_IF_SKIPPED; hidl_vec initVec; auto res = cryptoFactory->createPlugin( - getVendorUUID(), initVec, + getUUID(), initVec, [&](Status status, const sp& plugin) { EXPECT_EQ(Status::OK, status); EXPECT_NE(nullptr, plugin.get()); @@ -285,50 +193,6 @@ TEST_P(DrmHalVendorFactoryTest, CreateInvalidCryptoPlugin) { EXPECT_OK(res); } -class DrmHalVendorPluginTest : public DrmHalVendorFactoryTest { - public: - virtual ~DrmHalVendorPluginTest() {} - virtual void SetUp() override { - // Create factories - DrmHalVendorFactoryTest::SetUp(); - RETURN_IF_SKIPPED; - - hidl_string packageName("android.hardware.drm.test"); - auto res = drmFactory->createPlugin( - getVendorUUID(), packageName, - [this](Status status, const sp& plugin) { - EXPECT_EQ(Status::OK, status); - ASSERT_NE(nullptr, plugin.get()); - drmPlugin = plugin; - }); - ASSERT_OK(res); - - hidl_vec initVec; - res = cryptoFactory->createPlugin( - getVendorUUID(), initVec, - [this](Status status, const sp& plugin) { - EXPECT_EQ(Status::OK, status); - ASSERT_NE(nullptr, plugin.get()); - cryptoPlugin = plugin; - }); - ASSERT_OK(res); - } - - virtual void TearDown() override {} - - SessionId openSession(); - void closeSession(const SessionId& sessionId); - sp getDecryptMemory(size_t size, size_t index); - KeyedVector toHidlKeyedVector(const map& params); - hidl_vec loadKeys(const SessionId& sessionId, - const ContentConfiguration& configuration, - const KeyType& type); - - protected: - sp drmPlugin; - sp cryptoPlugin; -}; - /** * DrmPlugin tests */ @@ -1193,7 +1057,7 @@ sp DrmHalVendorPluginTest::getDecryptMemory(size_t size, EXPECT_OK(res); - sp mappedMemory = mapMemory(hidlMemory); + sp mappedMemory = android::hardware::mapMemory(hidlMemory); EXPECT_NE(nullptr, mappedMemory.get()); res = cryptoPlugin->setSharedBufferBase(hidlMemory, index); EXPECT_OK(res); @@ -1237,29 +1101,6 @@ TEST_P(DrmHalVendorPluginTest, SetMediaDrmSessionEmptySession) { * Decrypt tests */ -class DrmHalVendorDecryptTest : public DrmHalVendorPluginTest { - public: - DrmHalVendorDecryptTest() = default; - virtual ~DrmHalVendorDecryptTest() {} - - protected: - void fillRandom(const sp& memory); - hidl_array toHidlArray(const vector& vec) { - EXPECT_EQ(vec.size(), 16u); - return hidl_array(&vec[0]); - } - hidl_vec queryKeyStatus(SessionId sessionId); - void removeKeys(SessionId sessionId); - uint32_t decrypt(Mode mode, bool isSecure, - const hidl_array& keyId, uint8_t* iv, - const hidl_vec& subSamples, const Pattern& pattern, - const vector& key, Status expectedStatus); - void aes_ctr_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv, - const hidl_vec& subSamples, const vector& key); - void aes_cbc_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv, - const hidl_vec& subSamples, const vector& key); -}; - void DrmHalVendorDecryptTest::fillRandom(const sp& memory) { random_device rd; mt19937 rand(rd()); @@ -1566,47 +1407,8 @@ TEST_P(DrmHalVendorDecryptTest, AttemptDecryptWithKeysRemoved) { } } - -/** - * Instantiate the set of test cases for each vendor module - */ - -static const std::set kAllInstances = [] { - 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()); - return allInstances; -}(); - -INSTANTIATE_TEST_CASE_P(DrmHalVendorFactoryTestCases, DrmHalVendorFactoryTest, - testing::ValuesIn(kAllInstances), - android::hardware::PrintInstanceNameToString); - -INSTANTIATE_TEST_CASE_P(DrmHalVendorPluginTestCases, DrmHalVendorPluginTest, - testing::ValuesIn(kAllInstances), - android::hardware::PrintInstanceNameToString); - -INSTANTIATE_TEST_CASE_P(DrmHalVendorDecryptTestCases, DrmHalVendorDecryptTest, - testing::ValuesIn(kAllInstances), - android::hardware::PrintInstanceNameToString); - -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 - gVendorModules = new drm_vts::VendorModules(kModulePath); - if (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; -} +} // namespace vts +} // namespace V1_0 +} // namespace drm +} // namespace hardware +} // namespace android diff --git a/drm/1.0/vts/functional/include/android/hardware/drm/1.0/vts/drm_hal_clearkey_test.h b/drm/1.0/vts/functional/include/android/hardware/drm/1.0/vts/drm_hal_clearkey_test.h new file mode 100644 index 0000000000..ca707b81fb --- /dev/null +++ b/drm/1.0/vts/functional/include/android/hardware/drm/1.0/vts/drm_hal_clearkey_test.h @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2020 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_CLEARKEY_TEST_H +#define DRM_HAL_CLEARKEY_TEST_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "drm_vts_helper.h" + +using ::android::hidl::allocator::V1_0::IAllocator; +using ::android::hidl::memory::V1_0::IMemory; + +using ::drm_vts::DrmHalTestParam; +using ::drm_vts::PrintParamInstanceToString; + +using std::string; +using std::map; +using std::vector; + +/** + * These clearkey tests use white box knowledge of the legacy clearkey + * plugin to verify that the HIDL HAL services and interfaces are working. + * It is not intended to verify any vendor's HAL implementation. If you + * are looking for vendor HAL tests, see drm_hal_vendor_test.cpp + */ +#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) +#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk()) + +namespace android { +namespace hardware { +namespace drm { +namespace V1_0 { +namespace vts { + +class DrmHalClearkeyFactoryTest : public ::testing::TestWithParam { + public: + void SetUp() override { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + ALOGD("Running test %s.%s", test_info->test_case_name(), + test_info->name()); + + const std::string instanceName = GetParam().instance_; + drmFactory = IDrmFactory::getService(instanceName); + ASSERT_NE(nullptr, drmFactory.get()); + cryptoFactory = ICryptoFactory::getService(instanceName); + ASSERT_NE(nullptr, cryptoFactory.get()); + + const bool drmClearKey = drmFactory->isCryptoSchemeSupported(kClearKeyUUID); + const bool cryptoClearKey = cryptoFactory->isCryptoSchemeSupported(kClearKeyUUID); + EXPECT_EQ(drmClearKey, cryptoClearKey); + const bool supportsClearKey = drmClearKey && cryptoClearKey; + + const bool drmCommonPsshBox = drmFactory->isCryptoSchemeSupported(kCommonPsshBoxUUID); + const bool cryptoCommonPsshBox = cryptoFactory->isCryptoSchemeSupported(kCommonPsshBoxUUID); + EXPECT_EQ(drmCommonPsshBox, cryptoCommonPsshBox); + const bool supportsCommonPsshBox = drmCommonPsshBox && cryptoCommonPsshBox; + + EXPECT_EQ(supportsClearKey, supportsCommonPsshBox); + correspondsToThisTest = supportsClearKey && supportsCommonPsshBox; + + if (instanceName == "clearkey") { + EXPECT_TRUE(correspondsToThisTest); + + // TODO(b/147449315) + // Only the clearkey plugged into the "default" instance supports + // this test. Currently the "clearkey" instance fails some tests + // here. + GTEST_SKIP() << "Clearkey tests don't work with 'clearkey' instance yet."; + } + + if (!correspondsToThisTest) { + GTEST_SKIP() << "Cannot test clearkey features on non-clearkey DRM modules"; + } + } + + protected: + static constexpr uint8_t kCommonPsshBoxUUID[16] = { + 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, + 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B}; + + // To be used in mpd to specify drm scheme for players + static constexpr uint8_t kClearKeyUUID[16] = { + 0xE2, 0x71, 0x9D, 0x58, 0xA9, 0x85, 0xB3, 0xC9, + 0x78, 0x1A, 0xB0, 0x30, 0xAF, 0x78, 0xD3, 0x0E}; + + sp drmFactory; + sp cryptoFactory; + + bool correspondsToThisTest; +}; + +class DrmHalClearkeyPluginTest : public DrmHalClearkeyFactoryTest { + public: + virtual void SetUp() override { + // Create factories + DrmHalClearkeyFactoryTest::SetUp(); + + if (!correspondsToThisTest) { + GTEST_SKIP() << "Cannot test clearkey features on non-clearkey DRM modules"; + } + + ASSERT_NE(nullptr, drmFactory.get()); + hidl_string packageName("android.hardware.drm.test"); + auto res = drmFactory->createPlugin( + getUUID(), packageName, + [this](Status status, const sp& plugin) { + EXPECT_EQ(Status::OK, status); + ASSERT_NE(nullptr, plugin.get()); + drmPlugin = plugin; + }); + ASSERT_OK(res); + + hidl_vec initVec; + res = cryptoFactory->createPlugin( + getUUID(), initVec, + [this](Status status, const sp& plugin) { + EXPECT_EQ(Status::OK, status); + ASSERT_NE(nullptr, plugin.get()); + cryptoPlugin = plugin; + }); + ASSERT_OK(res); + } + + SessionId openSession(); + void closeSession(const SessionId& sessionId); + hidl_vec loadKeys(const SessionId& sessionId, const KeyType& type); + sp getDecryptMemory(size_t size, size_t index); + + protected: + hidl_array getUUID() { + if (GetParamUUID() == hidl_array()) { + return kClearKeyUUID; + } + return GetParamUUID(); + } + + hidl_array GetParamUUID() { + return GetParam().scheme_; + } + + sp drmPlugin; + sp cryptoPlugin; +}; + +class DrmHalClearkeyDecryptTest : public DrmHalClearkeyPluginTest { + public: + void SetUp() override { + DrmHalClearkeyPluginTest::SetUp(); + + if (!correspondsToThisTest) { + GTEST_SKIP() << "Cannot test clearkey features on non-clearkey DRM modules"; + } + } + void fillRandom(const sp& memory); + hidl_array toHidlArray(const vector& vec) { + EXPECT_EQ(16u, vec.size()); + return hidl_array(&vec[0]); + } + uint32_t decrypt(Mode mode, uint8_t* iv, const hidl_vec& subSamples, + const Pattern& pattern, Status status); + void aes_ctr_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv, + const hidl_vec& subSamples, const vector& key); + void aes_cbc_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv, + const hidl_vec& subSamples, const vector& key); + void decryptWithInvalidKeys(hidl_vec& invalidResponse, + vector& iv, const Pattern& noPattern, const vector& subSamples); +}; + +} // namespace vts +} // namespace V1_0 +} // namespace drm +} // namespace hardware +} // namespace android + +#endif // DRM_HAL_CLEARKEY_TEST_H diff --git a/drm/1.0/vts/functional/include/android/hardware/drm/1.0/vts/drm_hal_vendor_test.h b/drm/1.0/vts/functional/include/android/hardware/drm/1.0/vts/drm_hal_vendor_test.h new file mode 100644 index 0000000000..468d335df4 --- /dev/null +++ b/drm/1.0/vts/functional/include/android/hardware/drm/1.0/vts/drm_hal_vendor_test.h @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2020 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_VENDOR_TEST_H +#define DRM_HAL_VENDOR_TEST_H + +#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 + +using ::android::hidl::allocator::V1_0::IAllocator; +using ::android::hidl::memory::V1_0::IMemory; + +using ::drm_vts::DrmHalTestParam; +using ::drm_vts::PrintParamInstanceToString; + +using std::string; +using std::unique_ptr; +using std::map; +using std::vector; + +using ContentConfiguration = ::DrmHalVTSVendorModule_V1::ContentConfiguration; +using Key = ::DrmHalVTSVendorModule_V1::ContentConfiguration::Key; + +#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) +#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk()) + +#define RETURN_IF_SKIPPED \ + if (vendorModule == nullptr || !vendorModule->isInstalled()) { \ + GTEST_SKIP() << "This drm scheme not supported." \ + << " library:" << GetParam() << " service-name:" \ + << (vendorModule == nullptr ? "N/A" : vendorModule->getServiceName()) \ + << std::endl; \ + return; \ + } + +namespace android { +namespace hardware { +namespace drm { +namespace V1_0 { +namespace vts { + +class DrmHalVendorFactoryTest : public testing::TestWithParam { + public: + DrmHalVendorFactoryTest(); + virtual ~DrmHalVendorFactoryTest() {} + + virtual void SetUp() { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + ALOGD("Running test %s.%s from vendor module %s", test_info->test_case_name(), + test_info->name(), GetParam().instance_.c_str()); + + const std::string instance = GetParam().instance_; + if (instance == "widevine") { + ASSERT_NE(nullptr, vendorModule.get()); + } + + if (vendorModule == nullptr) { + GTEST_SKIP() << "No vendor module available"; + } else { + ASSERT_EQ(instance, vendorModule->getServiceName()); + contentConfigurations = vendorModule->getContentConfigurations(); + } + + drmFactory = IDrmFactory::getService(instance); + ASSERT_NE(nullptr, drmFactory.get()); + cryptoFactory = ICryptoFactory::getService(instance); + ASSERT_NE(nullptr, cryptoFactory.get()); + + // If drm scheme not installed skip subsequent tests + if (!drmFactory->isCryptoSchemeSupported(getUUID())) { + // no GTEST_SKIP since only some tests require the module + vendorModule->setInstalled(false); + hidl_array noUUID; + ASSERT_EQ(GetParamUUID(), noUUID) << "param uuid unsupported"; + } + } + + protected: + hidl_array getUUID() { + if (GetParamUUID() == hidl_array()) { + return getVendorUUID(); + } + return GetParamUUID(); + } + + hidl_array getVendorUUID() { + if (vendorModule == nullptr) return {}; + vector uuid = vendorModule->getUUID(); + return hidl_array(&uuid[0]); + } + + hidl_array GetParamUUID() { + return GetParam().scheme_; + } + + sp drmFactory; + sp cryptoFactory; + unique_ptr vendorModule; + vector contentConfigurations; +}; + +class DrmHalVendorPluginTest : public DrmHalVendorFactoryTest { + public: + virtual ~DrmHalVendorPluginTest() {} + virtual void SetUp() override { + // Create factories + DrmHalVendorFactoryTest::SetUp(); + RETURN_IF_SKIPPED; + + hidl_string packageName("android.hardware.drm.test"); + auto res = drmFactory->createPlugin( + getVendorUUID(), packageName, + [this](Status status, const sp& plugin) { + EXPECT_EQ(Status::OK, status); + ASSERT_NE(nullptr, plugin.get()); + drmPlugin = plugin; + }); + ASSERT_OK(res); + + hidl_vec initVec; + res = cryptoFactory->createPlugin( + getVendorUUID(), initVec, + [this](Status status, const sp& plugin) { + EXPECT_EQ(Status::OK, status); + ASSERT_NE(nullptr, plugin.get()); + cryptoPlugin = plugin; + }); + ASSERT_OK(res); + } + + virtual void TearDown() override {} + + SessionId openSession(); + void closeSession(const SessionId& sessionId); + sp getDecryptMemory(size_t size, size_t index); + KeyedVector toHidlKeyedVector(const map& params); + hidl_vec loadKeys(const SessionId& sessionId, + const ContentConfiguration& configuration, + const KeyType& type); + + protected: + sp drmPlugin; + sp cryptoPlugin; +}; + +class DrmHalVendorDecryptTest : public DrmHalVendorPluginTest { + public: + DrmHalVendorDecryptTest() = default; + virtual ~DrmHalVendorDecryptTest() {} + + protected: + void fillRandom(const sp& memory); + hidl_array toHidlArray(const vector& vec) { + EXPECT_EQ(vec.size(), 16u); + return hidl_array(&vec[0]); + } + hidl_vec queryKeyStatus(SessionId sessionId); + void removeKeys(SessionId sessionId); + uint32_t decrypt(Mode mode, bool isSecure, + const hidl_array& keyId, uint8_t* iv, + const hidl_vec& subSamples, const Pattern& pattern, + const vector& key, Status expectedStatus); + void aes_ctr_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv, + const hidl_vec& subSamples, const vector& key); + void aes_cbc_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv, + const hidl_vec& subSamples, const vector& key); +}; + +} // namespace vts +} // namespace V1_0 +} // namespace drm +} // namespace hardware +} // namespace android + +#endif // DRM_HAL_VENDOR_TEST_H diff --git a/drm/1.0/vts/functional/include/drm_hal_vendor_module_api.h b/drm/1.0/vts/functional/include/drm_hal_vendor_module_api.h new file mode 100644 index 0000000000..b8b205265d --- /dev/null +++ b/drm/1.0/vts/functional/include/drm_hal_vendor_module_api.h @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2017 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_VENDOR_MODULE_API_H +#define DRM_HAL_VENDOR_MODULE_API_H + +#include +#include +#include +#include + +/** + * The DRM and Crypto HALs interact with vendor-provided HAL implementations + * that have DRM-specific capabilities. Since the VTS tests cannot contain + * DRM-specific functionality, supporting modules are required to enable VTS + * to validate HAL implementations in a generic way. If the vendor-specific + * VTS module is not provided for a given drm HAL implementation, only very + * small subset of functionality can be verified. + * + * As an example, a DRM HAL implementation interacts with a DRM-specific + * license server to obtain licenses for decrypting content. The DRM HAL + * implementation generates a key request message, delivers it to the server + * and receives a key response message which is then loaded into the HAL. Once + * the keys are loaded, the Crypto HAL decryption functionality and performance + * and other associated APIs can be tested by the common VTS test suite. + * + * Vendor-specific VTS modules are shared libraries used by the DRM VTS test. + * They provide a set of functions to support VTS testing of the DRM HAL module. + * + * The modules are placed in a common location on the file system. The VTS test + * scans through all vendor-provided support libraries and runs the VTS test + * suite on each library that is found. + * + * The vendor-specific module exposes an extern ā€œCā€ vendorModuleFactory() + * function that returns a DrmHalVTSVendorModule instance. DrmHalVTSVendorModule + * instances are versioned, where each version is represented by subclass of + * DrmHalVTSVendorModule that corresponds to the API version. For example, a + * vendor-specific module that implements version 1 of the API would return a + * DrmHalVTSVendorModule_V1 from the vendorModuleFactory() function. + */ + +class DrmHalVTSVendorModule; + +extern "C" { +/** + * The factory method for creating DrmHalVTSVendorModule instances. The returned + * instance will be a subclass of DrmHalVTSVendorModule that corresponds to the + * supported API version. + */ +DrmHalVTSVendorModule* vendorModuleFactory(); +}; + +class DrmHalVTSVendorModule { + public: + DrmHalVTSVendorModule() : installed(true) {} + virtual ~DrmHalVTSVendorModule() {} + + /** + * Return the vendor-specific module API version. The version is an integer + * value with initial version 1. The API version indicates which subclass + * version DrmHalVTSVendorModule this instance is. + */ + virtual uint32_t getAPIVersion() const = 0; + + /** + * Return the UUID for the DRM HAL implementation. Protection System + * Specific + * UUID (see http://dashif.org/identifiers/protection/) + */ + virtual std::vector getUUID() const = 0; + + /** + * Return the service name for the DRM HAL implementation. If the hal is a + * legacy + * drm plugin, i.e. not running as a HIDL service, return the empty string. + */ + virtual std::string getServiceName() const = 0; + + /** + * Set a flag in the vendor module to indicate whether or not the drm + * scheme corresponding to this module is installed on the device. + */ + void setInstalled(bool flag) {installed = flag;} + bool isInstalled() const {return installed;} + + private: + bool installed; + DrmHalVTSVendorModule(const DrmHalVTSVendorModule&) = delete; + void operator=(const DrmHalVTSVendorModule&) = delete; +}; + +/** + * API Version 1. This is the baseline version that supports a minimal set + * of VTS tests. + */ +class DrmHalVTSVendorModule_V1 : public DrmHalVTSVendorModule { + public: + DrmHalVTSVendorModule_V1() {} + virtual ~DrmHalVTSVendorModule_V1() {} + + virtual uint32_t getAPIVersion() const { return 1; } + + /** + * Handle a provisioning request. This function will be called if the HAL + * module's getProvisionRequest returns a provision request. The vendor + * module should process the provisioning request, either by sending it + * to a provisioning server, or generating a mock response. The resulting + * provisioning response is returned to the VTS test. + * + * @param provisioningRequest the provisioning request recieved from + * the DRM HAL + * @param url the default url the HAL implementation provided with the + * provisioning request + * @return the generated provisioning response + */ + virtual std::vector handleProvisioningRequest( + const std::vector& provisioningRequest, + const std::string& url) = 0; + + /** + * Content configuration specifies content-specific parameters associated + * with a key request/response transaction. It allows the VTS test to + * request keys and use them to perform decryption. + */ + struct ContentConfiguration { + /** + * Assign a name for this configuration that will be referred to + * in log messages. + */ + const std::string name; + + /** + * Server to use when requesting a key response. This url will be + * passed as a parameter to the vendor vts module along with the + * key request to perform the key request transaction. + */ + const std::string serverUrl; + + /** + * Initialization data provided to getKeyRequest, e.g. PSSH for CENC + * content + */ + const std::vector initData; + + /** + * Mime type provided to getKeyRequest, e.g. "video/mp4", or "cenc" + */ + const std::string mimeType; + + /** + * Optional parameters to be associated with the key request + */ + const std::map optionalParameters; + + /** + * Define license policy attributes for the content configuration. + * These attributes can affect which tests are able to be applied. + */ + struct Policy { + /** + * Indicate if the license policy allows offline playback. + * Content configurated with this policy supports KeyType::OFFLINE + * key requests/responses. A vendor module should provide at least + * one content configuration where allowOffline is true if the drm + * scheme supports offline content. + */ + bool allowOffline; + } policy; + + /** + * The keys that will be available once the keys are loaded + */ + struct Key { + /** + * Indicate if the key content is configured to require secure + * buffers, where the output buffers are protected and cannot be + * accessed by the non-secure cpu. A vendor module should provide + * at least one content configurations where isSecure is false, to + * allow decrypt result verification tests to be run. + */ + bool isSecure; + + /** + * A key ID identifies a key to use for decryption + */ + const std::vector keyId; + + /** + * The clear content key is provided to generate expected values for + * validating decryption. + */ + const std::vector clearContentKey; + }; + std::vector keys; + }; + + /** + * Return a list of content configurations that can be exercised by the + * VTS test. + */ + virtual std::vector + getContentConfigurations() const = 0; + + /** + * Handle a key request. This function will be called if the HAL + * module's getKeyRequest returns a key request. The vendor + * module should process the key request, either by sending it + * to a license server, or by generating a mock response. The resulting + * key response is returned to the VTS test. + * + * @param keyRequest the key request recieved from the DRM HAL + * @param serverUrl the url of the key server that was supplied + * by the ContentConfiguration + * @return the generated key response + */ + virtual std::vector handleKeyRequest( + const std::vector& keyRequest, + const std::string& serverUrl) = 0; +}; + +#endif // DRM_HAL_VENDOR_MODULE_API_H