Merge "audio policy: fix media volume after ringtone" into nyc-mr1-dev
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index a750824..302e6ee 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -151,7 +151,7 @@
if (isCryptoError(result)) {
errorDetailMsg->setTo(reply.readCString());
} else if (dstType == kDestinationTypeVmPointer) {
- // For the non-secure case, copy the decrypted-in-place
+ // For the non-secure case, copy the decrypted
// data from shared memory to its final destination
memcpy(dstPtr, sharedBuffer->pointer(), result);
}
@@ -320,10 +320,7 @@
dstPtr = secureBufferId;
} else {
dstType = kDestinationTypeVmPointer;
-
- // For the non-secure case, decrypt in-place back to the
- // shared memory segment.
- dstPtr = sharedBuffer->pointer();
+ dstPtr = malloc(totalSize);
}
AString errorDetailMsg;
@@ -369,7 +366,18 @@
reply->writeCString(errorDetailMsg.c_str());
}
- if (dstType == kDestinationTypeNativeHandle) {
+ if (dstType == kDestinationTypeVmPointer) {
+ if (result >= 0) {
+ CHECK_LE(result, static_cast<ssize_t>(totalSize));
+ // For the non-secure case, pass the decrypted
+ // data back via the shared buffer rather than
+ // copying it separately over binder to avoid
+ // binder's 1MB limit.
+ memcpy(sharedBuffer->pointer(), dstPtr, result);
+ }
+ free(dstPtr);
+ dstPtr = NULL;
+ } else if (dstType == kDestinationTypeNativeHandle) {
int err;
if ((err = native_handle_close(nativeHandle)) < 0) {
ALOGW("secure buffer native_handle_close failed: %d", err);
diff --git a/media/libstagefright/SampleIterator.cpp b/media/libstagefright/SampleIterator.cpp
index ad7b6fd..54c9fa3 100644
--- a/media/libstagefright/SampleIterator.cpp
+++ b/media/libstagefright/SampleIterator.cpp
@@ -94,8 +94,6 @@
+ mFirstChunk;
if (!mInitialized || chunk != mCurrentChunkIndex) {
- mCurrentChunkIndex = chunk;
-
status_t err;
if ((err = getChunkOffset(chunk, &mCurrentChunkOffset)) != OK) {
ALOGE("getChunkOffset return error");
@@ -106,18 +104,21 @@
uint32_t firstChunkSampleIndex =
mFirstChunkSampleIndex
- + mSamplesPerChunk * (mCurrentChunkIndex - mFirstChunk);
+ + mSamplesPerChunk * (chunk - mFirstChunk);
for (uint32_t i = 0; i < mSamplesPerChunk; ++i) {
size_t sampleSize;
if ((err = getSampleSizeDirect(
firstChunkSampleIndex + i, &sampleSize)) != OK) {
ALOGE("getSampleSizeDirect return error");
+ mCurrentChunkSampleSizes.clear();
return err;
}
mCurrentChunkSampleSizes.push(sampleSize);
}
+
+ mCurrentChunkIndex = chunk;
}
uint32_t chunkRelativeSampleIndex =
diff --git a/media/libstagefright/SurfaceUtils.cpp b/media/libstagefright/SurfaceUtils.cpp
index 60ef662..568837a 100644
--- a/media/libstagefright/SurfaceUtils.cpp
+++ b/media/libstagefright/SurfaceUtils.cpp
@@ -186,10 +186,6 @@
break;
}
- if (img == NULL) {
- ALOGE("error pushing blank frames: lock returned NULL buffer");
- break;
- }
*img = 0;
err = buf->unlock();
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 90f1a77..e39dcdd 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -927,6 +927,10 @@
if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // sequence number
MtpStringBuffer name, created, modified;
if (!mData.getString(name)) return MTP_RESPONSE_INVALID_PARAMETER; // file name
+ if (name.getCharCount() == 0) {
+ ALOGE("empty name");
+ return MTP_RESPONSE_INVALID_PARAMETER;
+ }
if (!mData.getString(created)) return MTP_RESPONSE_INVALID_PARAMETER; // date created
if (!mData.getString(modified)) return MTP_RESPONSE_INVALID_PARAMETER; // date modified
// keywords follow
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index b0780a4..93f7ce5 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -412,6 +412,7 @@
}
ftDump->mUnderruns = underruns;
ftDump->mFramesReady = framesReady;
+ ftDump->mFramesWritten = trackFramesWritten;
}
if (anyEnabledTracks) {
diff --git a/services/audioflinger/FastMixerDumpState.cpp b/services/audioflinger/FastMixerDumpState.cpp
index 2326e2a..6475f22 100644
--- a/services/audioflinger/FastMixerDumpState.cpp
+++ b/services/audioflinger/FastMixerDumpState.cpp
@@ -168,7 +168,7 @@
uint32_t trackMask = mTrackMask;
dprintf(fd, " Fast tracks: sMaxFastTracks=%u activeMask=%#x\n",
FastMixerState::sMaxFastTracks, trackMask);
- dprintf(fd, " Index Active Full Partial Empty Recent Ready\n");
+ dprintf(fd, " Index Active Full Partial Empty Recent Ready Written\n");
for (uint32_t i = 0; i < FastMixerState::sMaxFastTracks; ++i, trackMask >>= 1) {
bool isActive = trackMask & 1;
const FastTrackDump *ftDump = &mTracks[i];
@@ -188,11 +188,13 @@
mostRecent = "?";
break;
}
- dprintf(fd, " %5u %6s %4u %7u %5u %7s %5zu\n", i, isActive ? "yes" : "no",
+ dprintf(fd, " %5u %6s %4u %7u %5u %7s %5zu %10lld\n",
+ i, isActive ? "yes" : "no",
(underruns.mBitFields.mFull) & UNDERRUN_MASK,
(underruns.mBitFields.mPartial) & UNDERRUN_MASK,
(underruns.mBitFields.mEmpty) & UNDERRUN_MASK,
- mostRecent, ftDump->mFramesReady);
+ mostRecent, ftDump->mFramesReady,
+ (long long)ftDump->mFramesWritten);
}
}
diff --git a/services/audioflinger/FastMixerDumpState.h b/services/audioflinger/FastMixerDumpState.h
index ac15e7c..301c5b1 100644
--- a/services/audioflinger/FastMixerDumpState.h
+++ b/services/audioflinger/FastMixerDumpState.h
@@ -57,6 +57,7 @@
/*virtual*/ ~FastTrackDump() { }
FastTrackUnderruns mUnderruns;
size_t mFramesReady; // most recent value only; no long-term statistics kept
+ int64_t mFramesWritten; // last value from track
};
struct FastMixerDumpState : FastThreadDumpState {
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index a91fc26..897873b 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1826,6 +1826,15 @@
audio_output_flags_t flags = output != NULL ? output->flags : AUDIO_OUTPUT_FLAG_NONE;
String8 flagsAsString = outputFlagsToString(flags);
dprintf(fd, " AudioStreamOut: %p flags %#x (%s)\n", output, flags, flagsAsString.string());
+ dprintf(fd, " Frames written: %lld\n", (long long)mFramesWritten);
+ dprintf(fd, " Suspended frames: %lld\n", (long long)mSuspendedFrames);
+ if (mPipeSink.get() != nullptr) {
+ dprintf(fd, " PipeSink frames written: %lld\n", (long long)mPipeSink->framesWritten());
+ }
+ if (output != nullptr) {
+ dprintf(fd, " Hal stream dump:\n");
+ (void)output->stream->common.dump(&output->stream->common, fd);
+ }
}
// Thread virtuals
@@ -4588,10 +4597,25 @@
return mixerStatus;
}
+// trackCountForUid_l() must be called with ThreadBase::mLock held
+uint32_t AudioFlinger::PlaybackThread::trackCountForUid_l(uid_t uid)
+{
+ uint32_t trackCount = 0;
+ for (size_t i = 0; i < mTracks.size() ; i++) {
+ if (mTracks[i]->uid() == (int)uid) {
+ trackCount++;
+ }
+ }
+ return trackCount;
+}
+
// getTrackName_l() must be called with ThreadBase::mLock held
int AudioFlinger::MixerThread::getTrackName_l(audio_channel_mask_t channelMask,
- audio_format_t format, audio_session_t sessionId)
+ audio_format_t format, audio_session_t sessionId, uid_t uid)
{
+ if (trackCountForUid_l(uid) > (PlaybackThread::kMaxTracksPerUid - 1)) {
+ return -1;
+ }
return mAudioMixer->getTrackName(channelMask, format, sessionId);
}
@@ -4696,7 +4720,7 @@
mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate);
for (size_t i = 0; i < mTracks.size() ; i++) {
int name = getTrackName_l(mTracks[i]->mChannelMask,
- mTracks[i]->mFormat, mTracks[i]->mSessionId);
+ mTracks[i]->mFormat, mTracks[i]->mSessionId, mTracks[i]->uid());
if (name < 0) {
break;
}
@@ -5141,8 +5165,11 @@
// getTrackName_l() must be called with ThreadBase::mLock held
int AudioFlinger::DirectOutputThread::getTrackName_l(audio_channel_mask_t channelMask __unused,
- audio_format_t format __unused, audio_session_t sessionId __unused)
+ audio_format_t format __unused, audio_session_t sessionId __unused, uid_t uid)
{
+ if (trackCountForUid_l(uid) > (PlaybackThread::kMaxTracksPerUid - 1)) {
+ return -1;
+ }
return 0;
}
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 1d5d3c8..f353f3b 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -506,6 +506,8 @@
static const int8_t kMaxTrackRetriesOffload = 20;
static const int8_t kMaxTrackStartupRetriesOffload = 100;
static const int8_t kMaxTrackStopRetriesOffload = 2;
+ // 14 tracks max per client allows for 2 misbehaving application leaving 4 available tracks.
+ static const uint32_t kMaxTracksPerUid = 14;
PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
audio_io_handle_t id, audio_devices_t device, type_t type, bool systemReady);
@@ -736,8 +738,8 @@
// Allocate a track name for a given channel mask.
// Returns name >= 0 if successful, -1 on failure.
- virtual int getTrackName_l(audio_channel_mask_t channelMask,
- audio_format_t format, audio_session_t sessionId) = 0;
+ virtual int getTrackName_l(audio_channel_mask_t channelMask, audio_format_t format,
+ audio_session_t sessionId, uid_t uid) = 0;
virtual void deleteTrackName_l(int name) = 0;
// Time to sleep between cycles when:
@@ -767,6 +769,8 @@
&& mHwSupportsPause
&& (mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC); }
+ uint32_t trackCountForUid_l(uid_t uid);
+
private:
friend class AudioFlinger; // for numerous
@@ -889,8 +893,8 @@
protected:
virtual mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
- virtual int getTrackName_l(audio_channel_mask_t channelMask,
- audio_format_t format, audio_session_t sessionId);
+ virtual int getTrackName_l(audio_channel_mask_t channelMask, audio_format_t format,
+ audio_session_t sessionId, uid_t uid);
virtual void deleteTrackName_l(int name);
virtual uint32_t idleSleepTimeUs() const;
virtual uint32_t suspendSleepTimeUs() const;
@@ -969,8 +973,8 @@
virtual void flushHw_l();
protected:
- virtual int getTrackName_l(audio_channel_mask_t channelMask,
- audio_format_t format, audio_session_t sessionId);
+ virtual int getTrackName_l(audio_channel_mask_t channelMask, audio_format_t format,
+ audio_session_t sessionId, uid_t uid);
virtual void deleteTrackName_l(int name);
virtual uint32_t activeSleepTimeUs() const;
virtual uint32_t idleSleepTimeUs() const;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 3cca054..ba6e6e5 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -388,7 +388,7 @@
}
mServerProxy = mAudioTrackServerProxy;
- mName = thread->getTrackName_l(channelMask, format, sessionId);
+ mName = thread->getTrackName_l(channelMask, format, sessionId, uid);
if (mName < 0) {
ALOGE("no more track names available");
return;