GenericSource: support disconnect before NuCachedSource2 is created

Bug: 17672488
Change-Id: I96776c9679fdcfbe9a442c86447c59802b1465ac
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index f84decd..016a764 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -36,6 +36,7 @@
 #include "../../libstagefright/include/DRMExtractor.h"
 #include "../../libstagefright/include/NuCachedSource2.h"
 #include "../../libstagefright/include/WVMExtractor.h"
+#include "../../libstagefright/include/HTTPBase.h"
 
 namespace android {
 
@@ -64,6 +65,7 @@
     mAudioTimeUs = 0;
     mVideoTimeUs = 0;
     mHTTPService.clear();
+    mHttpSource.clear();
     mUri.clear();
     mUriHeaders.clear();
     mFd = -1;
@@ -284,10 +286,23 @@
     // delayed data source creation
     if (mDataSource == NULL) {
         if (!mUri.empty()) {
-            mIsWidevine = !strncasecmp(mUri.c_str(), "widevine://", 11);
+            const char* uri = mUri.c_str();
+            mIsWidevine = !strncasecmp(uri, "widevine://", 11);
+
+            if (!strncasecmp("http://", uri, 7)
+                    || !strncasecmp("https://", uri, 8)
+                    || mIsWidevine) {
+                mHttpSource = DataSource::CreateMediaHTTP(mHTTPService);
+                if (mHttpSource == NULL) {
+                    ALOGE("Failed to create http source!");
+                    notifyPreparedAndCleanup(UNKNOWN_ERROR);
+                    return;
+                }
+            }
 
             mDataSource = DataSource::CreateFromURI(
-                   mHTTPService, mUri.c_str(), &mUriHeaders, &mContentType);
+                   mHTTPService, uri, &mUriHeaders, &mContentType,
+                   static_cast<HTTPBase *>(mHttpSource.get()));
         } else {
             // set to false first, if the extractor
             // comes back as secure, set it to true then.
@@ -360,6 +375,7 @@
         mSniffedMIME = "";
         mDataSource.clear();
         mCachedSource.clear();
+        mHttpSource.clear();
 
         cancelPollBuffering();
     }
@@ -479,6 +495,8 @@
         if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
             static_cast<NuCachedSource2 *>(mDataSource.get())->disconnect();
         }
+    } else if (mHttpSource != NULL) {
+        static_cast<HTTPBase *>(mHttpSource.get())->disconnect();
     }
 }
 
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 24bb6af..5ed4d52 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -126,6 +126,7 @@
 
     sp<DataSource> mDataSource;
     sp<NuCachedSource2> mCachedSource;
+    sp<DataSource> mHttpSource;
     sp<WVMExtractor> mWVMExtractor;
     sp<MetaData> mFileMeta;
     DrmManagerClient *mDrmManagerClient;
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index a72cbd5..c99db84 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -186,7 +186,8 @@
         const sp<IMediaHTTPService> &httpService,
         const char *uri,
         const KeyedVector<String8, String8> *headers,
-        String8 *contentType) {
+        String8 *contentType,
+        HTTPBase *httpSource) {
     if (contentType != NULL) {
         *contentType = "";
     }
@@ -204,14 +205,15 @@
             return NULL;
         }
 
-        sp<IMediaHTTPConnection> conn = httpService->makeHTTPConnection();
-        if (conn == NULL) {
-            ALOGE("Failed to make http connection from http service!");
-            return NULL;
+        if (httpSource == NULL) {
+            sp<IMediaHTTPConnection> conn = httpService->makeHTTPConnection();
+            if (conn == NULL) {
+                ALOGE("Failed to make http connection from http service!");
+                return NULL;
+            }
+            httpSource = new MediaHTTP(conn);
         }
 
-        sp<HTTPBase> httpSource = new MediaHTTP(conn);
-
         String8 tmp;
         if (isWidevine) {
             tmp = String8("http://");
@@ -264,6 +266,19 @@
     return source;
 }
 
+sp<DataSource> DataSource::CreateMediaHTTP(const sp<IMediaHTTPService> &httpService) {
+    if (httpService == NULL) {
+        return NULL;
+    }
+
+    sp<IMediaHTTPConnection> conn = httpService->makeHTTPConnection();
+    if (conn == NULL) {
+        return NULL;
+    } else {
+        return new MediaHTTP(conn);
+    }
+}
+
 String8 DataSource::getMIMEType() const {
     return String8("application/octet-stream");
 }