Merge "Check newAudioUniqueId() parameter 'use'" into nyc-dev
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index f2e14b6..caae75f 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -303,7 +303,9 @@
         const String8 value = drmInforequest->get(key);
         if (key == String8("FileDescriptorKey")) {
             int fd = -1;
-            sscanf(value.string(), "FileDescriptor[%d]", &fd);
+            if (sscanf(value.string(), "FileDescriptor[%d]", &fd) != 1) {
+                sscanf(value.string(), "%d", &fd);
+            }
             data.writeFileDescriptor(fd);
         } else {
             data.writeString8((value == String8("")) ? String8("NULL") : value);
diff --git a/drm/drmserver/main_drmserver.cpp b/drm/drmserver/main_drmserver.cpp
index 1ce42e8..8f697a4 100644
--- a/drm/drmserver/main_drmserver.cpp
+++ b/drm/drmserver/main_drmserver.cpp
@@ -28,6 +28,8 @@
 
 int main()
 {
+    signal(SIGPIPE, SIG_IGN);
+
     sp<ProcessState> proc(ProcessState::self());
     sp<IServiceManager> sm = defaultServiceManager();
     ALOGV("ServiceManager: %p", sm.get());
diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h
index dcde36f..c5e09c0 100644
--- a/include/media/stagefright/DataSource.h
+++ b/include/media/stagefright/DataSource.h
@@ -107,6 +107,8 @@
 
     virtual String8 getMIMEType() const;
 
+    virtual void close() {};
+
 protected:
     virtual ~DataSource() {}
 
diff --git a/include/media/stagefright/foundation/AUtils.h b/include/media/stagefright/foundation/AUtils.h
index 47444c1..255a0f4 100644
--- a/include/media/stagefright/foundation/AUtils.h
+++ b/include/media/stagefright/foundation/AUtils.h
@@ -68,6 +68,7 @@
 
 // needle is in range [hayStart, hayStart + haySize)
 template<class T, class U>
+__attribute__((no_sanitize("integer")))
 inline static bool isInRange(const T &hayStart, const U &haySize, const T &needle) {
     ENSURE_UNSIGNED_TYPE<U>();
     return (T)(hayStart + haySize) >= hayStart && needle >= hayStart && (U)(needle - hayStart) < haySize;
@@ -75,6 +76,7 @@
 
 // [needleStart, needleStart + needleSize) is in range [hayStart, hayStart + haySize)
 template<class T, class U>
+__attribute__((no_sanitize("integer")))
 inline static bool isInRange(
         const T &hayStart, const U &haySize, const T &needleStart, const U &needleSize) {
     ENSURE_UNSIGNED_TYPE<U>();
diff --git a/include/media/stagefright/foundation/Mutexed.h b/include/media/stagefright/foundation/Mutexed.h
index e905d86..143b140 100644
--- a/include/media/stagefright/foundation/Mutexed.h
+++ b/include/media/stagefright/foundation/Mutexed.h
@@ -103,6 +103,10 @@
     class Locked {
     public:
         inline Locked(Mutexed<T> &mParent);
+        inline Locked(Locked &&from) :
+            mLock(from.mLock),
+            mTreasure(from.mTreasure),
+            mLocked(from.mLocked) {}
         inline ~Locked();
 
         // dereference the protected structure. This returns nullptr if the
@@ -148,9 +152,9 @@
     // Lock the mutex, and create an accessor-guard (a Locked object) to access the underlying
     // structure. This returns an object that dereferences to the wrapped structure when the mutex
     // is locked by it, or otherwise to "null".
-    inline Locked&& lock() {
-        // use rvalue as Locked has no copy constructor
-        return std::move(Locked(*this));
+    // This is just a shorthand for Locked() constructor to avoid specifying the template type.
+    inline Locked lock() {
+        return Locked(*this);
     }
 
 private:
@@ -169,7 +173,6 @@
       mTreasure(mParent.mTreasure),
       mLocked(true) {
     mLock.lock();
-
 }
 
 template<typename T>
diff --git a/media/libmedia/IMediaSource.cpp b/media/libmedia/IMediaSource.cpp
index 8376c0a..84f1181 100644
--- a/media/libmedia/IMediaSource.cpp
+++ b/media/libmedia/IMediaSource.cpp
@@ -295,13 +295,19 @@
                             mGroup->add_buffer(new MediaBuffer(allocateSize));
                         }
 
+                        MediaBuffer *newBuf = NULL;
                         ret = mGroup->acquire_buffer(
-                                &transferBuf, false /* nonBlocking */, usedSize);
-                        if (ret != OK || transferBuf == NULL || transferBuf->mMemory == NULL) {
+                                &newBuf, false /* nonBlocking */, usedSize);
+                        if (ret != OK || newBuf == NULL || newBuf->mMemory == NULL) {
                             ALOGW("failed to acquire shared memory, ret %d", ret);
+                            buf->release();
+                            if (newBuf != NULL) {
+                                newBuf->release();
+                            }
                             reply->writeInt32(NULL_BUFFER);
                             return NO_ERROR;
                         }
+                        transferBuf = newBuf;
                         memcpy(transferBuf->data(), (uint8_t*)buf->data() + buf->range_offset(),
                                 buf->range_length());
                         offset = 0;
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index baa95fa..08ac941 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -876,7 +876,7 @@
 
 status_t NuPlayer::GenericSource::dequeueAccessUnit(
         bool audio, sp<ABuffer> *accessUnit) {
-    if (!mStarted) {
+    if (audio && !mStarted) {
         return -EWOULDBLOCK;
     }
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index aebe479..541c824 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -721,7 +721,7 @@
         if (storingMetadataInDecodedBuffers()
                 && !mLegacyAdaptiveExperiment
                 && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
-            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
+            ALOGV("skipping buffer");
             continue;
         }
         ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
diff --git a/media/libstagefright/CallbackDataSource.cpp b/media/libstagefright/CallbackDataSource.cpp
index e6303ba..bcbd78d 100644
--- a/media/libstagefright/CallbackDataSource.cpp
+++ b/media/libstagefright/CallbackDataSource.cpp
@@ -30,14 +30,15 @@
 
 CallbackDataSource::CallbackDataSource(
     const sp<IDataSource>& binderDataSource)
-    : mIDataSource(binderDataSource) {
+    : mIDataSource(binderDataSource),
+      mIsClosed(false) {
     // Set up the buffer to read into.
     mMemory = mIDataSource->getIMemory();
 }
 
 CallbackDataSource::~CallbackDataSource() {
     ALOGV("~CallbackDataSource");
-    mIDataSource->close();
+    close();
 }
 
 status_t CallbackDataSource::initCheck() const {
@@ -99,6 +100,13 @@
     return mIDataSource->getFlags();
 }
 
+void CallbackDataSource::close() {
+    if (!mIsClosed) {
+        mIDataSource->close();
+        mIsClosed = true;
+    }
+}
+
 TinyCacheSource::TinyCacheSource(const sp<DataSource>& source)
     : mSource(source), mCachedOffset(0), mCachedSize(0) {
 }
diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp
index 5d762d8..52688b1 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libstagefright/FileSource.cpp
@@ -57,17 +57,39 @@
       mDrmManagerClient(NULL),
       mDrmBufOffset(0),
       mDrmBufSize(0),
-      mDrmBuf(NULL){
+      mDrmBuf(NULL) {
     ALOGV("fd=%d (%s), offset=%lld, length=%lld",
             fd, nameForFd(fd).c_str(), (long long) offset, (long long) length);
 
-    CHECK(offset >= 0);
-    CHECK(length >= 0);
+    if (mOffset < 0) {
+        mOffset = 0;
+    }
+    if (mLength < 0) {
+        mLength = 0;
+    }
+    if (mLength > INT64_MAX - mOffset) {
+        mLength = INT64_MAX - mOffset;
+    }
+    struct stat s;
+    if (fstat(fd, &s) == 0) {
+        if (mOffset > s.st_size) {
+            mOffset = s.st_size;
+            mLength = 0;
+        }
+        if (mOffset + mLength > s.st_size) {
+            mLength = s.st_size - mOffset;
+        }
+    }
+    if (mOffset != offset || mLength != length) {
+        ALOGW("offset/length adjusted from %lld/%lld to %lld/%lld",
+                (long long) offset, (long long) length,
+                (long long) mOffset, (long long) mLength);
+    }
 }
 
 FileSource::~FileSource() {
     if (mFd >= 0) {
-        close(mFd);
+        ::close(mFd);
         mFd = -1;
     }
 
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 7240e1a..82e7a26 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -252,6 +252,7 @@
       mDataSource(source),
       mFirstFramePos(-1),
       mFixedHeader(0) {
+
     off64_t pos = 0;
     off64_t post_id3_pos;
     uint32_t header;
@@ -350,7 +351,13 @@
     if (mSeeker == NULL || !mSeeker->getDuration(&durationUs)) {
         off64_t fileSize;
         if (mDataSource->getSize(&fileSize) == OK) {
-            durationUs = 8000LL * (fileSize - mFirstFramePos) / bitrate;
+            off64_t dataLength = fileSize - mFirstFramePos;
+            if (dataLength > INT64_MAX / 8000LL) {
+                // duration would overflow
+                durationUs = INT64_MAX;
+            } else {
+                durationUs = 8000LL * dataLength / bitrate;
+            }
         } else {
             durationUs = -1;
         }
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 6d1a460..cc38a12 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -55,6 +55,7 @@
     }
 
     mSelectedTracks.clear();
+    mDataSource->close();
 }
 
 status_t NuMediaExtractor::setDataSource(
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 7027780..c6e3571 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -61,6 +61,7 @@
 StagefrightMetadataRetriever::~StagefrightMetadataRetriever() {
     ALOGV("~StagefrightMetadataRetriever()");
     clearMetadata();
+    mSource->close();
 }
 
 status_t StagefrightMetadataRetriever::setDataSource(
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 520ecb4..1fc5995 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -767,31 +767,31 @@
                  * Thus, we could not say for sure whether a stream is
                  * AAC+/eAAC+ until the first data frame is decoded.
                  */
-                if (mInputBufferCount <= 2 || mOutputBufferCount > 1) { // TODO: <= 1
-                    if (mStreamInfo->sampleRate != prevSampleRate ||
-                        mStreamInfo->numChannels != prevNumChannels) {
-                        ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
-                              prevSampleRate, mStreamInfo->sampleRate,
-                              prevNumChannels, mStreamInfo->numChannels);
-
-                        notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
-                        mOutputPortSettingsChange = AWAITING_DISABLED;
-
-                        if (inHeader && inHeader->nFilledLen == 0) {
-                            inInfo->mOwnedByUs = false;
-                            mInputBufferCount++;
-                            inQueue.erase(inQueue.begin());
-                            mLastInHeader = NULL;
-                            inInfo = NULL;
-                            notifyEmptyBufferDone(inHeader);
-                            inHeader = NULL;
-                        }
+                if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
+                    if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
+                        ALOGW("Invalid AAC stream");
+                        mSignalledError = true;
+                        notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
                         return;
                     }
-                } else if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
-                    ALOGW("Invalid AAC stream");
-                    mSignalledError = true;
-                    notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
+                } else if ((mStreamInfo->sampleRate != prevSampleRate) ||
+                           (mStreamInfo->numChannels != prevNumChannels)) {
+                    ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
+                          prevSampleRate, mStreamInfo->sampleRate,
+                          prevNumChannels, mStreamInfo->numChannels);
+
+                    notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+                    mOutputPortSettingsChange = AWAITING_DISABLED;
+
+                    if (inHeader && inHeader->nFilledLen == 0) {
+                        inInfo->mOwnedByUs = false;
+                        mInputBufferCount++;
+                        inQueue.erase(inQueue.begin());
+                        mLastInHeader = NULL;
+                        inInfo = NULL;
+                        notifyEmptyBufferDone(inHeader);
+                        inHeader = NULL;
+                    }
                     return;
                 }
                 if (inHeader && inHeader->nFilledLen == 0) {
@@ -826,10 +826,10 @@
             while (mOutputDelayCompensated > 0) {
                 // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
                 INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
- 
-                 // run DRC check
-                 mDrcWrap.submitStreamData(mStreamInfo);
-                 mDrcWrap.update();
+
+                // run DRC check
+                mDrcWrap.submitStreamData(mStreamInfo);
+                mDrcWrap.update();
 
                 AAC_DECODER_ERROR decoderErr =
                     aacDecoder_DecodeFrame(mAACDecoder,
diff --git a/media/libstagefright/foundation/ANetworkSession.cpp b/media/libstagefright/foundation/ANetworkSession.cpp
index 4bcb1f6..46314eb 100644
--- a/media/libstagefright/foundation/ANetworkSession.cpp
+++ b/media/libstagefright/foundation/ANetworkSession.cpp
@@ -457,7 +457,7 @@
         while (mInBuffer.size() >= 2) {
             size_t offset = 2;
 
-            unsigned payloadLen = data[1] & 0x7f;
+            uint64_t payloadLen = data[1] & 0x7f;
             if (payloadLen == 126) {
                 if (offset + 2 > mInBuffer.size()) {
                     break;
@@ -485,7 +485,7 @@
                 offset += 4;
             }
 
-            if (offset + payloadLen > mInBuffer.size()) {
+            if (payloadLen > mInBuffer.size() || offset > mInBuffer.size() - payloadLen) {
                 break;
             }
 
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 37847e3..0a1ed94 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -355,7 +355,11 @@
     if (!n) {
         return OK;
     }
-    CHECK(n % 16 == 0);
+
+    if (n < 16 || n % 16) {
+        ALOGE("not enough or trailing bytes (%zu) in encrypted buffer", n);
+        return ERROR_MALFORMED;
+    }
 
     if (first) {
         // If decrypting the first block in a file, read the iv from the manifest
diff --git a/media/libstagefright/include/CallbackDataSource.h b/media/libstagefright/include/CallbackDataSource.h
index 8c6fd8f..9b33810 100644
--- a/media/libstagefright/include/CallbackDataSource.h
+++ b/media/libstagefright/include/CallbackDataSource.h
@@ -37,10 +37,12 @@
     virtual ssize_t readAt(off64_t offset, void *data, size_t size);
     virtual status_t getSize(off64_t *size);
     virtual uint32_t flags();
+    virtual void close();
 
 private:
     sp<IDataSource> mIDataSource;
     sp<IMemory> mMemory;
+    bool mIsClosed;
 
     DISALLOW_EVIL_CONSTRUCTORS(CallbackDataSource);
 };
@@ -58,6 +60,7 @@
     virtual ssize_t readAt(off64_t offset, void* data, size_t size);
     virtual status_t getSize(off64_t* size);
     virtual uint32_t flags();
+    virtual void close() { mSource->close(); }
 
 private:
     // 2kb comes from experimenting with the time-to-first-frame from a MediaPlayer
diff --git a/media/libstagefright/webm/EbmlUtil.cpp b/media/libstagefright/webm/EbmlUtil.cpp
index 449fec6..c519f5c 100644
--- a/media/libstagefright/webm/EbmlUtil.cpp
+++ b/media/libstagefright/webm/EbmlUtil.cpp
@@ -29,7 +29,9 @@
 };
 
 int numberOfTrailingZeros32(int32_t i) {
-    uint32_t u = (i & -i) * 0x0450FBAF;
+    int64_t i64 = i;
+    i64 = (i64 & -i64) * 0x0450FBAF;
+    uint32_t u = i64;
     return NTZ_TABLE[(u) >> 26];
 }
 
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index 2cb7cc7..50b490d 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -151,6 +151,7 @@
             PRIORITY_FOREGROUND);
     if (res != OK) {
         ALOGE("Failed to start the looper");
+        AMediaCodec_delete(mData);
         return NULL;
     }
     if (name_is_type) {
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index 1086340..d2fedf8 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -147,12 +147,12 @@
 }
 
 status_t CameraClient::checkPidAndHardware() const {
-    status_t result = checkPid();
-    if (result != NO_ERROR) return result;
     if (mHardware == 0) {
         ALOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid());
         return INVALID_OPERATION;
     }
+    status_t result = checkPid();
+    if (result != NO_ERROR) return result;
     return NO_ERROR;
 }
 
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 51c8148..b6c9900 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1050,6 +1050,10 @@
 }
 
 binder::Status CameraDeviceClient::checkPidStatus(const char* checkLocation) {
+    if (mDisconnected) {
+        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED,
+                "The camera device has been disconnected");
+    }
     status_t res = checkPid(checkLocation);
     return (res == OK) ? binder::Status::ok() :
             STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,