Merge "libmedia: Preserve futex return status in client obtainBuffer"
am: 7253644736

* commit '7253644736198864a1f2fe95788e7eb41ecc2428':
  libmedia: Preserve futex return status in client obtainBuffer
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index a398ff7..22f8af7 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -321,7 +321,9 @@
 
             if (overflow || sumSubsampleSizes != totalSize) {
                 result = -EINVAL;
-            } else if (offset + totalSize > sharedBuffer->size()) {
+            } else if (totalSize > sharedBuffer->size()) {
+                result = -EINVAL;
+            } else if ((size_t)offset > sharedBuffer->size() - totalSize) {
                 result = -EINVAL;
             } else {
                 result = decrypt(
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 8db07ca..3c50747 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1890,8 +1890,13 @@
 void MediaPlayerService::AudioOutput::close()
 {
     ALOGV("close");
-    Mutex::Autolock lock(mLock);
-    close_l();
+    sp<AudioTrack> track;
+    {
+        Mutex::Autolock lock(mLock);
+        track = mTrack;
+        close_l(); // clears mTrack
+    }
+    // destruction of the track occurs outside of mutex.
 }
 
 void MediaPlayerService::AudioOutput::setVolume(float left, float right)
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index 8240f83..f2a4e65 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -37,6 +37,10 @@
 
 #include <inttypes.h>
 
+#ifndef INT32_MAX
+#define INT32_MAX   2147483647
+#endif
+
 namespace android {
 
 template<class T>
@@ -137,6 +141,11 @@
     if (mColorFormat != OMX_COLOR_FormatYUV420Planar || mInputDataIsMeta) {
         // Color conversion is needed.
         free(mInputFrameData);
+        mInputFrameData = NULL;
+        if (((uint64_t)mWidth * mHeight) > ((uint64_t)INT32_MAX / 3)) {
+            ALOGE("b/25812794, Buffer size is too big.");
+            return OMX_ErrorBadParameter;
+        }
         mInputFrameData =
             (uint8_t *) malloc((mWidth * mHeight * 3 ) >> 1);
         CHECK(mInputFrameData != NULL);
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
index e654843..410f9d0 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
@@ -26,6 +26,10 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaDefs.h>
 
+#ifndef INT32_MAX
+#define INT32_MAX   2147483647
+#endif
+
 namespace android {
 
 template<class T>
@@ -315,6 +319,11 @@
 
     if (mColorFormat != OMX_COLOR_FormatYUV420Planar || mInputDataIsMeta) {
         free(mConversionBuffer);
+        mConversionBuffer = NULL;
+        if (((uint64_t)mWidth * mHeight) > ((uint64_t)INT32_MAX / 3)) {
+            ALOGE("b/25812794, Buffer size is too big.");
+            return UNKNOWN_ERROR;
+        }
         mConversionBuffer = (uint8_t *)malloc(mWidth * mHeight * 3 / 2);
         if (mConversionBuffer == NULL) {
             ALOGE("Allocating conversion buffer failed.");
diff --git a/media/libstagefright/foundation/ALooper.cpp b/media/libstagefright/foundation/ALooper.cpp
index 5c2e9f9..9921636 100644
--- a/media/libstagefright/foundation/ALooper.cpp
+++ b/media/libstagefright/foundation/ALooper.cpp
@@ -234,31 +234,19 @@
 
 // to be called by AMessage::postAndAwaitResponse only
 status_t ALooper::awaitResponse(const sp<AReplyToken> &replyToken, sp<AMessage> *response) {
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (mThread == NULL) {
-            return -ENOENT;
-        }
-    }
-
     // return status in case we want to handle an interrupted wait
     Mutex::Autolock autoLock(mRepliesLock);
     CHECK(replyToken != NULL);
-    bool gotReply;
-    bool shouldContinue = true;
-    while (!(gotReply = replyToken->retrieveReply(response)) && shouldContinue) {
-        mRepliesCondition.wait(mRepliesLock);
-
+    while (!replyToken->retrieveReply(response)) {
         {
             Mutex::Autolock autoLock(mLock);
             if (mThread == NULL) {
-                shouldContinue = false;
-                // continue and try to get potential reply one more time before break the loop
+                return -ENOENT;
             }
         }
+        mRepliesCondition.wait(mRepliesLock);
     }
-
-    return gotReply ? OK : -ENOENT;
+    return OK;
 }
 
 status_t ALooper::postReply(const sp<AReplyToken> &replyToken, const sp<AMessage> &reply) {
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 4790754..6781a36 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -90,11 +90,7 @@
 }
 
 status_t ResourceManagerService::dump(int fd, const Vector<String16>& /* args */) {
-    Mutex::Autolock lock(mLock);
-
     String8 result;
-    const size_t SIZE = 256;
-    char buffer[SIZE];
 
     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
         result.format("Permission Denial: "
@@ -105,20 +101,35 @@
         return PERMISSION_DENIED;
     }
 
+    PidResourceInfosMap mapCopy;
+    bool supportsMultipleSecureCodecs;
+    bool supportsSecureWithNonSecureCodec;
+    String8 serviceLog;
+    {
+        Mutex::Autolock lock(mLock);
+        mapCopy = mMap;  // Shadow copy, real copy will happen on write.
+        supportsMultipleSecureCodecs = mSupportsMultipleSecureCodecs;
+        supportsSecureWithNonSecureCodec = mSupportsSecureWithNonSecureCodec;
+        serviceLog = mServiceLog->toString("    " /* linePrefix */);
+    }
+
+    const size_t SIZE = 256;
+    char buffer[SIZE];
     snprintf(buffer, SIZE, "ResourceManagerService: %p\n", this);
     result.append(buffer);
     result.append("  Policies:\n");
-    snprintf(buffer, SIZE, "    SupportsMultipleSecureCodecs: %d\n", mSupportsMultipleSecureCodecs);
+    snprintf(buffer, SIZE, "    SupportsMultipleSecureCodecs: %d\n", supportsMultipleSecureCodecs);
     result.append(buffer);
-    snprintf(buffer, SIZE, "    SupportsSecureWithNonSecureCodec: %d\n", mSupportsSecureWithNonSecureCodec);
+    snprintf(buffer, SIZE, "    SupportsSecureWithNonSecureCodec: %d\n",
+            supportsSecureWithNonSecureCodec);
     result.append(buffer);
 
     result.append("  Processes:\n");
-    for (size_t i = 0; i < mMap.size(); ++i) {
-        snprintf(buffer, SIZE, "    Pid: %d\n", mMap.keyAt(i));
+    for (size_t i = 0; i < mapCopy.size(); ++i) {
+        snprintf(buffer, SIZE, "    Pid: %d\n", mapCopy.keyAt(i));
         result.append(buffer);
 
-        const ResourceInfos &infos = mMap.valueAt(i);
+        const ResourceInfos &infos = mapCopy.valueAt(i);
         for (size_t j = 0; j < infos.size(); ++j) {
             result.append("      Client:\n");
             snprintf(buffer, SIZE, "        Id: %lld\n", (long long)infos[j].clientId);
@@ -136,7 +147,7 @@
         }
     }
     result.append("  Events logs (most recent at top):\n");
-    result.append(mServiceLog->toString("    " /* linePrefix */));
+    result.append(serviceLog);
 
     write(fd, result.string(), result.size());
     return OK;
@@ -307,6 +318,10 @@
         }
     }
 
+    if (failedClient == NULL) {
+        return true;
+    }
+
     {
         Mutex::Autolock lock(mLock);
         bool found = false;
@@ -329,7 +344,7 @@
         }
     }
 
-    return (failedClient == NULL);
+    return false;
 }
 
 bool ResourceManagerService::getAllClients_l(