OSDN Git Service

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