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