Added HTTP support for SDP files.

Added support for playing SDP files from http links. Previously,
SDP files only worked when started from rtsp links
(rtsp://a.b.c/abc.sdp), but they are just as common in http links.

patch provided by "Oscar Rydhé <oscar.rydhe@sonyericsson.com>"

Change-Id: Ic73af3a9a002009dbe8b04c267a4621bf7fe2f46
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp
index 3f69c11..bb441cc 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.cpp
+++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp
@@ -215,6 +215,10 @@
             if (strstr(url,"m3u8")) {
                 return kOurScore;
             }
+
+            if ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) || strstr(url, ".sdp?")) {
+                return kOurScore;
+            }
         }
 
         if (!strncasecmp("rtsp://", url, 7)) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 9585aba..0736fbe 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -177,6 +177,7 @@
 void NuPlayer::setDataSource(
         const char *url, const KeyedVector<String8, String8> *headers) {
     sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
+    size_t len = strlen(url);
 
     sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
 
@@ -185,6 +186,11 @@
         source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID);
     } else if (!strncasecmp(url, "rtsp://", 7)) {
         source = new RTSPSource(notify, url, headers, mUIDValid, mUID);
+    } else if ((!strncasecmp(url, "http://", 7)
+                || !strncasecmp(url, "https://", 8))
+                    && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
+                    || strstr(url, ".sdp?"))) {
+        source = new RTSPSource(notify, url, headers, mUIDValid, mUID, true);
     } else {
         source = new GenericSource(notify, url, headers, mUIDValid, mUID);
     }
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index e402115..3035589 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -22,6 +22,7 @@
 
 #include "AnotherPacketSource.h"
 #include "MyHandler.h"
+#include "SDPLoader.h"
 
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaData.h>
@@ -33,12 +34,14 @@
         const char *url,
         const KeyedVector<String8, String8> *headers,
         bool uidValid,
-        uid_t uid)
+        uid_t uid,
+        bool isSDP)
     : Source(notify),
       mURL(url),
       mUIDValid(uidValid),
       mUID(uid),
       mFlags(0),
+      mIsSDP(isSDP),
       mState(DISCONNECTED),
       mFinalResult(OK),
       mDisconnectReplyID(0),
@@ -73,16 +76,25 @@
     }
 
     CHECK(mHandler == NULL);
+    CHECK(mSDPLoader == NULL);
 
     sp<AMessage> notify = new AMessage(kWhatNotify, mReflector->id());
 
-    mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID);
-    mLooper->registerHandler(mHandler);
-
     CHECK_EQ(mState, (int)DISCONNECTED);
     mState = CONNECTING;
 
-    mHandler->connect();
+    if (mIsSDP) {
+        mSDPLoader = new SDPLoader(notify,
+                (mFlags & kFlagIncognito) ? SDPLoader::kFlagIncognito : 0,
+                mUIDValid, mUID);
+
+        mSDPLoader->load(mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
+    } else {
+        mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID);
+        mLooper->registerHandler(mHandler);
+
+        mHandler->connect();
+    }
 }
 
 void NuPlayer::RTSPSource::stop() {
@@ -408,6 +420,12 @@
             break;
         }
 
+        case SDPLoader::kWhatSDPLoaded:
+        {
+            onSDPLoaded(msg);
+            break;
+        }
+
         default:
             TRESPASS();
     }
@@ -461,6 +479,46 @@
     mState = CONNECTED;
 }
 
+void NuPlayer::RTSPSource::onSDPLoaded(const sp<AMessage> &msg) {
+    status_t err;
+    CHECK(msg->findInt32("result", &err));
+
+    mSDPLoader.clear();
+
+    if (mDisconnectReplyID != 0) {
+        err = UNKNOWN_ERROR;
+    }
+
+    if (err == OK) {
+        sp<ASessionDescription> desc;
+        sp<RefBase> obj;
+        CHECK(msg->findObject("description", &obj));
+        desc = static_cast<ASessionDescription *>(obj.get());
+
+        AString rtspUri;
+        if (!desc->findAttribute(0, "a=control", &rtspUri)) {
+            ALOGE("Unable to find url in SDP");
+            err = UNKNOWN_ERROR;
+        } else {
+            sp<AMessage> notify = new AMessage(kWhatNotify, mReflector->id());
+
+            mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID);
+            mLooper->registerHandler(mHandler);
+
+            mHandler->loadSDP(desc);
+        }
+    }
+
+    if (err != OK) {
+        mState = DISCONNECTED;
+        mFinalResult = err;
+
+        if (mDisconnectReplyID != 0) {
+            finishDisconnectIfPossible();
+        }
+    }
+}
+
 void NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) {
     status_t err;
     CHECK(msg->findInt32("result", &err));
@@ -479,7 +537,11 @@
 
 void NuPlayer::RTSPSource::finishDisconnectIfPossible() {
     if (mState != DISCONNECTED) {
-        mHandler->disconnect();
+        if (mHandler != NULL) {
+            mHandler->disconnect();
+        } else if (mSDPLoader != NULL) {
+            mSDPLoader->cancel();
+        }
         return;
     }
 
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h
index 033b3e8..b2a7dae 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.h
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h
@@ -29,6 +29,7 @@
 struct ALooper;
 struct AnotherPacketSource;
 struct MyHandler;
+struct SDPLoader;
 
 struct NuPlayer::RTSPSource : public NuPlayer::Source {
     RTSPSource(
@@ -36,7 +37,8 @@
             const char *url,
             const KeyedVector<String8, String8> *headers,
             bool uidValid = false,
-            uid_t uid = 0);
+            uid_t uid = 0,
+            bool isSDP = false);
 
     virtual void start();
     virtual void stop();
@@ -90,6 +92,7 @@
     bool mUIDValid;
     uid_t mUID;
     uint32_t mFlags;
+    bool mIsSDP;
     State mState;
     status_t mFinalResult;
     uint32_t mDisconnectReplyID;
@@ -98,6 +101,7 @@
     sp<ALooper> mLooper;
     sp<AHandlerReflector<RTSPSource> > mReflector;
     sp<MyHandler> mHandler;
+    sp<SDPLoader> mSDPLoader;
 
     Vector<TrackInfo> mTracks;
     sp<AnotherPacketSource> mAudioTrack;
@@ -110,6 +114,7 @@
     sp<AnotherPacketSource> getSource(bool audio);
 
     void onConnected();
+    void onSDPLoaded(const sp<AMessage> &msg);
     void onDisconnected(const sp<AMessage> &msg);
     void finishDisconnectIfPossible();