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: 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 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: 82 static void description(const std::string& description) { 83 RecordProperty("description", description); 84 } 85 }; 86 87 // Test Empty Flush 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 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 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 [¶ms](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 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 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