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_component_test"
18 #include <android-base/logging.h>
19 
20 #include <android/hardware/media/omx/1.0/IOmx.h>
21 #include <android/hardware/media/omx/1.0/IOmxNode.h>
22 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
23 #include <android/hardware/media/omx/1.0/types.h>
24 #include <android/hidl/allocator/1.0/IAllocator.h>
25 #include <android/hidl/memory/1.0/IMapper.h>
26 #include <android/hidl/memory/1.0/IMemory.h>
27 
28 using ::android::hardware::media::omx::V1_0::IOmx;
29 using ::android::hardware::media::omx::V1_0::IOmxObserver;
30 using ::android::hardware::media::omx::V1_0::IOmxNode;
31 using ::android::hardware::media::omx::V1_0::Message;
32 using ::android::hardware::media::omx::V1_0::CodecBuffer;
33 using ::android::hardware::media::omx::V1_0::PortMode;
34 using ::android::hidl::allocator::V1_0::IAllocator;
35 using ::android::hidl::memory::V1_0::IMemory;
36 using ::android::hidl::memory::V1_0::IMapper;
37 using ::android::hardware::Return;
38 using ::android::hardware::Void;
39 using ::android::hardware::hidl_vec;
40 using ::android::hardware::hidl_string;
41 using ::android::sp;
42 
43 #include <VtsHalHidlTargetTestBase.h>
44 #include <getopt.h>
45 #include <media_hidl_test_common.h>
46 
47 // A class for test environment setup
48 class ComponentTestEnvironment : public ::testing::Environment {
49    public:
SetUp()50     virtual void SetUp() {}
TearDown()51     virtual void TearDown() {}
52 
ComponentTestEnvironment()53     ComponentTestEnvironment() : instance("default") {}
54 
setInstance(const char * _instance)55     void setInstance(const char* _instance) { instance = _instance; }
56 
setComponent(const char * _component)57     void setComponent(const char* _component) { component = _component; }
58 
setRole(const char * _role)59     void setRole(const char* _role) { role = _role; }
60 
getInstance() const61     const hidl_string getInstance() const { return instance; }
62 
getComponent() const63     const hidl_string getComponent() const { return component; }
64 
getRole() const65     const hidl_string getRole() const { return role; }
66 
initFromOptions(int argc,char ** argv)67     int initFromOptions(int argc, char** argv) {
68         static struct option options[] = {
69             {"instance", required_argument, 0, 'I'},
70             {"component", required_argument, 0, 'C'},
71             {"role", required_argument, 0, 'R'},
72             {0, 0, 0, 0}};
73 
74         while (true) {
75             int index = 0;
76             int c = getopt_long(argc, argv, "I:C:R:", options, &index);
77             if (c == -1) {
78                 break;
79             }
80 
81             switch (c) {
82                 case 'I':
83                     setInstance(optarg);
84                     break;
85                 case 'C':
86                     setComponent(optarg);
87                     break;
88                 case 'R':
89                     setRole(optarg);
90                     break;
91                 case '?':
92                     break;
93             }
94         }
95 
96         if (optind < argc) {
97             fprintf(stderr,
98                     "unrecognized option: %s\n\n"
99                     "usage: %s <gtest options> <test options>\n\n"
100                     "test options are:\n\n"
101                     "-I, --instance: HAL instance to test\n"
102                     "-C, --component: OMX component to test\n"
103                     "-R, --Role: OMX component Role\n",
104                     argv[optind ?: 1], argv[0]);
105             return 2;
106         }
107         return 0;
108     }
109 
110    private:
111     hidl_string instance;
112     hidl_string component;
113     hidl_string role;
114 };
115 
116 static ComponentTestEnvironment* gEnv = nullptr;
117 
118 // generic component test fixture class
119 class ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase {
120    public:
SetUp()121     virtual void SetUp() override {
122         disableTest = false;
123         android::hardware::media::omx::V1_0::Status status;
124         omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
125             gEnv->getInstance());
126         ASSERT_NE(omx, nullptr);
127         observer = new CodecObserver(nullptr);
128         ASSERT_NE(observer, nullptr);
129         if (strncmp(gEnv->getComponent().c_str(), "OMX.", 4) != 0)
130             disableTest = true;
131         EXPECT_TRUE(omx->allocateNode(
132                            gEnv->getComponent(), observer,
133                            [&](android::hardware::media::omx::V1_0::Status _s,
134                                sp<IOmxNode> const& _nl) {
135                                status = _s;
136                                this->omxNode = _nl;
137                            })
138                         .isOk());
139         ASSERT_NE(omxNode, nullptr);
140         ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
141         struct StringToClass {
142             const char* Class;
143             standardCompClass CompClass;
144         };
145         const StringToClass kStringToClass[] = {
146             {"audio_decoder", audio_decoder},
147             {"audio_encoder", audio_encoder},
148             {"video_decoder", video_decoder},
149             {"video_encoder", video_encoder},
150         };
151         const size_t kNumStringToClass =
152             sizeof(kStringToClass) / sizeof(kStringToClass[0]);
153         const char* pch;
154         char substring[OMX_MAX_STRINGNAME_SIZE];
155         strcpy(substring, gEnv->getRole().c_str());
156         pch = strchr(substring, '.');
157         ASSERT_NE(pch, nullptr) << "Invalid Component Role";
158         substring[pch - substring] = '\0';
159         compClass = unknown_class;
160         for (size_t i = 0; i < kNumStringToClass; ++i) {
161             if (!strcasecmp(substring, kStringToClass[i].Class)) {
162                 compClass = kStringToClass[i].CompClass;
163                 break;
164             }
165         }
166         if (compClass == unknown_class) disableTest = true;
167         isSecure = false;
168         size_t suffixLen = strlen(".secure");
169         if (strlen(gEnv->getComponent().c_str()) >= suffixLen) {
170             isSecure =
171                 !strcmp(gEnv->getComponent().c_str() +
172                             strlen(gEnv->getComponent().c_str()) - suffixLen,
173                         ".secure");
174         }
175         if (disableTest) std::cerr << "[          ] Warning !  Test Disabled\n";
176     }
177 
TearDown()178     virtual void TearDown() override {
179         if (omxNode != nullptr) {
180             EXPECT_TRUE((omxNode->freeNode()).isOk());
181             omxNode = nullptr;
182         }
183     }
184 
185     enum standardCompClass {
186         audio_decoder,
187         audio_encoder,
188         video_decoder,
189         video_encoder,
190         unknown_class,
191     };
192 
193     sp<IOmx> omx;
194     sp<CodecObserver> observer;
195     sp<IOmxNode> omxNode;
196     standardCompClass compClass;
197     bool isSecure;
198     bool disableTest;
199 
200    protected:
description(const std::string & description)201     static void description(const std::string& description) {
202         RecordProperty("description", description);
203     }
204 };
205 
206 // Random Index used for monkey testing while get/set parameters
207 #define RANDOM_INDEX 1729
208 
initPortMode(PortMode * pm,bool isSecure,ComponentHidlTest::standardCompClass compClass)209 void initPortMode(PortMode* pm, bool isSecure,
210                   ComponentHidlTest::standardCompClass compClass) {
211     pm[0] = PortMode::PRESET_BYTE_BUFFER;
212     pm[1] = PortMode::PRESET_BYTE_BUFFER;
213     if (isSecure) {
214         switch (compClass) {
215             case ComponentHidlTest::video_decoder:
216                 pm[0] = PortMode::PRESET_SECURE_BUFFER;
217                 break;
218             case ComponentHidlTest::video_encoder:
219                 pm[1] = PortMode::PRESET_SECURE_BUFFER;
220                 break;
221             default:
222                 break;
223         }
224     }
225     return;
226 }
227 
228 // get/set video component port format
setVideoPortFormat(sp<IOmxNode> omxNode,OMX_U32 portIndex,OMX_VIDEO_CODINGTYPE eCompressionFormat,OMX_COLOR_FORMATTYPE eColorFormat,OMX_U32 xFramerate)229 Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
230     sp<IOmxNode> omxNode, OMX_U32 portIndex,
231     OMX_VIDEO_CODINGTYPE eCompressionFormat, OMX_COLOR_FORMATTYPE eColorFormat,
232     OMX_U32 xFramerate) {
233     OMX_U32 index = 0;
234     OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
235     std::vector<OMX_COLOR_FORMATTYPE> arrColorFormat;
236     std::vector<OMX_VIDEO_CODINGTYPE> arrCompressionFormat;
237     android::hardware::media::omx::V1_0::Status status;
238 
239     while (1) {
240         portFormat.nIndex = index;
241         status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
242                               &portFormat);
243         if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
244         if (eCompressionFormat == OMX_VIDEO_CodingUnused)
245             arrColorFormat.push_back(portFormat.eColorFormat);
246         else
247             arrCompressionFormat.push_back(portFormat.eCompressionFormat);
248         index++;
249         if (index == 512) {
250             // enumerated way too many formats, highly unusual for this to
251             // happen.
252             EXPECT_LE(index, 512U)
253                 << "Expecting OMX_ErrorNoMore but not received";
254             break;
255         }
256     }
257     if (!index) return status;
258     if (eCompressionFormat == OMX_VIDEO_CodingUnused) {
259         for (index = 0; index < arrColorFormat.size(); index++) {
260             if (arrColorFormat[index] == eColorFormat) {
261                 portFormat.eColorFormat = arrColorFormat[index];
262                 break;
263             }
264         }
265         if (index == arrColorFormat.size()) {
266             ALOGE("setting default color format %x", (int)arrColorFormat[0]);
267             portFormat.eColorFormat = arrColorFormat[0];
268         }
269         portFormat.eCompressionFormat = OMX_VIDEO_CodingUnused;
270     } else {
271         for (index = 0; index < arrCompressionFormat.size(); index++) {
272             if (arrCompressionFormat[index] == eCompressionFormat) {
273                 portFormat.eCompressionFormat = arrCompressionFormat[index];
274                 break;
275             }
276         }
277         if (index == arrCompressionFormat.size()) {
278             ALOGE("setting default compression format %x",
279                   (int)arrCompressionFormat[0]);
280             portFormat.eCompressionFormat = arrCompressionFormat[0];
281         }
282         portFormat.eColorFormat = OMX_COLOR_FormatUnused;
283     }
284     // In setParam call nIndex shall be ignored as per omx-il specification.
285     // see how this holds up by corrupting nIndex
286     portFormat.nIndex = RANDOM_INDEX;
287     portFormat.xFramerate = xFramerate;
288     status = setPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
289                           &portFormat);
290     return status;
291 }
292 
293 // get/set audio component port format
setAudioPortFormat(sp<IOmxNode> omxNode,OMX_U32 portIndex,OMX_AUDIO_CODINGTYPE eEncoding)294 Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
295     sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE eEncoding) {
296     OMX_U32 index = 0;
297     OMX_AUDIO_PARAM_PORTFORMATTYPE portFormat;
298     std::vector<OMX_AUDIO_CODINGTYPE> arrEncoding;
299     android::hardware::media::omx::V1_0::Status status;
300 
301     while (1) {
302         portFormat.nIndex = index;
303         status = getPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
304                               &portFormat);
305         if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
306         arrEncoding.push_back(portFormat.eEncoding);
307         index++;
308         if (index == 512) {
309             // enumerated way too many formats, highly unusual for this to
310             // happen.
311             EXPECT_LE(index, 512U)
312                 << "Expecting OMX_ErrorNoMore but not received";
313             break;
314         }
315     }
316     if (!index) return status;
317     for (index = 0; index < arrEncoding.size(); index++) {
318         if (arrEncoding[index] == eEncoding) {
319             portFormat.eEncoding = arrEncoding[index];
320             break;
321         }
322     }
323     if (index == arrEncoding.size()) {
324         ALOGE("setting default Port format %x", (int)arrEncoding[0]);
325         portFormat.eEncoding = arrEncoding[0];
326     }
327     // In setParam call nIndex shall be ignored as per omx-il specification.
328     // see how this holds up by corrupting nIndex
329     portFormat.nIndex = RANDOM_INDEX;
330     status = setPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
331                           &portFormat);
332     return status;
333 }
334 
335 // test dispatch message API call
TEST_F(ComponentHidlTest,dispatchMsg)336 TEST_F(ComponentHidlTest, dispatchMsg) {
337     description("test dispatch message API call");
338     if (disableTest) return;
339     android::hardware::media::omx::V1_0::Status status;
340     Message msgin, msgout;
341 
342     msgin.type = Message::Type::EVENT;
343     msgin.data.eventData.event = OMX_EventError;
344     msgin.data.eventData.data1 = 0xdeaf;
345     msgin.data.eventData.data2 = 0xd00d;
346     msgin.data.eventData.data3 = 0x01ce;
347     msgin.data.eventData.data4 = 0xfa11;
348     status = omxNode->dispatchMessage(msgin);
349     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
350     status = observer->dequeueMessage(&msgout, DEFAULT_TIMEOUT);
351     EXPECT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
352     EXPECT_EQ(msgout.type, msgin.type);
353     EXPECT_EQ(msgout.data.eventData.event, msgin.data.eventData.event);
354     EXPECT_EQ(msgout.data.eventData.data1, msgin.data.eventData.data1);
355     EXPECT_EQ(msgout.data.eventData.data2, msgin.data.eventData.data2);
356     EXPECT_EQ(msgout.data.eventData.data3, msgin.data.eventData.data3);
357     EXPECT_EQ(msgout.data.eventData.data4, msgin.data.eventData.data4);
358 }
359 
360 // set component role
TEST_F(ComponentHidlTest,SetRole)361 TEST_F(ComponentHidlTest, SetRole) {
362     description("Test Set Component Role");
363     if (disableTest) return;
364     android::hardware::media::omx::V1_0::Status status;
365     status = setRole(omxNode, gEnv->getRole().c_str());
366     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
367 }
368 
369 // port indices enumeration
TEST_F(ComponentHidlTest,DISABLED_GetPortIndices)370 TEST_F(ComponentHidlTest, DISABLED_GetPortIndices) {
371     description("Test Component on Mandatory Port Parameters (Port Indices)");
372     if (disableTest) return;
373     android::hardware::media::omx::V1_0::Status status;
374     OMX_PORT_PARAM_TYPE params;
375 
376     status = setRole(omxNode, gEnv->getRole().c_str());
377     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
378 
379     // Get Number of Ports and their Indices for all Domains
380     // (Audio/Video/Image/Other)
381     // All standard OMX components shall support following OMX Index types
382     status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
383     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
384     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
385     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
386     status = getParam(omxNode, OMX_IndexParamImageInit, &params);
387     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
388     status = getParam(omxNode, OMX_IndexParamOtherInit, &params);
389     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
390 }
391 
392 // port format enumeration
TEST_F(ComponentHidlTest,DISABLED_EnumeratePortFormat)393 TEST_F(ComponentHidlTest, DISABLED_EnumeratePortFormat) {
394     description("Test Component on Mandatory Port Parameters (Port Format)");
395     if (disableTest) return;
396     android::hardware::media::omx::V1_0::Status status;
397     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
398 
399     status = setRole(omxNode, gEnv->getRole().c_str());
400     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
401     OMX_PORT_PARAM_TYPE params;
402     if (compClass == audio_decoder || compClass == audio_encoder) {
403         status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
404     } else {
405         status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
406     }
407     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
408         ASSERT_EQ(params.nPorts, 2U);
409         kPortIndexInput = params.nStartPortNumber;
410         kPortIndexOutput = kPortIndexInput + 1;
411     }
412 
413     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
414     OMX_U32 xFramerate = 24U << 16;
415 
416     // Enumerate Port Format
417     if (compClass == audio_encoder) {
418         status =
419             setAudioPortFormat(omxNode, kPortIndexInput, OMX_AUDIO_CodingPCM);
420         EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
421         status = setAudioPortFormat(omxNode, kPortIndexOutput,
422                                     OMX_AUDIO_CodingAutoDetect);
423         EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
424     } else if (compClass == audio_decoder) {
425         status = setAudioPortFormat(omxNode, kPortIndexInput,
426                                     OMX_AUDIO_CodingAutoDetect);
427         EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
428         status =
429             setAudioPortFormat(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM);
430         EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
431     } else if (compClass == video_encoder) {
432         status =
433             setVideoPortFormat(omxNode, kPortIndexInput, OMX_VIDEO_CodingUnused,
434                                eColorFormat, xFramerate);
435         EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
436         status = setVideoPortFormat(omxNode, kPortIndexOutput,
437                                     OMX_VIDEO_CodingAutoDetect,
438                                     OMX_COLOR_FormatUnused, 0U);
439         EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
440     } else {
441         status = setVideoPortFormat(omxNode, kPortIndexInput,
442                                     OMX_VIDEO_CodingAutoDetect,
443                                     OMX_COLOR_FormatUnused, 0U);
444         EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
445         status = setVideoPortFormat(omxNode, kPortIndexOutput,
446                                     OMX_VIDEO_CodingUnused, eColorFormat,
447                                     xFramerate);
448         EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
449     }
450 }
451 
452 // get/set default port settings of a component
TEST_F(ComponentHidlTest,DISABLED_SetDefaultPortParams)453 TEST_F(ComponentHidlTest, DISABLED_SetDefaultPortParams) {
454     description(
455         "Test Component on Mandatory Port Parameters (Port Definition)");
456     if (disableTest) return;
457     android::hardware::media::omx::V1_0::Status status;
458     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
459 
460     status = setRole(omxNode, gEnv->getRole().c_str());
461     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
462     OMX_PORT_PARAM_TYPE params;
463     if (compClass == audio_decoder || compClass == audio_encoder) {
464         status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
465     } else {
466         status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
467     }
468     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
469         ASSERT_EQ(params.nPorts, 2U);
470         kPortIndexInput = params.nStartPortNumber;
471         kPortIndexOutput = kPortIndexInput + 1;
472     }
473 
474     for (size_t i = kPortIndexInput; i < kPortIndexOutput; i++) {
475         OMX_PARAM_PORTDEFINITIONTYPE portDef;
476         status =
477             getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
478         EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
479         if (status == android::hardware::media::omx::V1_0::Status::OK) {
480             EXPECT_EQ(portDef.eDir, i - kPortIndexInput);  // OMX_DirInput
481             EXPECT_EQ(portDef.bEnabled, OMX_TRUE);
482             EXPECT_EQ(portDef.bPopulated, OMX_FALSE);
483             EXPECT_GE(portDef.nBufferCountMin, 1U);
484             EXPECT_GE(portDef.nBufferCountActual, portDef.nBufferCountMin);
485             if (compClass == audio_encoder || compClass == audio_decoder) {
486                 EXPECT_EQ(portDef.eDomain, OMX_PortDomainAudio);
487             } else if (compClass == video_encoder ||
488                        compClass == video_decoder) {
489                 EXPECT_EQ(portDef.eDomain, OMX_PortDomainVideo);
490             }
491             OMX_PARAM_PORTDEFINITIONTYPE mirror = portDef;
492 
493             // nBufferCountActual >= nBufferCountMin
494             portDef.nBufferCountActual = portDef.nBufferCountMin - 1;
495             status = setPortParam(omxNode, OMX_IndexParamPortDefinition, i,
496                                   &portDef);
497             EXPECT_NE(status,
498                       ::android::hardware::media::omx::V1_0::Status::OK);
499 
500             // Edit Read-Only fields.
501             portDef = mirror;
502             portDef.eDir = static_cast<OMX_DIRTYPE>(RANDOM_INDEX);
503             setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
504             getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
505             EXPECT_EQ(portDef.eDir, mirror.eDir);
506             setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &mirror);
507 
508             portDef = mirror;
509             portDef.nBufferSize >>= 1;
510             setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
511             getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
512             EXPECT_EQ(portDef.nBufferSize, mirror.nBufferSize);
513             setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &mirror);
514 
515             portDef = mirror;
516             portDef.nBufferCountMin += 1;
517             setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
518             getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
519             EXPECT_EQ(portDef.nBufferCountMin, mirror.nBufferCountMin);
520             setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &mirror);
521 
522             portDef = mirror;
523             portDef.nBufferCountActual += 1;
524             status = setPortParam(omxNode, OMX_IndexParamPortDefinition, i,
525                                   &portDef);
526             if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
527                 status = getPortParam(omxNode, OMX_IndexParamPortDefinition, i,
528                                       &portDef);
529                 EXPECT_EQ(portDef.nBufferCountActual,
530                           mirror.nBufferCountActual + 1);
531             }
532 
533             portDef = mirror;
534             portDef.nBufferSize = mirror.nBufferSize << 1;
535             status = setPortParam(omxNode, OMX_IndexParamPortDefinition, i,
536                                   &portDef);
537             if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
538                 status = getPortParam(omxNode, OMX_IndexParamPortDefinition, i,
539                                       &portDef);
540                 if (portDef.nBufferSize != mirror.nBufferSize) {
541                     std::cout
542                         << "[          ] Warning ! Component input port does "
543                            "not  preserve Read-Only fields \n";
544                 }
545             }
546         }
547     }
548 }
549 
550 // populate port test
TEST_F(ComponentHidlTest,DISABLED_PopulatePort)551 TEST_F(ComponentHidlTest, DISABLED_PopulatePort) {
552     description("Verify bPopulated field of a component port");
553     if (disableTest || isSecure) return;
554     android::hardware::media::omx::V1_0::Status status;
555     OMX_U32 portBase = 0;
556 
557     status = setRole(omxNode, gEnv->getRole().c_str());
558     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
559     OMX_PORT_PARAM_TYPE params;
560     if (compClass == audio_decoder || compClass == audio_encoder) {
561         status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
562     } else {
563         status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
564     }
565     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
566         ASSERT_EQ(params.nPorts, 2U);
567         portBase = params.nStartPortNumber;
568     }
569 
570     sp<IAllocator> allocator = IAllocator::getService("ashmem");
571     EXPECT_NE(allocator.get(), nullptr);
572 
573     OMX_PARAM_PORTDEFINITIONTYPE portDef;
574     status =
575         getPortParam(omxNode, OMX_IndexParamPortDefinition, portBase, &portDef);
576     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
577     ASSERT_EQ(portDef.bPopulated, OMX_FALSE);
578 
579     android::Vector<BufferInfo> pBuffer;
580     pBuffer.clear();
581     uint32_t nBufferSize = portDef.nBufferSize >> 1;
582 
583     for (size_t i = 0; i < portDef.nBufferCountActual; i++) {
584         BufferInfo buffer;
585         buffer.owner = client;
586         buffer.omxBuffer.type = CodecBuffer::Type::SHARED_MEM;
587         buffer.omxBuffer.attr.preset.rangeOffset = 0;
588         buffer.omxBuffer.attr.preset.rangeLength = 0;
589         bool success = false;
590         allocator->allocate(
591             nBufferSize,
592             [&success, &buffer](bool _s,
593                                 ::android::hardware::hidl_memory const& mem) {
594                 success = _s;
595                 buffer.omxBuffer.sharedMemory = mem;
596             });
597         ASSERT_EQ(success, true);
598         ASSERT_EQ(buffer.omxBuffer.sharedMemory.size(), nBufferSize);
599 
600         omxNode->useBuffer(
601             portBase, buffer.omxBuffer,
602             [&status, &buffer](android::hardware::media::omx::V1_0::Status _s,
603                                uint32_t id) {
604                 status = _s;
605                 buffer.id = id;
606             });
607         pBuffer.push(buffer);
608         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
609     }
610 
611     status =
612         getPortParam(omxNode, OMX_IndexParamPortDefinition, portBase, &portDef);
613     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
614     // A port is populated when all of the buffers indicated by
615     // nBufferCountActual with a size of at least nBufferSizehave been
616     // allocated on the port.
617     ASSERT_EQ(portDef.bPopulated, OMX_FALSE);
618 }
619 
620 // Flush test
TEST_F(ComponentHidlTest,Flush)621 TEST_F(ComponentHidlTest, Flush) {
622     description("Test Flush");
623     if (disableTest) return;
624     android::hardware::media::omx::V1_0::Status status;
625     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
626     Message msg;
627 
628     status = setRole(omxNode, gEnv->getRole().c_str());
629     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
630     OMX_PORT_PARAM_TYPE params;
631     if (compClass == audio_decoder || compClass == audio_encoder) {
632         status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
633     } else {
634         status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
635     }
636     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
637         ASSERT_EQ(params.nPorts, 2U);
638         kPortIndexInput = params.nStartPortNumber;
639         kPortIndexOutput = kPortIndexInput + 1;
640     }
641 
642     android::Vector<BufferInfo> iBuffer, oBuffer;
643 
644     // set port mode
645     PortMode portMode[2];
646     initPortMode(portMode, isSecure, compClass);
647     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
648     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
649     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
650     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
651 
652     // set state to idle
653     changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
654                             kPortIndexInput, kPortIndexOutput, portMode);
655     // set state to executing
656     changeStateIdletoExecute(omxNode, observer);
657     // dispatch buffers
658     for (size_t i = 0; i < oBuffer.size(); i++) {
659         dispatchOutputBuffer(omxNode, &oBuffer, i, portMode[1]);
660     }
661     // flush port
662     flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
663                kPortIndexOutput);
664     // TODO: Sending empty input buffers is slightly tricky.
665     // Components sometimes process input buffers even when output buffers are
666     // not dispatched. For instance Parsing sequence header does not require
667     // output buffers. In such instances sending 0 size input buffers might
668     // make component to send error events. so lets skip this aspect of testing.
669     // dispatch buffers
670     //    for (size_t i = 0; i < iBuffer.size(); i++) {
671     //        dispatchInputBuffer(omxNode, &iBuffer, i, 0, 0, 0, portMode[0]);
672     //    }
673     //    // flush ports
674     //    flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
675     //               kPortIndexOutput);
676     // set state to idle
677     changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
678     // set state to loaded
679     changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
680                             kPortIndexInput, kPortIndexOutput);
681 }
682 
683 // state transitions test
TEST_F(ComponentHidlTest,StateTransitions)684 TEST_F(ComponentHidlTest, StateTransitions) {
685     description("Test State Transitions Loaded<->Idle<->Execute");
686     if (disableTest) return;
687     android::hardware::media::omx::V1_0::Status status;
688     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
689     Message msg;
690 
691     status = setRole(omxNode, gEnv->getRole().c_str());
692     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
693     OMX_PORT_PARAM_TYPE params;
694     if (compClass == audio_decoder || compClass == audio_encoder) {
695         status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
696     } else {
697         status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
698     }
699     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
700         ASSERT_EQ(params.nPorts, 2U);
701         kPortIndexInput = params.nStartPortNumber;
702         kPortIndexOutput = kPortIndexInput + 1;
703     }
704 
705     android::Vector<BufferInfo> iBuffer, oBuffer;
706 
707     // set port mode
708     PortMode portMode[2];
709     initPortMode(portMode, isSecure, compClass);
710     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
711     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
712     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
713     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
714 
715     // set state to idle
716     changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
717                             kPortIndexInput, kPortIndexOutput, portMode);
718     // set state to executing
719     changeStateIdletoExecute(omxNode, observer);
720     // dispatch buffers
721     for (size_t i = 0; i < oBuffer.size(); i++) {
722         dispatchOutputBuffer(omxNode, &oBuffer, i, portMode[1]);
723     }
724     // set state to idle
725     changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
726     //    // set state to executing
727     //    changeStateIdletoExecute(omxNode, observer);
728     //    // TODO: Sending empty input buffers is slightly tricky.
729     //    // dispatch buffers
730     //    for (size_t i = 0; i < iBuffer.size(); i++) {
731     //        dispatchInputBuffer(omxNode, &iBuffer, i, 0, 0, 0, portMode[0]);
732     //    }
733     //    // set state to idle
734     //    changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
735     // set state to loaded
736     changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
737                             kPortIndexInput, kPortIndexOutput);
738 }
739 
740 // state transitions test - monkeying
TEST_F(ComponentHidlTest,DISABLED_StateTransitions_M)741 TEST_F(ComponentHidlTest, DISABLED_StateTransitions_M) {
742     description("Test State Transitions monkeying");
743     if (disableTest || isSecure) return;
744     android::hardware::media::omx::V1_0::Status status;
745     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
746     Message msg;
747 
748     status = setRole(omxNode, gEnv->getRole().c_str());
749     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
750     OMX_PORT_PARAM_TYPE params;
751     if (compClass == audio_decoder || compClass == audio_encoder) {
752         status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
753     } else {
754         status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
755     }
756     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
757         ASSERT_EQ(params.nPorts, 2U);
758         kPortIndexInput = params.nStartPortNumber;
759         kPortIndexOutput = kPortIndexInput + 1;
760     }
761 
762     android::Vector<BufferInfo> iBuffer, oBuffer;
763 
764     // set state to loaded ; receive error OMX_ErrorSameState
765     status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
766                                   OMX_StateLoaded);
767     EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
768 
769     // set state to executing ; receive error OMX_ErrorIncorrectStateTransition
770     status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
771                                   OMX_StateExecuting);
772     EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
773 
774     // set state to idle
775     changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
776                             kPortIndexInput, kPortIndexOutput);
777 
778     // set state to idle ; receive error OMX_ErrorSameState
779     status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
780                                   OMX_StateIdle);
781     EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
782 
783     // set state to executing
784     changeStateIdletoExecute(omxNode, observer);
785 
786     // set state to executing ; receive error OMX_ErrorSameState
787     status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
788                                   OMX_StateExecuting);
789     EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
790 
791     // set state to Loaded ; receive error OMX_ErrorIncorrectStateTransition
792     status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
793                                   OMX_StateLoaded);
794     EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
795 
796     // set state to Idle
797     changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
798 
799     // set state to Loaded
800     changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
801                             kPortIndexInput, kPortIndexOutput);
802 }
803 
804 // port enable disable test
TEST_F(ComponentHidlTest,DISABLED_PortEnableDisable_Loaded)805 TEST_F(ComponentHidlTest, DISABLED_PortEnableDisable_Loaded) {
806     description("Test Port Enable and Disable (Component State :: Loaded)");
807     if (disableTest) return;
808     android::hardware::media::omx::V1_0::Status status;
809     OMX_U32 portBase = 0;
810     Message msg;
811     status = setRole(omxNode, gEnv->getRole().c_str());
812     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
813     OMX_PORT_PARAM_TYPE params;
814     if (compClass == audio_decoder || compClass == audio_encoder) {
815         status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
816     } else {
817         status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
818     }
819     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
820         ASSERT_EQ(params.nPorts, 2U);
821         portBase = params.nStartPortNumber;
822     }
823 
824     for (size_t i = portBase; i < portBase + 2; i++) {
825         status =
826             omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i);
827         ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
828         status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT);
829         ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
830         ASSERT_EQ(msg.type, Message::Type::EVENT);
831         if (msg.data.eventData.event == OMX_EventCmdComplete) {
832             ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
833             ASSERT_EQ(msg.data.eventData.data2, i);
834             // If you can disable a port, then you should be able to enable it
835             // as well
836             status = omxNode->sendCommand(
837                 toRawCommandType(OMX_CommandPortEnable), i);
838             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
839             status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT);
840             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
841             ASSERT_EQ(msg.type, Message::Type::EVENT);
842             ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
843             ASSERT_EQ(msg.data.eventData.data2, i);
844         } else if (msg.data.eventData.event == OMX_EventError) {
845             ALOGE("Port %d Disabling failed with error %d", (int)i,
846                   (int)msg.data.eventData.event);
847         } else {
848             // something unexpected happened
849             ASSERT_TRUE(false);
850         }
851     }
852 }
853 
854 // port enable disable test
TEST_F(ComponentHidlTest,PortEnableDisable_Idle)855 TEST_F(ComponentHidlTest, PortEnableDisable_Idle) {
856     description("Test Port Enable and Disable (Component State :: Idle)");
857     if (disableTest) return;
858     android::hardware::media::omx::V1_0::Status status;
859     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
860     OMX_U32 portBase = 0;
861     Message msg;
862     status = setRole(omxNode, gEnv->getRole().c_str());
863     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
864     OMX_PORT_PARAM_TYPE params;
865     if (compClass == audio_decoder || compClass == audio_encoder) {
866         status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
867     } else {
868         status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
869     }
870     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
871         ASSERT_EQ(params.nPorts, 2U);
872         portBase = params.nStartPortNumber;
873     }
874     kPortIndexInput = portBase;
875     kPortIndexOutput = portBase + 1;
876 
877     // Component State :: Idle
878     android::Vector<BufferInfo> pBuffer[2];
879 
880     // set port mode
881     PortMode portMode[2];
882     initPortMode(portMode, isSecure, compClass);
883     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
884     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
885     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
886     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
887 
888     // set state to idle
889     changeStateLoadedtoIdle(omxNode, observer, &pBuffer[0], &pBuffer[1],
890                             kPortIndexInput, kPortIndexOutput, portMode);
891 
892     for (size_t i = portBase; i < portBase + 2; i++) {
893         status =
894             omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i);
895         ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
896 
897         status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
898                                           &pBuffer[1]);
899         if (status == android::hardware::media::omx::V1_0::Status::OK) {
900             ASSERT_EQ(msg.type, Message::Type::EVENT);
901             if (msg.data.eventData.event == OMX_EventCmdComplete) {
902                 // do not disable the port until all the buffers are freed
903                 ASSERT_TRUE(false);
904             } else if (msg.data.eventData.event == OMX_EventError) {
905                 ALOGE("Port %d Disabling failed with error %d", (int)i,
906                       (int)msg.data.eventData.event);
907             } else {
908                 // something unexpected happened
909                 ASSERT_TRUE(false);
910             }
911         } else if (status ==
912                    android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
913             for (size_t j = 0; j < pBuffer[i - portBase].size(); ++j) {
914                 status = omxNode->freeBuffer(i, pBuffer[i - portBase][j].id);
915                 ASSERT_EQ(status,
916                           android::hardware::media::omx::V1_0::Status::OK);
917             }
918 
919             status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
920                                               &pBuffer[0], &pBuffer[1]);
921             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
922             ASSERT_EQ(msg.type, Message::Type::EVENT);
923             ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
924             ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
925             ASSERT_EQ(msg.data.eventData.data2, i);
926 
927             // If you can disable a port, then you should be able to enable it
928             // as well
929             status = omxNode->sendCommand(
930                 toRawCommandType(OMX_CommandPortEnable), i);
931             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
932 
933             // do not enable the port until all the buffers are supplied
934             status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
935                                               &pBuffer[0], &pBuffer[1]);
936             ASSERT_EQ(status,
937                       android::hardware::media::omx::V1_0::Status::TIMED_OUT);
938 
939             allocatePortBuffers(omxNode, &pBuffer[i - portBase], i,
940                                 portMode[i - portBase]);
941             status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
942                                               &pBuffer[0], &pBuffer[1]);
943             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
944             ASSERT_EQ(msg.type, Message::Type::EVENT);
945             ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
946             ASSERT_EQ(msg.data.eventData.data2, i);
947         } else {
948             // something unexpected happened
949             ASSERT_TRUE(false);
950         }
951     }
952 
953     // set state to Loaded
954     changeStateIdletoLoaded(omxNode, observer, &pBuffer[0], &pBuffer[1],
955                             kPortIndexInput, kPortIndexOutput);
956 }
957 
958 // port enable disable test
TEST_F(ComponentHidlTest,PortEnableDisable_Execute)959 TEST_F(ComponentHidlTest, PortEnableDisable_Execute) {
960     description("Test Port Enable and Disable (Component State :: Execute)");
961     if (disableTest) return;
962     android::hardware::media::omx::V1_0::Status status;
963     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
964     OMX_U32 portBase = 0;
965     Message msg;
966     status = setRole(omxNode, gEnv->getRole().c_str());
967     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
968     OMX_PORT_PARAM_TYPE params;
969     if (compClass == audio_decoder || compClass == audio_encoder) {
970         status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
971     } else {
972         status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
973     }
974     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
975         ASSERT_EQ(params.nPorts, 2U);
976         portBase = params.nStartPortNumber;
977     }
978     kPortIndexInput = portBase;
979     kPortIndexOutput = portBase + 1;
980 
981     // Component State :: Idle
982     android::Vector<BufferInfo> pBuffer[2];
983 
984     // set port mode
985     PortMode portMode[2];
986     initPortMode(portMode, isSecure, compClass);
987     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
988     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
989     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
990     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
991 
992     // set state to idle
993     changeStateLoadedtoIdle(omxNode, observer, &pBuffer[0], &pBuffer[1],
994                             kPortIndexInput, kPortIndexOutput, portMode);
995 
996     // set state to executing
997     changeStateIdletoExecute(omxNode, observer);
998 
999     // dispatch buffers
1000     for (size_t i = 0; i < pBuffer[1].size(); i++) {
1001         dispatchOutputBuffer(omxNode, &pBuffer[1], i, portMode[1]);
1002     }
1003 
1004     for (size_t i = portBase; i < portBase + 2; i++) {
1005         status =
1006             omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i);
1007         ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
1008 
1009         status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
1010                                           &pBuffer[1]);
1011         if (status == android::hardware::media::omx::V1_0::Status::OK) {
1012             ASSERT_EQ(msg.type, Message::Type::EVENT);
1013             if (msg.data.eventData.event == OMX_EventCmdComplete) {
1014                 // do not disable the port until all the buffers are freed
1015                 ASSERT_TRUE(false);
1016             } else if (msg.data.eventData.event == OMX_EventError) {
1017                 ALOGE("Port %d Disabling failed with error %d", (int)i,
1018                       (int)msg.data.eventData.event);
1019             } else {
1020                 // something unexpected happened
1021                 ASSERT_TRUE(false);
1022             }
1023         } else if (status ==
1024                    android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
1025             for (size_t j = 0; j < pBuffer[i - portBase].size(); ++j) {
1026                 // test if client got all its buffers back
1027                 EXPECT_EQ(pBuffer[i - portBase][j].owner, client);
1028                 // free the buffers
1029                 status = omxNode->freeBuffer(i, pBuffer[i - portBase][j].id);
1030                 ASSERT_EQ(status,
1031                           android::hardware::media::omx::V1_0::Status::OK);
1032             }
1033 
1034             status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
1035                                               &pBuffer[0], &pBuffer[1]);
1036             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
1037             ASSERT_EQ(msg.type, Message::Type::EVENT);
1038             ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
1039             ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
1040             ASSERT_EQ(msg.data.eventData.data2, i);
1041 
1042             // If you can disable a port, then you should be able to enable it
1043             // as well
1044             status = omxNode->sendCommand(
1045                 toRawCommandType(OMX_CommandPortEnable), i);
1046             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
1047 
1048             // do not enable the port until all the buffers are supplied
1049             status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
1050                                               &pBuffer[0], &pBuffer[1]);
1051             ASSERT_EQ(status,
1052                       android::hardware::media::omx::V1_0::Status::TIMED_OUT);
1053 
1054             allocatePortBuffers(omxNode, &pBuffer[i - portBase], i,
1055                                 portMode[i - portBase]);
1056             status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
1057                                               &pBuffer[0], &pBuffer[1]);
1058             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
1059             ASSERT_EQ(msg.type, Message::Type::EVENT);
1060             ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
1061             ASSERT_EQ(msg.data.eventData.data2, i);
1062         } else {
1063             // something unexpected happened
1064             ASSERT_TRUE(false);
1065         }
1066     }
1067 
1068     // set state to Idle
1069     changeStateExecutetoIdle(omxNode, observer, &pBuffer[0], &pBuffer[1]);
1070 
1071     // set state to Loaded
1072     changeStateIdletoLoaded(omxNode, observer, &pBuffer[0], &pBuffer[1],
1073                             kPortIndexInput, kPortIndexOutput);
1074 }
1075 
1076 // port enable disable test - monkeying
TEST_F(ComponentHidlTest,DISABLED_PortEnableDisable_M)1077 TEST_F(ComponentHidlTest, DISABLED_PortEnableDisable_M) {
1078     description(
1079         "Test Port Enable and Disable Monkeying (Component State :: Loaded)");
1080     if (disableTest || isSecure) return;
1081     android::hardware::media::omx::V1_0::Status status;
1082     OMX_U32 portBase = 0;
1083     Message msg;
1084     status = setRole(omxNode, gEnv->getRole().c_str());
1085     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1086     OMX_PORT_PARAM_TYPE params;
1087     if (compClass == audio_decoder || compClass == audio_encoder) {
1088         status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
1089     } else {
1090         status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
1091     }
1092     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1093         ASSERT_EQ(params.nPorts, 2U);
1094         portBase = params.nStartPortNumber;
1095     }
1096 
1097     // disable invalid port, expecting OMX_ErrorBadPortIndex
1098     status = omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable),
1099                                   RANDOM_INDEX);
1100     ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
1101 
1102     // enable invalid port, expecting OMX_ErrorBadPortIndex
1103     status = omxNode->sendCommand(toRawCommandType(OMX_CommandPortEnable),
1104                                   RANDOM_INDEX);
1105     ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
1106 
1107     // disable all ports
1108     status =
1109         omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), OMX_ALL);
1110     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
1111     for (size_t i = 0; i < 2; i++) {
1112         status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT);
1113         ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
1114         ASSERT_EQ(msg.type, Message::Type::EVENT);
1115         if (msg.data.eventData.event == OMX_EventCmdComplete) {
1116             ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
1117             if (msg.data.eventData.data2 != portBase ||
1118                 msg.data.eventData.data2 != portBase + 1)
1119                 EXPECT_TRUE(false);
1120         } else if (msg.data.eventData.event == OMX_EventError) {
1121             ALOGE("Port %d Disabling failed with error %d", (int)i,
1122                   (int)msg.data.eventData.event);
1123         } else {
1124             // something unexpected happened
1125             ASSERT_TRUE(false);
1126         }
1127     }
1128 
1129     // enable all ports
1130     status =
1131         omxNode->sendCommand(toRawCommandType(OMX_CommandPortEnable), OMX_ALL);
1132     ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
1133     for (size_t i = 0; i < 2; i++) {
1134         status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT);
1135         ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
1136         ASSERT_EQ(msg.type, Message::Type::EVENT);
1137         if (msg.data.eventData.event == OMX_EventCmdComplete) {
1138             ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
1139             if (msg.data.eventData.data2 != portBase ||
1140                 msg.data.eventData.data2 != portBase + 1)
1141                 EXPECT_TRUE(false);
1142         } else if (msg.data.eventData.event == OMX_EventError) {
1143             ALOGE("Port %d Enabling failed with error %d", (int)i,
1144                   (int)msg.data.eventData.event);
1145         } else {
1146             // something unexpected happened
1147             ASSERT_TRUE(false);
1148         }
1149     }
1150 }
1151 
main(int argc,char ** argv)1152 int main(int argc, char** argv) {
1153     gEnv = new ComponentTestEnvironment();
1154     ::testing::AddGlobalTestEnvironment(gEnv);
1155     ::testing::InitGoogleTest(&argc, argv);
1156     int status = gEnv->initFromOptions(argc, argv);
1157     if (status == 0) {
1158         status = RUN_ALL_TESTS();
1159         ALOGI("Test result = %d", status);
1160     }
1161     return status;
1162 }
1163