Merge "Separate the mode of the RTP and RTCP channels." into jb-mr2-dev
diff --git a/media/libstagefright/wifi-display/MediaReceiver.cpp b/media/libstagefright/wifi-display/MediaReceiver.cpp
index 10a2dff..e2e791d 100644
--- a/media/libstagefright/wifi-display/MediaReceiver.cpp
+++ b/media/libstagefright/wifi-display/MediaReceiver.cpp
@@ -73,7 +73,12 @@
     info.mReceiver->registerPacketType(
             97, RTPReceiver::PACKETIZATION_H264);
 
-    status_t err = info.mReceiver->initAsync(transportMode, localRTPPort);
+    status_t err = info.mReceiver->initAsync(
+            transportMode,  // rtpMode
+            transportMode == RTPReceiver::TRANSPORT_UDP
+                ? transportMode
+                : RTPReceiver::TRANSPORT_NONE,  // rtcpMode
+            localRTPPort);
 
     if (err != OK) {
         looper()->unregisterHandler(info.mReceiver->id());
diff --git a/media/libstagefright/wifi-display/MediaSender.cpp b/media/libstagefright/wifi-display/MediaSender.cpp
index d13a92e..6fc50f7 100644
--- a/media/libstagefright/wifi-display/MediaSender.cpp
+++ b/media/libstagefright/wifi-display/MediaSender.cpp
@@ -124,10 +124,14 @@
             looper()->registerHandler(mTSSender);
 
             err = mTSSender->initAsync(
-                    transportMode,
                     remoteHost,
                     remoteRTPPort,
+                    transportMode,  // rtpMode
                     remoteRTCPPort,
+                    (transportMode == RTPSender::TRANSPORT_UDP
+                        && remoteRTCPPort >= 0)
+                        ? transportMode
+                        : RTPSender::TRANSPORT_NONE,  // rtcpMode
                     localRTPPort);
 
             if (err != OK) {
@@ -174,10 +178,13 @@
     looper()->registerHandler(info->mSender);
 
     status_t err = info->mSender->initAsync(
-            transportMode,
             remoteHost,
             remoteRTPPort,
+            transportMode,  // rtpMode
             remoteRTCPPort,
+            (transportMode == RTPSender::TRANSPORT_UDP && remoteRTCPPort >= 0)
+                ? transportMode
+                : RTPSender::TRANSPORT_NONE,  // rtcpMode
             localRTPPort);
 
     if (err != OK) {
diff --git a/media/libstagefright/wifi-display/rtp/RTPBase.h b/media/libstagefright/wifi-display/rtp/RTPBase.h
index 6507a6f..e3fa845 100644
--- a/media/libstagefright/wifi-display/rtp/RTPBase.h
+++ b/media/libstagefright/wifi-display/rtp/RTPBase.h
@@ -29,6 +29,7 @@
 
     enum TransportMode {
         TRANSPORT_UNDEFINED,
+        TRANSPORT_NONE,
         TRANSPORT_UDP,
         TRANSPORT_TCP,
         TRANSPORT_TCP_INTERLEAVED,
diff --git a/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp b/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp
index 8711b08..c55e0be 100644
--- a/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp
+++ b/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp
@@ -407,13 +407,22 @@
         const sp<AMessage> &notify)
     : mNetSession(netSession),
       mNotify(notify),
-      mMode(TRANSPORT_UNDEFINED),
+      mRTPMode(TRANSPORT_UNDEFINED),
+      mRTCPMode(TRANSPORT_UNDEFINED),
       mRTPSessionID(0),
       mRTCPSessionID(0),
-      mRTPClientSessionID(0) {
+      mRTPConnected(false),
+      mRTCPConnected(false),
+      mRTPClientSessionID(0),
+      mRTCPClientSessionID(0) {
 }
 
 RTPReceiver::~RTPReceiver() {
+    if (mRTCPClientSessionID != 0) {
+        mNetSession->destroySession(mRTCPClientSessionID);
+        mRTCPClientSessionID = 0;
+    }
+
     if (mRTPClientSessionID != 0) {
         mNetSession->destroySession(mRTPClientSessionID);
         mRTPClientSessionID = 0;
@@ -430,17 +439,24 @@
     }
 }
 
-status_t RTPReceiver::initAsync(TransportMode mode, int32_t *outLocalRTPPort) {
-    if (mMode != TRANSPORT_UNDEFINED || mode == TRANSPORT_UNDEFINED) {
+status_t RTPReceiver::initAsync(
+        TransportMode rtpMode,
+        TransportMode rtcpMode,
+        int32_t *outLocalRTPPort) {
+    if (mRTPMode != TRANSPORT_UNDEFINED
+            || rtpMode == TRANSPORT_UNDEFINED
+            || rtpMode == TRANSPORT_NONE
+            || rtcpMode == TRANSPORT_UNDEFINED) {
         return INVALID_OPERATION;
     }
 
-    CHECK_NE(mMode, TRANSPORT_TCP_INTERLEAVED);
+    CHECK_NE(rtpMode, TRANSPORT_TCP_INTERLEAVED);
+    CHECK_NE(rtcpMode, TRANSPORT_TCP_INTERLEAVED);
 
     sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
 
     sp<AMessage> rtcpNotify;
-    if (mode == TRANSPORT_UDP) {
+    if (rtcpMode != TRANSPORT_NONE) {
         rtcpNotify = new AMessage(kWhatRTCPNotify, id());
     }
 
@@ -456,13 +472,13 @@
         localRTPPort = PickRandomRTPPort();
 
         status_t err;
-        if (mode == TRANSPORT_UDP) {
+        if (rtpMode == TRANSPORT_UDP) {
             err = mNetSession->createUDPSession(
                     localRTPPort,
                     rtpNotify,
                     &mRTPSessionID);
         } else {
-            CHECK_EQ(mode, TRANSPORT_TCP);
+            CHECK_EQ(rtpMode, TRANSPORT_TCP);
             err = mNetSession->createTCPDatagramSession(
                     ifaceAddr,
                     localRTPPort,
@@ -474,15 +490,22 @@
             continue;
         }
 
-        if (mode == TRANSPORT_TCP) {
+        if (rtcpMode == TRANSPORT_NONE) {
             break;
+        } else if (rtcpMode == TRANSPORT_UDP) {
+            err = mNetSession->createUDPSession(
+                    localRTPPort + 1,
+                    rtcpNotify,
+                    &mRTCPSessionID);
+        } else {
+            CHECK_EQ(rtpMode, TRANSPORT_TCP);
+            err = mNetSession->createTCPDatagramSession(
+                    ifaceAddr,
+                    localRTPPort + 1,
+                    rtcpNotify,
+                    &mRTCPSessionID);
         }
 
-        err = mNetSession->createUDPSession(
-                localRTPPort + 1,
-                rtcpNotify,
-                &mRTCPSessionID);
-
         if (err == OK) {
             break;
         }
@@ -491,7 +514,8 @@
         mRTPSessionID = 0;
     }
 
-    mMode = mode;
+    mRTPMode = rtpMode;
+    mRTCPMode = rtcpMode;
     *outLocalRTPPort = localRTPPort;
 
     return OK;
@@ -499,35 +523,46 @@
 
 status_t RTPReceiver::connect(
         const char *remoteHost, int32_t remoteRTPPort, int32_t remoteRTCPPort) {
-    if (mMode == TRANSPORT_TCP) {
-        return OK;
+    status_t err;
+
+    if (mRTPMode == TRANSPORT_UDP) {
+        CHECK(!mRTPConnected);
+
+        err = mNetSession->connectUDPSession(
+                mRTPSessionID, remoteHost, remoteRTPPort);
+
+        if (err != OK) {
+            notifyInitDone(err);
+            return err;
+        }
+
+        ALOGI("connectUDPSession RTP successful.");
+
+        mRTPConnected = true;
     }
 
-    status_t err = mNetSession->connectUDPSession(
-            mRTPSessionID, remoteHost, remoteRTPPort);
+    if (mRTCPMode == TRANSPORT_UDP) {
+        CHECK(!mRTCPConnected);
 
-    if (err != OK) {
-        notifyInitDone(err);
-        return err;
-    }
-
-    ALOGI("connectUDPSession RTP successful.");
-
-    if (remoteRTCPPort >= 0) {
         err = mNetSession->connectUDPSession(
                 mRTCPSessionID, remoteHost, remoteRTCPPort);
 
         if (err != OK) {
-        ALOGI("connect failed w/ err %d", err);
-
             notifyInitDone(err);
             return err;
         }
 
         scheduleSendRR();
+
+        ALOGI("connectUDPSession RTCP successful.");
+
+        mRTCPConnected = true;
     }
 
-    notifyInitDone(OK);
+    if (mRTPConnected
+            && (mRTCPConnected || mRTCPMode == TRANSPORT_NONE)) {
+        notifyInitDone(OK);
+    }
 
     return OK;
 }
@@ -615,15 +650,18 @@
 
             if (sessionID == mRTPSessionID) {
                 mRTPSessionID = 0;
-
-                if (mMode == TRANSPORT_TCP && mRTPClientSessionID == 0) {
-                    notifyInitDone(err);
-                    break;
-                }
             } else if (sessionID == mRTCPSessionID) {
                 mRTCPSessionID = 0;
             } else if (sessionID == mRTPClientSessionID) {
                 mRTPClientSessionID = 0;
+            } else if (sessionID == mRTCPClientSessionID) {
+                mRTCPClientSessionID = 0;
+            }
+
+            if (!mRTPConnected
+                    || (mRTCPMode != TRANSPORT_NONE && !mRTCPConnected)) {
+                notifyInitDone(err);
+                break;
             }
 
             notifyError(err);
@@ -645,22 +683,39 @@
 
         case ANetworkSession::kWhatClientConnected:
         {
-            CHECK_EQ(mMode, TRANSPORT_TCP);
-            CHECK(isRTP);
-
             int32_t sessionID;
             CHECK(msg->findInt32("sessionID", &sessionID));
 
-            if (mRTPClientSessionID != 0) {
-                // We only allow a single client connection.
-                mNetSession->destroySession(sessionID);
-                sessionID = 0;
-                break;
+            if (isRTP) {
+                CHECK_EQ(mRTPMode, TRANSPORT_TCP);
+
+                if (mRTPClientSessionID != 0) {
+                    // We only allow a single client connection.
+                    mNetSession->destroySession(sessionID);
+                    sessionID = 0;
+                    break;
+                }
+
+                mRTPClientSessionID = sessionID;
+                mRTPConnected = true;
+            } else {
+                CHECK_EQ(mRTCPMode, TRANSPORT_TCP);
+
+                if (mRTCPClientSessionID != 0) {
+                    // We only allow a single client connection.
+                    mNetSession->destroySession(sessionID);
+                    sessionID = 0;
+                    break;
+                }
+
+                mRTCPClientSessionID = sessionID;
+                mRTCPConnected = true;
             }
 
-            mRTPClientSessionID = sessionID;
-
-            notifyInitDone(OK);
+            if (mRTPConnected
+                    && (mRTCPConnected || mRTCPMode == TRANSPORT_NONE)) {
+                notifyInitDone(OK);
+            }
             break;
         }
     }
diff --git a/media/libstagefright/wifi-display/rtp/RTPReceiver.h b/media/libstagefright/wifi-display/rtp/RTPReceiver.h
index ec4671d..abbe6a8 100644
--- a/media/libstagefright/wifi-display/rtp/RTPReceiver.h
+++ b/media/libstagefright/wifi-display/rtp/RTPReceiver.h
@@ -46,7 +46,10 @@
     status_t registerPacketType(
             uint8_t packetType, PacketizationMode mode);
 
-    status_t initAsync(TransportMode mode, int32_t *outLocalRTPPort);
+    status_t initAsync(
+            TransportMode rtpMode,
+            TransportMode rtcpMode,
+            int32_t *outLocalRTPPort);
 
     status_t connect(
             const char *remoteHost,
@@ -79,11 +82,15 @@
 
     sp<ANetworkSession> mNetSession;
     sp<AMessage> mNotify;
-    TransportMode mMode;
+    TransportMode mRTPMode;
+    TransportMode mRTCPMode;
     int32_t mRTPSessionID;
     int32_t mRTCPSessionID;
+    bool mRTPConnected;
+    bool mRTCPConnected;
 
     int32_t mRTPClientSessionID;  // in TRANSPORT_TCP mode.
+    int32_t mRTCPClientSessionID;  // in TRANSPORT_TCP mode.
 
     KeyedVector<uint8_t, PacketizationMode> mPacketTypes;
     KeyedVector<uint32_t, sp<Source> > mSources;
diff --git a/media/libstagefright/wifi-display/rtp/RTPSender.cpp b/media/libstagefright/wifi-display/rtp/RTPSender.cpp
index c8e265c..c686e01 100644
--- a/media/libstagefright/wifi-display/rtp/RTPSender.cpp
+++ b/media/libstagefright/wifi-display/rtp/RTPSender.cpp
@@ -38,7 +38,8 @@
         const sp<AMessage> &notify)
     : mNetSession(netSession),
       mNotify(notify),
-      mMode(TRANSPORT_UNDEFINED),
+      mRTPMode(TRANSPORT_UNDEFINED),
+      mRTCPMode(TRANSPORT_UNDEFINED),
       mRTPSessionID(0),
       mRTCPSessionID(0),
       mRTPConnected(false),
@@ -74,18 +75,24 @@
 }
 
 status_t RTPSender::initAsync(
-        TransportMode mode,
         const char *remoteHost,
         int32_t remoteRTPPort,
+        TransportMode rtpMode,
         int32_t remoteRTCPPort,
+        TransportMode rtcpMode,
         int32_t *outLocalRTPPort) {
-    if (mMode != TRANSPORT_UNDEFINED || mode == TRANSPORT_UNDEFINED) {
+    if (mRTPMode != TRANSPORT_UNDEFINED
+            || rtpMode == TRANSPORT_UNDEFINED
+            || rtpMode == TRANSPORT_NONE
+            || rtcpMode == TRANSPORT_UNDEFINED) {
         return INVALID_OPERATION;
     }
 
-    CHECK_NE(mMode, TRANSPORT_TCP_INTERLEAVED);
+    CHECK_NE(rtpMode, TRANSPORT_TCP_INTERLEAVED);
+    CHECK_NE(rtcpMode, TRANSPORT_TCP_INTERLEAVED);
 
-    if (mode == TRANSPORT_TCP && remoteRTCPPort >= 0) {
+    if (rtcpMode == TRANSPORT_NONE && remoteRTCPPort >= 0
+            || rtcpMode != TRANSPORT_NONE && remoteRTCPPort < 0) {
         return INVALID_OPERATION;
     }
 
@@ -105,7 +112,7 @@
         localRTPPort = PickRandomRTPPort();
 
         status_t err;
-        if (mode == TRANSPORT_UDP) {
+        if (rtpMode == TRANSPORT_UDP) {
             err = mNetSession->createUDPSession(
                     localRTPPort,
                     remoteHost,
@@ -113,7 +120,7 @@
                     rtpNotify,
                     &mRTPSessionID);
         } else {
-            CHECK_EQ(mode, TRANSPORT_TCP);
+            CHECK_EQ(rtpMode, TRANSPORT_TCP);
             err = mNetSession->createTCPDatagramSession(
                     localRTPPort,
                     remoteHost,
@@ -130,7 +137,7 @@
             break;
         }
 
-        if (mode == TRANSPORT_UDP) {
+        if (rtcpMode == TRANSPORT_UDP) {
             err = mNetSession->createUDPSession(
                     localRTPPort + 1,
                     remoteHost,
@@ -138,7 +145,7 @@
                     rtcpNotify,
                     &mRTCPSessionID);
         } else {
-            CHECK_EQ(mode, TRANSPORT_TCP);
+            CHECK_EQ(rtcpMode, TRANSPORT_TCP);
             err = mNetSession->createTCPDatagramSession(
                     localRTPPort + 1,
                     remoteHost,
@@ -155,15 +162,20 @@
         mRTPSessionID = 0;
     }
 
-    if (mode == TRANSPORT_UDP) {
+    if (rtpMode == TRANSPORT_UDP) {
         mRTPConnected = true;
+    }
+
+    if (rtcpMode == TRANSPORT_UDP) {
         mRTCPConnected = true;
     }
 
-    mMode = mode;
+    mRTPMode = rtpMode;
+    mRTCPMode = rtcpMode;
     *outLocalRTPPort = localRTPPort;
 
-    if (mMode == TRANSPORT_UDP) {
+    if (mRTPMode == TRANSPORT_UDP
+            && (mRTCPMode == TRANSPORT_UDP || mRTCPMode == TRANSPORT_NONE)) {
         notifyInitDone(OK);
     }
 
@@ -496,12 +508,12 @@
                 mRTCPSessionID = 0;
             }
 
-            if (mMode == TRANSPORT_TCP) {
-                if (!mRTPConnected
-                        || (mRTCPSessionID > 0 && !mRTCPConnected)) {
-                    notifyInitDone(err);
-                    break;
-                }
+            if (!mRTPConnected
+                    || (mRTPMode != TRANSPORT_NONE && !mRTCPConnected)) {
+                // We haven't completed initialization, attach the error
+                // to the notification instead.
+                notifyInitDone(err);
+                break;
             }
 
             notifyError(err);
@@ -523,20 +535,21 @@
 
         case ANetworkSession::kWhatConnected:
         {
-            CHECK_EQ(mMode, TRANSPORT_TCP);
-
             int32_t sessionID;
             CHECK(msg->findInt32("sessionID", &sessionID));
 
             if  (isRTP) {
+                CHECK_EQ(mRTPMode, TRANSPORT_TCP);
                 CHECK_EQ(sessionID, mRTPSessionID);
                 mRTPConnected = true;
             } else {
+                CHECK_EQ(mRTCPMode, TRANSPORT_TCP);
                 CHECK_EQ(sessionID, mRTCPSessionID);
                 mRTCPConnected = true;
             }
 
-            if (mRTPConnected && (mRTCPSessionID == 0 || mRTCPConnected)) {
+            if (mRTPConnected
+                    && (mRTCPMode == TRANSPORT_NONE || mRTCPConnected)) {
                 notifyInitDone(OK);
             }
             break;
diff --git a/media/libstagefright/wifi-display/rtp/RTPSender.h b/media/libstagefright/wifi-display/rtp/RTPSender.h
index 90b1796..8409b8d 100644
--- a/media/libstagefright/wifi-display/rtp/RTPSender.h
+++ b/media/libstagefright/wifi-display/rtp/RTPSender.h
@@ -43,10 +43,11 @@
             const sp<AMessage> &notify);
 
     status_t initAsync(
-              TransportMode mode,
               const char *remoteHost,
               int32_t remoteRTPPort,
+              TransportMode rtpMode,
               int32_t remoteRTCPPort,
+              TransportMode rtcpMode,
               int32_t *outLocalRTPPort);
 
     status_t queueBuffer(
@@ -72,7 +73,8 @@
 
     sp<ANetworkSession> mNetSession;
     sp<AMessage> mNotify;
-    TransportMode mMode;
+    TransportMode mRTPMode;
+    TransportMode mRTCPMode;
     int32_t mRTPSessionID;
     int32_t mRTCPSessionID;
     bool mRTPConnected;
diff --git a/media/libstagefright/wifi-display/rtptest.cpp b/media/libstagefright/wifi-display/rtptest.cpp
index 607d9d2..eade832 100644
--- a/media/libstagefright/wifi-display/rtptest.cpp
+++ b/media/libstagefright/wifi-display/rtptest.cpp
@@ -106,7 +106,9 @@
             int32_t receiverRTPPort;
             CHECK_EQ((status_t)OK,
                      mReceiver->initAsync(
-                         RTPReceiver::TRANSPORT_UDP, &receiverRTPPort));
+                         RTPReceiver::TRANSPORT_UDP,  // rtpMode
+                         RTPReceiver::TRANSPORT_UDP,  // rtcpMode
+                         &receiverRTPPort));
 
             printf("picked receiverRTPPort %d\n", receiverRTPPort);
 
@@ -155,10 +157,11 @@
             int32_t senderRTPPort;
             CHECK_EQ((status_t)OK,
                      mSender->initAsync(
-                         RTPSender::TRANSPORT_UDP,
                          host.c_str(),
                          receiverRTPPort,
+                         RTPSender::TRANSPORT_UDP,  // rtpMode
                          receiverRTPPort + 1,
+                         RTPSender::TRANSPORT_UDP,  // rtcpMode
                          &senderRTPPort));
 
             printf("picked senderRTPPort %d\n", senderRTPPort);