Merge "Fix ProCameraTests to pass on Wolfie, disabling failing tests" into jb-mr2-dev
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 5cfe5bc..34bae29 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -264,12 +264,16 @@
 
     status_t pushBlankBuffersToNativeWindow();
 
-    // Returns true iff all buffers on the given port have status OWNED_BY_US.
+    // Returns true iff all buffers on the given port have status
+    // OWNED_BY_US or OWNED_BY_NATIVE_WINDOW.
     bool allYourBuffersAreBelongToUs(OMX_U32 portIndex);
 
     bool allYourBuffersAreBelongToUs();
 
+    void waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
+
     size_t countBuffersOwnedByComponent(OMX_U32 portIndex) const;
+    size_t countBuffersOwnedByNativeWindow() const;
 
     void deferMessage(const sp<AMessage> &msg);
     void processDeferredMessages();
diff --git a/include/media/stagefright/MediaErrors.h b/include/media/stagefright/MediaErrors.h
index bb01467..ee5e4e2 100644
--- a/include/media/stagefright/MediaErrors.h
+++ b/include/media/stagefright/MediaErrors.h
@@ -54,6 +54,8 @@
     ERROR_DRM_DECRYPT                       = DRM_ERROR_BASE - 5,
     ERROR_DRM_CANNOT_HANDLE                 = DRM_ERROR_BASE - 6,
     ERROR_DRM_TAMPER_DETECTED               = DRM_ERROR_BASE - 7,
+    ERROR_DRM_NOT_PROVISIONED               = DRM_ERROR_BASE - 8,
+    ERROR_DRM_DEVICE_REVOKED                = DRM_ERROR_BASE - 9,
 
     ERROR_DRM_VENDOR_MAX                    = DRM_ERROR_BASE - 500,
     ERROR_DRM_VENDOR_MIN                    = DRM_ERROR_BASE - 999,
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index ee49033..6d952c3 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -960,6 +960,19 @@
                 err = setupVideoDecoder(mime, width, height);
             }
         }
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
+        int32_t numChannels, sampleRate;
+        if (!msg->findInt32("channel-count", &numChannels)
+                || !msg->findInt32("sample-rate", &sampleRate)) {
+            // Since we did not always check for these, leave them optional
+            // and have the decoder figure it all out.
+            err = OK;
+        } else {
+            err = setupRawAudioFormat(
+                    encoder ? kPortIndexInput : kPortIndexOutput,
+                    sampleRate,
+                    numChannels);
+        }
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
         int32_t numChannels, sampleRate;
         if (!msg->findInt32("channel-count", &numChannels)
@@ -2122,6 +2135,42 @@
     return n;
 }
 
+size_t ACodec::countBuffersOwnedByNativeWindow() const {
+    size_t n = 0;
+
+    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
+        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
+
+        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
+            ++n;
+        }
+    }
+
+    return n;
+}
+
+void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
+    if (mNativeWindow == NULL) {
+        return;
+    }
+
+    int minUndequeuedBufs = 0;
+    status_t err = mNativeWindow->query(
+            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
+            &minUndequeuedBufs);
+
+    if (err != OK) {
+        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
+                mComponentName.c_str(), strerror(-err), -err);
+
+        minUndequeuedBufs = 0;
+    }
+
+    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
+            && dequeueBufferFromNativeWindow() != NULL) {
+    }
+}
+
 bool ACodec::allYourBuffersAreBelongToUs(
         OMX_U32 portIndex) {
     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
@@ -4164,6 +4213,10 @@
     if (mFlushComplete[kPortIndexInput]
             && mFlushComplete[kPortIndexOutput]
             && mCodec->allYourBuffersAreBelongToUs()) {
+        // We now own all buffers except possibly those still queued with
+        // the native window for rendering. Let's get those back as well.
+        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
+
         sp<AMessage> notify = mCodec->mNotify->dup();
         notify->setInt32("what", ACodec::kWhatFlushCompleted);
         notify->post();
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 3503aaf..145869e 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -83,7 +83,7 @@
     uint8_t mCryptoKey[16]; // passed in from extractor
     uint32_t mCurrentAuxInfoType;
     uint32_t mCurrentAuxInfoTypeParameter;
-    uint32_t mCurrentDefaultSampleInfoSize;
+    int32_t mCurrentDefaultSampleInfoSize;
     uint32_t mCurrentSampleInfoCount;
     uint32_t mCurrentSampleInfoAllocSize;
     uint8_t* mCurrentSampleInfoSizes;
@@ -320,6 +320,21 @@
     }
 }
 
+static bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) {
+    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) {
+        // AMR NB audio is always mono, 8kHz
+        *channels = 1;
+        *rate = 8000;
+        return true;
+    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) {
+        // AMR WB audio is always mono, 16kHz
+        *channels = 1;
+        *rate = 16000;
+        return true;
+    }
+    return false;
+}
+
 MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
     : mSidxDuration(0),
       mMoofOffset(0),
@@ -443,6 +458,14 @@
     return track->meta;
 }
 
+static void MakeFourCCString(uint32_t x, char *s) {
+    s[0] = x >> 24;
+    s[1] = (x >> 16) & 0xff;
+    s[2] = (x >> 8) & 0xff;
+    s[3] = x & 0xff;
+    s[4] = '\0';
+}
+
 status_t MPEG4Extractor::readMetaData() {
     if (mInitCheck != NO_INIT) {
         return mInitCheck;
@@ -673,14 +696,6 @@
     return UNKNOWN_ERROR;  // Return a dummy error.
 }
 
-static void MakeFourCCString(uint32_t x, char *s) {
-    s[0] = x >> 24;
-    s[1] = (x >> 16) & 0xff;
-    s[2] = (x >> 8) & 0xff;
-    s[3] = x & 0xff;
-    s[4] = '\0';
-}
-
 struct PathAdder {
     PathAdder(Vector<uint32_t> *path, uint32_t chunkType)
         : mPath(path) {
@@ -891,13 +906,19 @@
 
         case FOURCC('f', 'r', 'm', 'a'):
         {
-            int32_t original_fourcc;
+            uint32_t original_fourcc;
             if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) {
                 return ERROR_IO;
             }
             original_fourcc = ntohl(original_fourcc);
             ALOGV("read original format: %d", original_fourcc);
             mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc));
+            uint32_t num_channels = 0;
+            uint32_t sample_rate = 0;
+            if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) {
+                mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
+                mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
+            }
             *offset += chunk_size;
             break;
         }
@@ -1134,6 +1155,7 @@
         }
 
         case FOURCC('m', 'p', '4', 'a'):
+        case FOURCC('e', 'n', 'c', 'a'):
         case FOURCC('s', 'a', 'm', 'r'):
         case FOURCC('s', 'a', 'w', 'b'):
         {
@@ -1149,29 +1171,18 @@
             }
 
             uint16_t data_ref_index = U16_AT(&buffer[6]);
-            uint16_t num_channels = U16_AT(&buffer[16]);
+            uint32_t num_channels = U16_AT(&buffer[16]);
 
             uint16_t sample_size = U16_AT(&buffer[18]);
             uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
 
-            if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
-                            FourCC2MIME(chunk_type))) {
-                // AMR NB audio is always mono, 8kHz
-                num_channels = 1;
-                sample_rate = 8000;
-            } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
-                               FourCC2MIME(chunk_type))) {
-                // AMR WB audio is always mono, 16kHz
-                num_channels = 1;
-                sample_rate = 16000;
+            if (chunk_type != FOURCC('e', 'n', 'c', 'a')) {
+                // if the chunk type is enca, we'll get the type from the sinf/frma box later
+                mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
+                AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate);
             }
-
-#if 0
-            printf("*** coding='%s' %d channels, size %d, rate %d\n",
+            ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
                    chunk, num_channels, sample_size, sample_rate);
-#endif
-
-            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
             mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
             mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
 
@@ -2297,6 +2308,7 @@
       mSrcBuffer(NULL) {
 
     mFormat->findInt32(kKeyCryptoMode, &mCryptoMode);
+    mDefaultIVSize = 0;
     mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize);
     uint32_t keytype;
     const void *key;
@@ -2544,13 +2556,17 @@
     if (!mDataSource->getUInt32(offset, &smplcnt)) {
         return ERROR_MALFORMED;
     }
+    mCurrentSampleInfoCount = smplcnt;
     offset += 4;
 
+    if (mCurrentDefaultSampleInfoSize != 0) {
+        ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize);
+        return OK;
+    }
     if (smplcnt > mCurrentSampleInfoAllocSize) {
         mCurrentSampleInfoSizes = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt);
         mCurrentSampleInfoAllocSize = smplcnt;
     }
-    mCurrentSampleInfoCount = smplcnt;
 
     mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt);
     return OK;
@@ -2608,7 +2624,8 @@
     drmoffset += mCurrentMoofOffset;
     int ivlength;
     CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength));
-    int foo = 1;
+
+    // read CencSampleAuxiliaryDataFormats
     for (size_t i = 0; i < mCurrentSampleInfoCount; i++) {
         Sample *smpl = &mCurrentSamples.editItemAt(i);
 
@@ -2619,24 +2636,33 @@
 
         drmoffset += ivlength;
 
-        uint16_t numsubsamples;
-        if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) {
-            return ERROR_IO;
+        int32_t smplinfosize = mCurrentDefaultSampleInfoSize;
+        if (smplinfosize == 0) {
+            smplinfosize = mCurrentSampleInfoSizes[i];
         }
-        drmoffset += 2;
-        for (size_t j = 0; j < numsubsamples; j++) {
-            uint16_t numclear;
-            uint32_t numencrypted;
-            if (!mDataSource->getUInt16(drmoffset, &numclear)) {
+        if (smplinfosize > ivlength) {
+            uint16_t numsubsamples;
+            if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) {
                 return ERROR_IO;
             }
             drmoffset += 2;
-            if (!mDataSource->getUInt32(drmoffset, &numencrypted)) {
-                return ERROR_IO;
+            for (size_t j = 0; j < numsubsamples; j++) {
+                uint16_t numclear;
+                uint32_t numencrypted;
+                if (!mDataSource->getUInt16(drmoffset, &numclear)) {
+                    return ERROR_IO;
+                }
+                drmoffset += 2;
+                if (!mDataSource->getUInt32(drmoffset, &numencrypted)) {
+                    return ERROR_IO;
+                }
+                drmoffset += 4;
+                smpl->clearsizes.add(numclear);
+                smpl->encryptedsizes.add(numencrypted);
             }
-            drmoffset += 4;
-            smpl->clearsizes.add(numclear);
-            smpl->encryptedsizes.add(numencrypted);
+        } else {
+            smpl->clearsizes.add(0);
+            smpl->encryptedsizes.add(smpl->size);
         }
     }
 
@@ -3293,6 +3319,21 @@
         }
     }
 
+    const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
+    const sp<MetaData> bufmeta = mBuffer->meta_data();
+    bufmeta->clear();
+    if (smpl->encryptedsizes.size()) {
+        // store clear/encrypted lengths in metadata
+        bufmeta->setData(kKeyPlainSizes, 0,
+                smpl->clearsizes.array(), smpl->clearsizes.size() * 4);
+        bufmeta->setData(kKeyEncryptedSizes, 0,
+                smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4);
+        bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size?
+        bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize);
+        bufmeta->setInt32(kKeyCryptoMode, mCryptoMode);
+        bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16);
+    }
+
     if (!mIsAVC || mWantsNALFragments) {
         if (newBuffer) {
             ssize_t num_bytes_read =
@@ -3308,7 +3349,6 @@
 
             CHECK(mBuffer != NULL);
             mBuffer->set_range(0, size);
-            mBuffer->meta_data()->clear();
             mBuffer->meta_data()->setInt64(
                     kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
 
@@ -3432,7 +3472,6 @@
             mBuffer->set_range(0, dstOffset);
         }
 
-        mBuffer->meta_data()->clear();
         mBuffer->meta_data()->setInt64(
                 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
 
@@ -3445,20 +3484,6 @@
             mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
         }
 
-        const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
-        if (smpl->encryptedsizes.size()) {
-            // store clear/encrypted lengths in metadata
-            sp<MetaData> bufmeta = mBuffer->meta_data();
-            bufmeta->setData(kKeyPlainSizes, 0,
-                    smpl->clearsizes.array(), smpl->clearsizes.size() * 4);
-            bufmeta->setData(kKeyEncryptedSizes, 0,
-                    smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4);
-            bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size?
-            bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize);
-            bufmeta->setInt32(kKeyCryptoMode, mCryptoMode);
-            bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16);
-        }
-
         ++mCurrentSampleIndex;
 
         *out = mBuffer;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 0d89c0f..e4e95d2 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -534,6 +534,20 @@
                             // the shutdown complete notification.
 
                             sendErrorReponse = false;
+
+                            if (omxError == OMX_ErrorResourcesLost
+                                    && internalError == DEAD_OBJECT) {
+                                // MediaServer died, there definitely won't
+                                // be a shutdown complete notification after
+                                // all.
+
+                                // note that we're directly going from
+                                // STOPPING->UNINITIALIZED, instead of the
+                                // usual STOPPING->INITIALIZED state.
+                                setState(UNINITIALIZED);
+
+                                (new AMessage)->postReply(mReplyID);
+                            }
                             break;
                         }
 
@@ -1013,8 +1027,16 @@
 
             if (mState != INITIALIZED
                     && mState != CONFIGURED && mState != STARTED) {
+                // We may be in "UNINITIALIZED" state already without the
+                // client being aware of this if media server died while
+                // we were being stopped. The client would assume that
+                // after stop() returned, it would be safe to call release()
+                // and it should be in this case, no harm to allow a release()
+                // if we're already uninitialized.
                 sp<AMessage> response = new AMessage;
-                response->setInt32("err", INVALID_OPERATION);
+                response->setInt32(
+                        "err",
+                        mState == UNINITIALIZED ? OK : INVALID_OPERATION);
 
                 response->postReply(replyID);
                 break;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 6c0779d..9d349a1 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -522,6 +522,17 @@
             CODEC_LOGE("setAACFormat() failed (err = %d)", err);
             return err;
         }
+    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_MPEG, mMIME)) {
+        int32_t numChannels, sampleRate;
+        if (meta->findInt32(kKeyChannelCount, &numChannels)
+                && meta->findInt32(kKeySampleRate, &sampleRate)) {
+            // Since we did not always check for these, leave them optional
+            // and have the decoder figure it all out.
+            setRawAudioFormat(
+                    mIsEncoder ? kPortIndexInput : kPortIndexOutput,
+                    sampleRate,
+                    numChannels);
+        }
     } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_ALAW, mMIME)
             || !strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_MLAW, mMIME)) {
         // These are PCM-like formats with a fixed sample rate but
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index cf81c16..cf50dc9 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -586,9 +586,12 @@
 }
 
 void SoftAAC2::drainDecoder() {
-    short buf [2048];
-    aacDecoder_DecodeFrame(mAACDecoder, buf, 4096, AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR);
-    aacDecoder_DecodeFrame(mAACDecoder, buf, 4096, AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR);
+    // a buffer big enough for 6 channels of decoded HE-AAC
+    short buf [2048*6];
+    aacDecoder_DecodeFrame(mAACDecoder,
+            buf, sizeof(buf), AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR);
+    aacDecoder_DecodeFrame(mAACDecoder,
+            buf, sizeof(buf), AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR);
     aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
     mDecoderHasData = false;
 }
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index 849be87..9f25536 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -166,6 +166,21 @@
             return OMX_ErrorNone;
         }
 
+        case OMX_IndexParamAudioPcm:
+        {
+            const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+                (const OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+            if (pcmParams->nPortIndex != 1) {
+                return OMX_ErrorUndefined;
+            }
+
+            mNumChannels = pcmParams->nChannels;
+            mSamplingRate = pcmParams->nSamplingRate;
+
+            return OMX_ErrorNone;
+        }
+
         default:
             return SimpleSoftOMXComponent::internalSetParameter(index, params);
     }
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 971875f..e7d5e74 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -299,7 +299,9 @@
     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
 
     if (err != OMX_ErrorNone) {
-        ALOGE("OMX_GetExtensionIndex %s failed", name);
+        if (enable) {
+            ALOGE("OMX_GetExtensionIndex %s failed", name);
+        }
 
         return StatusFromOMXError(err);
     }
@@ -378,9 +380,8 @@
 
     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
     if (err != OMX_ErrorNone) {
-        if (enable) {
-            ALOGE("OMX_GetExtensionIndex %s failed", name);
-        }
+        ALOGE("OMX_GetExtensionIndex %s failed", name);
+
         return StatusFromOMXError(err);
     }
 
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index b3de526..87eb6aa 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -143,6 +143,7 @@
       mMode(AUDIO_MODE_INVALID),
       mBtNrecIsOff(false)
 {
+    getpid_cached = getpid();
     char value[PROPERTY_VALUE_MAX];
     bool doLog = (property_get("ro.test_harness", value, "0") > 0) && (atoi(value) == 1);
     if (doLog) {
diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp
index 6a58852..d15bd04 100644
--- a/services/audioflinger/ServiceUtilities.cpp
+++ b/services/audioflinger/ServiceUtilities.cpp
@@ -21,8 +21,9 @@
 
 namespace android {
 
-// This optimization assumes mediaserver process doesn't fork, which it doesn't
-const pid_t getpid_cached = getpid();
+// Not valid until initialized by AudioFlinger constructor.  It would have to be
+// re-initialized if the process containing AudioFlinger service forks (which it doesn't).
+pid_t getpid_cached;
 
 bool recordingAllowed() {
     if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;
diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h
index f77ec5b..80cecba 100644
--- a/services/audioflinger/ServiceUtilities.h
+++ b/services/audioflinger/ServiceUtilities.h
@@ -18,7 +18,7 @@
 
 namespace android {
 
-extern const pid_t getpid_cached;
+extern pid_t getpid_cached;
 
 bool recordingAllowed();
 bool settingsAllowed();
diff --git a/services/medialog/MediaLogService.cpp b/services/medialog/MediaLogService.cpp
index f60749d..683fdf3 100644
--- a/services/medialog/MediaLogService.cpp
+++ b/services/medialog/MediaLogService.cpp
@@ -60,7 +60,9 @@
     static const String16 sDump("android.permission.DUMP");
     if (!(IPCThreadState::self()->getCallingUid() == AID_MEDIA ||
             PermissionCache::checkCallingPermission(sDump))) {
-        fdprintf(fd, "Permission denied.\n");
+        fdprintf(fd, "Permission Denial: can't dump media.log from pid=%d, uid=%d\n",
+                IPCThreadState::self()->getCallingPid(),
+                IPCThreadState::self()->getCallingUid());
         return NO_ERROR;
     }