Loading tv/input/aidl/vts/functional/Android.bp 0 → 100644 +29 −0 Original line number Diff line number Diff line package { // See: http://go/android-license-faq // A large-scale-change added 'default_applicable_licenses' to import // all of the 'license_kinds' from "hardware_interfaces_license" // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["hardware_interfaces_license"], } cc_test { name: "VtsHalTvInputTargetTest", defaults: ["VtsHalTargetTestDefaults","use_libaidlvintf_gtest_helper_static",], srcs: ["VtsHalTvInputTargetTest.cpp"], static_libs: [ "android.hardware.tv.input-V1-ndk", "android.media.audio.common.types-V1-ndk", "android.hardware.common-V2-ndk", "libaidlcommonsupport", ], test_suites: [ "general-tests", "vts", ], shared_libs: [ "libbinder_ndk", "libvndksupport", ], require_root: true, } tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp 0 → 100644 +296 −0 Original line number Diff line number Diff line /* * Copyright 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "VtsHalTvInputTargetTest.h" #include <android-base/properties.h> #include <android/binder_ibinder.h> #include <android/binder_process.h> #include <android/binder_status.h> using namespace VtsHalTvInputTargetTest; TvInputAidlTest::TvInputCallback::TvInputCallback(shared_ptr<TvInputAidlTest> parent) : parent_(parent) {} ::ndk::ScopedAStatus TvInputAidlTest::TvInputCallback::notify(const TvInputEvent& in_event) { unique_lock<mutex> lock(parent_->mutex_); switch (in_event.type) { case TvInputEventType::DEVICE_AVAILABLE: parent_->onDeviceAvailable(in_event.deviceInfo); break; case TvInputEventType::DEVICE_UNAVAILABLE: parent_->onDeviceUnavailable(in_event.deviceInfo.deviceId); break; case TvInputEventType::STREAM_CONFIGURATIONS_CHANGED: parent_->onStreamConfigurationsChanged(in_event.deviceInfo.deviceId); break; } return ::ndk::ScopedAStatus::ok(); } void TvInputAidlTest::SetUp() { if (AServiceManager_isDeclared(GetParam().c_str())) { ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str())); tv_input_ = ITvInput::fromBinder(binder); } else { tv_input_ = nullptr; } ASSERT_NE(tv_input_, nullptr); tv_input_callback_ = ::ndk::SharedRefBase::make<TvInputCallback>(shared_ptr<TvInputAidlTest>(this)); ASSERT_NE(tv_input_callback_, nullptr); tv_input_->setCallback(tv_input_callback_); // All events received within the timeout should be handled. sleep(WAIT_FOR_EVENT_TIMEOUT); } void TvInputAidlTest::TearDown() { tv_input_ = nullptr; } void TvInputAidlTest::onDeviceAvailable(const TvInputDeviceInfo& deviceInfo) { ALOGD("onDeviceAvailable for device id %d", deviceInfo.deviceId); device_info_.add(deviceInfo.deviceId, deviceInfo); } void TvInputAidlTest::onDeviceUnavailable(int32_t deviceId) { ALOGD("onDeviceUnavailable for device id %d", deviceId); device_info_.removeItem(deviceId); stream_config_.removeItem(deviceId); } ::ndk::ScopedAStatus TvInputAidlTest::onStreamConfigurationsChanged(int32_t deviceId) { ALOGD("onStreamConfigurationsChanged for device id %d", deviceId); return updateStreamConfigurations(deviceId); } ::ndk::ScopedAStatus TvInputAidlTest::updateStreamConfigurations(int32_t deviceId) { stream_config_.removeItem(deviceId); vector<TvStreamConfig> list; ::ndk::ScopedAStatus status = tv_input_->getStreamConfigurations(deviceId, &list); if (status.isOk()) { stream_config_.add(deviceId, list); } return status; } void TvInputAidlTest::updateAllStreamConfigurations() { for (size_t i = 0; i < device_info_.size(); i++) { int32_t device_id = device_info_.keyAt(i); updateStreamConfigurations(device_id); } } vector<size_t> TvInputAidlTest::getConfigIndices() { vector<size_t> indices; for (size_t i = 0; i < stream_config_.size(); i++) { if (stream_config_.valueAt(i).size() != 0) { indices.push_back(i); } } return indices; } int32_t TvInputAidlTest::getNumNotIn(vector<int32_t>& nums) { int32_t result = DEFAULT_ID; int32_t size = static_cast<int32_t>(nums.size()); for (int32_t i = 0; i < size; i++) { // Put every element to its target position, if possible. int32_t target_pos = nums[i]; while (target_pos >= 0 && target_pos < size && i != target_pos && nums[i] != nums[target_pos]) { swap(nums[i], nums[target_pos]); target_pos = nums[i]; } } for (int32_t i = 0; i < size; i++) { if (nums[i] != i) { return i; } } return result; } /* * GetStreamConfigTest: * Calls updateStreamConfigurations() for each existing device * Checks returned results */ TEST_P(TvInputAidlTest, GetStreamConfigTest) { unique_lock<mutex> lock(mutex_); for (size_t i = 0; i < device_info_.size(); i++) { int32_t device_id = device_info_.keyAt(i); ALOGD("GetStreamConfigTest: device_id=%d", device_id); ASSERT_TRUE(updateStreamConfigurations(device_id).isOk()); } } /* * OpenAndCloseStreamTest: * Calls openStream() and then closeStream() for each existing stream * Checks returned results */ TEST_P(TvInputAidlTest, OpenAndCloseStreamTest) { unique_lock<mutex> lock(mutex_); updateAllStreamConfigurations(); for (size_t j = 0; j < stream_config_.size(); j++) { int32_t device_id = stream_config_.keyAt(j); vector<TvStreamConfig> config = stream_config_.valueAt(j); for (size_t i = 0; i < config.size(); i++) { int32_t stream_id = config[i].streamId; ALOGD("OpenAndCloseStreamTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id); ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle_).isOk()); ALOGD("OpenAndCloseStreamTest: close stream, device_id=%d, stream_id=%d", device_id, stream_id); ASSERT_TRUE(tv_input_->closeStream(device_id, stream_id).isOk()); } } } /* * InvalidDeviceIdTest: * Calls updateStreamConfigurations(), openStream(), and closeStream() * for a non-existing device * Checks returned results * The results should be ITvInput::STATUS_INVALID_ARGUMENTS */ TEST_P(TvInputAidlTest, InvalidDeviceIdTest) { unique_lock<mutex> lock(mutex_); vector<int32_t> device_ids; for (size_t i = 0; i < device_info_.size(); i++) { device_ids.push_back(device_info_.keyAt(i)); } // Get a non-existing device ID. int32_t id = getNumNotIn(device_ids); ALOGD("InvalidDeviceIdTest: update stream config, device_id=%d", id); ASSERT_TRUE(updateStreamConfigurations(id).getServiceSpecificError() == ITvInput::STATUS_INVALID_ARGUMENTS); int32_t stream_id = 0; ALOGD("InvalidDeviceIdTest: open stream, device_id=%d, stream_id=%d", id, stream_id); ASSERT_TRUE(tv_input_->openStream(id, stream_id, &handle_).getServiceSpecificError() == ITvInput::STATUS_INVALID_ARGUMENTS); ALOGD("InvalidDeviceIdTest: close stream, device_id=%d, stream_id=%d", id, stream_id); ASSERT_TRUE(tv_input_->closeStream(id, stream_id).getServiceSpecificError() == ITvInput::STATUS_INVALID_ARGUMENTS); } /* * InvalidStreamIdTest: * Calls openStream(), and closeStream() for a non-existing stream * Checks returned results * The results should be ITvInput::STATUS_INVALID_ARGUMENTS */ TEST_P(TvInputAidlTest, InvalidStreamIdTest) { unique_lock<mutex> lock(mutex_); if (device_info_.isEmpty()) { return; } updateAllStreamConfigurations(); int32_t device_id = device_info_.keyAt(0); // Get a non-existing stream ID. int32_t id = DEFAULT_ID; if (stream_config_.indexOfKey(device_id) >= 0) { vector<int32_t> stream_ids; vector<TvStreamConfig> config = stream_config_.valueFor(device_id); for (size_t i = 0; i < config.size(); i++) { stream_ids.push_back(config[i].streamId); } id = getNumNotIn(stream_ids); } ALOGD("InvalidStreamIdTest: open stream, device_id=%d, stream_id=%d", device_id, id); ASSERT_TRUE(tv_input_->openStream(device_id, id, &handle_).getServiceSpecificError() == ITvInput::STATUS_INVALID_ARGUMENTS); ALOGD("InvalidStreamIdTest: close stream, device_id=%d, stream_id=%d", device_id, id); ASSERT_TRUE(tv_input_->closeStream(device_id, id).getServiceSpecificError() == ITvInput::STATUS_INVALID_ARGUMENTS); } /* * OpenAnOpenedStreamsTest: * Calls openStream() twice for a stream (if any) * Checks returned results * The result of the second call should be ITvInput::STATUS_INVALID_STATE */ TEST_P(TvInputAidlTest, OpenAnOpenedStreamsTest) { unique_lock<mutex> lock(mutex_); updateAllStreamConfigurations(); vector<size_t> indices = getConfigIndices(); if (indices.empty()) { return; } int32_t device_id = stream_config_.keyAt(indices[0]); int32_t stream_id = stream_config_.valueAt(indices[0])[0].streamId; ALOGD("OpenAnOpenedStreamsTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id); ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle_).isOk()); ALOGD("OpenAnOpenedStreamsTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id); ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle_).getServiceSpecificError() == ITvInput::STATUS_INVALID_STATE); // close stream as subsequent tests assume no open streams ALOGD("OpenAnOpenedStreamsTest: close stream, device_id=%d, stream_id=%d", device_id, stream_id); ASSERT_TRUE(tv_input_->closeStream(device_id, stream_id).isOk()); } /* * CloseStreamBeforeOpenTest: * Calls closeStream() without calling openStream() for a stream (if any) * Checks the returned result * The result should be ITvInput::STATUS_INVALID_STATE */ TEST_P(TvInputAidlTest, CloseStreamBeforeOpenTest) { unique_lock<mutex> lock(mutex_); updateAllStreamConfigurations(); vector<size_t> indices = getConfigIndices(); if (indices.empty()) { return; } int32_t device_id = stream_config_.keyAt(indices[0]); int32_t stream_id = stream_config_.valueAt(indices[0])[0].streamId; ALOGD("CloseStreamBeforeOpenTest: close stream, device_id=%d, stream_id=%d", device_id, stream_id); ASSERT_TRUE(tv_input_->closeStream(device_id, stream_id).getServiceSpecificError() == ITvInput::STATUS_INVALID_STATE); } INSTANTIATE_TEST_SUITE_P(PerInstance, TvInputAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(ITvInput::descriptor)), android::PrintInstanceNameToString); // TODO remove from the allow list once the cf tv target is enabled for testing GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TvInputAidlTest); tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * Copyright 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <android/binder_manager.h> #include <aidl/Gtest.h> #include <aidl/Vintf.h> #include <aidl/android/hardware/tv/input/BnTvInputCallback.h> #include <aidl/android/hardware/tv/input/ITvInput.h> #include <aidl/android/hardware/tv/input/TvInputDeviceInfo.h> #include <aidl/android/hardware/tv/input/TvInputEvent.h> #include <aidl/android/hardware/tv/input/TvStreamConfig.h> #include <log/log.h> #include <utils/KeyedVector.h> using namespace aidl::android::hardware::tv::input; using namespace std; using ::aidl::android::hardware::common::NativeHandle; #define WAIT_FOR_EVENT_TIMEOUT 5 #define DEFAULT_ID INT32_MIN namespace VtsHalTvInputTargetTest { class TvInputAidlTest : public testing::TestWithParam<string> { public: class TvInputCallback : public BnTvInputCallback { public: TvInputCallback(shared_ptr<TvInputAidlTest> parent); ::ndk::ScopedAStatus notify(const TvInputEvent& in_event) override; private: shared_ptr<TvInputAidlTest> parent_; }; virtual void SetUp() override; virtual void TearDown() override; /* Called when a DEVICE_AVAILABLE event is received. */ void onDeviceAvailable(const TvInputDeviceInfo& deviceInfo); /* Called when a DEVICE_UNAVAILABLE event is received. */ void onDeviceUnavailable(int32_t deviceId); /* Called when a STREAM_CONFIGURATIONS_CHANGED event is received. */ ::ndk::ScopedAStatus onStreamConfigurationsChanged(int32_t deviceId); /* Gets and updates the stream configurations for a device. */ ::ndk::ScopedAStatus updateStreamConfigurations(int32_t deviceId); /* Gets and updates the stream configurations for all existing devices. */ void updateAllStreamConfigurations(); /* Returns a list of indices of stream_config_ whose corresponding values are not empty. */ vector<size_t> getConfigIndices(); /* * Returns DEFAULT_ID if there is no missing integer in the range [0, the size of nums). * Otherwise, returns the smallest missing non-negative integer. */ int32_t getNumNotIn(vector<int32_t>& nums); protected: shared_ptr<ITvInput> tv_input_; shared_ptr<TvInputCallback> tv_input_callback_; android::KeyedVector<int32_t, TvInputDeviceInfo> device_info_; android::KeyedVector<int32_t, vector<TvStreamConfig>> stream_config_; mutex mutex_; NativeHandle handle_; }; } // namespace VtsHalTvInputTargetTest Loading
tv/input/aidl/vts/functional/Android.bp 0 → 100644 +29 −0 Original line number Diff line number Diff line package { // See: http://go/android-license-faq // A large-scale-change added 'default_applicable_licenses' to import // all of the 'license_kinds' from "hardware_interfaces_license" // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["hardware_interfaces_license"], } cc_test { name: "VtsHalTvInputTargetTest", defaults: ["VtsHalTargetTestDefaults","use_libaidlvintf_gtest_helper_static",], srcs: ["VtsHalTvInputTargetTest.cpp"], static_libs: [ "android.hardware.tv.input-V1-ndk", "android.media.audio.common.types-V1-ndk", "android.hardware.common-V2-ndk", "libaidlcommonsupport", ], test_suites: [ "general-tests", "vts", ], shared_libs: [ "libbinder_ndk", "libvndksupport", ], require_root: true, }
tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp 0 → 100644 +296 −0 Original line number Diff line number Diff line /* * Copyright 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "VtsHalTvInputTargetTest.h" #include <android-base/properties.h> #include <android/binder_ibinder.h> #include <android/binder_process.h> #include <android/binder_status.h> using namespace VtsHalTvInputTargetTest; TvInputAidlTest::TvInputCallback::TvInputCallback(shared_ptr<TvInputAidlTest> parent) : parent_(parent) {} ::ndk::ScopedAStatus TvInputAidlTest::TvInputCallback::notify(const TvInputEvent& in_event) { unique_lock<mutex> lock(parent_->mutex_); switch (in_event.type) { case TvInputEventType::DEVICE_AVAILABLE: parent_->onDeviceAvailable(in_event.deviceInfo); break; case TvInputEventType::DEVICE_UNAVAILABLE: parent_->onDeviceUnavailable(in_event.deviceInfo.deviceId); break; case TvInputEventType::STREAM_CONFIGURATIONS_CHANGED: parent_->onStreamConfigurationsChanged(in_event.deviceInfo.deviceId); break; } return ::ndk::ScopedAStatus::ok(); } void TvInputAidlTest::SetUp() { if (AServiceManager_isDeclared(GetParam().c_str())) { ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str())); tv_input_ = ITvInput::fromBinder(binder); } else { tv_input_ = nullptr; } ASSERT_NE(tv_input_, nullptr); tv_input_callback_ = ::ndk::SharedRefBase::make<TvInputCallback>(shared_ptr<TvInputAidlTest>(this)); ASSERT_NE(tv_input_callback_, nullptr); tv_input_->setCallback(tv_input_callback_); // All events received within the timeout should be handled. sleep(WAIT_FOR_EVENT_TIMEOUT); } void TvInputAidlTest::TearDown() { tv_input_ = nullptr; } void TvInputAidlTest::onDeviceAvailable(const TvInputDeviceInfo& deviceInfo) { ALOGD("onDeviceAvailable for device id %d", deviceInfo.deviceId); device_info_.add(deviceInfo.deviceId, deviceInfo); } void TvInputAidlTest::onDeviceUnavailable(int32_t deviceId) { ALOGD("onDeviceUnavailable for device id %d", deviceId); device_info_.removeItem(deviceId); stream_config_.removeItem(deviceId); } ::ndk::ScopedAStatus TvInputAidlTest::onStreamConfigurationsChanged(int32_t deviceId) { ALOGD("onStreamConfigurationsChanged for device id %d", deviceId); return updateStreamConfigurations(deviceId); } ::ndk::ScopedAStatus TvInputAidlTest::updateStreamConfigurations(int32_t deviceId) { stream_config_.removeItem(deviceId); vector<TvStreamConfig> list; ::ndk::ScopedAStatus status = tv_input_->getStreamConfigurations(deviceId, &list); if (status.isOk()) { stream_config_.add(deviceId, list); } return status; } void TvInputAidlTest::updateAllStreamConfigurations() { for (size_t i = 0; i < device_info_.size(); i++) { int32_t device_id = device_info_.keyAt(i); updateStreamConfigurations(device_id); } } vector<size_t> TvInputAidlTest::getConfigIndices() { vector<size_t> indices; for (size_t i = 0; i < stream_config_.size(); i++) { if (stream_config_.valueAt(i).size() != 0) { indices.push_back(i); } } return indices; } int32_t TvInputAidlTest::getNumNotIn(vector<int32_t>& nums) { int32_t result = DEFAULT_ID; int32_t size = static_cast<int32_t>(nums.size()); for (int32_t i = 0; i < size; i++) { // Put every element to its target position, if possible. int32_t target_pos = nums[i]; while (target_pos >= 0 && target_pos < size && i != target_pos && nums[i] != nums[target_pos]) { swap(nums[i], nums[target_pos]); target_pos = nums[i]; } } for (int32_t i = 0; i < size; i++) { if (nums[i] != i) { return i; } } return result; } /* * GetStreamConfigTest: * Calls updateStreamConfigurations() for each existing device * Checks returned results */ TEST_P(TvInputAidlTest, GetStreamConfigTest) { unique_lock<mutex> lock(mutex_); for (size_t i = 0; i < device_info_.size(); i++) { int32_t device_id = device_info_.keyAt(i); ALOGD("GetStreamConfigTest: device_id=%d", device_id); ASSERT_TRUE(updateStreamConfigurations(device_id).isOk()); } } /* * OpenAndCloseStreamTest: * Calls openStream() and then closeStream() for each existing stream * Checks returned results */ TEST_P(TvInputAidlTest, OpenAndCloseStreamTest) { unique_lock<mutex> lock(mutex_); updateAllStreamConfigurations(); for (size_t j = 0; j < stream_config_.size(); j++) { int32_t device_id = stream_config_.keyAt(j); vector<TvStreamConfig> config = stream_config_.valueAt(j); for (size_t i = 0; i < config.size(); i++) { int32_t stream_id = config[i].streamId; ALOGD("OpenAndCloseStreamTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id); ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle_).isOk()); ALOGD("OpenAndCloseStreamTest: close stream, device_id=%d, stream_id=%d", device_id, stream_id); ASSERT_TRUE(tv_input_->closeStream(device_id, stream_id).isOk()); } } } /* * InvalidDeviceIdTest: * Calls updateStreamConfigurations(), openStream(), and closeStream() * for a non-existing device * Checks returned results * The results should be ITvInput::STATUS_INVALID_ARGUMENTS */ TEST_P(TvInputAidlTest, InvalidDeviceIdTest) { unique_lock<mutex> lock(mutex_); vector<int32_t> device_ids; for (size_t i = 0; i < device_info_.size(); i++) { device_ids.push_back(device_info_.keyAt(i)); } // Get a non-existing device ID. int32_t id = getNumNotIn(device_ids); ALOGD("InvalidDeviceIdTest: update stream config, device_id=%d", id); ASSERT_TRUE(updateStreamConfigurations(id).getServiceSpecificError() == ITvInput::STATUS_INVALID_ARGUMENTS); int32_t stream_id = 0; ALOGD("InvalidDeviceIdTest: open stream, device_id=%d, stream_id=%d", id, stream_id); ASSERT_TRUE(tv_input_->openStream(id, stream_id, &handle_).getServiceSpecificError() == ITvInput::STATUS_INVALID_ARGUMENTS); ALOGD("InvalidDeviceIdTest: close stream, device_id=%d, stream_id=%d", id, stream_id); ASSERT_TRUE(tv_input_->closeStream(id, stream_id).getServiceSpecificError() == ITvInput::STATUS_INVALID_ARGUMENTS); } /* * InvalidStreamIdTest: * Calls openStream(), and closeStream() for a non-existing stream * Checks returned results * The results should be ITvInput::STATUS_INVALID_ARGUMENTS */ TEST_P(TvInputAidlTest, InvalidStreamIdTest) { unique_lock<mutex> lock(mutex_); if (device_info_.isEmpty()) { return; } updateAllStreamConfigurations(); int32_t device_id = device_info_.keyAt(0); // Get a non-existing stream ID. int32_t id = DEFAULT_ID; if (stream_config_.indexOfKey(device_id) >= 0) { vector<int32_t> stream_ids; vector<TvStreamConfig> config = stream_config_.valueFor(device_id); for (size_t i = 0; i < config.size(); i++) { stream_ids.push_back(config[i].streamId); } id = getNumNotIn(stream_ids); } ALOGD("InvalidStreamIdTest: open stream, device_id=%d, stream_id=%d", device_id, id); ASSERT_TRUE(tv_input_->openStream(device_id, id, &handle_).getServiceSpecificError() == ITvInput::STATUS_INVALID_ARGUMENTS); ALOGD("InvalidStreamIdTest: close stream, device_id=%d, stream_id=%d", device_id, id); ASSERT_TRUE(tv_input_->closeStream(device_id, id).getServiceSpecificError() == ITvInput::STATUS_INVALID_ARGUMENTS); } /* * OpenAnOpenedStreamsTest: * Calls openStream() twice for a stream (if any) * Checks returned results * The result of the second call should be ITvInput::STATUS_INVALID_STATE */ TEST_P(TvInputAidlTest, OpenAnOpenedStreamsTest) { unique_lock<mutex> lock(mutex_); updateAllStreamConfigurations(); vector<size_t> indices = getConfigIndices(); if (indices.empty()) { return; } int32_t device_id = stream_config_.keyAt(indices[0]); int32_t stream_id = stream_config_.valueAt(indices[0])[0].streamId; ALOGD("OpenAnOpenedStreamsTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id); ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle_).isOk()); ALOGD("OpenAnOpenedStreamsTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id); ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle_).getServiceSpecificError() == ITvInput::STATUS_INVALID_STATE); // close stream as subsequent tests assume no open streams ALOGD("OpenAnOpenedStreamsTest: close stream, device_id=%d, stream_id=%d", device_id, stream_id); ASSERT_TRUE(tv_input_->closeStream(device_id, stream_id).isOk()); } /* * CloseStreamBeforeOpenTest: * Calls closeStream() without calling openStream() for a stream (if any) * Checks the returned result * The result should be ITvInput::STATUS_INVALID_STATE */ TEST_P(TvInputAidlTest, CloseStreamBeforeOpenTest) { unique_lock<mutex> lock(mutex_); updateAllStreamConfigurations(); vector<size_t> indices = getConfigIndices(); if (indices.empty()) { return; } int32_t device_id = stream_config_.keyAt(indices[0]); int32_t stream_id = stream_config_.valueAt(indices[0])[0].streamId; ALOGD("CloseStreamBeforeOpenTest: close stream, device_id=%d, stream_id=%d", device_id, stream_id); ASSERT_TRUE(tv_input_->closeStream(device_id, stream_id).getServiceSpecificError() == ITvInput::STATUS_INVALID_STATE); } INSTANTIATE_TEST_SUITE_P(PerInstance, TvInputAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(ITvInput::descriptor)), android::PrintInstanceNameToString); // TODO remove from the allow list once the cf tv target is enabled for testing GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TvInputAidlTest);
tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * Copyright 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <android/binder_manager.h> #include <aidl/Gtest.h> #include <aidl/Vintf.h> #include <aidl/android/hardware/tv/input/BnTvInputCallback.h> #include <aidl/android/hardware/tv/input/ITvInput.h> #include <aidl/android/hardware/tv/input/TvInputDeviceInfo.h> #include <aidl/android/hardware/tv/input/TvInputEvent.h> #include <aidl/android/hardware/tv/input/TvStreamConfig.h> #include <log/log.h> #include <utils/KeyedVector.h> using namespace aidl::android::hardware::tv::input; using namespace std; using ::aidl::android::hardware::common::NativeHandle; #define WAIT_FOR_EVENT_TIMEOUT 5 #define DEFAULT_ID INT32_MIN namespace VtsHalTvInputTargetTest { class TvInputAidlTest : public testing::TestWithParam<string> { public: class TvInputCallback : public BnTvInputCallback { public: TvInputCallback(shared_ptr<TvInputAidlTest> parent); ::ndk::ScopedAStatus notify(const TvInputEvent& in_event) override; private: shared_ptr<TvInputAidlTest> parent_; }; virtual void SetUp() override; virtual void TearDown() override; /* Called when a DEVICE_AVAILABLE event is received. */ void onDeviceAvailable(const TvInputDeviceInfo& deviceInfo); /* Called when a DEVICE_UNAVAILABLE event is received. */ void onDeviceUnavailable(int32_t deviceId); /* Called when a STREAM_CONFIGURATIONS_CHANGED event is received. */ ::ndk::ScopedAStatus onStreamConfigurationsChanged(int32_t deviceId); /* Gets and updates the stream configurations for a device. */ ::ndk::ScopedAStatus updateStreamConfigurations(int32_t deviceId); /* Gets and updates the stream configurations for all existing devices. */ void updateAllStreamConfigurations(); /* Returns a list of indices of stream_config_ whose corresponding values are not empty. */ vector<size_t> getConfigIndices(); /* * Returns DEFAULT_ID if there is no missing integer in the range [0, the size of nums). * Otherwise, returns the smallest missing non-negative integer. */ int32_t getNumNotIn(vector<int32_t>& nums); protected: shared_ptr<ITvInput> tv_input_; shared_ptr<TvInputCallback> tv_input_callback_; android::KeyedVector<int32_t, TvInputDeviceInfo> device_info_; android::KeyedVector<int32_t, vector<TvStreamConfig>> stream_config_; mutex mutex_; NativeHandle handle_; }; } // namespace VtsHalTvInputTargetTest