From e4af3c6ddf47e85b0ff573dc151df2ee6b6a8d7b Mon Sep 17 00:00:00 2001 From: Helen Date: Mon, 2 Jan 2023 04:26:31 +0000 Subject: [PATCH] VTS implementation for ImsMediaHal Bug: 263201546 Test: atest VtsHalRadioTargetTest (using cuttlefish) Change-Id: I38eacded9a4523b7c5121f2d759d9b118923bcc7 --- radio/aidl/compat/libradiocompat/Android.bp | 3 + .../ims/media/RadioImsMedia.cpp | 49 ++++ .../ims/media/RadioImsMediaSession.cpp | 64 +++++ .../include/libradiocompat/RadioImsMedia.h | 40 +++ .../libradiocompat/RadioImsMediaSession.h | 47 +++ .../include/libradiocompat/RadioResponse.h | 1 + radio/aidl/compat/service/Android.bp | 1 + radio/aidl/vts/Android.bp | 4 + radio/aidl/vts/VtsHalRadioTargetTest.cpp | 6 + radio/aidl/vts/radio_imsmedia_listener.cpp | 38 +++ .../vts/radio_imsmedia_session_listener.cpp | 51 ++++ radio/aidl/vts/radio_imsmedia_test.cpp | 271 ++++++++++++++++++ radio/aidl/vts/radio_imsmedia_utils.h | 98 +++++++ 13 files changed, 673 insertions(+) create mode 100644 radio/aidl/compat/libradiocompat/ims/media/RadioImsMedia.cpp create mode 100644 radio/aidl/compat/libradiocompat/ims/media/RadioImsMediaSession.cpp create mode 100644 radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMedia.h create mode 100644 radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMediaSession.h create mode 100644 radio/aidl/vts/radio_imsmedia_listener.cpp create mode 100644 radio/aidl/vts/radio_imsmedia_session_listener.cpp create mode 100644 radio/aidl/vts/radio_imsmedia_test.cpp create mode 100644 radio/aidl/vts/radio_imsmedia_utils.h diff --git a/radio/aidl/compat/libradiocompat/Android.bp b/radio/aidl/compat/libradiocompat/Android.bp index 6bbc9fe7b2..9aecf78d38 100644 --- a/radio/aidl/compat/libradiocompat/Android.bp +++ b/radio/aidl/compat/libradiocompat/Android.bp @@ -38,6 +38,7 @@ cc_library { "android.hardware.radio.config@1.3", "android.hardware.radio.data-V2-ndk", "android.hardware.radio.ims-V1-ndk", + "android.hardware.radio.ims.media-V1-ndk", "android.hardware.radio.messaging-V2-ndk", "android.hardware.radio.modem-V2-ndk", "android.hardware.radio.network-V2-ndk", @@ -75,6 +76,8 @@ cc_library { "ims/RadioIndication-ims.cpp", "ims/RadioResponse-ims.cpp", "ims/RadioIms.cpp", + "ims/media/RadioImsMediaSession.cpp", + "ims/media/RadioImsMedia.cpp", "messaging/RadioIndication-messaging.cpp", "messaging/RadioMessaging.cpp", "messaging/RadioResponse-messaging.cpp", diff --git a/radio/aidl/compat/libradiocompat/ims/media/RadioImsMedia.cpp b/radio/aidl/compat/libradiocompat/ims/media/RadioImsMedia.cpp new file mode 100644 index 0000000000..464a410535 --- /dev/null +++ b/radio/aidl/compat/libradiocompat/ims/media/RadioImsMedia.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2023 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 + +#include "commonStructs.h" +#include "debug.h" + +#include "collections.h" + +#define RADIO_MODULE "ImsMedia" + +namespace android::hardware::radio::compat { + +using ::ndk::ScopedAStatus; +constexpr auto ok = &ScopedAStatus::ok; + +ScopedAStatus RadioImsMedia::setListener( + const std::shared_ptr<::aidl::android::hardware::radio::ims::media:: + IImsMediaListener>& /*in_mediaListener*/) { + LOG(ERROR) << " setListener is unsupported by HIDL HALs"; + return ok(); +} +ScopedAStatus RadioImsMedia::openSession( + int32_t /*in_sessionId*/, + const ::aidl::android::hardware::radio::ims::media::LocalEndPoint& /*in_localEndPoint*/, + const ::aidl::android::hardware::radio::ims::media::RtpConfig& /*in_config*/) { + LOG(ERROR) << " openSession is unsupported by HIDL HALs"; + return ok(); +} +ScopedAStatus RadioImsMedia::closeSession(int32_t /*in_sessionId*/) { + LOG(ERROR) << " closeSession is unsupported by HIDL HALs"; + return ok(); +} + +} // namespace android::hardware::radio::compat diff --git a/radio/aidl/compat/libradiocompat/ims/media/RadioImsMediaSession.cpp b/radio/aidl/compat/libradiocompat/ims/media/RadioImsMediaSession.cpp new file mode 100644 index 0000000000..ae86914e27 --- /dev/null +++ b/radio/aidl/compat/libradiocompat/ims/media/RadioImsMediaSession.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2023 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 + +#include "commonStructs.h" +#include "debug.h" + +#include "collections.h" + +#define RADIO_MODULE "ImsMediaSession" + +namespace android::hardware::radio::compat { + +using ::ndk::ScopedAStatus; +namespace aidl = ::aidl::android::hardware::radio::ims::media; +constexpr auto ok = &ScopedAStatus::ok; + +ScopedAStatus RadioImsMediaSession::setListener( + const std::shared_ptr& /*in_sessionListener*/) { + LOG(ERROR) << " setListener is unsupported by HIDL HALs"; + return ok(); +} +ScopedAStatus RadioImsMediaSession::modifySession(const aidl::RtpConfig& /*in_config*/) { + LOG(ERROR) << " modifySession is unsupported by HIDL HALs"; + return ok(); +} +ScopedAStatus RadioImsMediaSession::sendDtmf(char16_t /*in_dtmfDigit*/, int32_t /*in_duration*/) { + LOG(ERROR) << " sendDtmf is unsupported by HIDL HALs"; + return ok(); +} +ScopedAStatus RadioImsMediaSession::startDtmf(char16_t /*in_dtmfDigit*/) { + LOG(ERROR) << " startDtmf is unsupported by HIDL HALs"; + return ok(); +} +ScopedAStatus RadioImsMediaSession::stopDtmf() { + LOG(ERROR) << " stopDtmf is unsupported by HIDL HALs"; + return ok(); +} +ScopedAStatus RadioImsMediaSession::sendHeaderExtension( + const std::vector& /*in_extensions*/) { + LOG(ERROR) << " sendHeaderExtension is unsupported by HIDL HALs"; + return ok(); +} +ScopedAStatus RadioImsMediaSession::setMediaQualityThreshold( + const aidl::MediaQualityThreshold& /*in_threshold*/) { + LOG(ERROR) << " setMediaQualityThreshold is unsupported by HIDL HALs"; + return ok(); +} + +} // namespace android::hardware::radio::compat diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMedia.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMedia.h new file mode 100644 index 0000000000..2ee6bf1a75 --- /dev/null +++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMedia.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2023 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 "RadioCompatBase.h" + +#include + +namespace android::hardware::radio::compat { + +class RadioImsMedia : public RadioCompatBase, + public aidl::android::hardware::radio::ims::media::BnImsMedia { + ::ndk::ScopedAStatus setListener( + const std::shared_ptr<::aidl::android::hardware::radio::ims::media::IImsMediaListener>& + in_mediaListener) override; + ::ndk::ScopedAStatus openSession( + int32_t in_sessionId, + const ::aidl::android::hardware::radio::ims::media::LocalEndPoint& in_localEndPoint, + const ::aidl::android::hardware::radio::ims::media::RtpConfig& in_config) override; + ::ndk::ScopedAStatus closeSession(int32_t in_sessionId) override; + + protected: + public: + using RadioCompatBase::RadioCompatBase; +}; + +} // namespace android::hardware::radio::compat diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMediaSession.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMediaSession.h new file mode 100644 index 0000000000..00f21fc077 --- /dev/null +++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMediaSession.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2023 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 "RadioCompatBase.h" + +#include + +namespace android::hardware::radio::compat { + +class RadioImsMediaSession : public RadioCompatBase, + public aidl::android::hardware::radio::ims::media::BnImsMediaSession { + ::ndk::ScopedAStatus setListener( + const std::shared_ptr< + ::aidl::android::hardware::radio::ims::media::IImsMediaSessionListener>& + in_sessionListener) override; + ::ndk::ScopedAStatus modifySession( + const ::aidl::android::hardware::radio::ims::media::RtpConfig& in_config) override; + ::ndk::ScopedAStatus sendDtmf(char16_t in_dtmfDigit, int32_t in_duration) override; + ::ndk::ScopedAStatus startDtmf(char16_t in_dtmfDigit) override; + ::ndk::ScopedAStatus stopDtmf() override; + ::ndk::ScopedAStatus sendHeaderExtension( + const std::vector<::aidl::android::hardware::radio::ims::media::RtpHeaderExtension>& + in_extensions) override; + ::ndk::ScopedAStatus setMediaQualityThreshold( + const ::aidl::android::hardware::radio::ims::media::MediaQualityThreshold& in_threshold) + override; + + protected: + public: + using RadioCompatBase::RadioCompatBase; +}; + +} // namespace android::hardware::radio::compat diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h index 636c1a4fa1..b976435064 100644 --- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h +++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/radio/aidl/compat/service/Android.bp b/radio/aidl/compat/service/Android.bp index a3717b4304..5d14c85f73 100644 --- a/radio/aidl/compat/service/Android.bp +++ b/radio/aidl/compat/service/Android.bp @@ -41,6 +41,7 @@ cc_binary { "android.hardware.radio.config@1.3", "android.hardware.radio.data-V2-ndk", "android.hardware.radio.ims-V1-ndk", + "android.hardware.radio.ims.media-V1-ndk", "android.hardware.radio.messaging-V2-ndk", "android.hardware.radio.modem-V2-ndk", "android.hardware.radio.network-V2-ndk", diff --git a/radio/aidl/vts/Android.bp b/radio/aidl/vts/Android.bp index 518dfd43e1..f112d6d73a 100644 --- a/radio/aidl/vts/Android.bp +++ b/radio/aidl/vts/Android.bp @@ -44,6 +44,9 @@ cc_test { "radio_ims_indication.cpp", "radio_ims_response.cpp", "radio_ims_test.cpp", + "radio_imsmedia_listener.cpp", + "radio_imsmedia_session_listener.cpp", + "radio_imsmedia_test.cpp", "radio_messaging_indication.cpp", "radio_messaging_response.cpp", "radio_messaging_test.cpp", @@ -75,6 +78,7 @@ cc_test { "android.hardware.radio.config-V2-ndk", "android.hardware.radio.data-V2-ndk", "android.hardware.radio.ims-V1-ndk", + "android.hardware.radio.ims.media-V1-ndk", "android.hardware.radio.messaging-V2-ndk", "android.hardware.radio.modem-V2-ndk", "android.hardware.radio.network-V2-ndk", diff --git a/radio/aidl/vts/VtsHalRadioTargetTest.cpp b/radio/aidl/vts/VtsHalRadioTargetTest.cpp index f718e57038..86c109948a 100644 --- a/radio/aidl/vts/VtsHalRadioTargetTest.cpp +++ b/radio/aidl/vts/VtsHalRadioTargetTest.cpp @@ -19,6 +19,7 @@ #include "radio_config_utils.h" #include "radio_data_utils.h" #include "radio_ims_utils.h" +#include "radio_imsmedia_utils.h" #include "radio_messaging_utils.h" #include "radio_modem_utils.h" #include "radio_network_utils.h" @@ -85,6 +86,11 @@ INSTANTIATE_TEST_SUITE_P( testing::ValuesIn(android::getAidlHalInstanceNames(IRadioSatellite::descriptor)), android::PrintInstanceNameToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioImsMediaTest); +INSTANTIATE_TEST_SUITE_P(PerInstance, RadioImsMediaTest, + testing::ValuesIn(android::getAidlHalInstanceNames(IImsMedia::descriptor)), + android::PrintInstanceNameToString); + int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); ABinderProcess_setThreadPoolMaxThreadCount(1); diff --git a/radio/aidl/vts/radio_imsmedia_listener.cpp b/radio/aidl/vts/radio_imsmedia_listener.cpp new file mode 100644 index 0000000000..78f66a9f4c --- /dev/null +++ b/radio/aidl/vts/radio_imsmedia_listener.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 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 "radio_imsmedia_utils.h" + +ImsMediaListener::ImsMediaListener(RadioServiceTest& parent) : parent_imsmedia(parent) {} + +ndk::ScopedAStatus ImsMediaListener::onOpenSessionSuccess( + int32_t in_sessionId, const std::shared_ptr& in_session) { + mSessionId = in_sessionId; + mSession = in_session; + parent_imsmedia.notify(SERIAL_OPEN_SESSION); + return ndk::ScopedAStatus::ok(); +} +ndk::ScopedAStatus ImsMediaListener::onOpenSessionFailure(int32_t in_sessionId, RtpError in_error) { + mSessionId = in_sessionId; + mError = in_error; + parent_imsmedia.notify(SERIAL_OPEN_SESSION); + return ndk::ScopedAStatus::ok(); +} +ndk::ScopedAStatus ImsMediaListener::onSessionClosed(int32_t in_sessionId) { + mSessionId = in_sessionId; + parent_imsmedia.notify(SERIAL_CLOSE_SESSION); + return ndk::ScopedAStatus::ok(); +} diff --git a/radio/aidl/vts/radio_imsmedia_session_listener.cpp b/radio/aidl/vts/radio_imsmedia_session_listener.cpp new file mode 100644 index 0000000000..986cab24c9 --- /dev/null +++ b/radio/aidl/vts/radio_imsmedia_session_listener.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023 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 "radio_imsmedia_utils.h" + +ImsMediaSessionListener::ImsMediaSessionListener(RadioServiceTest& parent) + : parent_imsmedia(parent) {} + +ndk::ScopedAStatus ImsMediaSessionListener::onModifySessionResponse(const RtpConfig& in_config, + RtpError in_error) { + mConfig = in_config; + mError = in_error; + parent_imsmedia.notify(SERIAL_MODIFY_SESSION); + return ndk::ScopedAStatus::ok(); +} +ndk::ScopedAStatus ImsMediaSessionListener::onFirstMediaPacketReceived( + const RtpConfig& /*in_config*/) { + return ndk::ScopedAStatus::ok(); +} +ndk::ScopedAStatus ImsMediaSessionListener::onHeaderExtensionReceived( + const std::vector& /*in_extensions*/) { + return ndk::ScopedAStatus::ok(); +} +ndk::ScopedAStatus ImsMediaSessionListener::notifyMediaQualityStatus( + const MediaQualityStatus& /*in_quality*/) { + return ndk::ScopedAStatus::ok(); +} +ndk::ScopedAStatus ImsMediaSessionListener::triggerAnbrQuery(const RtpConfig& /*in_config*/) { + return ndk::ScopedAStatus::ok(); +} +ndk::ScopedAStatus ImsMediaSessionListener::onDtmfReceived(char16_t /*in_dtmfDigit*/, + int32_t /*in_durationMs*/) { + return ndk::ScopedAStatus::ok(); +} +ndk::ScopedAStatus ImsMediaSessionListener::onCallQualityChanged( + const CallQuality& /*in_callQuality*/) { + return ndk::ScopedAStatus::ok(); +} diff --git a/radio/aidl/vts/radio_imsmedia_test.cpp b/radio/aidl/vts/radio_imsmedia_test.cpp new file mode 100644 index 0000000000..d9e57c9a63 --- /dev/null +++ b/radio/aidl/vts/radio_imsmedia_test.cpp @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2023 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 +#include +#include +#include + +#include "radio_imsmedia_utils.h" + +#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) + +void RadioImsMediaTest::SetUp() { + std::string serviceName = GetParam(); + + ALOGD("Enter RadioImsMediaTest."); + + radio_imsmedia = IImsMedia::fromBinder( + ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str()))); + ASSERT_NE(nullptr, radio_imsmedia.get()); + + radio_imsmedialistener = ndk::SharedRefBase::make(*this); + ASSERT_NE(nullptr, radio_imsmedialistener.get()); + + radio_imsmediasessionlistener = ndk::SharedRefBase::make(*this); + ASSERT_NE(nullptr, radio_imsmediasessionlistener.get()); + count_ = 0; +} + +TEST_P(RadioImsMediaTest, MOCallSuccess) { + int32_t sessionId = 1; + RtpConfig modifyRtpConfig; + + modifyRtpConfig.direction = + ::aidl::android::hardware::radio::ims::media::MediaDirection::SEND_RECEIVE; + modifyRtpConfig.remoteAddress.ipAddress = "122.22.22.33"; + modifyRtpConfig.remoteAddress.portNumber = 1234; + + if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) { + ALOGI("Skipping setListener because ims is not supported in device"); + return; + } else { + ALOGI("Running setListener because ims is supported in device"); + } + + ndk::ScopedAStatus res = radio_imsmedia->setListener(radio_imsmedialistener); + ASSERT_OK(res); + + serial = SERIAL_OPEN_SESSION; + res = triggerOpenSession(sessionId); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId); + ASSERT_NE(nullptr, radio_imsmedialistener->mSession); + + radio_imsmediasession = radio_imsmedialistener->mSession; + radio_imsmediasession->setListener(radio_imsmediasessionlistener); + ASSERT_OK(res); + + serial = SERIAL_MODIFY_SESSION; + res = radio_imsmediasession->modifySession(modifyRtpConfig); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(modifyRtpConfig, radio_imsmediasessionlistener->mConfig); + verifyError(radio_imsmediasessionlistener->mError); + + serial = SERIAL_CLOSE_SESSION; + res = radio_imsmedia->closeSession(sessionId); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId); +} + +TEST_P(RadioImsMediaTest, testDtmfOperation) { + int32_t sessionId = 1; + char16_t dtmfDight = 'a'; + int32_t duration = 200; + RtpConfig modifyRtpConfig; + + modifyRtpConfig.direction = + ::aidl::android::hardware::radio::ims::media::MediaDirection::SEND_RECEIVE; + modifyRtpConfig.remoteAddress.ipAddress = "122.22.22.33"; + modifyRtpConfig.remoteAddress.portNumber = 1234; + + if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) { + ALOGI("Skipping setListener because ims is not supported in device"); + return; + } else { + ALOGI("Running setListener because ims is supported in device"); + } + + ndk::ScopedAStatus res = radio_imsmedia->setListener(radio_imsmedialistener); + ASSERT_OK(res); + + serial = SERIAL_OPEN_SESSION; + res = triggerOpenSession(sessionId); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId); + ASSERT_NE(nullptr, radio_imsmedialistener->mSession); + + radio_imsmediasession = radio_imsmedialistener->mSession; + radio_imsmediasession->setListener(radio_imsmediasessionlistener); + ASSERT_OK(res); + + serial = SERIAL_MODIFY_SESSION; + res = radio_imsmediasession->modifySession(modifyRtpConfig); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(modifyRtpConfig, radio_imsmediasessionlistener->mConfig); + verifyError(radio_imsmediasessionlistener->mError); + + res = radio_imsmediasession->sendDtmf(dtmfDight, duration); + ASSERT_OK(res); + + res = radio_imsmediasession->startDtmf(dtmfDight); + ASSERT_OK(res); + + res = radio_imsmediasession->stopDtmf(); + ASSERT_OK(res); + + serial = SERIAL_CLOSE_SESSION; + res = radio_imsmedia->closeSession(sessionId); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); +} + +TEST_P(RadioImsMediaTest, sendHeaderExtension) { + int32_t sessionId = 1; + std::vector extensions; + RtpConfig modifyRtpConfig; + + modifyRtpConfig.direction = + ::aidl::android::hardware::radio::ims::media::MediaDirection::SEND_RECEIVE; + modifyRtpConfig.remoteAddress.ipAddress = "122.22.22.33"; + modifyRtpConfig.remoteAddress.portNumber = 1234; + + if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) { + ALOGI("Skipping setListener because ims is not supported in device"); + return; + } else { + ALOGI("Running setListener because ims is supported in device"); + } + + ndk::ScopedAStatus res = radio_imsmedia->setListener(radio_imsmedialistener); + ASSERT_OK(res); + + serial = SERIAL_OPEN_SESSION; + res = triggerOpenSession(sessionId); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId); + ASSERT_NE(nullptr, radio_imsmedialistener->mSession); + + radio_imsmediasession = radio_imsmedialistener->mSession; + radio_imsmediasession->setListener(radio_imsmediasessionlistener); + ASSERT_OK(res); + + serial = SERIAL_MODIFY_SESSION; + res = radio_imsmediasession->modifySession(modifyRtpConfig); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(modifyRtpConfig, radio_imsmediasessionlistener->mConfig); + verifyError(radio_imsmediasessionlistener->mError); + + res = radio_imsmediasession->sendHeaderExtension(extensions); + ASSERT_OK(res); + + serial = SERIAL_CLOSE_SESSION; + res = radio_imsmedia->closeSession(sessionId); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); +} + +TEST_P(RadioImsMediaTest, setMediaQualityThreshold) { + int32_t sessionId = 1; + MediaQualityThreshold threshold; + RtpConfig modifyRtpConfig; + + modifyRtpConfig.direction = + ::aidl::android::hardware::radio::ims::media::MediaDirection::SEND_RECEIVE; + modifyRtpConfig.remoteAddress.ipAddress = "122.22.22.33"; + modifyRtpConfig.remoteAddress.portNumber = 1234; + + if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) { + ALOGI("Skipping setListener because ims is not supported in device"); + return; + } else { + ALOGI("Running setListener because ims is supported in device"); + } + + ndk::ScopedAStatus res = radio_imsmedia->setListener(radio_imsmedialistener); + ASSERT_OK(res); + + serial = SERIAL_OPEN_SESSION; + res = triggerOpenSession(sessionId); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId); + ASSERT_NE(nullptr, radio_imsmedialistener->mSession); + + radio_imsmediasession = radio_imsmedialistener->mSession; + radio_imsmediasession->setListener(radio_imsmediasessionlistener); + ASSERT_OK(res); + + serial = SERIAL_MODIFY_SESSION; + res = radio_imsmediasession->modifySession(modifyRtpConfig); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(modifyRtpConfig, radio_imsmediasessionlistener->mConfig); + verifyError(radio_imsmediasessionlistener->mError); + + res = radio_imsmediasession->setMediaQualityThreshold(threshold); + ASSERT_OK(res); + + serial = SERIAL_CLOSE_SESSION; + res = radio_imsmedia->closeSession(sessionId); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); +} + +ndk::ScopedAStatus RadioImsMediaTest::triggerOpenSession(int32_t sessionId) { + LocalEndPoint localEndPoint; + RtpConfig rtpConfig; + ndk::ScopedAStatus result; + + int mSocketFd = ::socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + int mRtcpSocketFd = ::socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + localEndPoint.rtpFd = ndk::ScopedFileDescriptor(mSocketFd); + localEndPoint.rtcpFd = ndk::ScopedFileDescriptor(mRtcpSocketFd); + localEndPoint.modemId = 1; + + rtpConfig.direction = + ::aidl::android::hardware::radio::ims::media::MediaDirection::SEND_RECEIVE; + rtpConfig.remoteAddress.ipAddress = "122.22.22.22"; + rtpConfig.remoteAddress.portNumber = 2222; + + result = radio_imsmedia->openSession(sessionId, localEndPoint, rtpConfig); + + return result; +} + +void RadioImsMediaTest::verifyError(RtpError error) { + switch (error) { + case RtpError::NONE: + case RtpError::INVALID_PARAM: + case RtpError::NOT_READY: + case RtpError::NO_MEMORY: + case RtpError::NO_RESOURCES: + case RtpError::PORT_UNAVAILABLE: + case RtpError::NOT_SUPPORTED: + SUCCEED(); + break; + default: + FAIL(); + break; + } +} diff --git a/radio/aidl/vts/radio_imsmedia_utils.h b/radio/aidl/vts/radio_imsmedia_utils.h new file mode 100644 index 0000000000..6143addd03 --- /dev/null +++ b/radio/aidl/vts/radio_imsmedia_utils.h @@ -0,0 +1,98 @@ + +/* + * Copyright (C) 2023 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 +#include +#include +#include + +#include "radio_aidl_hal_utils.h" + +#define SERIAL_SET_LISTENER 1 +#define SERIAL_OPEN_SESSION 2 +#define SERIAL_CLOSE_SESSION 3 +#define SERIAL_MODIFY_SESSION 4 + +using namespace aidl::android::hardware::radio::ims::media; + +class RadioImsMediaTest; + +/* Listener class for ImsMedia. */ +class ImsMediaListener : public BnImsMediaListener { + protected: + RadioServiceTest& parent_imsmedia; + + public: + ImsMediaListener(RadioServiceTest& parent_imsmedialistener); + virtual ~ImsMediaListener() = default; + + int32_t mSessionId; + std::shared_ptr<::aidl::android::hardware::radio::ims::media::IImsMediaSession> mSession; + RtpError mError; + + virtual ndk::ScopedAStatus onOpenSessionSuccess( + int32_t in_sessionId, const std::shared_ptr& in_session) override; + virtual ndk::ScopedAStatus onOpenSessionFailure(int32_t in_sessionId, + RtpError in_error) override; + virtual ndk::ScopedAStatus onSessionClosed(int32_t in_sessionId) override; +}; + +/* Listener class for ImsMediaSession. */ +class ImsMediaSessionListener : public BnImsMediaSessionListener { + protected: + RadioServiceTest& parent_imsmedia; + + public: + ImsMediaSessionListener(RadioServiceTest& parent_imsmediasessionlistener); + virtual ~ImsMediaSessionListener() = default; + + RtpConfig mConfig; + RtpError mError; + + virtual ndk::ScopedAStatus onModifySessionResponse(const RtpConfig& in_config, + RtpError in_error) override; + virtual ndk::ScopedAStatus onFirstMediaPacketReceived(const RtpConfig& in_config) override; + virtual ndk::ScopedAStatus onHeaderExtensionReceived( + const std::vector& in_extensions) override; + virtual ndk::ScopedAStatus notifyMediaQualityStatus( + const MediaQualityStatus& in_quality) override; + virtual ndk::ScopedAStatus triggerAnbrQuery(const RtpConfig& in_config) override; + virtual ndk::ScopedAStatus onDtmfReceived(char16_t in_dtmfDigit, + int32_t in_durationMs) override; + virtual ndk::ScopedAStatus onCallQualityChanged(const CallQuality& in_callQuality) override; +}; + +/* The main test class for Radio AIDL ImsMedia. */ +class RadioImsMediaTest : public ::testing::TestWithParam, public RadioServiceTest { + protected: + virtual void verifyError(RtpError inError); + virtual ndk::ScopedAStatus triggerOpenSession(int32_t sessionId); + + public: + virtual void SetUp() override; + + /* radio imsmedia service handle */ + std::shared_ptr radio_imsmedia; + /* radio imsmediasession service handle */ + std::shared_ptr radio_imsmediasession; + /* radio imsmedia listener handle */ + std::shared_ptr radio_imsmedialistener; + /* radio imsmediasession listener handle */ + std::shared_ptr radio_imsmediasessionlistener; +};