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