Merge "Fix timer and RtcpEncoder mutex nesting" into udc-qpr-dev am: 27467d304b am: b61cf9f736
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/ImsMedia/+/25418378
Change-Id: Ib1af48a14516d858ac653f5361152b21a40524cd
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/OWNERS b/OWNERS
index 116f70a..0ba79c4 100644
--- a/OWNERS
+++ b/OWNERS
@@ -3,4 +3,5 @@
amruthr@google.com
seheele@google.com
koshytc@google.com
-
+ericdavison@google.com
+radhikaagrawal@google.com
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/src/TextConfig.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/src/TextConfig.cpp
index 4181fc5..b1fb5ea 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/src/TextConfig.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/src/TextConfig.cpp
@@ -64,6 +64,7 @@
{
if (this != &config)
{
+ RtpConfig::operator=(config);
this->mCodecType = config.mCodecType;
this->mBitrate = config.mBitrate;
this->mRedundantPayload = config.mRedundantPayload;
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/text/TextManager.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/text/TextManager.h
index 312d4ae..f23ac8f 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/text/TextManager.h
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/text/TextManager.h
@@ -67,7 +67,7 @@
virtual void setMediaQualityThreshold(const int sessionId, MediaQualityThreshold* threshold);
virtual ImsMediaResult sendRtt(const int sessionId, const android::String8* text);
- static TextManager* manager;
+ static TextManager* sManager;
std::unordered_map<int, std::unique_ptr<TextSession>> mSessions;
RequestHandler mRequestHandler;
ResponseHandler mResponseHandler;
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/VideoManager.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/VideoManager.h
index 91c2747..4b04baf 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/VideoManager.h
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/VideoManager.h
@@ -78,21 +78,21 @@
* @param event The event type
* @param sessionId The session id
*/
- void SendInternalEvent(
+ virtual void SendInternalEvent(
uint32_t event, uint64_t sessionId, uint64_t paramA = 0, uint64_t paramB = 0);
-private:
+protected:
VideoManager();
virtual ~VideoManager();
ImsMediaResult openSession(
const int sessionId, const int rtpFd, const int rtcpFd, VideoConfig* config);
ImsMediaResult closeSession(const int sessionId);
- ImsMediaResult setPreviewSurfaceToSession(const int sessionId, ANativeWindow* surface);
- ImsMediaResult setDisplaySurfaceToSession(const int sessionId, ANativeWindow* surface);
+ virtual ImsMediaResult setPreviewSurfaceToSession(const int sessionId, ANativeWindow* surface);
+ virtual ImsMediaResult setDisplaySurfaceToSession(const int sessionId, ANativeWindow* surface);
ImsMediaResult modifySession(const int sessionId, VideoConfig* config);
- void setMediaQualityThreshold(const int sessionId, MediaQualityThreshold* threshold);
+ virtual void setMediaQualityThreshold(const int sessionId, MediaQualityThreshold* threshold);
- static VideoManager* manager;
+ static VideoManager* sManager;
std::unordered_map<int, std::unique_ptr<VideoSession>> mSessions;
RequestHandler mRequestHandler;
ResponseHandler mResponseHandler;
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/text/TextManager.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/text/TextManager.cpp
index 2f9c5cf..54ca008 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/text/TextManager.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/text/TextManager.cpp
@@ -19,7 +19,7 @@
#include <ImsMediaNetworkUtil.h>
using namespace android;
-TextManager* TextManager::manager;
+TextManager* TextManager::sManager;
TextManager::TextManager()
{
@@ -31,17 +31,17 @@
{
mRequestHandler.Deinit();
mResponseHandler.Deinit();
- manager = nullptr;
+ sManager = nullptr;
}
TextManager* TextManager::getInstance()
{
- if (manager == nullptr)
+ if (sManager == nullptr)
{
- manager = new TextManager();
+ sManager = new TextManager();
}
- return manager;
+ return sManager;
}
int TextManager::getState(int sessionId)
@@ -224,6 +224,12 @@
{
IMLOGI4("[processEvent] event[%d], sessionId[%d], paramA[%d], paramB[%d]", event, sessionId,
paramA, paramB);
+
+ if (sManager == nullptr)
+ {
+ return;
+ }
+
ImsMediaResult result = RESULT_SUCCESS;
switch (event)
@@ -234,7 +240,7 @@
if (param != nullptr)
{
TextConfig* pConfig = reinterpret_cast<TextConfig*>(param->mConfig);
- result = TextManager::getInstance()->openSession(
+ result = sManager->openSession(
static_cast<int>(sessionId), param->rtpFd, param->rtcpFd, pConfig);
if (result == RESULT_SUCCESS)
@@ -263,8 +269,7 @@
}
break;
case kTextCloseSession:
- if (TextManager::getInstance()->closeSession(static_cast<int>(sessionId)) ==
- RESULT_SUCCESS)
+ if (sManager->closeSession(static_cast<int>(sessionId)) == RESULT_SUCCESS)
{
ImsMediaEventHandler::SendEvent(
"TEXT_RESPONSE_EVENT", kTextSessionClosed, sessionId, 0, 0);
@@ -273,7 +278,7 @@
case kTextModifySession:
{
TextConfig* config = reinterpret_cast<TextConfig*>(paramA);
- result = TextManager::getInstance()->modifySession(static_cast<int>(sessionId), config);
+ result = sManager->modifySession(static_cast<int>(sessionId), config);
ImsMediaEventHandler::SendEvent(
"TEXT_RESPONSE_EVENT", kTextModifySessionResponse, sessionId, result, paramA);
}
@@ -284,8 +289,7 @@
if (threshold != nullptr)
{
- TextManager::getInstance()->setMediaQualityThreshold(
- static_cast<int>(sessionId), threshold);
+ sManager->setMediaQualityThreshold(static_cast<int>(sessionId), threshold);
delete threshold;
}
}
@@ -296,7 +300,7 @@
if (text != nullptr)
{
- TextManager::getInstance()->sendRtt(static_cast<int>(sessionId), text);
+ sManager->sendRtt(static_cast<int>(sessionId), text);
delete text;
}
}
@@ -311,6 +315,12 @@
{
IMLOGI4("[processEvent] event[%d], sessionId[%d], paramA[%d], paramB[%d]", event, sessionId,
paramA, paramB);
+
+ if (sManager == nullptr)
+ {
+ return;
+ }
+
android::Parcel parcel;
switch (event)
{
@@ -325,7 +335,7 @@
parcel.writeInt32(static_cast<int>(paramA));
}
- TextManager::getInstance()->sendResponse(sessionId, parcel);
+ sManager->sendResponse(sessionId, parcel);
break;
case kTextModifySessionResponse: // fall through
{
@@ -336,7 +346,7 @@
if (config != nullptr)
{
config->writeToParcel(&parcel);
- TextManager::getInstance()->sendResponse(sessionId, parcel);
+ sManager->sendResponse(sessionId, parcel);
delete config;
}
}
@@ -345,7 +355,7 @@
parcel.writeInt32(event);
parcel.writeInt32(static_cast<int>(paramA)); // type
parcel.writeInt32(static_cast<int>(paramB)); // duration
- TextManager::getInstance()->sendResponse(sessionId, parcel);
+ sManager->sendResponse(sessionId, parcel);
break;
case kTextRttReceived:
{
@@ -356,7 +366,7 @@
{
String16 rttText(*text);
parcel.writeString16(rttText);
- TextManager::getInstance()->sendResponse(sessionId, parcel);
+ sManager->sendResponse(sessionId, parcel);
delete text;
}
}
@@ -364,7 +374,7 @@
case kTextSessionClosed:
parcel.writeInt32(event);
parcel.writeInt32(static_cast<int>(sessionId));
- TextManager::getInstance()->sendResponse(sessionId, parcel);
+ sManager->sendResponse(sessionId, parcel);
break;
default:
break;
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoManager.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoManager.cpp
index 4652511..0ad3439 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoManager.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoManager.cpp
@@ -19,7 +19,7 @@
#include <ImsMediaNetworkUtil.h>
using namespace android;
-VideoManager* VideoManager::manager;
+VideoManager* VideoManager::sManager;
VideoManager::VideoManager()
{
@@ -31,17 +31,17 @@
{
mRequestHandler.Deinit();
mResponseHandler.Deinit();
- manager = nullptr;
+ sManager = nullptr;
}
VideoManager* VideoManager::getInstance()
{
- if (manager == nullptr)
+ if (sManager == nullptr)
{
- manager = new VideoManager();
+ sManager = new VideoManager();
}
- return manager;
+ return sManager;
}
int VideoManager::getState(int sessionId)
@@ -261,6 +261,11 @@
paramA, paramB);
ImsMediaResult result = RESULT_SUCCESS;
+ if (sManager == nullptr)
+ {
+ return;
+ }
+
switch (event)
{
case kVideoOpenSession:
@@ -270,7 +275,7 @@
if (param != nullptr)
{
VideoConfig* pConfig = reinterpret_cast<VideoConfig*>(param->mConfig);
- result = VideoManager::getInstance()->openSession(
+ result = sManager->openSession(
static_cast<int>(sessionId), param->rtpFd, param->rtcpFd, pConfig);
if (result == RESULT_SUCCESS)
@@ -299,26 +304,24 @@
}
break;
case kVideoCloseSession:
- if (VideoManager::getInstance()->closeSession(static_cast<int>(sessionId)) ==
- RESULT_SUCCESS)
+ if (sManager->closeSession(static_cast<int>(sessionId)) == RESULT_SUCCESS)
{
ImsMediaEventHandler::SendEvent(
"VIDEO_RESPONSE_EVENT", kVideoSessionClosed, sessionId, 0, 0);
}
break;
case kVideoSetPreviewSurface:
- VideoManager::getInstance()->setPreviewSurfaceToSession(
+ sManager->setPreviewSurfaceToSession(
static_cast<int>(sessionId), reinterpret_cast<ANativeWindow*>(paramA));
break;
case kVideoSetDisplaySurface:
- VideoManager::getInstance()->setDisplaySurfaceToSession(
+ sManager->setDisplaySurfaceToSession(
static_cast<int>(sessionId), reinterpret_cast<ANativeWindow*>(paramA));
break;
case kVideoModifySession:
{
VideoConfig* config = reinterpret_cast<VideoConfig*>(paramA);
- result =
- VideoManager::getInstance()->modifySession(static_cast<int>(sessionId), config);
+ result = sManager->modifySession(static_cast<int>(sessionId), config);
ImsMediaEventHandler::SendEvent(
"VIDEO_RESPONSE_EVENT", kVideoModifySessionResponse, sessionId, result, paramA);
}
@@ -332,8 +335,7 @@
if (threshold != nullptr)
{
- VideoManager::getInstance()->setMediaQualityThreshold(
- static_cast<int>(sessionId), threshold);
+ sManager->setMediaQualityThreshold(static_cast<int>(sessionId), threshold);
delete threshold;
}
}
@@ -346,7 +348,7 @@
case kRequestVideoSendTmmbr:
case kRequestVideoSendTmmbn:
case kRequestRoundTripTimeDelayUpdate:
- VideoManager::getInstance()->SendInternalEvent(event, sessionId, paramA, paramB);
+ sManager->SendInternalEvent(event, sessionId, paramA, paramB);
break;
default:
break;
@@ -358,7 +360,14 @@
{
IMLOGI4("[processEvent] event[%d], sessionId[%d], paramA[%d], paramB[%d]", event, sessionId,
paramA, paramB);
+
+ if (sManager == nullptr)
+ {
+ return;
+ }
+
android::Parcel parcel;
+
switch (event)
{
case kVideoOpenSessionSuccess:
@@ -372,7 +381,7 @@
parcel.writeInt32(static_cast<int>(paramA));
}
- VideoManager::getInstance()->sendResponse(sessionId, parcel);
+ sManager->sendResponse(sessionId, parcel);
break;
case kVideoModifySessionResponse: // fall through
{
@@ -383,20 +392,20 @@
if (config != nullptr)
{
config->writeToParcel(&parcel);
- VideoManager::getInstance()->sendResponse(sessionId, parcel);
+ sManager->sendResponse(sessionId, parcel);
delete config;
}
}
break;
case kVideoFirstMediaPacketInd:
parcel.writeInt32(event);
- VideoManager::getInstance()->sendResponse(sessionId, parcel);
+ sManager->sendResponse(sessionId, parcel);
break;
case kVideoPeerDimensionChanged:
parcel.writeInt32(event);
parcel.writeInt32(static_cast<int>(paramA));
parcel.writeInt32(static_cast<int>(paramB));
- VideoManager::getInstance()->sendResponse(sessionId, parcel);
+ sManager->sendResponse(sessionId, parcel);
break;
case kVideoRtpHeaderExtensionInd:
// TODO : add implementation
@@ -405,17 +414,17 @@
case kVideoBitrateInd:
parcel.writeInt32(event);
parcel.writeInt32(static_cast<int>(paramA));
- VideoManager::getInstance()->sendResponse(sessionId, parcel);
+ sManager->sendResponse(sessionId, parcel);
break;
case kVideoDataUsageInd:
parcel.writeInt32(event);
parcel.writeInt64(static_cast<int>(paramA));
- VideoManager::getInstance()->sendResponse(sessionId, parcel);
+ sManager->sendResponse(sessionId, parcel);
break;
case kVideoSessionClosed:
parcel.writeInt32(event);
parcel.writeInt32(static_cast<int>(sessionId));
- VideoManager::getInstance()->sendResponse(sessionId, parcel);
+ sManager->sendResponse(sessionId, parcel);
break;
default:
break;
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoSession.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoSession.cpp
index ba43d0a..67c5684 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoSession.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoSession.cpp
@@ -249,7 +249,7 @@
break;
case kImsMediaEventFirstPacketReceived:
ImsMediaEventHandler::SendEvent(
- "VIDEO_RESPONSE_EVENT", kVideoFirstMediaPacketInd, param1, param2);
+ "VIDEO_RESPONSE_EVENT", kVideoFirstMediaPacketInd, mSessionId, param1, param2);
break;
case kImsMediaEventResolutionChanged:
ImsMediaEventHandler::SendEvent(
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoRenderer.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoRenderer.cpp
index 475425b..f3fff62 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoRenderer.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoRenderer.cpp
@@ -80,13 +80,13 @@
bool ImsMediaVideoRenderer::Start()
{
IMLOGD0("[Start]");
- mMutex.lock();
mFormat = AMediaFormat_new();
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_WIDTH, mWidth);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_HEIGHT, mHeight);
char kMimeType[128] = {'\0'};
sprintf(kMimeType, "video/avc");
+
if (mCodecType == kVideoCodecHevc)
{
sprintf(kMimeType, "video/hevc");
@@ -99,6 +99,7 @@
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_ROTATION, mFarOrientationDegree);
mCodec = AMediaCodec_createDecoderByType(kMimeType);
+
if (mCodec == nullptr)
{
IMLOGE0("[Start] Unable to create decoder");
@@ -111,6 +112,7 @@
}
media_status_t err = AMediaCodec_configure(mCodec, mFormat, mWindow, nullptr, 0);
+
if (err != AMEDIA_OK)
{
IMLOGE1("[Start] configure error[%d]", err);
@@ -122,6 +124,7 @@
}
err = AMediaCodec_start(mCodec);
+
if (err != AMEDIA_OK)
{
IMLOGE1("[Start] codec start[%d]", err);
@@ -133,7 +136,6 @@
}
mStopped = false;
- mMutex.unlock();
std::thread t1(&ImsMediaVideoRenderer::processBuffers, this);
t1.detach();
return true;
@@ -178,12 +180,17 @@
IMLOGD_PACKET2(IM_PACKET_LOG_VIDEO, "[OnDataFrame] frame size[%u], list[%d]", size,
mFrameDatas.size());
- std::lock_guard<std::mutex> guard(mMutex);
- if (mCodec == nullptr)
+
+ mMutex.lock();
+
+ if (mStopped)
{
+ mMutex.unlock();
return;
}
+ mMutex.unlock();
+
mFrameDatas.push_back(new FrameData(buffer, size, timestamp, isConfigFrame));
}
@@ -197,11 +204,13 @@
while (true)
{
mMutex.lock();
+
if (mStopped)
{
mMutex.unlock();
break;
}
+
mMutex.unlock();
if (mFrameDatas.size() == 0)
diff --git a/tests/native/Android.bp b/tests/native/Android.bp
index 255fa57..cf72ff1 100644
--- a/tests/native/Android.bp
+++ b/tests/native/Android.bp
@@ -23,6 +23,8 @@
export_include_dirs: [
"service/src/com/android/telephony/imsmedia/lib/libimsmedia/include",
"service/src/com/android/telephony/imsmedia/lib/libimsmedia/include/core/audio",
+ "service/src/com/android/telephony/imsmedia/lib/libimsmedia/include/core/video",
+ "service/src/com/android/telephony/imsmedia/lib/libimsmedia/include/core/text",
],
}
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/AudioConfigTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/AudioConfigTest.cpp
index 3beca9f..e390835 100644
--- a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/AudioConfigTest.cpp
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/AudioConfigTest.cpp
@@ -130,7 +130,8 @@
TEST_F(AudioConfigTest, TestAssign)
{
- AudioConfig testConfig = config1;
+ AudioConfig testConfig;
+ testConfig = config1;
EXPECT_EQ(config1, testConfig);
AudioConfig* testConfig2 = new AudioConfig(config1);
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/CallQualityTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/CallQualityTest.cpp
index 5fcc6f9..4cad123 100644
--- a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/CallQualityTest.cpp
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/CallQualityTest.cpp
@@ -93,7 +93,8 @@
TEST_F(CallQualityTest, TestAssign)
{
- CallQuality testQuality = quality1;
+ CallQuality testQuality;
+ testQuality = quality1;
EXPECT_EQ(quality1, testQuality);
}
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/MediaQualityStatusTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/MediaQualityStatusTest.cpp
index c32c2d2..aa8aed0 100644
--- a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/MediaQualityStatusTest.cpp
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/MediaQualityStatusTest.cpp
@@ -62,7 +62,8 @@
TEST_F(MediaQualityStatusTest, TestAssign)
{
- MediaQualityStatus status2 = status;
+ MediaQualityStatus status2;
+ status2 = status;
EXPECT_EQ(status, status2);
}
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/MediaQualityThresholdTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/MediaQualityThresholdTest.cpp
index 3349446..a68db0a 100644
--- a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/MediaQualityThresholdTest.cpp
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/MediaQualityThresholdTest.cpp
@@ -74,7 +74,8 @@
TEST_F(MediaQualityThresholdTest, TestAssign)
{
- MediaQualityThreshold threshold2 = threshold;
+ MediaQualityThreshold threshold2;
+ threshold2 = threshold;
EXPECT_EQ(threshold, threshold2);
}
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/TextConfigTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/TextConfigTest.cpp
index 00f4cd6..793bdf0 100644
--- a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/TextConfigTest.cpp
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/TextConfigTest.cpp
@@ -96,7 +96,8 @@
TEST_F(TextConfigTest, TestAssign)
{
- TextConfig testConfig = config1;
+ TextConfig testConfig;
+ testConfig = config1;
EXPECT_EQ(config1, testConfig);
TextConfig* testConfig2 = new TextConfig(config1);
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/VideoConfigTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/VideoConfigTest.cpp
index f18d081..66ba3b1 100644
--- a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/VideoConfigTest.cpp
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/config/VideoConfigTest.cpp
@@ -145,7 +145,8 @@
TEST_F(VideoConfigTest, TestAssign)
{
- VideoConfig testConfig = config1;
+ VideoConfig testConfig;
+ testConfig = config1;
EXPECT_EQ(config1, testConfig);
VideoConfig* testConfig2 = new VideoConfig(config1);
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioManagerTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioManagerTest.cpp
index 7f81b84..3a28e18 100644
--- a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioManagerTest.cpp
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioManagerTest.cpp
@@ -30,6 +30,8 @@
using ::testing::Ref;
using ::testing::Return;
+namespace
+{
// RtpConfig
const int32_t kMediaDirection = RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE;
const android::String8 kRemoteAddress("127.0.0.1");
@@ -68,7 +70,6 @@
const int8_t kcodecModeRequest = 15;
int32_t kSessionId = 0;
-
static ImsMediaCondition gCondition;
class AudioManagerCallback
@@ -686,4 +687,5 @@
EXPECT_EQ(callback.resSessionId, kSessionId);
EXPECT_EQ(callback.response, kAudioCallQualityChangedInd);
EXPECT_EQ(callback.callQuality, quality);
-}
\ No newline at end of file
+}
+} // namespace
\ No newline at end of file
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/text/TextManagerTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/text/TextManagerTest.cpp
new file mode 100644
index 0000000..d9e6aae
--- /dev/null
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/text/TextManagerTest.cpp
@@ -0,0 +1,390 @@
+/**
+ * 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 <gtest/gtest.h>
+#include <ImsMediaNetworkUtil.h>
+#include <TextConfig.h>
+#include <MockTextManager.h>
+#include <ImsMediaCondition.h>
+#include <unordered_map>
+#include <algorithm>
+
+using namespace android::telephony::imsmedia;
+
+using ::testing::Eq;
+using ::testing::Pointee;
+using ::testing::Return;
+
+namespace
+{
+// RtpConfig
+const int32_t kMediaDirection = RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE;
+const android::String8 kRemoteAddress("127.0.0.1");
+const int32_t kRemotePort = 10000;
+const int8_t kDscp = 0;
+const int8_t kRxPayload = 100;
+const int8_t kTxPayload = 100;
+const int8_t kSamplingRate = 8;
+
+// RtcpConfig
+const android::String8 kCanonicalName("name");
+const int32_t kTransmitPort = 10001;
+const int32_t kIntervalSec = 3;
+const int32_t kRtcpXrBlockTypes = 0;
+
+// TextConfig
+const int32_t kCodecType = TextConfig::TEXT_T140_RED;
+const int32_t kBitrate = 100;
+const int8_t kRedundantPayload = 102;
+const int8_t kRedundantLevel = 3;
+const bool kKeepRedundantLevel = true;
+
+int32_t kSessionId = 0;
+static ImsMediaCondition gCondition;
+
+class TextManagerCallback
+{
+public:
+ int32_t resSessionId;
+ int32_t response;
+ TextConfig resConfig;
+ ImsMediaResult result;
+ int32_t inactivityType;
+ int32_t inactivityDuration;
+ android::String8 receivedRtt;
+
+ void resetRespond()
+ {
+ resSessionId = -1;
+ response = -1;
+ result = RESULT_NOT_READY;
+ }
+
+ void onCallback(const int id, const int event, const ImsMediaResult res)
+ {
+ resSessionId = id;
+ response = event;
+ result = res;
+ }
+
+ void onCallbackConfig(
+ const int id, const int event, const ImsMediaResult res, const TextConfig& config)
+ {
+ resSessionId = id;
+ response = event;
+ resConfig = config;
+ result = res;
+ }
+
+ void onCallbackInactivity(const int id, const int event, const int type, const int duration)
+ {
+ resSessionId = id;
+ response = event;
+ inactivityType = type;
+ inactivityDuration = duration;
+ }
+
+ void onCallbackRttReceived(const int id, const int event, const android::String16& text)
+ {
+ resSessionId = id;
+ response = event;
+ receivedRtt = android::String8(text);
+ }
+};
+
+static std::unordered_map<int, TextManagerCallback*> gMapCallback;
+
+class TextManagerTest : public ::testing::Test
+{
+public:
+ MockTextManager manager;
+ TextConfig config;
+ RtcpConfig rtcp;
+ int socketRtpFd;
+ int socketRtcpFd;
+ TextManagerCallback callback;
+
+ TextManagerTest()
+ {
+ socketRtpFd = -1;
+ socketRtcpFd = -1;
+ callback.resetRespond();
+ gCondition.reset();
+ }
+ ~TextManagerTest() {}
+
+protected:
+ virtual void SetUp() override
+ {
+ rtcp.setCanonicalName(kCanonicalName);
+ rtcp.setTransmitPort(kTransmitPort);
+ rtcp.setIntervalSec(kIntervalSec);
+ rtcp.setRtcpXrBlockTypes(kRtcpXrBlockTypes);
+
+ config.setMediaDirection(kMediaDirection);
+ config.setRemoteAddress(kRemoteAddress);
+ config.setRemotePort(kRemotePort);
+ config.setRtcpConfig(rtcp);
+ config.setDscp(kDscp);
+ config.setRxPayloadTypeNumber(kRxPayload);
+ config.setTxPayloadTypeNumber(kTxPayload);
+ config.setSamplingRateKHz(kSamplingRate);
+ config.setCodecType(kCodecType);
+ config.setBitrate(kBitrate);
+ config.setRedundantPayload(kRedundantPayload);
+ config.setRedundantLevel(kRedundantLevel);
+ config.setKeepRedundantLevel(kKeepRedundantLevel);
+
+ manager.setCallback(&textCallback);
+ gMapCallback.insert(std::make_pair(kSessionId, &callback));
+ const char testIp[] = "127.0.0.1";
+ unsigned int testPortRtp = 50000;
+ socketRtpFd = ImsMediaNetworkUtil::openSocket(testIp, testPortRtp, AF_INET);
+ EXPECT_NE(socketRtpFd, -1);
+ unsigned int testPortRtcp = 50001;
+ socketRtcpFd = ImsMediaNetworkUtil::openSocket(testIp, testPortRtcp, AF_INET);
+ EXPECT_NE(socketRtcpFd, -1);
+ gCondition.reset();
+ }
+
+ virtual void TearDown() override
+ {
+ if (socketRtpFd != -1)
+ {
+ ImsMediaNetworkUtil::closeSocket(socketRtpFd);
+ }
+
+ if (socketRtcpFd != -1)
+ {
+ ImsMediaNetworkUtil::closeSocket(socketRtcpFd);
+ }
+
+ gMapCallback.erase(kSessionId);
+ }
+
+ void openSession(const int32_t sessionId)
+ {
+ callback.resetRespond();
+ android::Parcel parcel;
+ parcel.writeInt32(kTextOpenSession);
+ parcel.writeInt32(socketRtpFd);
+ parcel.writeInt32(socketRtcpFd);
+ parcel.setDataPosition(0);
+ gCondition.reset();
+ manager.sendMessage(sessionId, parcel);
+ EXPECT_TRUE(!gCondition.wait_timeout(1000));
+ EXPECT_EQ(callback.resSessionId, sessionId);
+ EXPECT_EQ(callback.response, kTextOpenSessionSuccess);
+ }
+
+ void closeSession(const int32_t sessionId)
+ {
+ callback.resetRespond();
+ android::Parcel parcel;
+ parcel.writeInt32(kTextCloseSession);
+ parcel.setDataPosition(0);
+ gCondition.reset();
+ manager.sendMessage(sessionId, parcel);
+ EXPECT_TRUE(!gCondition.wait_timeout(1000));
+ EXPECT_EQ(callback.resSessionId, sessionId);
+ EXPECT_EQ(callback.response, kTextSessionClosed);
+ }
+
+ void testEventResponse(const int32_t sessionId, const int32_t event, TextConfig* config,
+ const int32_t response, const int32_t result)
+ {
+ callback.resetRespond();
+ android::Parcel parcel;
+ parcel.writeInt32(event);
+
+ if (config != nullptr)
+ {
+ config->writeToParcel(&parcel);
+ }
+
+ parcel.setDataPosition(0);
+ gCondition.reset();
+ manager.sendMessage(sessionId, parcel);
+ EXPECT_TRUE(!gCondition.wait_timeout(1000));
+ EXPECT_EQ(callback.resSessionId, sessionId);
+ EXPECT_EQ(callback.response, response);
+
+ if (callback.response >= kTextOpenSessionFailure &&
+ callback.response <= kTextModifySessionResponse)
+ {
+ EXPECT_EQ(result, result);
+
+ if (config != nullptr && callback.response == kTextModifySessionResponse)
+ {
+ EXPECT_EQ(callback.resConfig, *config);
+ }
+ }
+ }
+
+ static int32_t textCallback(int sessionId, const android::Parcel& parcel)
+ {
+ parcel.setDataPosition(0);
+
+ int response = parcel.readInt32();
+ ImsMediaResult result = RESULT_INVALID_PARAM;
+
+ auto callback = gMapCallback.find(sessionId);
+
+ if (callback != gMapCallback.end())
+ {
+ if (response >= kTextOpenSessionFailure && response <= kTextModifySessionResponse)
+ {
+ result = static_cast<ImsMediaResult>(parcel.readInt32());
+ }
+
+ switch (response)
+ {
+ case kTextModifySessionResponse:
+ {
+ TextConfig resConfig;
+ resConfig.readFromParcel(&parcel);
+ (callback->second)->onCallbackConfig(sessionId, response, result, resConfig);
+ }
+ break;
+ case kTextMediaInactivityInd:
+ (callback->second)
+ ->onCallbackInactivity(
+ sessionId, response, parcel.readInt32(), parcel.readInt32());
+ break;
+ case kTextRttReceived:
+ {
+ android::String16 text;
+ parcel.readString16(&text);
+ (callback->second)->onCallbackRttReceived(sessionId, response, text);
+ }
+ break;
+ default:
+ (callback->second)->onCallback(sessionId, response, result);
+ break;
+ }
+ }
+
+ gCondition.signal();
+ return 0;
+ }
+};
+
+TEST_F(TextManagerTest, testOpenCloseSession)
+{
+ EXPECT_EQ(manager.getState(kSessionId), kSessionStateClosed);
+ openSession(kSessionId);
+ closeSession(kSessionId);
+}
+
+TEST_F(TextManagerTest, testModifySession)
+{
+ testEventResponse(kSessionId, kTextModifySession, nullptr, kTextModifySessionResponse,
+ RESULT_INVALID_PARAM);
+
+ openSession(kSessionId);
+
+ testEventResponse(kSessionId, kTextModifySession, nullptr, kTextModifySessionResponse,
+ RESULT_INVALID_PARAM);
+
+ testEventResponse(
+ kSessionId, kTextModifySession, &config, kTextModifySessionResponse, RESULT_SUCCESS);
+
+ closeSession(kSessionId);
+}
+
+TEST_F(TextManagerTest, testSendRtt)
+{
+ openSession(kSessionId);
+
+ const android::String8 text = android::String8("hello");
+ android::Parcel parcel;
+ parcel.writeInt32(kTextSendRtt);
+ android::String16 rttText(text);
+ parcel.writeString16(rttText);
+ parcel.setDataPosition(0);
+
+ EXPECT_CALL(manager, sendRtt(kSessionId, Pointee(Eq(text))))
+ .Times(1)
+ .WillOnce(Return(RESULT_NOT_READY));
+ manager.sendMessage(kSessionId, parcel);
+
+ closeSession(kSessionId);
+}
+
+TEST_F(TextManagerTest, testSetMediaQualityThreshold)
+{
+ openSession(kSessionId);
+
+ const std::vector<int32_t> kRtpInactivityTimerMillis = {10000, 20000};
+ const int32_t kRtcpInactivityTimerMillis = 20000;
+ const int32_t kRtpHysteresisTimeInMillis = 3000;
+ const int32_t kRtpPacketLossDurationMillis = 5000;
+ const std::vector<int32_t> kRtpPacketLossRate = {3, 5};
+ const std::vector<int32_t> kRtpJitterMillis = {100, 200};
+ const bool kNotifyCurrentStatus = false;
+
+ MediaQualityThreshold threshold;
+ threshold.setRtpInactivityTimerMillis(kRtpInactivityTimerMillis);
+ threshold.setRtcpInactivityTimerMillis(kRtcpInactivityTimerMillis);
+ threshold.setRtpHysteresisTimeInMillis(kRtpHysteresisTimeInMillis);
+ threshold.setRtpPacketLossDurationMillis(kRtpPacketLossDurationMillis);
+ threshold.setRtpPacketLossRate(kRtpPacketLossRate);
+ threshold.setRtpJitterMillis(kRtpJitterMillis);
+ threshold.setNotifyCurrentStatus(kNotifyCurrentStatus);
+
+ android::Parcel parcel;
+ parcel.writeInt32(kTextSetMediaQualityThreshold);
+ threshold.writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+
+ EXPECT_CALL(manager, setMediaQualityThreshold(kSessionId, Pointee(Eq(threshold))))
+ .Times(1)
+ .WillOnce(Return());
+
+ manager.sendMessage(kSessionId, parcel);
+
+ closeSession(kSessionId);
+}
+
+TEST_F(TextManagerTest, testMediaInactivityInd)
+{
+ const int32_t kInactivityType = kProtocolRtp;
+ const int32_t kInactivityDuration = 10000;
+
+ ImsMediaEventHandler::SendEvent("TEXT_RESPONSE_EVENT", kTextMediaInactivityInd, kSessionId,
+ kInactivityType, kInactivityDuration);
+
+ gCondition.wait_timeout(20);
+ EXPECT_EQ(callback.resSessionId, kSessionId);
+ EXPECT_EQ(callback.response, kTextMediaInactivityInd);
+ EXPECT_EQ(callback.inactivityType, kInactivityType);
+ EXPECT_EQ(callback.inactivityDuration, kInactivityDuration);
+}
+
+TEST_F(TextManagerTest, testRttReceivedInd)
+{
+ const android::String8 testText = android::String8("hello");
+ android::String8* text = new android::String8(testText);
+
+ ImsMediaEventHandler::SendEvent("TEXT_RESPONSE_EVENT", kTextRttReceived, kSessionId,
+ reinterpret_cast<uint64_t>(text), 0);
+
+ gCondition.wait_timeout(20);
+ EXPECT_EQ(callback.resSessionId, kSessionId);
+ EXPECT_EQ(callback.response, kTextRttReceived);
+ EXPECT_EQ(callback.receivedRtt, testText);
+}
+} // namespace
\ No newline at end of file
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoManagerTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoManagerTest.cpp
new file mode 100644
index 0000000..63b8943
--- /dev/null
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoManagerTest.cpp
@@ -0,0 +1,465 @@
+/**
+ * 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 <gtest/gtest.h>
+#include <ImsMediaNetworkUtil.h>
+#include <media/NdkImageReader.h>
+#include <VideoConfig.h>
+#include <MockVideoManager.h>
+#include <ImsMediaCondition.h>
+#include <unordered_map>
+#include <algorithm>
+
+using namespace android::telephony::imsmedia;
+
+using ::testing::Eq;
+using ::testing::Pointee;
+using ::testing::Return;
+
+namespace
+{
+// RtpConfig
+const int32_t kMediaDirection = RtpConfig::MEDIA_DIRECTION_NO_FLOW;
+const android::String8 kRemoteAddress("0.0.0.0");
+const int32_t kRemotePort = 1000;
+const int32_t kMtu = 1500;
+const int8_t kDscp = 0;
+const int8_t kRxPayload = 102;
+const int8_t kTxPayload = 102;
+const int8_t kSamplingRate = 90;
+
+// RtcpConfig
+const android::String8 kCanonicalName("name");
+const int32_t kTransmitPort = 1001;
+const int32_t kIntervalSec = 1500;
+const int32_t kRtcpXrBlockTypes = RtcpConfig::FLAG_RTCPXR_STATISTICS_SUMMARY_REPORT_BLOCK |
+ RtcpConfig::FLAG_RTCPXR_VOIP_METRICS_REPORT_BLOCK;
+
+// VideoConfig
+const int32_t kVideoMode = VideoConfig::VIDEO_MODE_PREVIEW;
+const int32_t kCodecType = VideoConfig::CODEC_AVC;
+const int32_t kFramerate = DEFAULT_FRAMERATE;
+const int32_t kBitrate = DEFAULT_BITRATE;
+const int32_t kCodecProfile = VideoConfig::AVC_PROFILE_BASELINE;
+const int32_t kCodecLevel = VideoConfig::AVC_LEVEL_12;
+const int32_t kIntraFrameIntervalSec = 1;
+const int32_t kPacketizationMode = VideoConfig::MODE_NON_INTERLEAVED;
+const int32_t kCameraId = 0;
+const int32_t kCameraZoom = 10;
+const int32_t kResolutionWidth = DEFAULT_RESOLUTION_WIDTH;
+const int32_t kResolutionHeight = DEFAULT_RESOLUTION_HEIGHT;
+const android::String8 kPauseImagePath("data/user_de/0/com.android.telephony.imsmedia/test.jpg");
+const int32_t kDeviceOrientationDegree = 0;
+const int32_t kCvoValue = 1;
+const int32_t kRtcpFbTypes = VideoConfig::RTP_FB_NONE;
+
+int32_t kSessionId = 0;
+static ImsMediaCondition gCondition;
+
+class VideoManagerCallback
+{
+public:
+ int32_t resSessionId;
+ int32_t response;
+ VideoConfig resConfig;
+ ImsMediaResult result;
+ int32_t inactivityType;
+ int32_t inactivityDuration;
+ int32_t peerResolutionWidth;
+ int32_t peerResolutionHeight;
+
+ void resetRespond()
+ {
+ resSessionId = -1;
+ response = -1;
+ result = RESULT_NOT_READY;
+ }
+
+ void onCallback(const int id, const int event, const ImsMediaResult res)
+ {
+ resSessionId = id;
+ response = event;
+ result = res;
+ }
+
+ void onCallbackConfig(
+ const int id, const int event, const ImsMediaResult res, const VideoConfig& config)
+ {
+ resSessionId = id;
+ response = event;
+ resConfig = config;
+ result = res;
+ }
+
+ void onCallbackInactivity(const int id, const int event, const int type, const int duration)
+ {
+ resSessionId = id;
+ response = event;
+ inactivityType = type;
+ inactivityDuration = duration;
+ }
+
+ void onCallbackPeerDimensionChanged(
+ const int id, const int event, const int width, const int height)
+ {
+ resSessionId = id;
+ response = event;
+ peerResolutionWidth = width;
+ peerResolutionHeight = height;
+ }
+};
+
+static std::unordered_map<int, VideoManagerCallback*> gMapCallback;
+
+class VideoManagerTest : public ::testing::Test
+{
+public:
+ MockVideoManager manager;
+ VideoConfig config;
+ RtcpConfig rtcp;
+ int socketRtpFd;
+ int socketRtcpFd;
+ VideoManagerCallback callback;
+
+ VideoManagerTest()
+ {
+ socketRtpFd = -1;
+ socketRtcpFd = -1;
+ callback.resetRespond();
+ gCondition.reset();
+ }
+ ~VideoManagerTest() {}
+
+protected:
+ virtual void SetUp() override
+ {
+ rtcp.setCanonicalName(kCanonicalName);
+ rtcp.setTransmitPort(kTransmitPort);
+ rtcp.setIntervalSec(kIntervalSec);
+ rtcp.setRtcpXrBlockTypes(kRtcpXrBlockTypes);
+ config.setMediaDirection(kMediaDirection);
+ config.setRemoteAddress(kRemoteAddress);
+ config.setRemotePort(kRemotePort);
+ config.setRtcpConfig(rtcp);
+ config.setMaxMtuBytes(kMtu);
+ config.setDscp(kDscp);
+ config.setRxPayloadTypeNumber(kRxPayload);
+ config.setTxPayloadTypeNumber(kTxPayload);
+ config.setSamplingRateKHz(kSamplingRate);
+ config.setVideoMode(kVideoMode);
+ config.setCodecType(kCodecType);
+ config.setFramerate(kFramerate);
+ config.setBitrate(kBitrate);
+ config.setCodecProfile(kCodecProfile);
+ config.setCodecLevel(kCodecLevel);
+ config.setIntraFrameInterval(kIntraFrameIntervalSec);
+ config.setPacketizationMode(kPacketizationMode);
+ config.setCameraId(kCameraId);
+ config.setCameraZoom(kCameraZoom);
+ config.setResolutionWidth(kResolutionWidth);
+ config.setResolutionHeight(kResolutionHeight);
+ config.setPauseImagePath(kPauseImagePath);
+ config.setDeviceOrientationDegree(kDeviceOrientationDegree);
+ config.setCvoValue(kCvoValue);
+ config.setRtcpFbType(kRtcpFbTypes);
+
+ manager.setCallback(&VideoCallback);
+ gMapCallback.insert(std::make_pair(kSessionId, &callback));
+ const char testIp[] = "127.0.0.1";
+ unsigned int testPortRtp = 50000;
+ socketRtpFd = ImsMediaNetworkUtil::openSocket(testIp, testPortRtp, AF_INET);
+ EXPECT_NE(socketRtpFd, -1);
+ unsigned int testPortRtcp = 50001;
+ socketRtcpFd = ImsMediaNetworkUtil::openSocket(testIp, testPortRtcp, AF_INET);
+ EXPECT_NE(socketRtcpFd, -1);
+ gCondition.reset();
+ }
+
+ virtual void TearDown() override
+ {
+ if (socketRtpFd != -1)
+ {
+ ImsMediaNetworkUtil::closeSocket(socketRtpFd);
+ }
+
+ if (socketRtcpFd != -1)
+ {
+ ImsMediaNetworkUtil::closeSocket(socketRtcpFd);
+ }
+
+ gMapCallback.erase(kSessionId);
+ }
+
+ void openSession(const int32_t sessionId)
+ {
+ callback.resetRespond();
+ android::Parcel parcel;
+ parcel.writeInt32(kVideoOpenSession);
+ parcel.writeInt32(socketRtpFd);
+ parcel.writeInt32(socketRtcpFd);
+ parcel.setDataPosition(0);
+ gCondition.reset();
+ manager.sendMessage(sessionId, parcel);
+ EXPECT_TRUE(!gCondition.wait_timeout(1000));
+ EXPECT_EQ(callback.resSessionId, sessionId);
+ EXPECT_EQ(callback.response, kVideoOpenSessionSuccess);
+ }
+
+ void closeSession(const int32_t sessionId)
+ {
+ callback.resetRespond();
+ android::Parcel parcel;
+ parcel.writeInt32(kVideoCloseSession);
+ parcel.setDataPosition(0);
+ gCondition.reset();
+ manager.sendMessage(sessionId, parcel);
+ EXPECT_TRUE(!gCondition.wait_timeout(1000));
+ EXPECT_EQ(callback.resSessionId, sessionId);
+ EXPECT_EQ(callback.response, kVideoSessionClosed);
+ }
+
+ void testEventResponse(const int32_t sessionId, const int32_t event, VideoConfig* config,
+ const int32_t response, const int32_t result)
+ {
+ callback.resetRespond();
+ android::Parcel parcel;
+ parcel.writeInt32(event);
+
+ if (config != nullptr)
+ {
+ config->writeToParcel(&parcel);
+ }
+
+ parcel.setDataPosition(0);
+ gCondition.reset();
+ manager.sendMessage(sessionId, parcel);
+ EXPECT_TRUE(!gCondition.wait_timeout(1000));
+ EXPECT_EQ(callback.resSessionId, sessionId);
+ EXPECT_EQ(callback.response, response);
+
+ if (callback.response >= kVideoOpenSessionFailure &&
+ callback.response <= kVideoModifySessionResponse)
+ {
+ EXPECT_EQ(result, result);
+
+ if (config != nullptr && callback.response == kVideoModifySessionResponse)
+ {
+ EXPECT_EQ(callback.resConfig, *config);
+ }
+ }
+ }
+
+ static int32_t VideoCallback(int sessionId, const android::Parcel& parcel)
+ {
+ parcel.setDataPosition(0);
+
+ int response = parcel.readInt32();
+ ImsMediaResult result = RESULT_INVALID_PARAM;
+
+ auto callback = gMapCallback.find(sessionId);
+
+ if (callback != gMapCallback.end())
+ {
+ if (response >= kVideoOpenSessionFailure && response <= kVideoModifySessionResponse)
+ {
+ result = static_cast<ImsMediaResult>(parcel.readInt32());
+ }
+
+ switch (response)
+ {
+ case kVideoModifySessionResponse:
+ {
+ VideoConfig resConfig;
+ resConfig.readFromParcel(&parcel);
+ (callback->second)->onCallbackConfig(sessionId, response, result, resConfig);
+ }
+ break;
+ case kVideoPeerDimensionChanged:
+ (callback->second)
+ ->onCallbackPeerDimensionChanged(
+ sessionId, response, parcel.readInt32(), parcel.readInt32());
+ break;
+ case kVideoMediaInactivityInd:
+ (callback->second)
+ ->onCallbackInactivity(
+ sessionId, response, parcel.readInt32(), parcel.readInt32());
+ break;
+ case kVideoFirstMediaPacketInd:
+ default:
+ (callback->second)->onCallback(sessionId, response, result);
+ break;
+ }
+ }
+
+ gCondition.signal();
+ return 0;
+ }
+};
+
+TEST_F(VideoManagerTest, testOpenCloseSession)
+{
+ EXPECT_EQ(manager.getState(kSessionId), kSessionStateClosed);
+ openSession(kSessionId);
+ closeSession(kSessionId);
+}
+
+TEST_F(VideoManagerTest, testModifySession)
+{
+ testEventResponse(kSessionId, kVideoModifySession, nullptr, kVideoModifySessionResponse,
+ RESULT_INVALID_PARAM);
+
+ openSession(kSessionId);
+
+ testEventResponse(kSessionId, kVideoModifySession, nullptr, kVideoModifySessionResponse,
+ RESULT_INVALID_PARAM);
+
+ testEventResponse(
+ kSessionId, kVideoModifySession, &config, kVideoModifySessionResponse, RESULT_SUCCESS);
+
+ closeSession(kSessionId);
+}
+
+TEST_F(VideoManagerTest, testSetPreviewSurface)
+{
+ openSession(kSessionId);
+
+ AImageReader* previewReader;
+ AImageReader_new(
+ kResolutionWidth, kResolutionHeight, AIMAGE_FORMAT_YUV_420_888, 1, &previewReader);
+
+ ANativeWindow* previewSurface;
+ AImageReader_getWindow(previewReader, &previewSurface);
+
+ EXPECT_CALL(manager, setPreviewSurfaceToSession(kSessionId, Eq(previewSurface)))
+ .Times(1)
+ .WillOnce(Return(RESULT_SUCCESS));
+
+ manager.setPreviewSurface(kSessionId, previewSurface);
+
+ gCondition.wait_timeout(20);
+ closeSession(kSessionId);
+}
+
+TEST_F(VideoManagerTest, testSetDisplaySurface)
+{
+ openSession(kSessionId);
+
+ AImageReader* displayReader;
+ AImageReader_new(
+ kResolutionWidth, kResolutionHeight, AIMAGE_FORMAT_YUV_420_888, 1, &displayReader);
+
+ ANativeWindow* displaySurface;
+ AImageReader_getWindow(displayReader, &displaySurface);
+
+ EXPECT_CALL(manager, setDisplaySurfaceToSession(kSessionId, Eq(displaySurface)))
+ .Times(1)
+ .WillOnce(Return(RESULT_SUCCESS));
+
+ manager.setDisplaySurface(kSessionId, displaySurface);
+
+ gCondition.wait_timeout(20);
+ closeSession(kSessionId);
+}
+
+TEST_F(VideoManagerTest, testSetMediaQualityThreshold)
+{
+ openSession(kSessionId);
+
+ const std::vector<int32_t> kRtpInactivityTimerMillis = {10000, 20000};
+ const int32_t kRtcpInactivityTimerMillis = 20000;
+ const int32_t kRtpHysteresisTimeInMillis = 3000;
+ const int32_t kRtpPacketLossDurationMillis = 5000;
+ const std::vector<int32_t> kRtpPacketLossRate = {3, 5};
+ const std::vector<int32_t> kRtpJitterMillis = {100, 200};
+ const bool kNotifyCurrentStatus = false;
+
+ MediaQualityThreshold threshold;
+ threshold.setRtpInactivityTimerMillis(kRtpInactivityTimerMillis);
+ threshold.setRtcpInactivityTimerMillis(kRtcpInactivityTimerMillis);
+ threshold.setRtpHysteresisTimeInMillis(kRtpHysteresisTimeInMillis);
+ threshold.setRtpPacketLossDurationMillis(kRtpPacketLossDurationMillis);
+ threshold.setRtpPacketLossRate(kRtpPacketLossRate);
+ threshold.setRtpJitterMillis(kRtpJitterMillis);
+ threshold.setNotifyCurrentStatus(kNotifyCurrentStatus);
+
+ android::Parcel parcel;
+ parcel.writeInt32(kVideoSetMediaQualityThreshold);
+ threshold.writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+
+ EXPECT_CALL(manager, setMediaQualityThreshold(kSessionId, Pointee(Eq(threshold))))
+ .Times(1)
+ .WillOnce(Return());
+
+ manager.sendMessage(kSessionId, parcel);
+
+ closeSession(kSessionId);
+}
+
+TEST_F(VideoManagerTest, testFirstMediaPacketInd)
+{
+ ImsMediaEventHandler::SendEvent(
+ "VIDEO_RESPONSE_EVENT", kVideoFirstMediaPacketInd, kSessionId, 0, 0);
+
+ gCondition.wait_timeout(20);
+ EXPECT_EQ(callback.resSessionId, kSessionId);
+ EXPECT_EQ(callback.response, kVideoFirstMediaPacketInd);
+}
+
+TEST_F(VideoManagerTest, testPeerDimensionChangedInd)
+{
+ ImsMediaEventHandler::SendEvent("VIDEO_RESPONSE_EVENT", kVideoPeerDimensionChanged, kSessionId,
+ kResolutionWidth, kResolutionHeight);
+
+ gCondition.wait_timeout(20);
+ EXPECT_EQ(callback.resSessionId, kSessionId);
+ EXPECT_EQ(callback.response, kVideoPeerDimensionChanged);
+ EXPECT_EQ(callback.peerResolutionWidth, kResolutionWidth);
+ EXPECT_EQ(callback.peerResolutionHeight, kResolutionHeight);
+}
+
+TEST_F(VideoManagerTest, testMediaInactivityInd)
+{
+ const int32_t kInactivityType = kProtocolRtp;
+
+ ImsMediaEventHandler::SendEvent(
+ "VIDEO_RESPONSE_EVENT", kVideoMediaInactivityInd, kSessionId, kInactivityType, 0);
+
+ gCondition.wait_timeout(20);
+ EXPECT_EQ(callback.resSessionId, kSessionId);
+ EXPECT_EQ(callback.response, kVideoMediaInactivityInd);
+ EXPECT_EQ(callback.inactivityType, kInactivityType);
+}
+
+TEST_F(VideoManagerTest, testInternalEvent)
+{
+ const uint64_t kParamA = 1;
+ const uint64_t kParamB = 2;
+
+ for (int32_t request = kRequestVideoCvoUpdate; request <= kRequestRoundTripTimeDelayUpdate;
+ request++)
+ {
+ EXPECT_CALL(manager, SendInternalEvent(request, kSessionId, Eq(kParamA), Eq(kParamB)))
+ .Times(1)
+ .WillOnce(Return());
+
+ ImsMediaEventHandler::SendEvent(
+ "VIDEO_REQUEST_EVENT", request, kSessionId, kParamA, kParamB);
+ gCondition.wait_timeout(20);
+ }
+}
+
+} // namespace
\ No newline at end of file
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/include/core/text/MockTextManager.h b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/include/core/text/MockTextManager.h
new file mode 100644
index 0000000..c7bbe92
--- /dev/null
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/include/core/text/MockTextManager.h
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+
+#ifndef MOCK_TEXT_MANAGER_H
+#define MOCK_TEXT_MANAGER_H
+
+#include <TextManager.h>
+#include <ImsMediaDefine.h>
+#include <gmock/gmock.h>
+
+class MockTextManager : public TextManager
+{
+public:
+ MockTextManager() { sManager = this; }
+ virtual ~MockTextManager() { sManager = nullptr; }
+ MOCK_METHOD(ImsMediaResult, sendRtt, (int sessionId, const android::String8* text), (override));
+ MOCK_METHOD(void, setMediaQualityThreshold, (int sessionId, MediaQualityThreshold* threshold),
+ (override));
+};
+
+#endif
\ No newline at end of file
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/include/core/video/MockVideoManager.h b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/include/core/video/MockVideoManager.h
new file mode 100644
index 0000000..ff31cbd
--- /dev/null
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/include/core/video/MockVideoManager.h
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+
+#ifndef MOCK_VIDEO_MANAGER_H
+#define MOCK_VIDEO_MANAGER_H
+
+#include <VideoManager.h>
+#include <ImsMediaDefine.h>
+#include <gmock/gmock.h>
+
+class MockVideoManager : public VideoManager
+{
+public:
+ MockVideoManager() { sManager = this; }
+ virtual ~MockVideoManager() { sManager = nullptr; }
+ MOCK_METHOD(ImsMediaResult, setPreviewSurfaceToSession,
+ (const int sessionId, ANativeWindow* surface), (override));
+ MOCK_METHOD(ImsMediaResult, setDisplaySurfaceToSession,
+ (const int sessionId, ANativeWindow* surface), (override));
+ MOCK_METHOD(void, setMediaQualityThreshold,
+ (const int sessionId, MediaQualityThreshold* threshold), (override));
+ MOCK_METHOD(void, SendInternalEvent,
+ (uint32_t event, uint64_t sessionId, uint64_t paramA, uint64_t paramB), (override));
+};
+
+#endif
\ No newline at end of file