OSDN Git Service

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