• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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_NDEBUG 0
18 #define LOG_TAG "codec2_hidl_hal_component_test"
19 
20 #include <android-base/logging.h>
21 #include <gtest/gtest.h>
22 
23 #include <hardware/google/media/c2/1.0/IComponent.h>
24 #include <hardware/google/media/c2/1.0/IComponentStore.h>
25 
26 using ::hardware::google::media::c2::V1_0::IComponent;
27 using ::hardware::google::media::c2::V1_0::IComponentStore;
28 using ::hardware::google::media::c2::V1_0::IComponentInterface;
29 using ::hardware::google::media::c2::V1_0::FieldSupportedValuesQuery;
30 using ::hardware::google::media::c2::V1_0::FieldSupportedValuesQueryResult;
31 using ::hardware::google::media::c2::V1_0::ParamDescriptor;
32 using ::hardware::google::media::c2::V1_0::SettingResult;
33 using ::android::hardware::hidl_vec;
34 using ::android::hardware::hidl_string;
35 using ::android::sp;
36 
37 #include <VtsHalHidlTargetTestBase.h>
38 #include "media_c2_hidl_test_common.h"
39 
40 static ComponentTestEnvironment* gEnv = nullptr;
41 
42 namespace {
43 
44 // google.codec2 Component test setup
45 class Codec2ComponentHalTest : public ::testing::VtsHalHidlTargetTestBase {
46    private:
47     typedef ::testing::VtsHalHidlTargetTestBase Super;
48 
49    public:
SetUp()50     virtual void SetUp() override {
51         Super::SetUp();
52         mStore = Super::getService<IComponentStore>(gEnv->getInstance());
53         ASSERT_NE(mStore, nullptr);
54         mListener = new CodecListener();
55         ASSERT_NE(mListener, nullptr);
56         mStore->createComponent(gEnv->getComponent().c_str(), mListener,
57                                 nullptr,
58                                 [&](Status _s, const sp<IComponent>& _nl) {
59                                     ASSERT_EQ(_s, Status::OK);
60                                     this->mComponent = _nl;
61                                 });
62         ASSERT_NE(mComponent, nullptr);
63     }
64 
TearDown()65     virtual void TearDown() override {
66         if (mComponent != nullptr) {
67             // If you have encountered a fatal failure, it is possible that
68             // freeNode() will not go through. Instead of hanging the app.
69             // let it pass through and report errors
70             if (::testing::Test::HasFatalFailure()) return;
71             mComponent->release();
72             mComponent = nullptr;
73         }
74         Super::TearDown();
75     }
76 
77     sp<IComponent> mComponent;
78     sp<IComponentStore> mStore;
79     sp<CodecListener> mListener;
80 
81    protected:
description(const std::string & description)82     static void description(const std::string& description) {
83         RecordProperty("description", description);
84     }
85 };
86 
87 // Test Empty Flush
TEST_F(Codec2ComponentHalTest,EmptyFlush)88 TEST_F(Codec2ComponentHalTest, EmptyFlush) {
89     ALOGV("Empty Flush Test");
90     Status err = mComponent->start();
91     ASSERT_EQ(err, Status::OK);
92 
93     // Flushed output expected to be of 0 size, as no input has been fed
94     mComponent->flush([&](Status _s, const WorkBundle& _flushedWorkBundle) {
95         ASSERT_EQ(_s, Status::OK);
96         ASSERT_EQ(_flushedWorkBundle.works.size(), 0u)
97             << "Invalid Flushed Work Size";
98         ASSERT_EQ(_flushedWorkBundle.baseBlocks.size(), 0u);
99     });
100 }
101 
102 // Test Queue Empty Work
TEST_F(Codec2ComponentHalTest,QueueEmptyWork)103 TEST_F(Codec2ComponentHalTest, QueueEmptyWork) {
104     ALOGV("Queue Empty Work Test");
105     Status err = mComponent->start();
106     ASSERT_EQ(err, Status::OK);
107 
108     // Queueing an empty WorkBundle
109     const WorkBundle workBundle = {};
110     err = mComponent->queue(workBundle);
111     ASSERT_EQ(err, Status::OK);
112 
113     err = mComponent->reset();
114     ASSERT_EQ(err, Status::OK);
115 }
116 
117 // Test Component Configuration
TEST_F(Codec2ComponentHalTest,Config)118 TEST_F(Codec2ComponentHalTest, Config) {
119     ALOGV("Configuration Test");
120     mComponent->getName([](const hidl_string& name) {
121         EXPECT_NE(name.empty(), true) << "Invalid Component Store Name";
122         ALOGV("Component under Test %s", name.c_str());
123     });
124 
125 #define MAX_PARAMS 64
126     /* Querry Supported Params */
127     hidl_vec<ParamDescriptor> params;
128     mComponent->querySupportedParams(
129         0, MAX_PARAMS,
130         [&params](Status _s, const hidl_vec<ParamDescriptor>& _p) {
131             ASSERT_EQ(_s, Status::OK);
132             params = _p;
133             ALOGE("TEMP - Params capacity - %zu", _p.size());
134         });
135 
136     std::vector<uint32_t> tempIndices;
137     std::vector<FieldSupportedValuesQuery> tempInFields;
138     for (size_t i = 0; i < params.size(); i++) {
139         EXPECT_NE(params[i].name.empty(), true)
140             << "Invalid Supported Param Name";
141         ALOGV("Params Supported : %s", params[i].name.c_str());
142         tempIndices.push_back(params[i].index);
143         FieldSupportedValuesQuery tempFSV;
144         tempFSV.field.index = params[i].index;
145         tempInFields.push_back(tempFSV);
146     }
147 
148 
149     /* Query Supported Values */
150     const hidl_vec<FieldSupportedValuesQuery> inFields = tempInFields;
151     bool mayBlock = false;
152     hidl_vec<FieldSupportedValuesQueryResult> outFields;
153     mComponent->querySupportedValues(
154         inFields, mayBlock,
155         [&outFields](
156             Status _s,
157             const hidl_vec<FieldSupportedValuesQueryResult>& _outFields) {
158             ASSERT_EQ(_s, Status::OK);
159             outFields = _outFields;
160         });
161 
162     // Fileds size should match
163     ASSERT_EQ(inFields.size(), outFields.size());
164 
165     /* TODO: How to give proper indices */
166     const hidl_vec<uint32_t> indices = tempIndices;
167     hidl_vec<uint8_t> inParamsQuery;
168     mComponent->query(indices, mayBlock,
169                       [&inParamsQuery](Status _s, const hidl_vec<uint8_t>& _p) {
170                           ASSERT_EQ(_s, Status::OK);
171                           inParamsQuery = _p;
172                       });
173 
174     /* Config default parameters*/
175     const hidl_vec<uint8_t> inParams = inParamsQuery;
176     hidl_vec<uint8_t> outParamsQuery;
177     mComponent->config(
178         inParams, mayBlock,
179         [&outParamsQuery](Status _s, const hidl_vec<SettingResult>& _f,
180                           const hidl_vec<uint8_t>& _outParams) {
181             ASSERT_EQ(_s, Status::OK);
182             // There should be no failures, since default config is reapplied
183             ASSERT_EQ(_f.size(), 0u);
184             outParamsQuery = _outParams;
185         });
186 
187     // Fileds size should match
188     ASSERT_EQ(inParams.size(), outParamsQuery.size());
189 }
190 
191 // Test Multiple Start Stop Reset Test
TEST_F(Codec2ComponentHalTest,MultipleStartStopReset)192 TEST_F(Codec2ComponentHalTest, MultipleStartStopReset) {
193     ALOGV("Multiple Start Stop and Reset Test");
194     Status err = Status::OK;
195 
196 #define MAX_RETRY 16
197 
198     for (size_t i = 0; i < MAX_RETRY; i++) {
199         err = mComponent->start();
200         ASSERT_EQ(err, Status::OK);
201 
202         err = mComponent->stop();
203         ASSERT_EQ(err, Status::OK);
204     }
205 
206     err = mComponent->start();
207     ASSERT_EQ(err, Status::OK);
208 
209     for (size_t i = 0; i < MAX_RETRY; i++) {
210         err = mComponent->reset();
211         ASSERT_EQ(err, Status::OK);
212     }
213 
214     err = mComponent->start();
215     ASSERT_EQ(err, Status::OK);
216 
217     err = mComponent->stop();
218     ASSERT_EQ(err, Status::OK);
219 
220     // Second stop should return error
221     err = mComponent->stop();
222     ASSERT_NE(err, Status::OK);
223 }
224 
225 }  // anonymous namespace
226 
227 // TODO: Add test for Invalid work, Invalid Config handling
228 // TODO: Add test for Invalid states
main(int argc,char ** argv)229 int main(int argc, char** argv) {
230     gEnv = new ComponentTestEnvironment();
231     ::testing::AddGlobalTestEnvironment(gEnv);
232     ::testing::InitGoogleTest(&argc, argv);
233     gEnv->init(&argc, argv);
234     int status = gEnv->initFromOptions(argc, argv);
235     if (status == 0) {
236         status = RUN_ALL_TESTS();
237         LOG(INFO) << "C2 Test result = " << status;
238     }
239     return status;
240 }
241 
242