Merge "Adjust activity manager process OOM adj." into kraken
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 2a8c035..4a1580f 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1152,7 +1152,7 @@
         mConnectingDataSource = new NuHTTPDataSource;
 
         mLock.unlock();
-        status_t err = mConnectingDataSource->connect(mUri/*, mUriHeaders */);
+        status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
         mLock.lock();
 
         if (err != OK) {
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 6e4f9df..90a596c 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -109,7 +109,7 @@
         source = new FileSource(uri + 7);
     } else if (!strncasecmp("http://", uri, 7)) {
         sp<NuHTTPDataSource> httpSource = new NuHTTPDataSource;
-        if (httpSource->connect(uri /* , headers */) != OK) {
+        if (httpSource->connect(uri, headers) != OK) {
             return NULL;
         }
         source = new NuCachedSource2(httpSource);
diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp
index 8587c1b..ab9285d 100644
--- a/media/libstagefright/NuHTTPDataSource.cpp
+++ b/media/libstagefright/NuHTTPDataSource.cpp
@@ -4,6 +4,7 @@
 
 #include "include/NuHTTPDataSource.h"
 
+#include <cutils/properties.h>
 #include <media/stagefright/MediaDebug.h>
 #include <media/stagefright/MediaErrors.h>
 
@@ -72,18 +73,33 @@
 NuHTTPDataSource::~NuHTTPDataSource() {
 }
 
-status_t NuHTTPDataSource::connect(const char *uri, off_t offset) {
+status_t NuHTTPDataSource::connect(
+        const char *uri,
+        const KeyedVector<String8, String8> *overrides,
+        off_t offset) {
+    String8 headers;
+    MakeFullHeaders(overrides, &headers);
+
+    return connect(uri, headers, offset);
+}
+
+status_t NuHTTPDataSource::connect(
+        const char *uri,
+        const String8 &headers,
+        off_t offset) {
     String8 host, path;
     unsigned port;
     if (!ParseURL(uri, &host, &port, &path)) {
         return ERROR_MALFORMED;
     }
 
-    return connect(host, port, path, offset);
+    return connect(host, port, path, headers, offset);
 }
 
 status_t NuHTTPDataSource::connect(
-        const char *host, unsigned port, const char *path, off_t offset) {
+        const char *host, unsigned port, const char *path,
+        const String8 &headers,
+        off_t offset) {
     LOGI("connect to %s:%u%s @%ld", host, port, path, offset);
 
     bool needsToReconnect = true;
@@ -99,6 +115,7 @@
     mHost = host;
     mPort = port;
     mPath = path;
+    mHeaders = headers;
 
     status_t err = OK;
 
@@ -133,6 +150,7 @@
             request.append(rangeHeader);
         }
 
+        request.append(mHeaders);
         request.append("\r\n");
 
         int httpStatus;
@@ -151,10 +169,17 @@
 
             mHTTP.disconnect();
 
-            return connect(value.c_str());
+            return connect(value.c_str(), headers, offset);
         }
 
-        CHECK(httpStatus >= 200 && httpStatus < 300);
+        if (httpStatus < 200 || httpStatus >= 300) {
+            mState = DISCONNECTED;
+            mHTTP.disconnect();
+
+            return ERROR_IO;
+        }
+
+        applyTimeoutResponse();
 
         if (offset == 0) {
             string value;
@@ -200,7 +225,8 @@
     if (offset != mOffset) {
         String8 host = mHost;
         String8 path = mPath;
-        status_t err = connect(host, mPort, path, offset);
+        String8 headers = mHeaders;
+        status_t err = connect(host, mPort, path, headers, offset);
 
         if (err != OK) {
             return err;
@@ -262,4 +288,51 @@
     return kWantsPrefetching;
 }
 
+// static
+void NuHTTPDataSource::MakeFullHeaders(
+        const KeyedVector<String8, String8> *overrides, String8 *headers) {
+    headers->setTo("");
+
+    headers->append("User-Agent: stagefright/1.1 (Linux;Android ");
+
+#if (PROPERTY_VALUE_MAX < 8)
+#error "PROPERTY_VALUE_MAX must be at least 8"
+#endif
+
+    char value[PROPERTY_VALUE_MAX];
+    property_get("ro.build.version.release", value, "Unknown");
+    headers->append(value);
+    headers->append(")\r\n");
+
+    if (overrides == NULL) {
+        return;
+    }
+
+    for (size_t i = 0; i < overrides->size(); ++i) {
+        String8 line;
+        line.append(overrides->keyAt(i));
+        line.append(": ");
+        line.append(overrides->valueAt(i));
+        line.append("\r\n");
+
+        headers->append(line);
+    }
+}
+
+void NuHTTPDataSource::applyTimeoutResponse() {
+    string timeout;
+    if (mHTTP.find_header_value("X-SocketTimeout", &timeout)) {
+        const char *s = timeout.c_str();
+        char *end;
+        long tmp = strtol(s, &end, 10);
+        if (end == s || *end != '\0') {
+            LOGW("Illegal X-SocketTimeout value given.");
+            return;
+        }
+
+        LOGI("overriding default timeout, new timeout is %ld seconds", tmp);
+        mHTTP.setReceiveTimeout(tmp);
+    }
+}
+
 }  // namespace android
diff --git a/media/libstagefright/include/NuHTTPDataSource.h b/media/libstagefright/include/NuHTTPDataSource.h
index 33339e2..8593a91 100644
--- a/media/libstagefright/include/NuHTTPDataSource.h
+++ b/media/libstagefright/include/NuHTTPDataSource.h
@@ -13,10 +13,9 @@
 struct NuHTTPDataSource : public DataSource {
     NuHTTPDataSource();
 
-    status_t connect(const char *uri, off_t offset = 0);
-
     status_t connect(
-            const char *host, unsigned port, const char *path,
+            const char *uri,
+            const KeyedVector<String8, String8> *headers = NULL,
             off_t offset = 0);
 
     void disconnect();
@@ -44,12 +43,27 @@
     String8 mHost;
     unsigned mPort;
     String8 mPath;
+    String8 mHeaders;
 
     HTTPStream mHTTP;
     off_t mOffset;
     off_t mContentLength;
     bool mContentLengthValid;
 
+    status_t connect(
+            const char *uri, const String8 &headers, off_t offset);
+
+    status_t connect(
+            const char *host, unsigned port, const char *path,
+            const String8 &headers,
+            off_t offset);
+
+    void applyTimeoutResponse();
+
+    static void MakeFullHeaders(
+            const KeyedVector<String8, String8> *overrides,
+            String8 *headers);
+
     NuHTTPDataSource(const NuHTTPDataSource &);
     NuHTTPDataSource &operator=(const NuHTTPDataSource &);
 };