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