Home | History | Annotate | Download | only in functional
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "drm_hal_vendor_test (at) 1.0"
     18 
     19 #include <android/hardware/drm/1.0/ICryptoFactory.h>
     20 #include <android/hardware/drm/1.0/ICryptoPlugin.h>
     21 #include <android/hardware/drm/1.0/IDrmFactory.h>
     22 #include <android/hardware/drm/1.0/IDrmPlugin.h>
     23 #include <android/hardware/drm/1.0/IDrmPluginListener.h>
     24 #include <android/hardware/drm/1.0/types.h>
     25 #include <android/hidl/allocator/1.0/IAllocator.h>
     26 #include <gtest/gtest.h>
     27 #include <hidlmemory/mapping.h>
     28 #include <log/log.h>
     29 #include <memory>
     30 #include <openssl/aes.h>
     31 #include <random>
     32 
     33 #include "drm_hal_vendor_module_api.h"
     34 #include "vendor_modules.h"
     35 #include <VtsHalHidlTargetCallbackBase.h>
     36 #include <VtsHalHidlTargetTestBase.h>
     37 
     38 using ::android::hardware::drm::V1_0::BufferType;
     39 using ::android::hardware::drm::V1_0::DestinationBuffer;
     40 using ::android::hardware::drm::V1_0::EventType;
     41 using ::android::hardware::drm::V1_0::ICryptoFactory;
     42 using ::android::hardware::drm::V1_0::ICryptoPlugin;
     43 using ::android::hardware::drm::V1_0::IDrmFactory;
     44 using ::android::hardware::drm::V1_0::IDrmPlugin;
     45 using ::android::hardware::drm::V1_0::IDrmPluginListener;
     46 using ::android::hardware::drm::V1_0::KeyedVector;
     47 using ::android::hardware::drm::V1_0::KeyRequestType;
     48 using ::android::hardware::drm::V1_0::KeyStatus;
     49 using ::android::hardware::drm::V1_0::KeyStatusType;
     50 using ::android::hardware::drm::V1_0::KeyType;
     51 using ::android::hardware::drm::V1_0::KeyValue;
     52 using ::android::hardware::drm::V1_0::Mode;
     53 using ::android::hardware::drm::V1_0::Pattern;
     54 using ::android::hardware::drm::V1_0::SecureStop;
     55 using ::android::hardware::drm::V1_0::SecureStopId;
     56 using ::android::hardware::drm::V1_0::SessionId;
     57 using ::android::hardware::drm::V1_0::SharedBuffer;
     58 using ::android::hardware::drm::V1_0::Status;
     59 using ::android::hardware::drm::V1_0::SubSample;
     60 
     61 using ::android::hardware::hidl_array;
     62 using ::android::hardware::hidl_memory;
     63 using ::android::hardware::hidl_string;
     64 using ::android::hardware::hidl_vec;
     65 using ::android::hardware::Return;
     66 using ::android::hardware::Void;
     67 using ::android::hidl::allocator::V1_0::IAllocator;
     68 using ::android::hidl::memory::V1_0::IMemory;
     69 using ::android::sp;
     70 
     71 using std::string;
     72 using std::unique_ptr;
     73 using std::random_device;
     74 using std::map;
     75 using std::mt19937;
     76 using std::vector;
     77 
     78 using ContentConfiguration = ::DrmHalVTSVendorModule_V1::ContentConfiguration;
     79 using Key = ::DrmHalVTSVendorModule_V1::ContentConfiguration::Key;
     80 using VtsTestBase = ::testing::VtsHalHidlTargetTestBase;
     81 
     82 #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
     83 #define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk())
     84 
     85 #define RETURN_IF_SKIPPED \
     86     if (!vendorModule->isInstalled()) { \
     87         std::cout << "[  SKIPPED ] This drm scheme not supported." << \
     88                 " library:" << GetParam() << " service-name:" << \
     89                 vendorModule->getServiceName() << std::endl; \
     90         return; \
     91     }
     92 
     93 static const uint8_t kInvalidUUID[16] = {
     94         0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
     95         0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
     96 };
     97 
     98 static drm_vts::VendorModules* gVendorModules = nullptr;
     99 
    100 // Test environment for drm
    101 class DrmHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
    102    public:
    103     // get the test environment singleton
    104     static DrmHidlEnvironment* Instance() {
    105         static DrmHidlEnvironment* instance = new DrmHidlEnvironment;
    106         return instance;
    107     }
    108 
    109     void registerTestServices() override {
    110         registerTestService<ICryptoFactory>();
    111         registerTestService<IDrmFactory>();
    112         setServiceCombMode(::testing::HalServiceCombMode::NO_COMBINATION);
    113     }
    114 
    115    private:
    116     DrmHidlEnvironment() {}
    117 
    118     GTEST_DISALLOW_COPY_AND_ASSIGN_(DrmHidlEnvironment);
    119 };
    120 
    121 class DrmHalVendorFactoryTest : public testing::TestWithParam<std::string> {
    122    public:
    123     DrmHalVendorFactoryTest()
    124         : vendorModule(static_cast<DrmHalVTSVendorModule_V1*>(
    125                         gVendorModules->getModule(GetParam()))),
    126           contentConfigurations(vendorModule->getContentConfigurations()) {}
    127 
    128     virtual ~DrmHalVendorFactoryTest() {}
    129 
    130     virtual void SetUp() {
    131         const ::testing::TestInfo* const test_info =
    132                 ::testing::UnitTest::GetInstance()->current_test_info();
    133         ALOGD("Running test %s.%s from vendor module %s",
    134               test_info->test_case_name(), test_info->name(),
    135               GetParam().c_str());
    136 
    137         ASSERT_NE(nullptr, vendorModule.get());
    138 
    139         // First try the binderized service name provided by the vendor module.
    140         // If that fails, which it can on non-binderized devices, try the default
    141         // service.
    142         string name = vendorModule->getServiceName();
    143         drmFactory = VtsTestBase::getService<IDrmFactory>(name);
    144         if (drmFactory == nullptr) {
    145             drmFactory = VtsTestBase::getService<IDrmFactory>();
    146         }
    147         ASSERT_NE(nullptr, drmFactory.get());
    148 
    149         // Do the same for the crypto factory
    150         cryptoFactory = VtsTestBase::getService<ICryptoFactory>(name);
    151         if (cryptoFactory == nullptr) {
    152             cryptoFactory = VtsTestBase::getService<ICryptoFactory>();
    153         }
    154         ASSERT_NE(nullptr, cryptoFactory.get());
    155 
    156         // If drm scheme not installed skip subsequent tests
    157         if (!drmFactory->isCryptoSchemeSupported(getVendorUUID())) {
    158             vendorModule->setInstalled(false);
    159             return;
    160         }
    161     }
    162 
    163     virtual void TearDown() override {}
    164 
    165    protected:
    166     hidl_array<uint8_t, 16> getVendorUUID() {
    167         vector<uint8_t> uuid = vendorModule->getUUID();
    168         return hidl_array<uint8_t, 16>(&uuid[0]);
    169     }
    170 
    171     sp<IDrmFactory> drmFactory;
    172     sp<ICryptoFactory> cryptoFactory;
    173     unique_ptr<DrmHalVTSVendorModule_V1> vendorModule;
    174     const vector<ContentConfiguration> contentConfigurations;
    175 };
    176 
    177 TEST_P(DrmHalVendorFactoryTest, ValidateConfigurations) {
    178     const char* kVendorStr = "Vendor module ";
    179     size_t count = 0;
    180     for (auto config : contentConfigurations) {
    181         ASSERT_TRUE(config.name.size() > 0) << kVendorStr << "has no name";
    182         ASSERT_TRUE(config.serverUrl.size() > 0) << kVendorStr
    183                                                  << "has no serverUrl";
    184         ASSERT_TRUE(config.initData.size() > 0) << kVendorStr
    185                                                 << "has no init data";
    186         ASSERT_TRUE(config.mimeType.size() > 0) << kVendorStr
    187                                                 << "has no mime type";
    188         ASSERT_TRUE(config.keys.size() >= 1) << kVendorStr << "has no keys";
    189         for (auto key : config.keys) {
    190             ASSERT_TRUE(key.keyId.size() > 0) << kVendorStr
    191                                               << " has zero length keyId";
    192             ASSERT_TRUE(key.keyId.size() > 0) << kVendorStr
    193                                               << " has zero length key value";
    194         }
    195         count++;
    196     }
    197     EXPECT_NE(0u, count);
    198 }
    199 
    200 /**
    201  * Ensure the factory doesn't support an invalid scheme UUID
    202  */
    203 TEST_P(DrmHalVendorFactoryTest, InvalidPluginNotSupported) {
    204     EXPECT_FALSE(drmFactory->isCryptoSchemeSupported(kInvalidUUID));
    205     EXPECT_FALSE(cryptoFactory->isCryptoSchemeSupported(kInvalidUUID));
    206 }
    207 
    208 /**
    209  * Ensure the factory doesn't support an empty UUID
    210  */
    211 TEST_P(DrmHalVendorFactoryTest, EmptyPluginUUIDNotSupported) {
    212     hidl_array<uint8_t, 16> emptyUUID;
    213     memset(emptyUUID.data(), 0, 16);
    214     EXPECT_FALSE(drmFactory->isCryptoSchemeSupported(emptyUUID));
    215     EXPECT_FALSE(cryptoFactory->isCryptoSchemeSupported(emptyUUID));
    216 }
    217 
    218 /**
    219  * Check if the factory supports the scheme uuid in the config.
    220  */
    221 TEST_P(DrmHalVendorFactoryTest, PluginConfigUUIDSupported) {
    222     RETURN_IF_SKIPPED;
    223     EXPECT_TRUE(drmFactory->isCryptoSchemeSupported(getVendorUUID()));
    224     EXPECT_TRUE(cryptoFactory->isCryptoSchemeSupported(getVendorUUID()));
    225 }
    226 
    227 /**
    228  * Ensure empty content type is not supported
    229  */
    230 TEST_P(DrmHalVendorFactoryTest, EmptyContentTypeNotSupported) {
    231     hidl_string empty;
    232     EXPECT_FALSE(drmFactory->isContentTypeSupported(empty));
    233 }
    234 
    235 /**
    236  * Ensure invalid content type is not supported
    237  */
    238 TEST_P(DrmHalVendorFactoryTest, InvalidContentTypeNotSupported) {
    239     hidl_string invalid("abcdabcd");
    240     EXPECT_FALSE(drmFactory->isContentTypeSupported(invalid));
    241 }
    242 
    243 /**
    244  * Ensure valid content types in the configs are supported
    245  */
    246 TEST_P(DrmHalVendorFactoryTest, ValidContentTypeSupported) {
    247     RETURN_IF_SKIPPED;
    248     for (auto config : contentConfigurations) {
    249         EXPECT_TRUE(drmFactory->isContentTypeSupported(config.mimeType));
    250     }
    251 }
    252 
    253 /**
    254  * Ensure vendor drm plugin can be created
    255  */
    256 TEST_P(DrmHalVendorFactoryTest, CreateVendorDrmPlugin) {
    257     RETURN_IF_SKIPPED;
    258     hidl_string packageName("android.hardware.drm.test");
    259     auto res = drmFactory->createPlugin(
    260             getVendorUUID(), packageName,
    261             [&](Status status, const sp<IDrmPlugin>& plugin) {
    262                 EXPECT_EQ(Status::OK, status);
    263                 EXPECT_NE(nullptr, plugin.get());
    264             });
    265     EXPECT_OK(res);
    266 }
    267 
    268 /**
    269  * Ensure vendor crypto plugin can be created
    270  */
    271 TEST_P(DrmHalVendorFactoryTest, CreateVendorCryptoPlugin) {
    272     RETURN_IF_SKIPPED;
    273     hidl_vec<uint8_t> initVec;
    274     auto res = cryptoFactory->createPlugin(
    275             getVendorUUID(), initVec,
    276             [&](Status status, const sp<ICryptoPlugin>& plugin) {
    277                 EXPECT_EQ(Status::OK, status);
    278                 EXPECT_NE(nullptr, plugin.get());
    279             });
    280     EXPECT_OK(res);
    281 }
    282 
    283 /**
    284  * Ensure invalid drm plugin can't be created
    285  */
    286 TEST_P(DrmHalVendorFactoryTest, CreateInvalidDrmPlugin) {
    287     RETURN_IF_SKIPPED;
    288     hidl_string packageName("android.hardware.drm.test");
    289     auto res = drmFactory->createPlugin(
    290             kInvalidUUID, packageName,
    291             [&](Status status, const sp<IDrmPlugin>& plugin) {
    292                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
    293                 EXPECT_EQ(nullptr, plugin.get());
    294             });
    295     EXPECT_OK(res);
    296 }
    297 
    298 /**
    299  * Ensure invalid crypto plugin can't be created
    300  */
    301 TEST_P(DrmHalVendorFactoryTest, CreateInvalidCryptoPlugin) {
    302     RETURN_IF_SKIPPED;
    303     hidl_vec<uint8_t> initVec;
    304     auto res = cryptoFactory->createPlugin(
    305             kInvalidUUID, initVec,
    306             [&](Status status, const sp<ICryptoPlugin>& plugin) {
    307                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
    308                 EXPECT_EQ(nullptr, plugin.get());
    309             });
    310     EXPECT_OK(res);
    311 }
    312 
    313 class DrmHalVendorPluginTest : public DrmHalVendorFactoryTest {
    314    public:
    315     virtual ~DrmHalVendorPluginTest() {}
    316     virtual void SetUp() override {
    317         // Create factories
    318         DrmHalVendorFactoryTest::SetUp();
    319         RETURN_IF_SKIPPED;
    320 
    321         hidl_string packageName("android.hardware.drm.test");
    322         auto res = drmFactory->createPlugin(
    323                 getVendorUUID(), packageName,
    324                 [this](Status status, const sp<IDrmPlugin>& plugin) {
    325                     EXPECT_EQ(Status::OK, status);
    326                     ASSERT_NE(nullptr, plugin.get());
    327                     drmPlugin = plugin;
    328                 });
    329         ASSERT_OK(res);
    330 
    331         hidl_vec<uint8_t> initVec;
    332         res = cryptoFactory->createPlugin(
    333                 getVendorUUID(), initVec,
    334                 [this](Status status, const sp<ICryptoPlugin>& plugin) {
    335                     EXPECT_EQ(Status::OK, status);
    336                     ASSERT_NE(nullptr, plugin.get());
    337                     cryptoPlugin = plugin;
    338                 });
    339         ASSERT_OK(res);
    340     }
    341 
    342     virtual void TearDown() override {}
    343 
    344     SessionId openSession();
    345     void closeSession(const SessionId& sessionId);
    346     sp<IMemory> getDecryptMemory(size_t size, size_t index);
    347     KeyedVector toHidlKeyedVector(const map<string, string>& params);
    348     hidl_vec<uint8_t> loadKeys(const SessionId& sessionId,
    349                                const ContentConfiguration& configuration,
    350                                const KeyType& type);
    351 
    352    protected:
    353     sp<IDrmPlugin> drmPlugin;
    354     sp<ICryptoPlugin> cryptoPlugin;
    355 };
    356 
    357 /**
    358  *  DrmPlugin tests
    359  */
    360 
    361 /**
    362  * Test that a DRM plugin can handle provisioning.  While
    363  * it is not required that a DRM scheme require provisioning,
    364  * it should at least return appropriate status values. If
    365  * a provisioning request is returned, it is passed to the
    366  * vendor module which should provide a provisioning response
    367  * that is delivered back to the HAL.
    368  */
    369 
    370 TEST_P(DrmHalVendorPluginTest, DoProvisioning) {
    371     RETURN_IF_SKIPPED;
    372     hidl_string certificateType;
    373     hidl_string certificateAuthority;
    374     hidl_vec<uint8_t> provisionRequest;
    375     hidl_string defaultUrl;
    376     auto res = drmPlugin->getProvisionRequest(
    377             certificateType, certificateAuthority,
    378             [&](Status status, const hidl_vec<uint8_t>& request,
    379                 const hidl_string& url) {
    380                 if (status == Status::OK) {
    381                     EXPECT_NE(request.size(), 0u);
    382                     provisionRequest = request;
    383                     defaultUrl = url;
    384                 } else if (status == Status::ERROR_DRM_CANNOT_HANDLE) {
    385                     EXPECT_EQ(0u, request.size());
    386                 }
    387             });
    388     EXPECT_OK(res);
    389 
    390     if (provisionRequest.size() > 0) {
    391         vector<uint8_t> response = vendorModule->handleProvisioningRequest(
    392                 provisionRequest, defaultUrl);
    393         ASSERT_NE(0u, response.size());
    394 
    395         auto res = drmPlugin->provideProvisionResponse(
    396                 response, [&](Status status, const hidl_vec<uint8_t>&,
    397                               const hidl_vec<uint8_t>&) {
    398                     EXPECT_EQ(Status::OK, status);
    399                 });
    400         EXPECT_OK(res);
    401     }
    402 }
    403 
    404 /**
    405  * The DRM HAL should return BAD_VALUE if an empty provisioning
    406  * response is provided.
    407  */
    408 TEST_P(DrmHalVendorPluginTest, ProvideEmptyProvisionResponse) {
    409     RETURN_IF_SKIPPED;
    410     hidl_vec<uint8_t> response;
    411     auto res = drmPlugin->provideProvisionResponse(
    412             response, [&](Status status, const hidl_vec<uint8_t>&,
    413                           const hidl_vec<uint8_t>&) {
    414                 EXPECT_EQ(Status::BAD_VALUE, status);
    415             });
    416     EXPECT_OK(res);
    417 }
    418 
    419 /**
    420  * Helper method to open a session and verify that a non-empty
    421  * session ID is returned
    422  */
    423 SessionId DrmHalVendorPluginTest::openSession() {
    424     SessionId sessionId;
    425 
    426     auto res = drmPlugin->openSession([&](Status status, const SessionId& id) {
    427         EXPECT_EQ(Status::OK, status);
    428         EXPECT_NE(id.size(), 0u);
    429         sessionId = id;
    430     });
    431     EXPECT_OK(res);
    432     return sessionId;
    433 }
    434 
    435 /**
    436  * Helper method to close a session
    437  */
    438 void DrmHalVendorPluginTest::closeSession(const SessionId& sessionId) {
    439     Status status = drmPlugin->closeSession(sessionId);
    440     EXPECT_EQ(Status::OK, status);
    441 }
    442 
    443 KeyedVector DrmHalVendorPluginTest::toHidlKeyedVector(
    444     const map<string, string>& params) {
    445     std::vector<KeyValue> stdKeyedVector;
    446     for (auto it = params.begin(); it != params.end(); ++it) {
    447         KeyValue keyValue;
    448         keyValue.key = it->first;
    449         keyValue.value = it->second;
    450         stdKeyedVector.push_back(keyValue);
    451     }
    452     return KeyedVector(stdKeyedVector);
    453 }
    454 
    455 /**
    456  * Helper method to load keys for subsequent decrypt tests.
    457  * These tests use predetermined key request/response to
    458  * avoid requiring a round trip to a license server.
    459  */
    460 hidl_vec<uint8_t> DrmHalVendorPluginTest::loadKeys(
    461     const SessionId& sessionId, const ContentConfiguration& configuration,
    462     const KeyType& type = KeyType::STREAMING) {
    463     hidl_vec<uint8_t> keyRequest;
    464     auto res = drmPlugin->getKeyRequest(
    465         sessionId, configuration.initData, configuration.mimeType, type,
    466         toHidlKeyedVector(configuration.optionalParameters),
    467         [&](Status status, const hidl_vec<uint8_t>& request,
    468             KeyRequestType type, const hidl_string&) {
    469             EXPECT_EQ(Status::OK, status) << "Failed to get "
    470                                              "key request for configuration "
    471                                           << configuration.name;
    472             EXPECT_EQ(type, KeyRequestType::INITIAL);
    473             EXPECT_NE(request.size(), 0u) << "Expected key request size"
    474                                              " to have length > 0 bytes";
    475             keyRequest = request;
    476         });
    477     EXPECT_OK(res);
    478 
    479     /**
    480      * Get key response from vendor module
    481      */
    482     hidl_vec<uint8_t> keyResponse =
    483         vendorModule->handleKeyRequest(keyRequest, configuration.serverUrl);
    484 
    485     EXPECT_NE(keyResponse.size(), 0u) << "Expected key response size "
    486                                          "to have length > 0 bytes";
    487 
    488     hidl_vec<uint8_t> keySetId;
    489     res = drmPlugin->provideKeyResponse(
    490         sessionId, keyResponse,
    491         [&](Status status, const hidl_vec<uint8_t>& myKeySetId) {
    492             EXPECT_EQ(Status::OK, status) << "Failure providing "
    493                                              "key response for configuration "
    494                                           << configuration.name;
    495             keySetId = myKeySetId;
    496         });
    497     EXPECT_OK(res);
    498     return keySetId;
    499 }
    500 
    501 /**
    502  * Test that a session can be opened and closed
    503  */
    504 TEST_P(DrmHalVendorPluginTest, OpenCloseSession) {
    505     RETURN_IF_SKIPPED;
    506     auto sessionId = openSession();
    507     closeSession(sessionId);
    508 }
    509 
    510 /**
    511  * Test that attempting to close an invalid (empty) sessionId
    512  * is prohibited with the documented error code.
    513  */
    514 TEST_P(DrmHalVendorPluginTest, CloseInvalidSession) {
    515     RETURN_IF_SKIPPED;
    516     SessionId invalidSessionId;
    517     Status status = drmPlugin->closeSession(invalidSessionId);
    518     EXPECT_EQ(Status::BAD_VALUE, status);
    519 }
    520 
    521 /**
    522  * Test that attempting to close a valid session twice
    523  * is prohibited with the documented error code.
    524  */
    525 TEST_P(DrmHalVendorPluginTest, CloseClosedSession) {
    526     RETURN_IF_SKIPPED;
    527     auto sessionId = openSession();
    528     closeSession(sessionId);
    529     Status status = drmPlugin->closeSession(sessionId);
    530     EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
    531 }
    532 
    533 /**
    534  * A get key request should fail if no sessionId is provided
    535  */
    536 TEST_P(DrmHalVendorPluginTest, GetKeyRequestNoSession) {
    537     RETURN_IF_SKIPPED;
    538     SessionId invalidSessionId;
    539     hidl_vec<uint8_t> initData;
    540     hidl_string mimeType = "video/mp4";
    541     KeyedVector optionalParameters;
    542     auto res = drmPlugin->getKeyRequest(
    543             invalidSessionId, initData, mimeType, KeyType::STREAMING,
    544             optionalParameters,
    545             [&](Status status, const hidl_vec<uint8_t>&, KeyRequestType,
    546                 const hidl_string&) { EXPECT_EQ(Status::BAD_VALUE, status); });
    547     EXPECT_OK(res);
    548 }
    549 
    550 /**
    551  * Test that an empty sessionID returns BAD_VALUE
    552  */
    553 TEST_P(DrmHalVendorPluginTest, ProvideKeyResponseEmptySessionId) {
    554     RETURN_IF_SKIPPED;
    555     SessionId session;
    556 
    557     hidl_vec<uint8_t> keyResponse = {0x7b, 0x22, 0x6b, 0x65,
    558                                      0x79, 0x73, 0x22, 0x3a};
    559     auto res = drmPlugin->provideKeyResponse(
    560             session, keyResponse,
    561             [&](Status status, const hidl_vec<uint8_t>& keySetId) {
    562                 EXPECT_EQ(Status::BAD_VALUE, status);
    563                 EXPECT_EQ(keySetId.size(), 0u);
    564             });
    565     EXPECT_OK(res);
    566 }
    567 
    568 /**
    569  * Test that an empty key response returns BAD_VALUE
    570  */
    571 TEST_P(DrmHalVendorPluginTest, ProvideKeyResponseEmptyResponse) {
    572     RETURN_IF_SKIPPED;
    573     SessionId session = openSession();
    574     hidl_vec<uint8_t> emptyResponse;
    575     auto res = drmPlugin->provideKeyResponse(
    576             session, emptyResponse,
    577             [&](Status status, const hidl_vec<uint8_t>& keySetId) {
    578                 EXPECT_EQ(Status::BAD_VALUE, status);
    579                 EXPECT_EQ(keySetId.size(), 0u);
    580             });
    581     EXPECT_OK(res);
    582     closeSession(session);
    583 }
    584 
    585 /**
    586  * Test that a removeKeys on an empty sessionID returns BAD_VALUE
    587  */
    588 TEST_P(DrmHalVendorPluginTest, RemoveKeysEmptySessionId) {
    589     RETURN_IF_SKIPPED;
    590     SessionId sessionId;
    591     Status status = drmPlugin->removeKeys(sessionId);
    592     EXPECT_TRUE(status == Status::BAD_VALUE);
    593 }
    594 
    595 /**
    596  * Test that remove keys returns okay on an initialized session
    597  * that has no keys.
    598  */
    599 TEST_P(DrmHalVendorPluginTest, RemoveKeysNewSession) {
    600     RETURN_IF_SKIPPED;
    601     SessionId sessionId = openSession();
    602     Status status = drmPlugin->removeKeys(sessionId);
    603     EXPECT_TRUE(status == Status::OK);
    604     closeSession(sessionId);
    605 }
    606 
    607 /**
    608  * Test that keys are successfully restored to a new session
    609  * for all content having a policy that allows offline use.
    610  */
    611 TEST_P(DrmHalVendorPluginTest, RestoreKeys) {
    612     RETURN_IF_SKIPPED;
    613     for (auto config : contentConfigurations) {
    614         if (config.policy.allowOffline) {
    615             auto sessionId = openSession();
    616             hidl_vec<uint8_t> keySetId =
    617                     loadKeys(sessionId, config, KeyType::OFFLINE);
    618             closeSession(sessionId);
    619             sessionId = openSession();
    620             EXPECT_NE(0u, keySetId.size());
    621             Status status = drmPlugin->restoreKeys(sessionId, keySetId);
    622             EXPECT_EQ(Status::OK, status);
    623             closeSession(sessionId);
    624         }
    625     }
    626 }
    627 
    628 /**
    629  * Test that restoreKeys fails with a null key set ID.
    630  * Error message is expected to be Status::BAD_VALUE.
    631  */
    632 TEST_P(DrmHalVendorPluginTest, RestoreKeysNull) {
    633     RETURN_IF_SKIPPED;
    634     SessionId sessionId = openSession();
    635     hidl_vec<uint8_t> nullKeySetId;
    636     Status status = drmPlugin->restoreKeys(sessionId, nullKeySetId);
    637     EXPECT_EQ(Status::BAD_VALUE, status);
    638     closeSession(sessionId);
    639 }
    640 
    641 /**
    642  * Test that restoreKeys fails to restore keys to a closed
    643  * session. Error message is expected to be
    644  * Status::ERROR_DRM_SESSION_NOT_OPENED.
    645  */
    646 TEST_P(DrmHalVendorPluginTest, RestoreKeysClosedSession) {
    647     RETURN_IF_SKIPPED;
    648     for (auto config : contentConfigurations) {
    649         if (config.policy.allowOffline) {
    650             auto sessionId = openSession();
    651             hidl_vec<uint8_t> keySetId =
    652                     loadKeys(sessionId, config, KeyType::OFFLINE);
    653             EXPECT_NE(0u, keySetId.size());
    654             closeSession(sessionId);
    655             sessionId = openSession();
    656             closeSession(sessionId);
    657             Status status = drmPlugin->restoreKeys(sessionId, keySetId);
    658             EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
    659         }
    660     }
    661 }
    662 
    663 /**
    664  * Test that the plugin either doesn't support getting
    665  * secure stops, or has no secure stops available after
    666  * clearing them.
    667  */
    668 TEST_P(DrmHalVendorPluginTest, GetSecureStops) {
    669     RETURN_IF_SKIPPED;
    670     // There may be secure stops, depending on if there were keys
    671     // loaded and unloaded previously. Clear them to get to a known
    672     // state, then make sure there are none.
    673     auto res = drmPlugin->getSecureStops(
    674             [&](Status status, const hidl_vec<SecureStop>&) {
    675                 if (status != Status::OK) {
    676                     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
    677                 }
    678             });
    679     EXPECT_OK(res);
    680 
    681     res = drmPlugin->getSecureStops(
    682             [&](Status status, const hidl_vec<SecureStop>& secureStops) {
    683                 if (status == Status::OK) {
    684                     EXPECT_EQ(secureStops.size(), 0u);
    685                 } else {
    686                     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
    687                 }
    688             });
    689     EXPECT_OK(res);
    690 }
    691 
    692 /**
    693  * Test that the clearkey plugin returns BAD_VALUE if
    694  * an empty ssid is provided.
    695  */
    696 TEST_P(DrmHalVendorPluginTest, GetSecureStopEmptySSID) {
    697     RETURN_IF_SKIPPED;
    698     SecureStopId ssid;
    699     auto res = drmPlugin->getSecureStop(
    700             ssid, [&](Status status, const SecureStop&) {
    701                 EXPECT_EQ(Status::BAD_VALUE, status);
    702             });
    703     EXPECT_OK(res);
    704 }
    705 
    706 /**
    707  * Test that releasing all secure stops either isn't supported
    708  * or is completed successfully
    709  */
    710 TEST_P(DrmHalVendorPluginTest, ReleaseAllSecureStops) {
    711     RETURN_IF_SKIPPED;
    712     Status status = drmPlugin->releaseAllSecureStops();
    713     EXPECT_TRUE(status == Status::OK ||
    714                 status == Status::ERROR_DRM_CANNOT_HANDLE);
    715 }
    716 
    717 /**
    718  * Releasing a secure stop without first getting one and sending it to the
    719  * server to get a valid SSID should return ERROR_DRM_INVALID_STATE.
    720  * This is an optional API so it can also return CANNOT_HANDLE.
    721  */
    722 TEST_P(DrmHalVendorPluginTest, ReleaseSecureStopSequenceError) {
    723     RETURN_IF_SKIPPED;
    724     SecureStopId ssid = {1, 2, 3, 4};
    725     Status status = drmPlugin->releaseSecureStop(ssid);
    726     EXPECT_TRUE(status == Status::ERROR_DRM_INVALID_STATE ||
    727                 status == Status::ERROR_DRM_CANNOT_HANDLE);
    728 }
    729 
    730 /**
    731  * Test that releasing a specific secure stop with an empty ssid
    732  * return BAD_VALUE. This is an optional API so it can also return
    733  * CANNOT_HANDLE.
    734  */
    735 TEST_P(DrmHalVendorPluginTest, ReleaseSecureStopEmptySSID) {
    736     RETURN_IF_SKIPPED;
    737     SecureStopId ssid;
    738     Status status = drmPlugin->releaseSecureStop(ssid);
    739     EXPECT_TRUE(status == Status::BAD_VALUE ||
    740                 status == Status::ERROR_DRM_CANNOT_HANDLE);
    741 }
    742 
    743 /**
    744  * The following five tests verify that the properties
    745  * defined in the MediaDrm API are supported by
    746  * the plugin.
    747  */
    748 TEST_P(DrmHalVendorPluginTest, GetVendorProperty) {
    749     RETURN_IF_SKIPPED;
    750     auto res = drmPlugin->getPropertyString(
    751             "vendor", [&](Status status, const hidl_string& value) {
    752                 EXPECT_EQ(Status::OK, status);
    753                 EXPECT_NE(value.size(), 0u);
    754             });
    755     EXPECT_OK(res);
    756 }
    757 
    758 TEST_P(DrmHalVendorPluginTest, GetVersionProperty) {
    759     RETURN_IF_SKIPPED;
    760     auto res = drmPlugin->getPropertyString(
    761             "version", [&](Status status, const hidl_string& value) {
    762                 EXPECT_EQ(Status::OK, status);
    763                 EXPECT_NE(value.size(), 0u);
    764             });
    765     EXPECT_OK(res);
    766 }
    767 
    768 TEST_P(DrmHalVendorPluginTest, GetDescriptionProperty) {
    769     RETURN_IF_SKIPPED;
    770     auto res = drmPlugin->getPropertyString(
    771             "description", [&](Status status, const hidl_string& value) {
    772                 EXPECT_EQ(Status::OK, status);
    773                 EXPECT_NE(value.size(), 0u);
    774             });
    775     EXPECT_OK(res);
    776 }
    777 
    778 TEST_P(DrmHalVendorPluginTest, GetAlgorithmsProperty) {
    779     RETURN_IF_SKIPPED;
    780     auto res = drmPlugin->getPropertyString(
    781             "algorithms", [&](Status status, const hidl_string& value) {
    782                 if (status == Status::OK) {
    783                     EXPECT_NE(value.size(), 0u);
    784                 } else {
    785                     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
    786                 }
    787             });
    788     EXPECT_OK(res);
    789 }
    790 
    791 TEST_P(DrmHalVendorPluginTest, GetPropertyUniqueDeviceID) {
    792     RETURN_IF_SKIPPED;
    793     auto res = drmPlugin->getPropertyByteArray(
    794             "deviceUniqueId",
    795             [&](Status status, const hidl_vec<uint8_t>& value) {
    796                 if (status == Status::OK) {
    797                     EXPECT_NE(value.size(), 0u);
    798                 } else {
    799                     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
    800                 }
    801             });
    802     EXPECT_OK(res);
    803 }
    804 
    805 /**
    806  * Test that attempting to read invalid string and byte array
    807  * properties returns the documented error code.
    808  */
    809 TEST_P(DrmHalVendorPluginTest, GetInvalidStringProperty) {
    810     RETURN_IF_SKIPPED;
    811     auto res = drmPlugin->getPropertyString(
    812             "invalid", [&](Status status, const hidl_string&) {
    813                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
    814             });
    815     EXPECT_OK(res);
    816 }
    817 
    818 TEST_P(DrmHalVendorPluginTest, GetInvalidByteArrayProperty) {
    819     RETURN_IF_SKIPPED;
    820     auto res = drmPlugin->getPropertyByteArray(
    821             "invalid", [&](Status status, const hidl_vec<uint8_t>&) {
    822                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
    823             });
    824     EXPECT_OK(res);
    825 }
    826 
    827 /**
    828  * Test that setting invalid string and byte array properties returns
    829  * the expected status value.
    830  */
    831 TEST_P(DrmHalVendorPluginTest, SetStringPropertyNotSupported) {
    832     RETURN_IF_SKIPPED;
    833     EXPECT_EQ(drmPlugin->setPropertyString("awefijaeflijwef", "value"),
    834               Status::ERROR_DRM_CANNOT_HANDLE);
    835 }
    836 
    837 TEST_P(DrmHalVendorPluginTest, SetByteArrayPropertyNotSupported) {
    838     RETURN_IF_SKIPPED;
    839     hidl_vec<uint8_t> value;
    840     EXPECT_EQ(drmPlugin->setPropertyByteArray("awefijaeflijwef", value),
    841               Status::ERROR_DRM_CANNOT_HANDLE);
    842 }
    843 
    844 /**
    845  * Test that setting an invalid cipher algorithm returns
    846  * the expected status value.
    847  */
    848 TEST_P(DrmHalVendorPluginTest, SetCipherInvalidAlgorithm) {
    849     RETURN_IF_SKIPPED;
    850     SessionId session = openSession();
    851     hidl_string algorithm;
    852     Status status = drmPlugin->setCipherAlgorithm(session, algorithm);
    853     EXPECT_EQ(Status::BAD_VALUE, status);
    854     closeSession(session);
    855 }
    856 
    857 /**
    858  * Test that setting a cipher algorithm with no session returns
    859  * the expected status value.
    860  */
    861 TEST_P(DrmHalVendorPluginTest, SetCipherAlgorithmNoSession) {
    862     RETURN_IF_SKIPPED;
    863     SessionId session;
    864     hidl_string algorithm = "AES/CBC/NoPadding";
    865     Status status = drmPlugin->setCipherAlgorithm(session, algorithm);
    866     EXPECT_EQ(Status::BAD_VALUE, status);
    867 }
    868 
    869 /**
    870  * Test that setting a valid cipher algorithm returns
    871  * the expected status value. It is not required that all
    872  * vendor modules support this algorithm, but they must
    873  * either accept it or return ERROR_DRM_CANNOT_HANDLE
    874  */
    875 TEST_P(DrmHalVendorPluginTest, SetCipherAlgorithm) {
    876     RETURN_IF_SKIPPED;
    877     SessionId session = openSession();
    878     ;
    879     hidl_string algorithm = "AES/CBC/NoPadding";
    880     Status status = drmPlugin->setCipherAlgorithm(session, algorithm);
    881     EXPECT_TRUE(status == Status::OK ||
    882                 status == Status::ERROR_DRM_CANNOT_HANDLE);
    883     closeSession(session);
    884 }
    885 
    886 /**
    887  * Test that setting an invalid mac algorithm returns
    888  * the expected status value.
    889  */
    890 TEST_P(DrmHalVendorPluginTest, SetMacInvalidAlgorithm) {
    891     RETURN_IF_SKIPPED;
    892     SessionId session = openSession();
    893     hidl_string algorithm;
    894     Status status = drmPlugin->setMacAlgorithm(session, algorithm);
    895     EXPECT_EQ(Status::BAD_VALUE, status);
    896     closeSession(session);
    897 }
    898 
    899 /**
    900  * Test that setting a mac algorithm with no session returns
    901  * the expected status value.
    902  */
    903 TEST_P(DrmHalVendorPluginTest, SetMacNullAlgorithmNoSession) {
    904     RETURN_IF_SKIPPED;
    905     SessionId session;
    906     hidl_string algorithm = "HmacSHA256";
    907     Status status = drmPlugin->setMacAlgorithm(session, algorithm);
    908     EXPECT_EQ(Status::BAD_VALUE, status);
    909 }
    910 
    911 /**
    912  * Test that setting a valid mac algorithm returns
    913  * the expected status value. It is not required that all
    914  * vendor modules support this algorithm, but they must
    915  * either accept it or return ERROR_DRM_CANNOT_HANDLE
    916  */
    917 TEST_P(DrmHalVendorPluginTest, SetMacAlgorithm) {
    918     RETURN_IF_SKIPPED;
    919     SessionId session = openSession();
    920     hidl_string algorithm = "HmacSHA256";
    921     Status status = drmPlugin->setMacAlgorithm(session, algorithm);
    922     EXPECT_TRUE(status == Status::OK ||
    923                 status == Status::ERROR_DRM_CANNOT_HANDLE);
    924     closeSession(session);
    925 }
    926 
    927 /**
    928  * The Generic* methods provide general purpose crypto operations
    929  * that may be used for applications other than DRM. They leverage
    930  * the hardware root of trust and secure key distribution mechanisms
    931  * of a DRM system to enable app-specific crypto functionality where
    932  * the crypto keys are not exposed outside of the trusted execution
    933  * environment.
    934  *
    935  * Generic encrypt/decrypt/sign/verify should fail on invalid
    936  * inputs, e.g. empty sessionId
    937  */
    938 TEST_P(DrmHalVendorPluginTest, GenericEncryptNoSession) {
    939     RETURN_IF_SKIPPED;
    940     SessionId session;
    941     hidl_vec<uint8_t> keyId, input, iv;
    942     auto res = drmPlugin->encrypt(
    943             session, keyId, input, iv,
    944             [&](Status status, const hidl_vec<uint8_t>&) {
    945                 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
    946             });
    947     EXPECT_OK(res);
    948 }
    949 
    950 TEST_P(DrmHalVendorPluginTest, GenericDecryptNoSession) {
    951     RETURN_IF_SKIPPED;
    952     SessionId session;
    953     hidl_vec<uint8_t> keyId, input, iv;
    954     auto res = drmPlugin->decrypt(
    955             session, keyId, input, iv,
    956             [&](Status status, const hidl_vec<uint8_t>&) {
    957                 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
    958             });
    959     EXPECT_OK(res);
    960 }
    961 
    962 TEST_P(DrmHalVendorPluginTest, GenericSignNoSession) {
    963     RETURN_IF_SKIPPED;
    964     SessionId session;
    965     hidl_vec<uint8_t> keyId, message;
    966     auto res = drmPlugin->sign(
    967             session, keyId, message,
    968             [&](Status status, const hidl_vec<uint8_t>&) {
    969                 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
    970             });
    971     EXPECT_OK(res);
    972 }
    973 
    974 TEST_P(DrmHalVendorPluginTest, GenericVerifyNoSession) {
    975     RETURN_IF_SKIPPED;
    976     SessionId session;
    977     hidl_vec<uint8_t> keyId, message, signature;
    978     auto res = drmPlugin->verify(
    979             session, keyId, message, signature, [&](Status status, bool) {
    980                 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
    981             });
    982     EXPECT_OK(res);
    983 }
    984 
    985 TEST_P(DrmHalVendorPluginTest, GenericSignRSANoSession) {
    986     RETURN_IF_SKIPPED;
    987     SessionId session;
    988     hidl_string algorithm;
    989     hidl_vec<uint8_t> message, wrappedKey;
    990     auto res = drmPlugin->signRSA(session, algorithm, message, wrappedKey,
    991                                   [&](Status status, const hidl_vec<uint8_t>&) {
    992                                       EXPECT_EQ(Status::BAD_VALUE, status);
    993                                   });
    994     EXPECT_OK(res);
    995 }
    996 
    997 /**
    998  * Exercise the requiresSecureDecoderComponent method. Additional tests
    999  * will verify positive cases with specific vendor content configurations.
   1000  * Below we just test the negative cases.
   1001  */
   1002 
   1003 /**
   1004  * Verify that requiresSecureDecoderComponent handles empty mimetype.
   1005  */
   1006 TEST_P(DrmHalVendorPluginTest, RequiresSecureDecoderEmptyMimeType) {
   1007     RETURN_IF_SKIPPED;
   1008     EXPECT_FALSE(cryptoPlugin->requiresSecureDecoderComponent(""));
   1009 }
   1010 
   1011 /**
   1012  * Verify that requiresSecureDecoderComponent handles invalid mimetype.
   1013  */
   1014 TEST_P(DrmHalVendorPluginTest, RequiresSecureDecoderInvalidMimeType) {
   1015     RETURN_IF_SKIPPED;
   1016     EXPECT_FALSE(cryptoPlugin->requiresSecureDecoderComponent("bad"));
   1017 }
   1018 
   1019 /**
   1020  * Verify that requiresSecureDecoderComponent returns true for secure
   1021  * configurations
   1022  */
   1023 TEST_P(DrmHalVendorPluginTest, RequiresSecureDecoderConfig) {
   1024     RETURN_IF_SKIPPED;
   1025     for (auto config : contentConfigurations) {
   1026         for (auto key : config.keys) {
   1027             if (key.isSecure) {
   1028                 EXPECT_TRUE(cryptoPlugin->requiresSecureDecoderComponent(config.mimeType));
   1029                 break;
   1030             }
   1031         }
   1032     }
   1033 }
   1034 
   1035 /**
   1036  *  Event Handling tests
   1037  */
   1038 struct ListenerEventArgs {
   1039     EventType eventType;
   1040     SessionId sessionId;
   1041     hidl_vec<uint8_t> data;
   1042     int64_t expiryTimeInMS;
   1043     hidl_vec<KeyStatus> keyStatusList;
   1044     bool hasNewUsableKey;
   1045 };
   1046 
   1047 const char *kCallbackEvent = "SendEvent";
   1048 const char *kCallbackExpirationUpdate = "SendExpirationUpdate";
   1049 const char *kCallbackKeysChange = "SendKeysChange";
   1050 
   1051 class TestDrmPluginListener
   1052     : public ::testing::VtsHalHidlTargetCallbackBase<ListenerEventArgs>,
   1053       public IDrmPluginListener {
   1054 public:
   1055     TestDrmPluginListener() {
   1056         SetWaitTimeoutDefault(std::chrono::milliseconds(500));
   1057     }
   1058     virtual ~TestDrmPluginListener() {}
   1059 
   1060     virtual Return<void> sendEvent(EventType eventType, const hidl_vec<uint8_t>& sessionId,
   1061             const hidl_vec<uint8_t>& data) override {
   1062         ListenerEventArgs args;
   1063         args.eventType = eventType;
   1064         args.sessionId = sessionId;
   1065         args.data = data;
   1066         NotifyFromCallback(kCallbackEvent, args);
   1067         return Void();
   1068     }
   1069 
   1070     virtual Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
   1071             int64_t expiryTimeInMS) override {
   1072         ListenerEventArgs args;
   1073         args.sessionId = sessionId;
   1074         args.expiryTimeInMS = expiryTimeInMS;
   1075         NotifyFromCallback(kCallbackExpirationUpdate, args);
   1076         return Void();
   1077     }
   1078 
   1079     virtual Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
   1080             const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) override {
   1081         ListenerEventArgs args;
   1082         args.sessionId = sessionId;
   1083         args.keyStatusList = keyStatusList;
   1084         args.hasNewUsableKey = hasNewUsableKey;
   1085         NotifyFromCallback(kCallbackKeysChange, args);
   1086         return Void();
   1087     }
   1088 };
   1089 
   1090 
   1091 /**
   1092  * Simulate the plugin sending events. Make sure the listener
   1093  * gets them.
   1094  */
   1095 TEST_P(DrmHalVendorPluginTest, ListenerEvents) {
   1096     RETURN_IF_SKIPPED;
   1097     sp<TestDrmPluginListener> listener = new TestDrmPluginListener();
   1098     drmPlugin->setListener(listener);
   1099     auto sessionId = openSession();
   1100     hidl_vec<uint8_t> data = {0, 1, 2};
   1101     EventType eventTypes[] = {EventType::PROVISION_REQUIRED,
   1102                               EventType::KEY_NEEDED,
   1103                               EventType::KEY_EXPIRED,
   1104                               EventType::VENDOR_DEFINED,
   1105                               EventType::SESSION_RECLAIMED};
   1106     for (auto eventType : eventTypes) {
   1107         drmPlugin->sendEvent(eventType, sessionId, data);
   1108         auto result = listener->WaitForCallback(kCallbackEvent);
   1109         EXPECT_TRUE(result.no_timeout);
   1110         EXPECT_TRUE(result.args);
   1111         EXPECT_EQ(eventType, result.args->eventType);
   1112         EXPECT_EQ(sessionId, result.args->sessionId);
   1113         EXPECT_EQ(data, result.args->data);
   1114     }
   1115     closeSession(sessionId);
   1116 }
   1117 
   1118 /**
   1119  * Simulate the plugin sending expiration updates and make sure
   1120  * the listener gets them.
   1121  */
   1122 TEST_P(DrmHalVendorPluginTest, ListenerExpirationUpdate) {
   1123     RETURN_IF_SKIPPED;
   1124     sp<TestDrmPluginListener> listener = new TestDrmPluginListener();
   1125     drmPlugin->setListener(listener);
   1126     auto sessionId = openSession();
   1127     drmPlugin->sendExpirationUpdate(sessionId, 100);
   1128     auto result = listener->WaitForCallback(kCallbackExpirationUpdate);
   1129     EXPECT_TRUE(result.no_timeout);
   1130     EXPECT_TRUE(result.args);
   1131     EXPECT_EQ(sessionId, result.args->sessionId);
   1132     EXPECT_EQ(100, result.args->expiryTimeInMS);
   1133     closeSession(sessionId);
   1134 }
   1135 
   1136 /**
   1137  * Simulate the plugin sending keys change and make sure
   1138  * the listener gets them.
   1139  */
   1140 TEST_P(DrmHalVendorPluginTest, ListenerKeysChange) {
   1141     RETURN_IF_SKIPPED;
   1142     sp<TestDrmPluginListener> listener = new TestDrmPluginListener();
   1143     drmPlugin->setListener(listener);
   1144     auto sessionId = openSession();
   1145     const hidl_vec<KeyStatus> keyStatusList = {
   1146         {{1}, KeyStatusType::USABLE},
   1147         {{2}, KeyStatusType::EXPIRED},
   1148         {{3}, KeyStatusType::OUTPUTNOTALLOWED},
   1149         {{4}, KeyStatusType::STATUSPENDING},
   1150         {{5}, KeyStatusType::INTERNALERROR},
   1151     };
   1152 
   1153     drmPlugin->sendKeysChange(sessionId, keyStatusList, true);
   1154     auto result = listener->WaitForCallback(kCallbackKeysChange);
   1155     EXPECT_TRUE(result.no_timeout);
   1156     EXPECT_TRUE(result.args);
   1157     EXPECT_EQ(sessionId, result.args->sessionId);
   1158     EXPECT_EQ(keyStatusList, result.args->keyStatusList);
   1159     closeSession(sessionId);
   1160 }
   1161 
   1162 /**
   1163  * Negative listener tests. Call send methods with no
   1164  * listener set.
   1165  */
   1166 TEST_P(DrmHalVendorPluginTest, NotListening) {
   1167     RETURN_IF_SKIPPED;
   1168     sp<TestDrmPluginListener> listener = new TestDrmPluginListener();
   1169     drmPlugin->setListener(listener);
   1170     drmPlugin->setListener(nullptr);
   1171 
   1172     SessionId sessionId;
   1173     hidl_vec<uint8_t> data;
   1174     hidl_vec<KeyStatus> keyStatusList;
   1175     drmPlugin->sendEvent(EventType::PROVISION_REQUIRED, sessionId, data);
   1176     drmPlugin->sendExpirationUpdate(sessionId, 100);
   1177     drmPlugin->sendKeysChange(sessionId, keyStatusList, true);
   1178     auto result = listener->WaitForCallbackAny(
   1179             {kCallbackEvent, kCallbackExpirationUpdate, kCallbackKeysChange});
   1180     EXPECT_FALSE(result.no_timeout);
   1181 }
   1182 
   1183 
   1184 /**
   1185  *  CryptoPlugin tests
   1186  */
   1187 
   1188 /**
   1189  * Exercise the NotifyResolution API. There is no observable result,
   1190  * just call the method for coverage.
   1191  */
   1192 TEST_P(DrmHalVendorPluginTest, NotifyResolution) {
   1193     RETURN_IF_SKIPPED;
   1194     cryptoPlugin->notifyResolution(1920, 1080);
   1195 }
   1196 
   1197 /**
   1198  * getDecryptMemory allocates memory for decryption, then sets it
   1199  * as a shared buffer base in the crypto hal.  The allocated and
   1200  * mapped IMemory is returned.
   1201  *
   1202  * @param size the size of the memory segment to allocate
   1203  * @param the index of the memory segment which will be used
   1204  * to refer to it for decryption.
   1205  */
   1206 sp<IMemory> DrmHalVendorPluginTest::getDecryptMemory(size_t size,
   1207                                                      size_t index) {
   1208     sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem");
   1209     EXPECT_NE(nullptr, ashmemAllocator.get());
   1210 
   1211     hidl_memory hidlMemory;
   1212     auto res = ashmemAllocator->allocate(
   1213             size, [&](bool success, const hidl_memory& memory) {
   1214                 EXPECT_EQ(success, true);
   1215                 EXPECT_EQ(memory.size(), size);
   1216                 hidlMemory = memory;
   1217             });
   1218 
   1219     EXPECT_OK(res);
   1220 
   1221     sp<IMemory> mappedMemory = mapMemory(hidlMemory);
   1222     EXPECT_NE(nullptr, mappedMemory.get());
   1223     res = cryptoPlugin->setSharedBufferBase(hidlMemory, index);
   1224     EXPECT_OK(res);
   1225     return mappedMemory;
   1226 }
   1227 
   1228 /**
   1229  * Exercise the setMediaDrmSession method. setMediaDrmSession
   1230  * is used to associate a drm session with a crypto session.
   1231  */
   1232 TEST_P(DrmHalVendorPluginTest, SetMediaDrmSession) {
   1233     RETURN_IF_SKIPPED;
   1234     auto sessionId = openSession();
   1235     Status status = cryptoPlugin->setMediaDrmSession(sessionId);
   1236     EXPECT_EQ(Status::OK, status);
   1237     closeSession(sessionId);
   1238 }
   1239 
   1240 /**
   1241  * setMediaDrmSession with a closed session id
   1242  */
   1243 TEST_P(DrmHalVendorPluginTest, SetMediaDrmSessionClosedSession) {
   1244     RETURN_IF_SKIPPED;
   1245     auto sessionId = openSession();
   1246     closeSession(sessionId);
   1247     Status status = cryptoPlugin->setMediaDrmSession(sessionId);
   1248     EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
   1249 }
   1250 
   1251 /**
   1252  * setMediaDrmSession with a empty session id: BAD_VALUE
   1253  */
   1254 TEST_P(DrmHalVendorPluginTest, SetMediaDrmSessionEmptySession) {
   1255     RETURN_IF_SKIPPED;
   1256     SessionId sessionId;
   1257     Status status = cryptoPlugin->setMediaDrmSession(sessionId);
   1258     EXPECT_EQ(Status::BAD_VALUE, status);
   1259 }
   1260 
   1261 /**
   1262  * Decrypt tests
   1263  */
   1264 
   1265 class DrmHalVendorDecryptTest : public DrmHalVendorPluginTest {
   1266    public:
   1267     DrmHalVendorDecryptTest() = default;
   1268     virtual ~DrmHalVendorDecryptTest() {}
   1269 
   1270    protected:
   1271     void fillRandom(const sp<IMemory>& memory);
   1272     hidl_array<uint8_t, 16> toHidlArray(const vector<uint8_t>& vec) {
   1273         EXPECT_EQ(vec.size(), 16u);
   1274         return hidl_array<uint8_t, 16>(&vec[0]);
   1275     }
   1276     hidl_vec<KeyValue> queryKeyStatus(SessionId sessionId);
   1277     void removeKeys(SessionId sessionId);
   1278     uint32_t decrypt(Mode mode, bool isSecure,
   1279             const hidl_array<uint8_t, 16>& keyId, uint8_t* iv,
   1280             const hidl_vec<SubSample>& subSamples, const Pattern& pattern,
   1281             const vector<uint8_t>& key, Status expectedStatus);
   1282     void aes_ctr_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv,
   1283             const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key);
   1284     void aes_cbc_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv,
   1285             const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key);
   1286 };
   1287 
   1288 void DrmHalVendorDecryptTest::fillRandom(const sp<IMemory>& memory) {
   1289     random_device rd;
   1290     mt19937 rand(rd());
   1291     for (size_t i = 0; i < memory->getSize() / sizeof(uint32_t); i++) {
   1292         auto p = static_cast<uint32_t*>(
   1293                 static_cast<void*>(memory->getPointer()));
   1294         p[i] = rand();
   1295     }
   1296 }
   1297 
   1298 hidl_vec<KeyValue> DrmHalVendorDecryptTest::queryKeyStatus(SessionId sessionId) {
   1299     hidl_vec<KeyValue> keyStatus;
   1300     auto res = drmPlugin->queryKeyStatus(sessionId,
   1301             [&](Status status, KeyedVector info) {
   1302                 EXPECT_EQ(Status::OK, status);
   1303                 keyStatus = info;
   1304             });
   1305     EXPECT_OK(res);
   1306     return keyStatus;
   1307 }
   1308 
   1309 void DrmHalVendorDecryptTest::removeKeys(SessionId sessionId) {
   1310     auto res = drmPlugin->removeKeys(sessionId);
   1311     EXPECT_OK(res);
   1312 }
   1313 
   1314 uint32_t DrmHalVendorDecryptTest::decrypt(Mode mode, bool isSecure,
   1315         const hidl_array<uint8_t, 16>& keyId, uint8_t* iv,
   1316         const hidl_vec<SubSample>& subSamples, const Pattern& pattern,
   1317         const vector<uint8_t>& key, Status expectedStatus) {
   1318     const size_t kSegmentIndex = 0;
   1319 
   1320     uint8_t localIv[AES_BLOCK_SIZE];
   1321     memcpy(localIv, iv, AES_BLOCK_SIZE);
   1322 
   1323     size_t totalSize = 0;
   1324     for (size_t i = 0; i < subSamples.size(); i++) {
   1325         totalSize += subSamples[i].numBytesOfClearData;
   1326         totalSize += subSamples[i].numBytesOfEncryptedData;
   1327     }
   1328 
   1329     // The first totalSize bytes of shared memory is the encrypted
   1330     // input, the second totalSize bytes is the decrypted output.
   1331     sp<IMemory> sharedMemory =
   1332             getDecryptMemory(totalSize * 2, kSegmentIndex);
   1333 
   1334     SharedBuffer sourceBuffer = {
   1335             .bufferId = kSegmentIndex, .offset = 0, .size = totalSize};
   1336     fillRandom(sharedMemory);
   1337 
   1338     DestinationBuffer destBuffer = {.type = BufferType::SHARED_MEMORY,
   1339                                     {.bufferId = kSegmentIndex,
   1340                                      .offset = totalSize,
   1341                                      .size = totalSize},
   1342                                     .secureMemory = nullptr};
   1343     uint64_t offset = 0;
   1344     uint32_t bytesWritten = 0;
   1345     auto res = cryptoPlugin->decrypt(isSecure, keyId, localIv, mode, pattern,
   1346             subSamples, sourceBuffer, offset, destBuffer,
   1347             [&](Status status, uint32_t count, string detailedError) {
   1348                 EXPECT_EQ(expectedStatus, status) << "Unexpected decrypt status " <<
   1349                 detailedError;
   1350                 bytesWritten = count;
   1351             });
   1352     EXPECT_OK(res);
   1353 
   1354     if (bytesWritten != totalSize) {
   1355         return bytesWritten;
   1356     }
   1357     uint8_t* base = static_cast<uint8_t*>(
   1358             static_cast<void*>(sharedMemory->getPointer()));
   1359 
   1360     // generate reference vector
   1361     vector<uint8_t> reference(totalSize);
   1362 
   1363     memcpy(localIv, iv, AES_BLOCK_SIZE);
   1364     switch (mode) {
   1365     case Mode::UNENCRYPTED:
   1366         memcpy(&reference[0], base, totalSize);
   1367         break;
   1368     case Mode::AES_CTR:
   1369         aes_ctr_decrypt(&reference[0], base, localIv, subSamples, key);
   1370         break;
   1371     case Mode::AES_CBC:
   1372         aes_cbc_decrypt(&reference[0], base, localIv, subSamples, key);
   1373         break;
   1374     case Mode::AES_CBC_CTS:
   1375         EXPECT_TRUE(false) << "AES_CBC_CTS mode not supported";
   1376         break;
   1377     }
   1378 
   1379     // compare reference to decrypted data which is at base + total size
   1380     EXPECT_EQ(0, memcmp(static_cast<void*>(&reference[0]),
   1381                         static_cast<void*>(base + totalSize), totalSize))
   1382             << "decrypt data mismatch";
   1383     return totalSize;
   1384 }
   1385 
   1386 /**
   1387  * Decrypt a list of clear+encrypted subsamples using the specified key
   1388  * in AES-CTR mode
   1389  */
   1390 void DrmHalVendorDecryptTest::aes_ctr_decrypt(uint8_t* dest, uint8_t* src,
   1391         uint8_t* iv, const hidl_vec<SubSample>& subSamples,
   1392         const vector<uint8_t>& key) {
   1393 
   1394     AES_KEY decryptionKey;
   1395     AES_set_encrypt_key(&key[0], 128, &decryptionKey);
   1396 
   1397     size_t offset = 0;
   1398     unsigned blockOffset = 0;
   1399     uint8_t previousEncryptedCounter[AES_BLOCK_SIZE];
   1400     memset(previousEncryptedCounter, 0, AES_BLOCK_SIZE);
   1401 
   1402     for (size_t i = 0; i < subSamples.size(); i++) {
   1403         const SubSample& subSample = subSamples[i];
   1404 
   1405         if (subSample.numBytesOfClearData > 0) {
   1406             memcpy(dest + offset, src + offset, subSample.numBytesOfClearData);
   1407             offset += subSample.numBytesOfClearData;
   1408         }
   1409 
   1410         if (subSample.numBytesOfEncryptedData > 0) {
   1411             AES_ctr128_encrypt(src + offset, dest + offset,
   1412                     subSample.numBytesOfEncryptedData, &decryptionKey,
   1413                     iv, previousEncryptedCounter, &blockOffset);
   1414             offset += subSample.numBytesOfEncryptedData;
   1415         }
   1416     }
   1417 }
   1418 
   1419 /**
   1420  * Decrypt a list of clear+encrypted subsamples using the specified key
   1421  * in AES-CBC mode
   1422  */
   1423 void DrmHalVendorDecryptTest::aes_cbc_decrypt(uint8_t* dest, uint8_t* src,
   1424         uint8_t* iv, const hidl_vec<SubSample>& subSamples,
   1425         const vector<uint8_t>& key) {
   1426     AES_KEY decryptionKey;
   1427     AES_set_encrypt_key(&key[0], 128, &decryptionKey);
   1428 
   1429     size_t offset = 0;
   1430     for (size_t i = 0; i < subSamples.size(); i++) {
   1431         const SubSample& subSample = subSamples[i];
   1432 
   1433         memcpy(dest + offset, src + offset, subSample.numBytesOfClearData);
   1434         offset += subSample.numBytesOfClearData;
   1435 
   1436         AES_cbc_encrypt(src + offset, dest + offset, subSample.numBytesOfEncryptedData,
   1437                 &decryptionKey, iv, 0 /* decrypt */);
   1438         offset += subSample.numBytesOfEncryptedData;
   1439     }
   1440 }
   1441 
   1442 
   1443 /**
   1444  * Test key status with empty session id, should return BAD_VALUE
   1445  */
   1446 TEST_P(DrmHalVendorDecryptTest, QueryKeyStatusInvalidSession) {
   1447     RETURN_IF_SKIPPED;
   1448     SessionId sessionId;
   1449     auto res = drmPlugin->queryKeyStatus(sessionId,
   1450             [&](Status status, KeyedVector /* info */) {
   1451                 EXPECT_EQ(Status::BAD_VALUE, status);
   1452             });
   1453     EXPECT_OK(res);
   1454 }
   1455 
   1456 
   1457 /**
   1458  * Test key status.  There should be no key status prior to loading keys
   1459  */
   1460 TEST_P(DrmHalVendorDecryptTest, QueryKeyStatusWithNoKeys) {
   1461     RETURN_IF_SKIPPED;
   1462     auto sessionId = openSession();
   1463     auto keyStatus = queryKeyStatus(sessionId);
   1464     EXPECT_EQ(0u, keyStatus.size());
   1465     closeSession(sessionId);
   1466 }
   1467 
   1468 
   1469 /**
   1470  * Test key status.  There should be key status after loading keys.
   1471  */
   1472 TEST_P(DrmHalVendorDecryptTest, QueryKeyStatus) {
   1473     RETURN_IF_SKIPPED;
   1474     for (auto config : contentConfigurations) {
   1475         auto sessionId = openSession();
   1476         loadKeys(sessionId, config);
   1477         auto keyStatus = queryKeyStatus(sessionId);
   1478         EXPECT_NE(0u, keyStatus.size());
   1479         closeSession(sessionId);
   1480     }
   1481 }
   1482 
   1483 /**
   1484  * Positive decrypt test. "Decrypt" a single clear segment and verify.
   1485  */
   1486 TEST_P(DrmHalVendorDecryptTest, ClearSegmentTest) {
   1487     RETURN_IF_SKIPPED;
   1488     for (auto config : contentConfigurations) {
   1489         for (auto key : config.keys) {
   1490             const size_t kSegmentSize = 1024;
   1491             vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
   1492             const Pattern noPattern = {0, 0};
   1493             const vector<SubSample> subSamples = {{.numBytesOfClearData = kSegmentSize,
   1494                                                    .numBytesOfEncryptedData = 0}};
   1495             auto sessionId = openSession();
   1496             loadKeys(sessionId, config);
   1497 
   1498             Status status = cryptoPlugin->setMediaDrmSession(sessionId);
   1499             EXPECT_EQ(Status::OK, status);
   1500 
   1501             uint32_t byteCount = decrypt(Mode::UNENCRYPTED, key.isSecure, toHidlArray(key.keyId),
   1502                     &iv[0], subSamples, noPattern, key.clearContentKey, Status::OK);
   1503             EXPECT_EQ(kSegmentSize, byteCount);
   1504 
   1505             closeSession(sessionId);
   1506         }
   1507     }
   1508 }
   1509 
   1510 /**
   1511  * Positive decrypt test.  Decrypt a single segment using aes_ctr.
   1512  * Verify data matches.
   1513  */
   1514 TEST_P(DrmHalVendorDecryptTest, EncryptedAesCtrSegmentTest) {
   1515     RETURN_IF_SKIPPED;
   1516     for (auto config : contentConfigurations) {
   1517         for (auto key : config.keys) {
   1518             const size_t kSegmentSize = 1024;
   1519             vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
   1520             const Pattern noPattern = {0, 0};
   1521             const vector<SubSample> subSamples = {{.numBytesOfClearData = kSegmentSize,
   1522                                                    .numBytesOfEncryptedData = 0}};
   1523             auto sessionId = openSession();
   1524             loadKeys(sessionId, config);
   1525 
   1526             Status status = cryptoPlugin->setMediaDrmSession(sessionId);
   1527             EXPECT_EQ(Status::OK, status);
   1528 
   1529             uint32_t byteCount = decrypt(Mode::AES_CTR, key.isSecure, toHidlArray(key.keyId),
   1530                     &iv[0], subSamples, noPattern, key.clearContentKey, Status::OK);
   1531             EXPECT_EQ(kSegmentSize, byteCount);
   1532 
   1533             closeSession(sessionId);
   1534         }
   1535     }
   1536 }
   1537 
   1538 /**
   1539  * Negative decrypt test. Decrypt without loading keys.
   1540  */
   1541 TEST_P(DrmHalVendorDecryptTest, EncryptedAesCtrSegmentTestNoKeys) {
   1542     RETURN_IF_SKIPPED;
   1543     for (auto config : contentConfigurations) {
   1544         for (auto key : config.keys) {
   1545             vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
   1546             const Pattern noPattern = {0, 0};
   1547             const vector<SubSample> subSamples = {{.numBytesOfClearData = 256,
   1548                                                    .numBytesOfEncryptedData = 256}};
   1549             auto sessionId = openSession();
   1550 
   1551             Status status = cryptoPlugin->setMediaDrmSession(sessionId);
   1552             EXPECT_EQ(Status::OK, status);
   1553 
   1554             uint32_t byteCount = decrypt(Mode::AES_CTR, key.isSecure,
   1555                     toHidlArray(key.keyId), &iv[0], subSamples, noPattern,
   1556                     key.clearContentKey, Status::ERROR_DRM_NO_LICENSE);
   1557             EXPECT_EQ(0u, byteCount);
   1558 
   1559             closeSession(sessionId);
   1560         }
   1561     }
   1562 }
   1563 
   1564 /**
   1565  * Test key removal.  Load keys then remove them and verify that
   1566  * decryption can't be performed.
   1567  */
   1568 TEST_P(DrmHalVendorDecryptTest, AttemptDecryptWithKeysRemoved) {
   1569     RETURN_IF_SKIPPED;
   1570     for (auto config : contentConfigurations) {
   1571         for (auto key : config.keys) {
   1572             vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
   1573             const Pattern noPattern = {0, 0};
   1574             const vector<SubSample> subSamples = {{.numBytesOfClearData = 256,
   1575                                                    .numBytesOfEncryptedData = 256}};
   1576             auto sessionId = openSession();
   1577 
   1578             Status status = cryptoPlugin->setMediaDrmSession(sessionId);
   1579             EXPECT_EQ(Status::OK, status);
   1580 
   1581             loadKeys(sessionId, config);
   1582             removeKeys(sessionId);
   1583 
   1584             uint32_t byteCount = decrypt(Mode::AES_CTR, key.isSecure,
   1585                     toHidlArray(key.keyId), &iv[0], subSamples, noPattern,
   1586                     key.clearContentKey, Status::ERROR_DRM_NO_LICENSE);
   1587             EXPECT_EQ(0u, byteCount);
   1588 
   1589             closeSession(sessionId);
   1590         }
   1591     }
   1592 }
   1593 
   1594 
   1595 /**
   1596  * Instantiate the set of test cases for each vendor module
   1597  */
   1598 
   1599 INSTANTIATE_TEST_CASE_P(
   1600         DrmHalVendorFactoryTestCases, DrmHalVendorFactoryTest,
   1601         testing::ValuesIn(gVendorModules->getPathList()));
   1602 
   1603 INSTANTIATE_TEST_CASE_P(
   1604         DrmHalVendorPluginTestCases, DrmHalVendorPluginTest,
   1605         testing::ValuesIn(gVendorModules->getPathList()));
   1606 
   1607 INSTANTIATE_TEST_CASE_P(
   1608         DrmHalVendorDecryptTestCases, DrmHalVendorDecryptTest,
   1609         testing::ValuesIn(gVendorModules->getPathList()));
   1610 
   1611 int main(int argc, char** argv) {
   1612 #if defined(__LP64__)
   1613     const char* kModulePath = "/data/local/tmp/64/lib";
   1614 #else
   1615     const char* kModulePath = "/data/local/tmp/32/lib";
   1616 #endif
   1617     gVendorModules = new drm_vts::VendorModules(kModulePath);
   1618     if (gVendorModules->getPathList().size() == 0) {
   1619         std::cerr << "WARNING: No vendor modules found in " << kModulePath <<
   1620                 ", all vendor tests will be skipped" << std::endl;
   1621     }
   1622     ::testing::AddGlobalTestEnvironment(DrmHidlEnvironment::Instance());
   1623     ::testing::InitGoogleTest(&argc, argv);
   1624     DrmHidlEnvironment::Instance()->init(&argc, argv);
   1625     int status = RUN_ALL_TESTS();
   1626     ALOGI("Test result = %d", status);
   1627     return status;
   1628 }
   1629