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