• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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
Instance()104     static DrmHidlEnvironment* Instance() {
105         static DrmHidlEnvironment* instance = new DrmHidlEnvironment;
106         return instance;
107     }
108 
registerTestServices()109     void registerTestServices() override {
110         registerTestService<ICryptoFactory>();
111         registerTestService<IDrmFactory>();
112         setServiceCombMode(::testing::HalServiceCombMode::NO_COMBINATION);
113     }
114 
115    private:
DrmHidlEnvironment()116     DrmHidlEnvironment() {}
117 
118     GTEST_DISALLOW_COPY_AND_ASSIGN_(DrmHidlEnvironment);
119 };
120 
121 class DrmHalVendorFactoryTest : public testing::TestWithParam<std::string> {
122    public:
DrmHalVendorFactoryTest()123     DrmHalVendorFactoryTest()
124         : vendorModule(static_cast<DrmHalVTSVendorModule_V1*>(
125                         gVendorModules->getModule(GetParam()))),
126           contentConfigurations(vendorModule->getContentConfigurations()) {}
127 
~DrmHalVendorFactoryTest()128     virtual ~DrmHalVendorFactoryTest() {}
129 
SetUp()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 
TearDown()163     virtual void TearDown() override {}
164 
165    protected:
getVendorUUID()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 
TEST_P(DrmHalVendorFactoryTest,ValidateConfigurations)177 TEST_P(DrmHalVendorFactoryTest, ValidateConfigurations) {
178     const char* kVendorStr = "Vendor module ";
179     size_t count = 0;
180     for (const 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 (const 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  */
TEST_P(DrmHalVendorFactoryTest,InvalidPluginNotSupported)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  */
TEST_P(DrmHalVendorFactoryTest,EmptyPluginUUIDNotSupported)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  */
TEST_P(DrmHalVendorFactoryTest,PluginConfigUUIDSupported)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  */
TEST_P(DrmHalVendorFactoryTest,EmptyContentTypeNotSupported)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  */
TEST_P(DrmHalVendorFactoryTest,InvalidContentTypeNotSupported)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  */
TEST_P(DrmHalVendorFactoryTest,ValidContentTypeSupported)246 TEST_P(DrmHalVendorFactoryTest, ValidContentTypeSupported) {
247     RETURN_IF_SKIPPED;
248     for (const auto& config : contentConfigurations) {
249         EXPECT_TRUE(drmFactory->isContentTypeSupported(config.mimeType));
250     }
251 }
252 
253 /**
254  * Ensure vendor drm plugin can be created
255  */
TEST_P(DrmHalVendorFactoryTest,CreateVendorDrmPlugin)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  */
TEST_P(DrmHalVendorFactoryTest,CreateVendorCryptoPlugin)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  */
TEST_P(DrmHalVendorFactoryTest,CreateInvalidDrmPlugin)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  */
TEST_P(DrmHalVendorFactoryTest,CreateInvalidCryptoPlugin)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:
~DrmHalVendorPluginTest()315     virtual ~DrmHalVendorPluginTest() {}
SetUp()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 
TearDown()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 
TEST_P(DrmHalVendorPluginTest,DoProvisioning)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  */
TEST_P(DrmHalVendorPluginTest,ProvideEmptyProvisionResponse)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  */
openSession()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  */
closeSession(const SessionId & sessionId)438 void DrmHalVendorPluginTest::closeSession(const SessionId& sessionId) {
439     Status status = drmPlugin->closeSession(sessionId);
440     EXPECT_EQ(Status::OK, status);
441 }
442 
toHidlKeyedVector(const map<string,string> & params)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  */
loadKeys(const SessionId & sessionId,const ContentConfiguration & configuration,const KeyType & type=KeyType::STREAMING)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  */
TEST_P(DrmHalVendorPluginTest,OpenCloseSession)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  */
TEST_P(DrmHalVendorPluginTest,CloseInvalidSession)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  */
TEST_P(DrmHalVendorPluginTest,CloseClosedSession)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  */
TEST_P(DrmHalVendorPluginTest,GetKeyRequestNoSession)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  */
TEST_P(DrmHalVendorPluginTest,ProvideKeyResponseEmptySessionId)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  */
TEST_P(DrmHalVendorPluginTest,ProvideKeyResponseEmptyResponse)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  */
TEST_P(DrmHalVendorPluginTest,RemoveKeysEmptySessionId)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  */
TEST_P(DrmHalVendorPluginTest,RemoveKeysNewSession)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  */
TEST_P(DrmHalVendorPluginTest,RestoreKeys)611 TEST_P(DrmHalVendorPluginTest, RestoreKeys) {
612     RETURN_IF_SKIPPED;
613     for (const 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  */
TEST_P(DrmHalVendorPluginTest,RestoreKeysNull)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  */
TEST_P(DrmHalVendorPluginTest,RestoreKeysClosedSession)646 TEST_P(DrmHalVendorPluginTest, RestoreKeysClosedSession) {
647     RETURN_IF_SKIPPED;
648     for (const 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  */
TEST_P(DrmHalVendorPluginTest,GetSecureStops)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  */
TEST_P(DrmHalVendorPluginTest,GetSecureStopEmptySSID)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  */
TEST_P(DrmHalVendorPluginTest,ReleaseAllSecureStops)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  */
TEST_P(DrmHalVendorPluginTest,ReleaseSecureStopSequenceError)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  */
TEST_P(DrmHalVendorPluginTest,ReleaseSecureStopEmptySSID)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  */
TEST_P(DrmHalVendorPluginTest,GetVendorProperty)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 
TEST_P(DrmHalVendorPluginTest,GetVersionProperty)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 
TEST_P(DrmHalVendorPluginTest,GetDescriptionProperty)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 
TEST_P(DrmHalVendorPluginTest,GetAlgorithmsProperty)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 
TEST_P(DrmHalVendorPluginTest,GetPropertyUniqueDeviceID)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  */
TEST_P(DrmHalVendorPluginTest,GetInvalidStringProperty)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 
TEST_P(DrmHalVendorPluginTest,GetInvalidByteArrayProperty)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  */
TEST_P(DrmHalVendorPluginTest,SetStringPropertyNotSupported)831 TEST_P(DrmHalVendorPluginTest, SetStringPropertyNotSupported) {
832     RETURN_IF_SKIPPED;
833     EXPECT_EQ(drmPlugin->setPropertyString("awefijaeflijwef", "value"),
834               Status::ERROR_DRM_CANNOT_HANDLE);
835 }
836 
TEST_P(DrmHalVendorPluginTest,SetByteArrayPropertyNotSupported)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  */
TEST_P(DrmHalVendorPluginTest,SetCipherInvalidAlgorithm)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  */
TEST_P(DrmHalVendorPluginTest,SetCipherAlgorithmNoSession)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  */
TEST_P(DrmHalVendorPluginTest,SetCipherAlgorithm)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  */
TEST_P(DrmHalVendorPluginTest,SetMacInvalidAlgorithm)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  */
TEST_P(DrmHalVendorPluginTest,SetMacNullAlgorithmNoSession)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  */
TEST_P(DrmHalVendorPluginTest,SetMacAlgorithm)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  */
TEST_P(DrmHalVendorPluginTest,GenericEncryptNoSession)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 
TEST_P(DrmHalVendorPluginTest,GenericDecryptNoSession)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 
TEST_P(DrmHalVendorPluginTest,GenericSignNoSession)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 
TEST_P(DrmHalVendorPluginTest,GenericVerifyNoSession)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 
TEST_P(DrmHalVendorPluginTest,GenericSignRSANoSession)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  */
TEST_P(DrmHalVendorPluginTest,RequiresSecureDecoderEmptyMimeType)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  */
TEST_P(DrmHalVendorPluginTest,RequiresSecureDecoderInvalidMimeType)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  */
TEST_P(DrmHalVendorPluginTest,RequiresSecureDecoderConfig)1023 TEST_P(DrmHalVendorPluginTest, RequiresSecureDecoderConfig) {
1024     RETURN_IF_SKIPPED;
1025     for (const auto& config : contentConfigurations) {
1026         for (const 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:
TestDrmPluginListener()1055     TestDrmPluginListener() {
1056         SetWaitTimeoutDefault(std::chrono::milliseconds(500));
1057     }
~TestDrmPluginListener()1058     virtual ~TestDrmPluginListener() {}
1059 
sendEvent(EventType eventType,const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & data)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 
sendExpirationUpdate(const hidl_vec<uint8_t> & sessionId,int64_t expiryTimeInMS)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 
sendKeysChange(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus> & keyStatusList,bool hasNewUsableKey)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  */
TEST_P(DrmHalVendorPluginTest,ListenerEvents)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  */
TEST_P(DrmHalVendorPluginTest,ListenerExpirationUpdate)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  */
TEST_P(DrmHalVendorPluginTest,ListenerKeysChange)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  */
TEST_P(DrmHalVendorPluginTest,NotListening)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  */
TEST_P(DrmHalVendorPluginTest,NotifyResolution)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  */
getDecryptMemory(size_t size,size_t index)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  */
TEST_P(DrmHalVendorPluginTest,SetMediaDrmSession)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  */
TEST_P(DrmHalVendorPluginTest,SetMediaDrmSessionClosedSession)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  */
TEST_P(DrmHalVendorPluginTest,SetMediaDrmSessionEmptySession)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;
~DrmHalVendorDecryptTest()1268     virtual ~DrmHalVendorDecryptTest() {}
1269 
1270    protected:
1271     void fillRandom(const sp<IMemory>& memory);
toHidlArray(const vector<uint8_t> & vec)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 
fillRandom(const sp<IMemory> & memory)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 
queryKeyStatus(SessionId sessionId)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 
removeKeys(SessionId sessionId)1309 void DrmHalVendorDecryptTest::removeKeys(SessionId sessionId) {
1310     auto res = drmPlugin->removeKeys(sessionId);
1311     EXPECT_OK(res);
1312 }
1313 
decrypt(Mode mode,bool isSecure,const hidl_array<uint8_t,16> & keyId,uint8_t * iv,const hidl_vec<SubSample> & subSamples,const Pattern & pattern,const vector<uint8_t> & key,Status expectedStatus)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  */
aes_ctr_decrypt(uint8_t * dest,uint8_t * src,uint8_t * iv,const hidl_vec<SubSample> & subSamples,const vector<uint8_t> & key)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  */
aes_cbc_decrypt(uint8_t * dest,uint8_t * src,uint8_t * iv,const hidl_vec<SubSample> & subSamples,const vector<uint8_t> & key)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  */
TEST_P(DrmHalVendorDecryptTest,QueryKeyStatusInvalidSession)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  */
TEST_P(DrmHalVendorDecryptTest,QueryKeyStatusWithNoKeys)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  */
TEST_P(DrmHalVendorDecryptTest,QueryKeyStatus)1472 TEST_P(DrmHalVendorDecryptTest, QueryKeyStatus) {
1473     RETURN_IF_SKIPPED;
1474     for (const 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  */
TEST_P(DrmHalVendorDecryptTest,ClearSegmentTest)1486 TEST_P(DrmHalVendorDecryptTest, ClearSegmentTest) {
1487     RETURN_IF_SKIPPED;
1488     for (const auto& config : contentConfigurations) {
1489         for (const 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  */
TEST_P(DrmHalVendorDecryptTest,EncryptedAesCtrSegmentTest)1514 TEST_P(DrmHalVendorDecryptTest, EncryptedAesCtrSegmentTest) {
1515     RETURN_IF_SKIPPED;
1516     for (const auto& config : contentConfigurations) {
1517         for (const 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  */
TEST_P(DrmHalVendorDecryptTest,EncryptedAesCtrSegmentTestNoKeys)1541 TEST_P(DrmHalVendorDecryptTest, EncryptedAesCtrSegmentTestNoKeys) {
1542     RETURN_IF_SKIPPED;
1543     for (const auto& config : contentConfigurations) {
1544         for (const 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  */
TEST_P(DrmHalVendorDecryptTest,AttemptDecryptWithKeysRemoved)1568 TEST_P(DrmHalVendorDecryptTest, AttemptDecryptWithKeysRemoved) {
1569     RETURN_IF_SKIPPED;
1570     for (const auto& config : contentConfigurations) {
1571         for (const 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 
main(int argc,char ** argv)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