14344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/*
24344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Copyright 2017 The Android Open Source Project
34344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
44344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Licensed under the Apache License, Version 2.0 (the "License");
54344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * you may not use this file except in compliance with the License.
64344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * You may obtain a copy of the License at
74344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
84344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *      http://www.apache.org/licenses/LICENSE-2.0
94344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Unless required by applicable law or agreed to in writing, software
114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * distributed under the License is distributed on an "AS IS" BASIS,
124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * See the License for the specific language governing permissions and
144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * limitations under the License.
154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define LOG_TAG "C2ComponentInterface_test"
184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <dlfcn.h>
204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <stdio.h>
214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <gtest/gtest.h>
234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <utils/Log.h>
244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2Component.h>
2651ea56a991d6371e35c8d0bb5001e721cc63f8eeLajos Molnar#include <C2Config.h>
27259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar#include <util/C2InterfaceHelper.h>
284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2Param.h>
294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#if !defined(UNUSED)
314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define UNUSED(expr)                                                           \
324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim  do {                                                                         \
334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim      (void)(expr);                                                            \
344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim  } while (0)
354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#endif //!defined(UNUSED)
374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace android {
394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <class T> std::unique_ptr<T> alloc_unique_cstr(const char *cstr) {
414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    size_t len = strlen(cstr);
424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<T> ptr = T::AllocUnique(len);
434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    memcpy(ptr->m.value, cstr, len);
444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return ptr;
454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2CompIntfTest : public ::testing::Test {
484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprotected:
494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    C2CompIntfTest() {}
504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ~C2CompIntfTest() override {}
514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void setComponent(std::shared_ptr<C2ComponentInterface> intf) {
534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mIntf = intf;
544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void resetResults() {
574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mIntf = nullptr;
584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mParamResults.clear();
594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T> void testUnsupportedParam();
624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T> void testSupportedParam();
644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // testReadOnlyParam() and testWritableParam() are the main functions for testing a parameter.
664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // A caller should find out if a tested parameter is read-only or writable before calling them
674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // and it must call one of the corresponded them.
684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // If a parameter is read-only this is called.
704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Test read-only parameter |preParam|. The test expects failure while config() with |newParam|,
714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // and make sure |preParam| stay unchanged.
724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T>
734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void testReadOnlyParam(const T &preParam, const T &newParam);
744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // If a parameter is writable this is called.
764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Test one filed |writableField| for given writable parameter |param|.
774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // |validValues| contains all values obtained from querySupportedValues() for |writableField|.
784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // The test checks validity for config() with each value, and make sure values are config-ed
794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // by query() them out. |invalidValues| contains some values which are not in |validValues|.
804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // The test expects C2_BAD_VALUE while config() with these values,
814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // and |param| should stay unchanged.
824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename TParam, typename TRealField, typename TField>
834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void testWritableParam(TParam *const param, TRealField *const writableField,
844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                           const std::vector<TField> &validValues,
854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                           const std::vector<TField> &invalidValues);
864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Test all the defined parameters in C2Param.h.
884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void testMain(std::shared_ptr<C2ComponentInterface> intf,
894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                  const std::string &componentName);
904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Check permission of parameter type |T| for testing interface.
924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This should be called first of the testing per parameter type,
934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // therefore different testing process is applied according to the permission type.
944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T>
954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void checkParamPermission(
964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            int *const writable,
974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<std::shared_ptr<C2ParamDescriptor>> &supportedParams);
984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
1004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    enum ParamPermission : int {
1014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        WRITABLE,
1024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        READONLY,
1034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        UNSUPPORTED,
1044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
1054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    struct paramTestInfo {
1074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::string name;
1084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        int result;
1094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        paramTestInfo(const char *name_, int result_)
1104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : name(name_), result(result_) {}
1114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
1124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // queryOnStack() and queryonHeap() both call an interface's query_vb() and
1144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // check if a component has a parameter whose type is |T|.
1154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // If a component has, the value should be copied into an argument, that is
1164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // |p| in queryOnStack() and |heapParams| in queryOnHeap().
1174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // The return value is c2_status_t (e.g. C2_OK).
1184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T> c2_status_t queryOnStack(T *const p);
1194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T>
1214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t queryOnHeap(const T &p,
1224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                         std::vector<std::unique_ptr<C2Param>> *const heapParams);
1234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Get a value whose type is |T| in a component. The value is copied to |param|.
1254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This should be called only if a component has the parameter.
1264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T> void getValue(T *const param);
1274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Check if the parameter's value in component is equal to |expected| and
1294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // queryOnStack() and queryOnHeap() are succeeded. When this function called,
1304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // it should be guaranteed a component has the parameter.
1314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T> void queryParamAsExpected(const T &expected);
1324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Test if query functions works correctly for supported parameters.
1344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // "Support" means here a component has the parameter.
1354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T> void querySupportedParam();
1364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Test query functions works correctly for unsupported parameters.
1384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // "Unsupport" means here a component doesn't have the parameter.
1394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T> void queryUnsupportedParam();
1404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Execute an interface's config_vb(). |T| is a single parameter type, not std::vector.
1424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // config() creates std::vector<C2Param *> {p} and passes it to config_vb().
1434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T>
1444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t
1454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    config(T *const p,
1464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim           std::vector<std::unique_ptr<C2SettingResult>> *const failures);
1474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Test if config works correctly for read-only parameters.
1494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Because the failure of config() is assumed, |newParam| doesn't matter.
1504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T> void configReadOnlyParam(const T &newParam);
1514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Test if config works correctly for writable parameters.
1534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This changes the parameter's value to |newParam|.
1544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // |stConfig| is a return value of config().
1554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T> void configWritableParamValidValue(const T &newParam, c2_status_t *stConfig);
1564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Test if config works correctly in the case an invalid value |newParam| is tried to write
1584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // to an writable parameter.
1594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename T> void configWritableParamInvalidValue(const T &newParam);
1604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Create values for testing from |validValueInfos|. The values are returned as arguments.
1624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // |validValues| : valid values, which can be written for the parameter.
1634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // |InvalidValues| : invalid values, which cannot be written for the parameter.
1644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    //                   config() should be failed if these values are used as new values.
1654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This function should be called only for writable and supported parameters.
1664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    template <typename TField>
1674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void getTestValues(const C2FieldSupportedValues &validValueInfos,
1684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                       std::vector<TField> *const validValues,
1694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                       std::vector<TField> *const invalidValues);
1704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Output the summary of test results. Categorizes parameters with their configuration.
1724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void outputResults(const std::string &name);
1734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2ComponentInterface> mIntf;
1754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<paramTestInfo> mParamResults;
1764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::string mCurrentParamName;
1774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
1784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// factory function
1804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// TODO(hiroh): Add factory functions for other types.
1814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T> std::unique_ptr<T> makeParam() {
1824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return std::make_unique<T>();
1834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
1844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <> std::unique_ptr<C2PortMimeConfig::input> makeParam() {
1864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO(hiroh): Set more precise length.
1874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2PortMimeConfig::input::AllocUnique(100);
1884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
1894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define TRACED_FAILURE(func)                            \
1914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    do {                                                \
1924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        SCOPED_TRACE(mCurrentParamName);             \
1934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        func;                                           \
1944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (::testing::Test::HasFatalFailure()) {       \
1954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return;                                     \
1964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }                                               \
1974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } while (false)
1984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T> c2_status_t C2CompIntfTest::queryOnStack(T *const p) {
2004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<C2Param*> stackParams{p};
2014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mIntf->query_vb(stackParams, {}, C2_DONT_BLOCK, nullptr);
2024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T>
2054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2CompIntfTest::queryOnHeap(
2064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const T &p, std::vector<std::unique_ptr<C2Param>> *const heapParams) {
2074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    uint32_t index = p.index() & ~0x03FE0000;
2084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (p.forStream()) {
2094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        index |= ((p.stream() << 17) & 0x01FE0000) | 0x02000000;
2104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mIntf->query_vb({}, {index}, C2_DONT_BLOCK, heapParams);
2124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T> void C2CompIntfTest::getValue(T *const param) {
2154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // When getValue() is called, a component has to have the parameter.
2164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ASSERT_EQ(C2_OK, queryOnStack(param));
2174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T>
2204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid C2CompIntfTest::queryParamAsExpected(const T &expected) {
2214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO(hiroh): Don't create param on stack and call queryOnStack for flex params.
2224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Note that all the current supported parameters are non-flex params.
2234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    T stack;
2244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<T> pHeap = makeParam<T>();
2254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<std::unique_ptr<C2Param>> heapParams;
2264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ASSERT_EQ(C2_OK, queryOnStack(&stack));
2284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // |stack| is a parameter value. The parameter size shouldn't be 0.
2304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EXPECT_NE(0u, stack.size());
2314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EXPECT_EQ(stack, expected);
2324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ASSERT_EQ(C2_OK, queryOnHeap(*pHeap, &heapParams));
2344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // |*heapParams[0]| is a parameter value. The size of |heapParams| has to be one.
2364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ASSERT_EQ(1u, heapParams.size());
2374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EXPECT_TRUE(heapParams[0]);
2384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EXPECT_EQ(*heapParams[0], expected);
2394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T> void C2CompIntfTest::querySupportedParam() {
2424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<T> param = makeParam<T>();
2434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // The current parameter's value is acquired by getValue(), which should be succeeded.
2444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    getValue(param.get());
2454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    queryParamAsExpected(*param);
2464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T> void C2CompIntfTest::queryUnsupportedParam() {
2494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO(hiroh): Don't create param on stack and call queryOnStack for flex params.
2504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Note that all the current supported parameters are non-flex params.
2514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    T stack;
2524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<T> pHeap = makeParam<T>();
2534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<std::unique_ptr<C2Param>> heapParams;
2544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // If a component doesn't have the parameter, queryOnStack() and queryOnHeap()
2554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // should return C2_BAD_INDEX.
2564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ASSERT_EQ(C2_BAD_INDEX, queryOnStack(&stack));
2574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EXPECT_FALSE(stack);
2584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ASSERT_EQ(C2_BAD_INDEX, queryOnHeap(*pHeap, &heapParams));
2594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EXPECT_EQ(0u, heapParams.size());
2604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T>
2634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2CompIntfTest::config(
2644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        T *const p, std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
2654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<C2Param*> params{p};
2664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mIntf->config_vb(params, C2_DONT_BLOCK, failures);
2674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// Create a new parameter copied from |p|.
2704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T> std::unique_ptr<T> makeParamFrom(const T &p) {
2714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<T> retP = makeParam<T>();
2724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EXPECT_TRUE(retP->updateFrom(p));
2734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EXPECT_TRUE(memcmp(retP.get(), &p, sizeof(T)) == 0);
2744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return retP;
2754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T>
2784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid C2CompIntfTest::configReadOnlyParam(const T &newParam) {
2794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<T> p = makeParamFrom(newParam);
2804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<C2Param*> params{p.get()};
2824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<std::unique_ptr<C2SettingResult>> failures;
2834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // config_vb should be failed because a parameter is read-only.
2854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ASSERT_EQ(C2_BAD_VALUE, mIntf->config_vb(params, C2_DONT_BLOCK, &failures));
2864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ASSERT_EQ(1u, failures.size());
2874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EXPECT_EQ(C2SettingResult::READ_ONLY, failures[0]->failure);
2884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T>
2914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid C2CompIntfTest::configWritableParamValidValue(const T &newParam, c2_status_t *configResult) {
2924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<T> p = makeParamFrom(newParam);
2934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<C2Param*> params{p.get()};
2954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<std::unique_ptr<C2SettingResult>> failures;
2964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // In most cases, config_vb return C2_OK and the parameter's value should be changed
2974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // to |newParam|, which is confirmed in a caller of configWritableParamValueValue().
2984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // However, this can return ~~~~ and the parameter's values is not changed,
2994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // because there may be dependent limitations between fields or between parameters.
3004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO(hiroh): I have to fill the return value. Comments in C2Component.h doesn't mention
3014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // about the return value when conflict happens. I set C2_BAD_VALUE to it temporarily now.
3024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t stConfig = mIntf->config_vb(params, C2_DONT_BLOCK, &failures);
3034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (stConfig == C2_OK) {
3044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        EXPECT_EQ(0u, failures.size());
3054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } else {
3064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ASSERT_EQ(C2_BAD_VALUE, stConfig);
3074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        EXPECT_EQ(1u, failures.size());
3084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        EXPECT_EQ(C2SettingResult::CONFLICT, failures[0]->failure);
3094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    *configResult = stConfig;
3114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
3124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T>
3144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid C2CompIntfTest::configWritableParamInvalidValue(const T &newParam) {
3154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<T> p = makeParamFrom(newParam);
3164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<C2Param*> params{p.get()};
3184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<std::unique_ptr<C2SettingResult>> failures;
3194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Although a parameter is writable, config_vb should be failed,
3204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // because a new value is invalid.
3214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ASSERT_EQ(C2_BAD_VALUE, mIntf->config_vb(params, C2_DONT_BLOCK, &failures));
3224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ASSERT_EQ(1u, failures.size());
3234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EXPECT_EQ(C2SettingResult::BAD_VALUE, failures[0]->failure);
3244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
3254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// There is only used enum type for the field type, that is C2DomainKind.
3274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// If another field type is added, it is necessary to add function for that.
3284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <>
3294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid C2CompIntfTest::getTestValues(
3304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const C2FieldSupportedValues &validValueInfos,
3314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<C2DomainKind> *const validValues,
3324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<C2DomainKind> *const invalidValues) {
3334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    UNUSED(validValueInfos);
3344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    validValues->emplace_back(C2DomainVideo);
3354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    validValues->emplace_back(C2DomainAudio);
3364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    validValues->emplace_back(C2DomainOther);
3374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // There is no invalid value.
3394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    UNUSED(invalidValues);
3404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
3414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename TField>
3434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid C2CompIntfTest::getTestValues(
3444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const C2FieldSupportedValues &validValueInfos,
3454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<TField> *const validValues,
3464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<TField> *const invalidValues) {
347259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar    using TStorage = typename _c2_reduce_enum_to_underlying_type<TField>::type;
3484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // The supported values are represented by C2Values. C2Value::Primitive needs to
3504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // be transformed to a primitive value. This function is one to do that.
3514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    auto prim2Value = [](const C2Value::Primitive &prim) -> TField {
352259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar        return (TField)prim.ref<TStorage>();
353259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar        static_assert(std::is_same<TStorage, int32_t>::value ||
354259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                      std::is_same<TStorage, uint32_t>::value ||
355259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                      std::is_same<TStorage, int64_t>::value ||
356259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                      std::is_same<TStorage, uint64_t>::value ||
357259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                      std::is_same<TStorage, float>::value, "Invalid TField type.");
3584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
3594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // The size of validValueInfos is one.
3614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const auto &c2FSV = validValueInfos;
3624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    switch (c2FSV.type) {
3644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2FieldSupportedValues::type_t::EMPTY: {
3654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        invalidValues->emplace_back(TField(0));
3664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // TODO(hiroh) : Should other invalid values be tested?
3674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
3684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2FieldSupportedValues::type_t::RANGE: {
3704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const auto &range = c2FSV.range;
3714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        auto rmin = prim2Value(range.min);
3724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        auto rmax = prim2Value(range.max);
3734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        auto rstep = prim2Value(range.step);
3744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ASSERT_LE(rmin, rmax);
3764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (rstep != 0) {
3784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // Increase linear
379259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar            for (auto v = rmin; v <= rmax; v = TField(v + rstep)) {
3804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                validValues->emplace_back(v);
3814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
3824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (rmin > std::numeric_limits<TField>::min()) {
383259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                invalidValues->emplace_back(TField(rmin - 1));
3844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
3854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (rmax < std::numeric_limits<TField>::max()) {
386259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                invalidValues->emplace_back(TField(rmax + 1));
3874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
3884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const unsigned int N = validValues->size();
3894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (N >= 2) {
3904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                if (std::is_same<TField, float>::value) {
391259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                    invalidValues->emplace_back(TField((validValues->at(0) + validValues->at(1)) / 2));
392259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                    invalidValues->emplace_back(TField((validValues->at(N - 2) + validValues->at(N - 1)) / 2));
3934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                } else {
3944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    if (rstep > 1) {
395259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                        invalidValues->emplace_back(TField(validValues->at(0) + 1));
396259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                        invalidValues->emplace_back(TField(validValues->at(N - 1) - 1));
3974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    }
3984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
3994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
4004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        } else {
4014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // There should be two cases, except linear case.
4024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // 1. integer geometric case
4034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // 2. float geometric case
4044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            auto num = prim2Value(range.num);
4064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            auto denom = prim2Value(range.denom);
4074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // If both range.num and range.denom are 1 and step is 0, we should use
4094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // VALUES, shouldn't we?
4104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ASSERT_FALSE(num == 1 && denom == 1);
4114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // (num / denom) is not less than 1.
4134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ASSERT_FALSE(denom == 0);
4144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ASSERT_LE(denom, num);
415259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar            for (auto v = rmin; v <= rmax; v = TField(v * num / denom)) {
4164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                validValues->emplace_back(v);
4174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
4184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (rmin > std::numeric_limits<TField>::min()) {
420259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                invalidValues->emplace_back(TField(rmin - 1));
4214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
4224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (rmax < std::numeric_limits<TField>::max()) {
423259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                invalidValues->emplace_back(TField(rmax + 1));
4244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
4254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const unsigned int N = validValues->size();
4274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (N >= 2) {
4284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                if (std::is_same<TField, float>::value) {
429259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                    invalidValues->emplace_back(TField((validValues->at(0) + validValues->at(1)) / 2));
430259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                    invalidValues->emplace_back(TField((validValues->at(N - 2) + validValues->at(N - 1)) / 2));
4314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                } else {
4324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    if (validValues->at(1) - validValues->at(0) > 1) {
433259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                        invalidValues->emplace_back(TField(validValues->at(0) + 1));
4344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    }
4354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    if (validValues->at(N - 1) - validValues->at(N - 2) > 1) {
436259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar                        invalidValues->emplace_back(TField(validValues->at(N - 1) - 1));
4374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    }
4384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
4394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
4404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
4424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2FieldSupportedValues::type_t::VALUES: {
4444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        for (const C2Value::Primitive &prim : c2FSV.values) {
4454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            validValues->emplace_back(prim2Value(prim));
4464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        auto minv = *std::min_element(validValues->begin(), validValues->end());
4484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        auto maxv = *std::max_element(validValues->begin(), validValues->end());
4494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (minv - 1 > std::numeric_limits<TField>::min()) {
450259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar            invalidValues->emplace_back(TField(minv - 1));
4514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (maxv + 1 < std::numeric_limits<TField>::max()) {
453259d49d7f7a69205808f95d5ea8cb4ce2c3ac8b2Lajos Molnar            invalidValues->emplace_back(TField(maxv + 1));
4544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
4564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2FieldSupportedValues::type_t::FLAGS: {
4584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // TODO(hiroh) : Implement the case that param.type is FLAGS.
4594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
4604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T>
4654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid C2CompIntfTest::testReadOnlyParam(const T &preParam, const T &newParam) {
4664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    TRACED_FAILURE(configReadOnlyParam(newParam));
4674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Parameter value must not be changed
4684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    TRACED_FAILURE(queryParamAsExpected(preParam));
4694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename TParam, typename TRealField, typename TField>
4724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid C2CompIntfTest::testWritableParam(
4734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        TParam *const param, TRealField *const writableField,
4744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<TField> &validValues,
4754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<TField> &invalidValues) {
4764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t stConfig;
4774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Get the parameter's value in the beginning in order to reset the value at the end.
4794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    TRACED_FAILURE(getValue(param));
4804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<TParam> defaultParam = makeParamFrom(*param);
4814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Test valid values
4834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    for (const auto &val : validValues) {
4844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::unique_ptr<TParam> preParam = makeParamFrom(*param);
4854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // Param is try to be changed
4874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *writableField = val;
4884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        TRACED_FAILURE(configWritableParamValidValue(*param, &stConfig));
4894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (stConfig == C2_OK) {
4904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            TRACED_FAILURE(queryParamAsExpected(*param));
4914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        } else {
4924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // Param is unchanged because a field value conflicts with other field or parameter.
4934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            TRACED_FAILURE(queryParamAsExpected(*preParam));
4944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Store the current parameter in order to test |param| is unchanged
4984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // after trying to write an invalid value.
4994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<TParam> lastValidParam = makeParamFrom(*param);
5004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Test invalid values
5024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    for (const auto &val : invalidValues) {
5034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // Param is changed
5044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *writableField = val;
5054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        TRACED_FAILURE(configWritableParamInvalidValue(*param));
5064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        TRACED_FAILURE(queryParamAsExpected(*lastValidParam));
5074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Reset the parameter by config().
5094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    TRACED_FAILURE(configWritableParamValidValue(*defaultParam, &stConfig));
5104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T> void C2CompIntfTest::testUnsupportedParam() {
5134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    TRACED_FAILURE(queryUnsupportedParam<T>());
5144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T> void C2CompIntfTest::testSupportedParam() {
5174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    TRACED_FAILURE(querySupportedParam<T>());
5184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimbool isSupportedParam(
5214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const C2Param &param,
5224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<std::shared_ptr<C2ParamDescriptor>> &sParams) {
5234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    for (const auto &pd : sParams) {
5244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (param.type() == pd->index().type()) {
5254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return true;
5264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
5274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return false;
5294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate <typename T>
5324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid C2CompIntfTest::checkParamPermission(
5334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    int *const result,
5344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const std::vector<std::shared_ptr<C2ParamDescriptor>> &supportedParams) {
5354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<T> param = makeParam<T>();
5364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!isSupportedParam(*param, supportedParams)) {
5384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // If a parameter isn't supported, it just finish after calling testUnsupportedParam().
5394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        testUnsupportedParam<T>();
5404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *result = ParamPermission::UNSUPPORTED;
5414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return;
5424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    testSupportedParam<T>();
5454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    TRACED_FAILURE(getValue(param.get()));
5474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<std::unique_ptr<C2SettingResult>> failures;
5484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Config does not change the parameter, because param is the present param.
5494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This config is executed to find out if a parameter is read-only or writable.
5504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t stStack = config(param.get(), &failures);
5514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (stStack == C2_BAD_VALUE) {
5524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // Read-only
5534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::unique_ptr<T> newParam = makeParam<T>();
5544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        testReadOnlyParam(*param, *newParam);
5554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *result = ParamPermission::READONLY;
5564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } else {
5574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // Writable
5584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        EXPECT_EQ(stStack, C2_OK);
5594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *result = ParamPermission::WRITABLE;
5604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid C2CompIntfTest::outputResults(const std::string &name) {
5644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<std::string> params[3];
5654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    for (const auto &testInfo : mParamResults) {
5664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        int result = testInfo.result;
5674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ASSERT_TRUE(0 <= result && result <= 2);
5684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        params[result].emplace_back(testInfo.name);
5694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const char *resultString[] = {"Writable", "Read-Only", "Unsupported"};
5714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    printf("\n----TEST RESULTS (%s)----\n\n", name.c_str());
5724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    for (int i = 0; i < 3; i++) {
5734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        printf("[ %s ]\n", resultString[i]);
5744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        for (const auto &t : params[i]) {
5754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            printf("%s\n", t.c_str());
5764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
5774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        printf("\n");
5784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, field_name_) \
5824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    do {                                                                \
5834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::unique_ptr<TParam_> param = makeParam<TParam_>();          \
5844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<C2FieldSupportedValuesQuery> validValueInfos = {    \
5854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2FieldSupportedValuesQuery::Current(                       \
5864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    C2ParamField(param.get(), &field_type_name_::field_name_)) \
5874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        };                                                              \
5884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ASSERT_EQ(C2_OK,                                                \
5894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                  mIntf->querySupportedValues_vb(validValueInfos, C2_DONT_BLOCK));     \
5904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ASSERT_EQ(1u, validValueInfos.size());                          \
5914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<decltype(param->field_name_)> validValues;          \
5924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<decltype(param->field_name_)> invalidValues;        \
5934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        getTestValues(validValueInfos[0].values, &validValues, &invalidValues);   \
5944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        testWritableParam(param.get(), &param->field_name_, validValues,\
5954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                          invalidValues);                               \
5964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } while (0)
5974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define TEST_VSSTRUCT_WRITABLE_FIELD(TParam_, field_type_name_)         \
5994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    do {                                                                \
6004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, width);  \
6014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, height); \
6024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } while (0)
6034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define TEST_U32_WRITABLE_FIELD(TParam_, field_type_name_)              \
6054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim  TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, value)
6064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define TEST_ENUM_WRITABLE_FIELD(TParam_, field_type_name_)             \
6084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim  TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, value)
6094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// TODO(hiroh): Support parameters based on char[] and uint32_t[].
6114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim//#define TEST_STRING_WRITABLE_FIELD(TParam_, field_type_name_)
6124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, m.value)
6134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim//#define TEST_U32ARRAY_WRITABLE_FIELD(Tparam_, field_type_name_)
6144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// TEST_GENERAL_WRITABLE_FIELD(Tparam_, uint32_t[], field_type_name_, values)
6154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define EACH_TEST(TParam_, field_type_name_, test_name)                 \
6174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    do {                                                                \
6184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim      int result = 0;                                                   \
6194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim      this->mCurrentParamName = #TParam_;                            \
6204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim      checkParamPermission<TParam_>(&result, supportedParams);          \
6214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim      if (result == ParamPermission::WRITABLE) {                        \
6224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim          test_name(TParam_, field_type_name_);                         \
6234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim      }                                                                 \
6244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim      mParamResults.emplace_back(#TParam_, result);                      \
6254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim  } while (0)
6264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define EACH_TEST_SELF(type_, test_name) EACH_TEST(type_, type_, test_name)
6284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define EACH_TEST_INPUT(type_, test_name) EACH_TEST(type_::input, type_, test_name)
6294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define EACH_TEST_OUTPUT(type_, test_name) EACH_TEST(type_::output, type_, test_name)
6304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid C2CompIntfTest::testMain(std::shared_ptr<C2ComponentInterface> intf,
6314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                              const std::string &componentName) {
6324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    setComponent(intf);
6334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<std::shared_ptr<C2ParamDescriptor>> supportedParams;
6354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ASSERT_EQ(C2_OK, mIntf->querySupportedParams_nb(&supportedParams));
6364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_SELF(C2ComponentLatencyInfo, TEST_U32_WRITABLE_FIELD);
6384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_SELF(C2ComponentTemporalInfo, TEST_U32_WRITABLE_FIELD);
6394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_INPUT(C2PortLatencyInfo, TEST_U32_WRITABLE_FIELD);
6404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_OUTPUT(C2PortLatencyInfo, TEST_U32_WRITABLE_FIELD);
6414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_INPUT(C2StreamFormatConfig, TEST_U32_WRITABLE_FIELD);
6424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_OUTPUT(C2StreamFormatConfig, TEST_U32_WRITABLE_FIELD);
6434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_INPUT(C2PortStreamCountConfig, TEST_U32_WRITABLE_FIELD);
6444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_OUTPUT(C2PortStreamCountConfig, TEST_U32_WRITABLE_FIELD);
6454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_SELF(C2ComponentDomainInfo, TEST_ENUM_WRITABLE_FIELD);
6474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO(hiroh): Support parameters based on uint32_t[] and char[].
6494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // EACH_TEST_INPUT(C2PortMimeConfig, TEST_STRING_WRITABLE_FIELD);
6504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // EACH_TEST_OUTPUT(C2PortMimeConfig, TEST_STRING_WRITABLE_FIELD);
6514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // EACH_TEST_INPUT(C2StreamMimeConfig, TEST_STRING_WRITABLE_FIELD);
6524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // EACH_TEST_OUTPUT(C2StreamMimeConfig, TEST_STRING_WRITABLE_FIELD);
6534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // EACH_TEST_SELF(C2SupportedParamsInfo, TEST_U32ARRAY_WRITABLE_FIELD);
6554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // EACH_TEST_SELF(C2RequiredParamsInfo, TEST_U32ARRAY_WRITABLE_FIELD);
6564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // EACH_TEST_SELF(C2ReadOnlyParamsInfo, TEST_U32ARRAY_WRITABLE_FIELD);
6574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // EACH_TEST_SELF(C2RequestedInfosInfo, TEST_U32ARRAY_WRITABLE_FIELD);
6584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_INPUT(C2VideoSizeStreamInfo, TEST_VSSTRUCT_WRITABLE_FIELD);
6604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_OUTPUT(C2VideoSizeStreamInfo, TEST_VSSTRUCT_WRITABLE_FIELD);
6614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_INPUT(C2VideoSizeStreamTuning, TEST_VSSTRUCT_WRITABLE_FIELD);
6624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_OUTPUT(C2VideoSizeStreamTuning, TEST_VSSTRUCT_WRITABLE_FIELD);
6634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_INPUT(C2MaxVideoSizeHintPortSetting, TEST_VSSTRUCT_WRITABLE_FIELD);
6644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    EACH_TEST_OUTPUT(C2MaxVideoSizeHintPortSetting, TEST_VSSTRUCT_WRITABLE_FIELD);
6654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    outputResults(componentName);
6674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    resetResults();
6684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimTEST_F(C2CompIntfTest, C2V4L2CodecIntf) {
6714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Read a shared object library.
6734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void* compLib = dlopen("system/lib/libv4l2_codec2.so", RTLD_NOW);
6744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!compLib) {
6764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        printf("Cannot open library: %s.\n", dlerror());
6774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        FAIL();
6784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return;
6794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    typedef C2ComponentStore* create_t();
6824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    create_t* create_store= (create_t*) dlsym(compLib, "create_store");
6834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const char* dlsym_error = dlerror();
6844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (dlsym_error) {
6854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        printf("Cannot load symbol create: %s.\n", dlsym_error);
6864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        FAIL();
6874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return;
6884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    typedef void destroy_t(C2ComponentStore*);
6914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    destroy_t* destroy_store = (destroy_t*) dlsym(compLib, "destroy_store");
6924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    dlsym_error = dlerror();
6934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (dlsym_error) {
6944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        printf("Cannot load symbol destroy: %s.\n", dlsym_error);
6954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        FAIL();
6964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return;
6974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2ComponentStore> componentStore(create_store(), destroy_store);
7004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2ComponentInterface> componentIntf;
7014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    componentStore->createInterface("v4l2.decoder", &componentIntf);
7024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    auto componentName = "C2V4L2Codec";
7034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    testMain(componentIntf, componentName);
7044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim} // namespace android
707