While streaming media data, upon a socket-read error, try reconnecting to the server and attempt to re-read for at most 3 times.

Change-Id: I7534905e07a6456d18b26d5d60fa8915f25ae99e
related-to-bug: 2492187
diff --git a/include/media/stagefright/HTTPDataSource.h b/include/media/stagefright/HTTPDataSource.h
index b6176eb..b5d1e7a 100644
--- a/include/media/stagefright/HTTPDataSource.h
+++ b/include/media/stagefright/HTTPDataSource.h
@@ -54,7 +54,11 @@
 
 private:
     enum {
-        kBufferSize = 32 * 1024
+        kBufferSize = 32 * 1024,
+
+        // If we encounter a socket-read error we'll try reconnecting
+        // and restarting the read for at most this many times.
+        kMaxNumRetries = 3,
     };
 
     enum State {
@@ -84,6 +88,8 @@
     bool mContentLengthValid;
     unsigned long long mContentLength;
 
+    int32_t mNumRetriesLeft;
+
     void init(const KeyedVector<String8, String8> *headers);
 
     ssize_t sendRangeRequest(size_t offset);
diff --git a/media/libstagefright/HTTPDataSource.cpp b/media/libstagefright/HTTPDataSource.cpp
index 451fc26..00af8a3 100644
--- a/media/libstagefright/HTTPDataSource.cpp
+++ b/media/libstagefright/HTTPDataSource.cpp
@@ -154,8 +154,8 @@
     initHeaders(headers);
 
     mBuffer = malloc(kBufferSize);
-    mBufferLength = 0;
-    mBufferOffset = 0;
+
+    mNumRetriesLeft = kMaxNumRetries;
 }
 
 status_t HTTPDataSource::connect() {
@@ -169,6 +169,8 @@
         mState = CONNECTING;
     }
 
+    mBufferLength = 0;
+    mBufferOffset = 0;
     mContentLengthValid = false;
 
     string host = mStartingHost.string();
@@ -328,6 +330,7 @@
 ssize_t HTTPDataSource::readAt(off_t offset, void *data, size_t size) {
     LOGV("readAt %ld, size %d", offset, size);
 
+rinse_repeat:
     {
         Mutex::Autolock autoLock(mStateLock);
         if (mState != CONNECTED) {
@@ -383,6 +386,15 @@
     ssize_t num_bytes_received = mHttp->receive(mBuffer, contentLength);
 
     if (num_bytes_received < 0) {
+        if (mNumRetriesLeft-- > 0) {
+            disconnect();
+            if (connect() == OK) {
+                LOGI("retrying connection succeeded.");
+                goto rinse_repeat;
+            }
+            LOGE("retrying connection failed");
+        }
+
         mBufferLength = 0;
 
         return num_bytes_received;
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index 66eadf6..3aad72c 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -289,11 +289,15 @@
                 continue;
             }
 
+            LOGE("recv failed, errno = %d (%s)", errno, strerror(errno));
+
             disconnect();
-            return total == 0 ? (ssize_t)ERROR_IO : total;
+            return (ssize_t)ERROR_IO;
         } else if (n == 0) {
             disconnect();
 
+            LOGE("recv failed, server is gone");
+
             return total == 0 ? (ssize_t)ERROR_CONNECTION_LOST : total;
         }