1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "media_omx_hidl_master_test"
18#ifdef __LP64__
19#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
20#endif
21
22#include <android-base/logging.h>
23
24#include <android/hardware/media/omx/1.0/IOmx.h>
25#include <android/hardware/media/omx/1.0/IOmxNode.h>
26#include <android/hardware/media/omx/1.0/IOmxObserver.h>
27#include <android/hardware/media/omx/1.0/IOmxStore.h>
28#include <android/hardware/media/omx/1.0/types.h>
29#include <android/hidl/allocator/1.0/IAllocator.h>
30#include <android/hidl/memory/1.0/IMapper.h>
31#include <android/hidl/memory/1.0/IMemory.h>
32
33using ::android::hardware::media::omx::V1_0::IOmx;
34using ::android::hardware::media::omx::V1_0::IOmxObserver;
35using ::android::hardware::media::omx::V1_0::IOmxNode;
36using ::android::hardware::media::omx::V1_0::IOmxStore;
37using ::android::hardware::media::omx::V1_0::Message;
38using ::android::hardware::media::omx::V1_0::CodecBuffer;
39using ::android::hardware::media::omx::V1_0::PortMode;
40using ::android::hidl::allocator::V1_0::IAllocator;
41using ::android::hidl::memory::V1_0::IMemory;
42using ::android::hidl::memory::V1_0::IMapper;
43using ::android::hardware::Return;
44using ::android::hardware::Void;
45using ::android::hardware::hidl_vec;
46using ::android::hardware::hidl_string;
47using ::android::sp;
48
49#include <VtsHalHidlTargetTestBase.h>
50#include <getopt.h>
51#include <media_hidl_test_common.h>
52
53// A class for test environment setup
54class ComponentTestEnvironment : public ::testing::Environment {
55   public:
56    virtual void SetUp() {}
57    virtual void TearDown() {}
58
59    ComponentTestEnvironment() : instance("default") {}
60
61    void setInstance(const char* _instance) { instance = _instance; }
62
63    const hidl_string getInstance() const { return instance; }
64
65    int initFromOptions(int argc, char** argv) {
66        static struct option options[] = {
67            {"instance", required_argument, 0, 'I'}, {0, 0, 0, 0}};
68
69        while (true) {
70            int index = 0;
71            int c = getopt_long(argc, argv, "I:", options, &index);
72            if (c == -1) {
73                break;
74            }
75
76            switch (c) {
77                case 'I':
78                    setInstance(optarg);
79                    break;
80                case '?':
81                    break;
82            }
83        }
84
85        if (optind < argc) {
86            fprintf(stderr,
87                    "unrecognized option: %s\n\n"
88                    "usage: %s <gtest options> <test options>\n\n"
89                    "test options are:\n\n"
90                    "-I, --instance: HAL instance to test\n",
91                    argv[optind ?: 1], argv[0]);
92            return 2;
93        }
94        return 0;
95    }
96
97   private:
98    hidl_string instance;
99};
100
101static ComponentTestEnvironment* gEnv = nullptr;
102
103class MasterHidlTest : public ::testing::VtsHalHidlTargetTestBase {
104   private:
105    typedef ::testing::VtsHalHidlTargetTestBase Super;
106   public:
107    virtual void SetUp() override {
108        Super::SetUp();
109        omxStore = nullptr;
110        omxStore = Super::getService<IOmxStore>();
111        ASSERT_NE(omxStore, nullptr);
112        omx = nullptr;
113        omx = omxStore->getOmx(gEnv->getInstance());
114        ASSERT_NE(omx, nullptr);
115    }
116
117    virtual void TearDown() override {
118        Super::TearDown();
119    }
120
121    sp<IOmxStore> omxStore;
122    sp<IOmx> omx;
123
124   protected:
125    static void description(const std::string& description) {
126        RecordProperty("description", description);
127    }
128};
129
130void displayComponentInfo(hidl_vec<IOmx::ComponentInfo>& nodeList) {
131    for (size_t i = 0; i < nodeList.size(); i++) {
132        printf("%s | ", nodeList[i].mName.c_str());
133        for (size_t j = 0; j < ((nodeList[i]).mRoles).size(); j++) {
134            printf("%s ", nodeList[i].mRoles[j].c_str());
135        }
136        printf("\n");
137    }
138}
139
140// list service attributes
141TEST_F(MasterHidlTest, ListServiceAttr) {
142    description("list service attributes");
143    android::hardware::media::omx::V1_0::Status status;
144    hidl_vec<IOmxStore::Attribute> attributes;
145    EXPECT_TRUE(omxStore
146                    ->listServiceAttributes([&status, &attributes](
147                        android::hardware::media::omx::V1_0::Status _s,
148                        hidl_vec<IOmxStore::Attribute> const& _nl) {
149                        status = _s;
150                        attributes = _nl;
151                    })
152                    .isOk());
153    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
154    if (attributes.size() == 0) ALOGV("Warning, Attribute list empty");
155}
156
157// get node prefix
158TEST_F(MasterHidlTest, getNodePrefix) {
159    description("get node prefix");
160    hidl_string prefix;
161    omxStore->getNodePrefix(
162        [&prefix](hidl_string const& _nl) { prefix = _nl; });
163    if (prefix.empty()) ALOGV("Warning, Node Prefix empty");
164}
165
166// list roles
167TEST_F(MasterHidlTest, ListRoles) {
168    description("list roles");
169    hidl_vec<IOmxStore::RoleInfo> roleList;
170    omxStore->listRoles([&roleList](hidl_vec<IOmxStore::RoleInfo> const& _nl) {
171        roleList = _nl;
172    });
173    if (roleList.size() == 0) ALOGV("Warning, RoleInfo list empty");
174}
175
176// list components and roles.
177TEST_F(MasterHidlTest, ListNodes) {
178    description("enumerate component and roles");
179    android::hardware::media::omx::V1_0::Status status;
180    hidl_vec<IOmx::ComponentInfo> nodeList;
181    bool isPass = true;
182    EXPECT_TRUE(
183        omx->listNodes([&status, &nodeList](
184                           android::hardware::media::omx::V1_0::Status _s,
185                           hidl_vec<IOmx::ComponentInfo> const& _nl) {
186               status = _s;
187               nodeList = _nl;
188           })
189            .isOk());
190    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
191    if (nodeList.size() == 0)
192        ALOGV("Warning, ComponentInfo list empty");
193    else {
194        // displayComponentInfo(nodeList);
195        for (size_t i = 0; i < nodeList.size(); i++) {
196            sp<CodecObserver> observer = nullptr;
197            sp<IOmxNode> omxNode = nullptr;
198            observer = new CodecObserver(nullptr);
199            ASSERT_NE(observer, nullptr);
200            EXPECT_TRUE(
201                omx->allocateNode(
202                       nodeList[i].mName, observer,
203                       [&](android::hardware::media::omx::V1_0::Status _s,
204                           sp<IOmxNode> const& _nl) {
205                           status = _s;
206                           omxNode = _nl;
207                       })
208                    .isOk());
209            ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
210            if (omxNode == nullptr) {
211                isPass = false;
212                std::cerr << "[    !OK   ] " << nodeList[i].mName.c_str()
213                          << "\n";
214            } else {
215                EXPECT_TRUE((omxNode->freeNode()).isOk());
216                omxNode = nullptr;
217                // std::cout << "[     OK   ] " << nodeList[i].mName.c_str() <<
218                // "\n";
219            }
220        }
221    }
222    EXPECT_TRUE(isPass);
223}
224
225int main(int argc, char** argv) {
226    gEnv = new ComponentTestEnvironment();
227    ::testing::AddGlobalTestEnvironment(gEnv);
228    ::testing::InitGoogleTest(&argc, argv);
229    int status = gEnv->initFromOptions(argc, argv);
230    if (status == 0) {
231        status = RUN_ALL_TESTS();
232        ALOGI("Test result = %d", status);
233    }
234    return status;
235}
236