Disconnect HTTP-based data source upon reset

Bug: 17425250

Change-Id: Ieb4c93fd9848489f9dbf35a36474376924fd8eb9
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index d8ed836..0b85b23 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -464,6 +464,15 @@
     mStarted = true;
 }
 
+void NuPlayer::GenericSource::disconnect() {
+    if (mDataSource != NULL) {
+        // disconnect data source
+        if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
+            static_cast<NuCachedSource2 *>(mDataSource.get())->disconnect();
+        }
+    }
+}
+
 void NuPlayer::GenericSource::setDrmPlaybackStatusIfNeeded(int playbackStatus, int64_t position) {
     if (mDecryptHandle != NULL) {
         mDrmManagerClient->setPlaybackStatus(mDecryptHandle, playbackStatus, position);
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index c70c48e..454edeb 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -55,6 +55,8 @@
     virtual void pause();
     virtual void resume();
 
+    virtual void disconnect();
+
     virtual status_t feedMoreTSData();
 
     virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index df3e992..078e78b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -306,6 +306,16 @@
 }
 
 void NuPlayer::resetAsync() {
+    if (mSource != NULL) {
+        // During a reset, the data source might be unresponsive already, we need to
+        // disconnect explicitly so that reads exit promptly.
+        // We can't queue the disconnect request to the looper, as it might be
+        // queued behind a stuck read and never gets processed.
+        // Doing a disconnect outside the looper to allows the pending reads to exit
+        // (either successfully or with error).
+        mSource->disconnect();
+    }
+
     (new AMessage(kWhatReset, id()))->post();
 }
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index 7ccf3b1..7d994fa 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -67,6 +67,9 @@
     virtual void pause() {}
     virtual void resume() {}
 
+    // Explicitly disconnect the underling data source
+    virtual void disconnect() {}
+
     // Returns OK iff more data was available,
     // an error or ERROR_END_OF_STREAM if not.
     virtual status_t feedMoreTSData() = 0;