Don't allow AudioTrack frameCount to decrease
This is a workaround for bug that client can cache return value of
frameCount(), and is not notified when this value changes due to automatic
re-recreation of the underlying IAudioTrack.
A better long-term fix would be to notify clients when these kinds of
parameters change, and to fix assumptions in client code that they are
constant (e.g. in SoundPool and maybe obtainBuffer).
Also, once a fast track request is denied, don't request it again.
Bug: 6431187
Change-Id: I55b4ff30bbd9ed3a402e39452a38de52cdea53a9
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index b5b7adc..6189be5 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -269,6 +269,7 @@
mNotificationFramesReq = notificationFrames;
mSessionId = sessionId;
mAuxEffectId = 0;
+ mFlags = flags;
mCbf = cbf;
if (cbf != NULL) {
@@ -310,7 +311,6 @@
mNewPosition = 0;
mUpdatePeriod = 0;
mFlushed = false;
- mFlags = flags;
AudioSystem::acquireAudioSessionId(mSessionId);
mRestoreStatus = NO_ERROR;
return NO_ERROR;
@@ -770,7 +770,9 @@
// use case 2: callback handler
(mCbf != NULL))) {
ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client");
+ // once denied, do not request again if IAudioTrack is re-created
flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST);
+ mFlags = flags;
}
ALOGV("createTrack_l() output %d afLatency %d", output, afLatency);
@@ -899,6 +901,9 @@
ALOGV("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %u", mCblk->frameCount);
} else {
ALOGV("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %u", mCblk->frameCount);
+ // once denied, do not request again if IAudioTrack is re-created
+ flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST);
+ mFlags = flags;
}
if (sharedBuffer == 0) {
mNotificationFramesAct = mCblk->frameCount/2;
@@ -920,6 +925,11 @@
mRemainingFrames = mNotificationFramesAct;
// FIXME don't believe this lie
mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate;
+ // If IAudioTrack is re-created, don't let the requested frameCount
+ // decrease. This can confuse clients that cache frameCount().
+ if (mCblk->frameCount > mFrameCount) {
+ mFrameCount = mCblk->frameCount;
+ }
return NO_ERROR;
}