1 /* 2 * Copyright 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 "C2ComponentInterface_test" 18 19 #include <dlfcn.h> 20 #include <stdio.h> 21 22 #include <gtest/gtest.h> 23 #include <utils/Log.h> 24 25 #include <C2Component.h> 26 #include <C2Config.h> 27 #include <util/C2InterfaceHelper.h> 28 #include <C2Param.h> 29 30 #if !defined(UNUSED) 31 #define UNUSED(expr) \ 32 do { \ 33 (void)(expr); \ 34 } while (0) 35 36 #endif //!defined(UNUSED) 37 38 namespace android { 39 40 template <class T> std::unique_ptr<T> alloc_unique_cstr(const char *cstr) { 41 size_t len = strlen(cstr); 42 std::unique_ptr<T> ptr = T::AllocUnique(len); 43 memcpy(ptr->m.value, cstr, len); 44 return ptr; 45 } 46 47 class C2CompIntfTest : public ::testing::Test { 48 protected: 49 C2CompIntfTest() {} 50 ~C2CompIntfTest() override {} 51 52 void setComponent(std::shared_ptr<C2ComponentInterface> intf) { 53 mIntf = intf; 54 } 55 56 void resetResults() { 57 mIntf = nullptr; 58 mParamResults.clear(); 59 } 60 61 template <typename T> void testUnsupportedParam(); 62 63 template <typename T> void testSupportedParam(); 64 65 // testReadOnlyParam() and testWritableParam() are the main functions for testing a parameter. 66 // A caller should find out if a tested parameter is read-only or writable before calling them 67 // and it must call one of the corresponded them. 68 69 // If a parameter is read-only this is called. 70 // Test read-only parameter |preParam|. The test expects failure while config() with |newParam|, 71 // and make sure |preParam| stay unchanged. 72 template <typename T> 73 void testReadOnlyParam(const T &preParam, const T &newParam); 74 75 // If a parameter is writable this is called. 76 // Test one filed |writableField| for given writable parameter |param|. 77 // |validValues| contains all values obtained from querySupportedValues() for |writableField|. 78 // The test checks validity for config() with each value, and make sure values are config-ed 79 // by query() them out. |invalidValues| contains some values which are not in |validValues|. 80 // The test expects C2_BAD_VALUE while config() with these values, 81 // and |param| should stay unchanged. 82 template <typename TParam, typename TRealField, typename TField> 83 void testWritableParam(TParam *const param, TRealField *const writableField, 84 const std::vector<TField> &validValues, 85 const std::vector<TField> &invalidValues); 86 87 // Test all the defined parameters in C2Param.h. 88 void testMain(std::shared_ptr<C2ComponentInterface> intf, 89 const std::string &componentName); 90 91 // Check permission of parameter type |T| for testing interface. 92 // This should be called first of the testing per parameter type, 93 // therefore different testing process is applied according to the permission type. 94 template <typename T> 95 void checkParamPermission( 96 int *const writable, 97 const std::vector<std::shared_ptr<C2ParamDescriptor>> &supportedParams); 98 99 private: 100 enum ParamPermission : int { 101 WRITABLE, 102 READONLY, 103 UNSUPPORTED, 104 }; 105 106 struct paramTestInfo { 107 std::string name; 108 int result; 109 paramTestInfo(const char *name_, int result_) 110 : name(name_), result(result_) {} 111 }; 112 113 // queryOnStack() and queryonHeap() both call an interface's query_vb() and 114 // check if a component has a parameter whose type is |T|. 115 // If a component has, the value should be copied into an argument, that is 116 // |p| in queryOnStack() and |heapParams| in queryOnHeap(). 117 // The return value is c2_status_t (e.g. C2_OK). 118 template <typename T> c2_status_t queryOnStack(T *const p); 119 120 template <typename T> 121 c2_status_t queryOnHeap(const T &p, 122 std::vector<std::unique_ptr<C2Param>> *const heapParams); 123 124 // Get a value whose type is |T| in a component. The value is copied to |param|. 125 // This should be called only if a component has the parameter. 126 template <typename T> void getValue(T *const param); 127 128 // Check if the parameter's value in component is equal to |expected| and 129 // queryOnStack() and queryOnHeap() are succeeded. When this function called, 130 // it should be guaranteed a component has the parameter. 131 template <typename T> void queryParamAsExpected(const T &expected); 132 133 // Test if query functions works correctly for supported parameters. 134 // "Support" means here a component has the parameter. 135 template <typename T> void querySupportedParam(); 136 137 // Test query functions works correctly for unsupported parameters. 138 // "Unsupport" means here a component doesn't have the parameter. 139 template <typename T> void queryUnsupportedParam(); 140 141 // Execute an interface's config_vb(). |T| is a single parameter type, not std::vector. 142 // config() creates std::vector<C2Param *> {p} and passes it to config_vb(). 143 template <typename T> 144 c2_status_t 145 config(T *const p, 146 std::vector<std::unique_ptr<C2SettingResult>> *const failures); 147 148 // Test if config works correctly for read-only parameters. 149 // Because the failure of config() is assumed, |newParam| doesn't matter. 150 template <typename T> void configReadOnlyParam(const T &newParam); 151 152 // Test if config works correctly for writable parameters. 153 // This changes the parameter's value to |newParam|. 154 // |stConfig| is a return value of config(). 155 template <typename T> void configWritableParamValidValue(const T &newParam, c2_status_t *stConfig); 156 157 // Test if config works correctly in the case an invalid value |newParam| is tried to write 158 // to an writable parameter. 159 template <typename T> void configWritableParamInvalidValue(const T &newParam); 160 161 // Create values for testing from |validValueInfos|. The values are returned as arguments. 162 // |validValues| : valid values, which can be written for the parameter. 163 // |InvalidValues| : invalid values, which cannot be written for the parameter. 164 // config() should be failed if these values are used as new values. 165 // This function should be called only for writable and supported parameters. 166 template <typename TField> 167 void getTestValues(const C2FieldSupportedValues &validValueInfos, 168 std::vector<TField> *const validValues, 169 std::vector<TField> *const invalidValues); 170 171 // Output the summary of test results. Categorizes parameters with their configuration. 172 void outputResults(const std::string &name); 173 174 std::shared_ptr<C2ComponentInterface> mIntf; 175 std::vector<paramTestInfo> mParamResults; 176 std::string mCurrentParamName; 177 }; 178 179 // factory function 180 // TODO(hiroh): Add factory functions for other types. 181 template <typename T> std::unique_ptr<T> makeParam() { 182 return std::make_unique<T>(); 183 } 184 185 template <> std::unique_ptr<C2PortMediaTypeSetting::input> makeParam() { 186 // TODO(hiroh): Set more precise length. 187 return C2PortMediaTypeSetting::input::AllocUnique(100); 188 } 189 190 #define TRACED_FAILURE(func) \ 191 do { \ 192 SCOPED_TRACE(mCurrentParamName); \ 193 func; \ 194 if (::testing::Test::HasFatalFailure()) { \ 195 return; \ 196 } \ 197 } while (false) 198 199 template <typename T> c2_status_t C2CompIntfTest::queryOnStack(T *const p) { 200 std::vector<C2Param*> stackParams{p}; 201 return mIntf->query_vb(stackParams, {}, C2_DONT_BLOCK, nullptr); 202 } 203 204 template <typename T> 205 c2_status_t C2CompIntfTest::queryOnHeap( 206 const T &p, std::vector<std::unique_ptr<C2Param>> *const heapParams) { 207 uint32_t index = p.index() & ~0x03FE0000; 208 if (p.forStream()) { 209 index |= ((p.stream() << 17) & 0x01FE0000) | 0x02000000; 210 } 211 return mIntf->query_vb({}, {index}, C2_DONT_BLOCK, heapParams); 212 } 213 214 template <typename T> void C2CompIntfTest::getValue(T *const param) { 215 // When getValue() is called, a component has to have the parameter. 216 ASSERT_EQ(C2_OK, queryOnStack(param)); 217 } 218 219 template <typename T> 220 void C2CompIntfTest::queryParamAsExpected(const T &expected) { 221 // TODO(hiroh): Don't create param on stack and call queryOnStack for flex params. 222 // Note that all the current supported parameters are non-flex params. 223 T stack; 224 std::unique_ptr<T> pHeap = makeParam<T>(); 225 std::vector<std::unique_ptr<C2Param>> heapParams; 226 227 ASSERT_EQ(C2_OK, queryOnStack(&stack)); 228 229 // |stack| is a parameter value. The parameter size shouldn't be 0. 230 EXPECT_NE(0u, stack.size()); 231 EXPECT_EQ(stack, expected); 232 233 ASSERT_EQ(C2_OK, queryOnHeap(*pHeap, &heapParams)); 234 235 // |*heapParams[0]| is a parameter value. The size of |heapParams| has to be one. 236 ASSERT_EQ(1u, heapParams.size()); 237 EXPECT_TRUE(heapParams[0]); 238 EXPECT_EQ(*heapParams[0], expected); 239 } 240 241 template <typename T> void C2CompIntfTest::querySupportedParam() { 242 std::unique_ptr<T> param = makeParam<T>(); 243 // The current parameter's value is acquired by getValue(), which should be succeeded. 244 getValue(param.get()); 245 queryParamAsExpected(*param); 246 } 247 248 template <typename T> void C2CompIntfTest::queryUnsupportedParam() { 249 // TODO(hiroh): Don't create param on stack and call queryOnStack for flex params. 250 // Note that all the current supported parameters are non-flex params. 251 T stack; 252 std::unique_ptr<T> pHeap = makeParam<T>(); 253 std::vector<std::unique_ptr<C2Param>> heapParams; 254 // If a component doesn't have the parameter, queryOnStack() and queryOnHeap() 255 // should return C2_BAD_INDEX. 256 ASSERT_EQ(C2_BAD_INDEX, queryOnStack(&stack)); 257 EXPECT_FALSE(stack); 258 ASSERT_EQ(C2_BAD_INDEX, queryOnHeap(*pHeap, &heapParams)); 259 EXPECT_EQ(0u, heapParams.size()); 260 } 261 262 template <typename T> 263 c2_status_t C2CompIntfTest::config( 264 T *const p, std::vector<std::unique_ptr<C2SettingResult>> *const failures) { 265 std::vector<C2Param*> params{p}; 266 return mIntf->config_vb(params, C2_DONT_BLOCK, failures); 267 } 268 269 // Create a new parameter copied from |p|. 270 template <typename T> std::unique_ptr<T> makeParamFrom(const T &p) { 271 std::unique_ptr<T> retP = makeParam<T>(); 272 EXPECT_TRUE(retP->updateFrom(p)); 273 EXPECT_TRUE(memcmp(retP.get(), &p, sizeof(T)) == 0); 274 return retP; 275 } 276 277 template <typename T> 278 void C2CompIntfTest::configReadOnlyParam(const T &newParam) { 279 std::unique_ptr<T> p = makeParamFrom(newParam); 280 281 std::vector<C2Param*> params{p.get()}; 282 std::vector<std::unique_ptr<C2SettingResult>> failures; 283 284 // config_vb should be failed because a parameter is read-only. 285 ASSERT_EQ(C2_BAD_VALUE, mIntf->config_vb(params, C2_DONT_BLOCK, &failures)); 286 ASSERT_EQ(1u, failures.size()); 287 EXPECT_EQ(C2SettingResult::READ_ONLY, failures[0]->failure); 288 } 289 290 template <typename T> 291 void C2CompIntfTest::configWritableParamValidValue(const T &newParam, c2_status_t *configResult) { 292 std::unique_ptr<T> p = makeParamFrom(newParam); 293 294 std::vector<C2Param*> params{p.get()}; 295 std::vector<std::unique_ptr<C2SettingResult>> failures; 296 // In most cases, config_vb return C2_OK and the parameter's value should be changed 297 // to |newParam|, which is confirmed in a caller of configWritableParamValueValue(). 298 // However, this can return ~~~~ and the parameter's values is not changed, 299 // because there may be dependent limitations between fields or between parameters. 300 // TODO(hiroh): I have to fill the return value. Comments in C2Component.h doesn't mention 301 // about the return value when conflict happens. I set C2_BAD_VALUE to it temporarily now. 302 c2_status_t stConfig = mIntf->config_vb(params, C2_DONT_BLOCK, &failures); 303 if (stConfig == C2_OK) { 304 EXPECT_EQ(0u, failures.size()); 305 } else { 306 ASSERT_EQ(C2_BAD_VALUE, stConfig); 307 EXPECT_EQ(1u, failures.size()); 308 EXPECT_EQ(C2SettingResult::CONFLICT, failures[0]->failure); 309 } 310 *configResult = stConfig; 311 } 312 313 template <typename T> 314 void C2CompIntfTest::configWritableParamInvalidValue(const T &newParam) { 315 std::unique_ptr<T> p = makeParamFrom(newParam); 316 317 std::vector<C2Param*> params{p.get()}; 318 std::vector<std::unique_ptr<C2SettingResult>> failures; 319 // Although a parameter is writable, config_vb should be failed, 320 // because a new value is invalid. 321 ASSERT_EQ(C2_BAD_VALUE, mIntf->config_vb(params, C2_DONT_BLOCK, &failures)); 322 ASSERT_EQ(1u, failures.size()); 323 EXPECT_EQ(C2SettingResult::BAD_VALUE, failures[0]->failure); 324 } 325 326 // There is only used enum type for the field type, that is C2Component::domain_t. 327 // If another field type is added, it is necessary to add function for that. 328 template <> 329 void C2CompIntfTest::getTestValues( 330 const C2FieldSupportedValues &validValueInfos, 331 std::vector<C2Component::domain_t> *const validValues, 332 std::vector<C2Component::domain_t> *const invalidValues) { 333 UNUSED(validValueInfos); 334 validValues->emplace_back(C2Component::DOMAIN_VIDEO); 335 validValues->emplace_back(C2Component::DOMAIN_AUDIO); 336 validValues->emplace_back(C2Component::DOMAIN_OTHER); 337 338 // There is no invalid value. 339 UNUSED(invalidValues); 340 } 341 342 template <typename TField> 343 void C2CompIntfTest::getTestValues( 344 const C2FieldSupportedValues &validValueInfos, 345 std::vector<TField> *const validValues, 346 std::vector<TField> *const invalidValues) { 347 using TStorage = typename _c2_reduce_enum_to_underlying_type<TField>::type; 348 349 // The supported values are represented by C2Values. C2Value::Primitive needs to 350 // be transformed to a primitive value. This function is one to do that. 351 auto prim2Value = [](const C2Value::Primitive &prim) -> TField { 352 return (TField)prim.ref<TStorage>(); 353 static_assert(std::is_same<TStorage, int32_t>::value || 354 std::is_same<TStorage, uint32_t>::value || 355 std::is_same<TStorage, int64_t>::value || 356 std::is_same<TStorage, uint64_t>::value || 357 std::is_same<TStorage, float>::value, "Invalid TField type."); 358 }; 359 360 // The size of validValueInfos is one. 361 const auto &c2FSV = validValueInfos; 362 363 switch (c2FSV.type) { 364 case C2FieldSupportedValues::type_t::EMPTY: { 365 invalidValues->emplace_back(TField(0)); 366 // TODO(hiroh) : Should other invalid values be tested? 367 break; 368 } 369 case C2FieldSupportedValues::type_t::RANGE: { 370 const auto &range = c2FSV.range; 371 auto rmin = prim2Value(range.min); 372 auto rmax = prim2Value(range.max); 373 auto rstep = prim2Value(range.step); 374 375 ASSERT_LE(rmin, rmax); 376 377 if (rstep != 0) { 378 // Increase linear 379 for (auto v = rmin; v <= rmax; v = TField(v + rstep)) { 380 validValues->emplace_back(v); 381 } 382 if (rmin > std::numeric_limits<TField>::min()) { 383 invalidValues->emplace_back(TField(rmin - 1)); 384 } 385 if (rmax < std::numeric_limits<TField>::max()) { 386 invalidValues->emplace_back(TField(rmax + 1)); 387 } 388 const unsigned int N = validValues->size(); 389 if (N >= 2) { 390 if (std::is_same<TField, float>::value) { 391 invalidValues->emplace_back(TField((validValues->at(0) + validValues->at(1)) / 2)); 392 invalidValues->emplace_back(TField((validValues->at(N - 2) + validValues->at(N - 1)) / 2)); 393 } else { 394 if (rstep > 1) { 395 invalidValues->emplace_back(TField(validValues->at(0) + 1)); 396 invalidValues->emplace_back(TField(validValues->at(N - 1) - 1)); 397 } 398 } 399 } 400 } else { 401 // There should be two cases, except linear case. 402 // 1. integer geometric case 403 // 2. float geometric case 404 405 auto num = prim2Value(range.num); 406 auto denom = prim2Value(range.denom); 407 408 // If both range.num and range.denom are 1 and step is 0, we should use 409 // VALUES, shouldn't we? 410 ASSERT_FALSE(num == 1 && denom == 1); 411 412 // (num / denom) is not less than 1. 413 ASSERT_FALSE(denom == 0); 414 ASSERT_LE(denom, num); 415 for (auto v = rmin; v <= rmax; v = TField(v * num / denom)) { 416 validValues->emplace_back(v); 417 } 418 419 if (rmin > std::numeric_limits<TField>::min()) { 420 invalidValues->emplace_back(TField(rmin - 1)); 421 } 422 if (rmax < std::numeric_limits<TField>::max()) { 423 invalidValues->emplace_back(TField(rmax + 1)); 424 } 425 426 const unsigned int N = validValues->size(); 427 if (N >= 2) { 428 if (std::is_same<TField, float>::value) { 429 invalidValues->emplace_back(TField((validValues->at(0) + validValues->at(1)) / 2)); 430 invalidValues->emplace_back(TField((validValues->at(N - 2) + validValues->at(N - 1)) / 2)); 431 } else { 432 if (validValues->at(1) - validValues->at(0) > 1) { 433 invalidValues->emplace_back(TField(validValues->at(0) + 1)); 434 } 435 if (validValues->at(N - 1) - validValues->at(N - 2) > 1) { 436 invalidValues->emplace_back(TField(validValues->at(N - 1) - 1)); 437 } 438 } 439 } 440 } 441 break; 442 } 443 case C2FieldSupportedValues::type_t::VALUES: { 444 for (const C2Value::Primitive &prim : c2FSV.values) { 445 validValues->emplace_back(prim2Value(prim)); 446 } 447 auto minv = *std::min_element(validValues->begin(), validValues->end()); 448 auto maxv = *std::max_element(validValues->begin(), validValues->end()); 449 if (minv - 1 > std::numeric_limits<TField>::min()) { 450 invalidValues->emplace_back(TField(minv - 1)); 451 } 452 if (maxv + 1 < std::numeric_limits<TField>::max()) { 453 invalidValues->emplace_back(TField(maxv + 1)); 454 } 455 break; 456 } 457 case C2FieldSupportedValues::type_t::FLAGS: { 458 // TODO(hiroh) : Implement the case that param.type is FLAGS. 459 break; 460 } 461 } 462 } 463 464 template <typename T> 465 void C2CompIntfTest::testReadOnlyParam(const T &preParam, const T &newParam) { 466 TRACED_FAILURE(configReadOnlyParam(newParam)); 467 // Parameter value must not be changed 468 TRACED_FAILURE(queryParamAsExpected(preParam)); 469 } 470 471 template <typename TParam, typename TRealField, typename TField> 472 void C2CompIntfTest::testWritableParam( 473 TParam *const param, TRealField *const writableField, 474 const std::vector<TField> &validValues, 475 const std::vector<TField> &invalidValues) { 476 c2_status_t stConfig; 477 478 // Get the parameter's value in the beginning in order to reset the value at the end. 479 TRACED_FAILURE(getValue(param)); 480 std::unique_ptr<TParam> defaultParam = makeParamFrom(*param); 481 482 // Test valid values 483 for (const auto &val : validValues) { 484 std::unique_ptr<TParam> preParam = makeParamFrom(*param); 485 486 // Param is try to be changed 487 *writableField = val; 488 TRACED_FAILURE(configWritableParamValidValue(*param, &stConfig)); 489 if (stConfig == C2_OK) { 490 TRACED_FAILURE(queryParamAsExpected(*param)); 491 } else { 492 // Param is unchanged because a field value conflicts with other field or parameter. 493 TRACED_FAILURE(queryParamAsExpected(*preParam)); 494 } 495 } 496 497 // Store the current parameter in order to test |param| is unchanged 498 // after trying to write an invalid value. 499 std::unique_ptr<TParam> lastValidParam = makeParamFrom(*param); 500 501 // Test invalid values 502 for (const auto &val : invalidValues) { 503 // Param is changed 504 *writableField = val; 505 TRACED_FAILURE(configWritableParamInvalidValue(*param)); 506 TRACED_FAILURE(queryParamAsExpected(*lastValidParam)); 507 } 508 // Reset the parameter by config(). 509 TRACED_FAILURE(configWritableParamValidValue(*defaultParam, &stConfig)); 510 } 511 512 template <typename T> void C2CompIntfTest::testUnsupportedParam() { 513 TRACED_FAILURE(queryUnsupportedParam<T>()); 514 } 515 516 template <typename T> void C2CompIntfTest::testSupportedParam() { 517 TRACED_FAILURE(querySupportedParam<T>()); 518 } 519 520 bool isSupportedParam( 521 const C2Param ¶m, 522 const std::vector<std::shared_ptr<C2ParamDescriptor>> &sParams) { 523 for (const auto &pd : sParams) { 524 if (param.type() == pd->index().type()) { 525 return true; 526 } 527 } 528 return false; 529 } 530 531 template <typename T> 532 void C2CompIntfTest::checkParamPermission( 533 int *const result, 534 const std::vector<std::shared_ptr<C2ParamDescriptor>> &supportedParams) { 535 std::unique_ptr<T> param = makeParam<T>(); 536 537 if (!isSupportedParam(*param, supportedParams)) { 538 // If a parameter isn't supported, it just finish after calling testUnsupportedParam(). 539 testUnsupportedParam<T>(); 540 *result = ParamPermission::UNSUPPORTED; 541 return; 542 } 543 544 testSupportedParam<T>(); 545 546 TRACED_FAILURE(getValue(param.get())); 547 std::vector<std::unique_ptr<C2SettingResult>> failures; 548 // Config does not change the parameter, because param is the present param. 549 // This config is executed to find out if a parameter is read-only or writable. 550 c2_status_t stStack = config(param.get(), &failures); 551 if (stStack == C2_BAD_VALUE) { 552 // Read-only 553 std::unique_ptr<T> newParam = makeParam<T>(); 554 testReadOnlyParam(*param, *newParam); 555 *result = ParamPermission::READONLY; 556 } else { 557 // Writable 558 EXPECT_EQ(stStack, C2_OK); 559 *result = ParamPermission::WRITABLE; 560 } 561 } 562 563 void C2CompIntfTest::outputResults(const std::string &name) { 564 std::vector<std::string> params[3]; 565 for (const auto &testInfo : mParamResults) { 566 int result = testInfo.result; 567 ASSERT_TRUE(0 <= result && result <= 2); 568 params[result].emplace_back(testInfo.name); 569 } 570 const char *resultString[] = {"Writable", "Read-Only", "Unsupported"}; 571 printf("\n----TEST RESULTS (%s)----\n\n", name.c_str()); 572 for (int i = 0; i < 3; i++) { 573 printf("[ %s ]\n", resultString[i]); 574 for (const auto &t : params[i]) { 575 printf("%s\n", t.c_str()); 576 } 577 printf("\n"); 578 } 579 } 580 581 #define TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, field_name_) \ 582 do { \ 583 std::unique_ptr<TParam_> param = makeParam<TParam_>(); \ 584 std::vector<C2FieldSupportedValuesQuery> validValueInfos = { \ 585 C2FieldSupportedValuesQuery::Current( \ 586 C2ParamField(param.get(), &field_type_name_::field_name_)) \ 587 }; \ 588 ASSERT_EQ(C2_OK, \ 589 mIntf->querySupportedValues_vb(validValueInfos, C2_DONT_BLOCK)); \ 590 ASSERT_EQ(1u, validValueInfos.size()); \ 591 std::vector<decltype(param->field_name_)> validValues; \ 592 std::vector<decltype(param->field_name_)> invalidValues; \ 593 getTestValues(validValueInfos[0].values, &validValues, &invalidValues); \ 594 testWritableParam(param.get(), ¶m->field_name_, validValues,\ 595 invalidValues); \ 596 } while (0) 597 598 #define TEST_VSSTRUCT_WRITABLE_FIELD(TParam_, field_type_name_) \ 599 do { \ 600 TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, width); \ 601 TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, height); \ 602 } while (0) 603 604 #define TEST_U32_WRITABLE_FIELD(TParam_, field_type_name_) \ 605 TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, value) 606 607 #define TEST_ENUM_WRITABLE_FIELD(TParam_, field_type_name_) \ 608 TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, value) 609 610 // TODO(hiroh): Support parameters based on char[] and uint32_t[]. 611 //#define TEST_STRING_WRITABLE_FIELD(TParam_, field_type_name_) 612 // TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, m.value) 613 //#define TEST_U32ARRAY_WRITABLE_FIELD(Tparam_, field_type_name_) 614 // TEST_GENERAL_WRITABLE_FIELD(Tparam_, uint32_t[], field_type_name_, values) 615 616 #define EACH_TEST(TParam_, field_type_name_, test_name) \ 617 do { \ 618 int result = 0; \ 619 this->mCurrentParamName = #TParam_; \ 620 checkParamPermission<TParam_>(&result, supportedParams); \ 621 if (result == ParamPermission::WRITABLE) { \ 622 test_name(TParam_, field_type_name_); \ 623 } \ 624 mParamResults.emplace_back(#TParam_, result); \ 625 } while (0) 626 627 #define EACH_TEST_SELF(type_, test_name) EACH_TEST(type_, type_, test_name) 628 #define EACH_TEST_INPUT(type_, test_name) EACH_TEST(type_::input, type_, test_name) 629 #define EACH_TEST_OUTPUT(type_, test_name) EACH_TEST(type_::output, type_, test_name) 630 void C2CompIntfTest::testMain(std::shared_ptr<C2ComponentInterface> intf, 631 const std::string &componentName) { 632 setComponent(intf); 633 634 std::vector<std::shared_ptr<C2ParamDescriptor>> supportedParams; 635 ASSERT_EQ(C2_OK, mIntf->querySupportedParams_nb(&supportedParams)); 636 637 EACH_TEST_SELF(C2ActualPipelineDelayTuning, TEST_U32_WRITABLE_FIELD); 638 EACH_TEST_SELF(C2ComponentAttributesSetting, TEST_U32_WRITABLE_FIELD); 639 EACH_TEST_INPUT(C2PortActualDelayTuning, TEST_U32_WRITABLE_FIELD); 640 EACH_TEST_OUTPUT(C2PortActualDelayTuning, TEST_U32_WRITABLE_FIELD); 641 EACH_TEST_INPUT(C2StreamBufferTypeSetting, TEST_U32_WRITABLE_FIELD); 642 EACH_TEST_OUTPUT(C2StreamBufferTypeSetting, TEST_U32_WRITABLE_FIELD); 643 EACH_TEST_INPUT(C2PortStreamCountTuning, TEST_U32_WRITABLE_FIELD); 644 EACH_TEST_OUTPUT(C2PortStreamCountTuning, TEST_U32_WRITABLE_FIELD); 645 646 EACH_TEST_SELF(C2ComponentDomainSetting, TEST_ENUM_WRITABLE_FIELD); 647 648 // TODO(hiroh): Support parameters based on uint32_t[] and char[]. 649 // EACH_TEST_INPUT(C2PortMediaTypeSetting, TEST_STRING_WRITABLE_FIELD); 650 // EACH_TEST_OUTPUT(C2PortMediaTypeSetting, TEST_STRING_WRITABLE_FIELD); 651 // EACH_TEST_INPUT(C2StreamMimeConfig, TEST_STRING_WRITABLE_FIELD); 652 // EACH_TEST_OUTPUT(C2StreamMimeConfig, TEST_STRING_WRITABLE_FIELD); 653 654 // EACH_TEST_SELF(C2SupportedParamsInfo, TEST_U32ARRAY_WRITABLE_FIELD); 655 // EACH_TEST_SELF(C2RequiredParamsInfo, TEST_U32ARRAY_WRITABLE_FIELD); 656 // EACH_TEST_SELF(C2ReadOnlyParamsInfo, TEST_U32ARRAY_WRITABLE_FIELD); 657 // EACH_TEST_SELF(C2RequestedInfosInfo, TEST_U32ARRAY_WRITABLE_FIELD); 658 659 EACH_TEST_INPUT(C2StreamPictureSizeInfo, TEST_VSSTRUCT_WRITABLE_FIELD); 660 EACH_TEST_OUTPUT(C2StreamPictureSizeInfo, TEST_VSSTRUCT_WRITABLE_FIELD); 661 EACH_TEST_INPUT(C2StreamPictureSizeInfo, TEST_VSSTRUCT_WRITABLE_FIELD); 662 EACH_TEST_OUTPUT(C2StreamPictureSizeInfo, TEST_VSSTRUCT_WRITABLE_FIELD); 663 EACH_TEST_INPUT(C2MaxVideoSizeHintPortSetting, TEST_VSSTRUCT_WRITABLE_FIELD); 664 EACH_TEST_OUTPUT(C2MaxVideoSizeHintPortSetting, TEST_VSSTRUCT_WRITABLE_FIELD); 665 666 outputResults(componentName); 667 resetResults(); 668 } 669 670 TEST_F(C2CompIntfTest, C2V4L2CodecIntf) { 671 672 // Read a shared object library. 673 void* compLib = dlopen("system/lib/libv4l2_codec2.so", RTLD_NOW); 674 675 if (!compLib) { 676 printf("Cannot open library: %s.\n", dlerror()); 677 FAIL(); 678 return; 679 } 680 681 typedef C2ComponentStore* create_t(); 682 create_t* create_store= (create_t*) dlsym(compLib, "create_store"); 683 const char* dlsym_error = dlerror(); 684 if (dlsym_error) { 685 printf("Cannot load symbol create: %s.\n", dlsym_error); 686 FAIL(); 687 return; 688 } 689 690 typedef void destroy_t(C2ComponentStore*); 691 destroy_t* destroy_store = (destroy_t*) dlsym(compLib, "destroy_store"); 692 dlsym_error = dlerror(); 693 if (dlsym_error) { 694 printf("Cannot load symbol destroy: %s.\n", dlsym_error); 695 FAIL(); 696 return; 697 } 698 699 std::shared_ptr<C2ComponentStore> componentStore(create_store(), destroy_store); 700 std::shared_ptr<C2ComponentInterface> componentIntf; 701 componentStore->createInterface("v4l2.decoder", &componentIntf); 702 auto componentName = "C2V4L2Codec"; 703 testMain(componentIntf, componentName); 704 } 705 706 } // namespace android 707