AudioFlinger track flags and server's fast policy
Change-Id: I72358c8e6829d173b3e60ced8a8babc089869fac
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index fb5a7e1..ad386f6 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -504,7 +504,7 @@
bool isTimed = (flags & IAudioFlinger::TRACK_TIMED) != 0;
track = thread->createTrack_l(client, streamType, sampleRate, format,
- channelMask, frameCount, sharedBuffer, lSessionId, isTimed, &lStatus);
+ channelMask, frameCount, sharedBuffer, lSessionId, flags, &lStatus);
// move effect chain to this output thread if an effect on same session was waiting
// for a track to be created
@@ -1608,12 +1608,50 @@
int frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
- bool isTimed,
+ IAudioFlinger::track_flags_t flags,
status_t *status)
{
sp<Track> track;
status_t lStatus;
+ bool isTimed = (flags & IAudioFlinger::TRACK_TIMED) != 0;
+
+ // client expresses a preference for FAST, but we get the final say
+ if ((flags & IAudioFlinger::TRACK_FAST) &&
+ !(
+ // not timed
+ (!isTimed) &&
+ // either of these use cases:
+ (
+ // use case 1: shared buffer with any frame count
+ (
+ (sharedBuffer != 0)
+ ) ||
+ // use case 2: callback handler and small power-of-2 frame count
+ (
+ // unfortunately we can't verify that there's a callback until start()
+ // FIXME supported frame counts should not be hard-coded
+ (
+ (frameCount == 128) ||
+ (frameCount == 256) ||
+ (frameCount == 512)
+ )
+ )
+ ) &&
+ // PCM data
+ audio_is_linear_pcm(format) &&
+ // mono or stereo
+ ( (channelMask == AUDIO_CHANNEL_OUT_MONO) ||
+ (channelMask == AUDIO_CHANNEL_OUT_STEREO) ) &&
+ // hardware sample rate
+ (sampleRate == mSampleRate)
+ // FIXME test that MixerThread for this fast track has a capable output HAL
+ // FIXME add a permission test also?
+ ) ) {
+ ALOGW("AUDIO_POLICY_OUTPUT_FLAG_FAST denied");
+ flags &= ~IAudioFlinger::TRACK_FAST;
+ }
+
if (mType == DIRECT) {
if ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) {
if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) {
@@ -1661,7 +1699,7 @@
if (!isTimed) {
track = new Track(this, client, streamType, sampleRate, format,
- channelMask, frameCount, sharedBuffer, sessionId);
+ channelMask, frameCount, sharedBuffer, sessionId, flags);
} else {
track = TimedTrack::create(this, client, streamType, sampleRate, format,
channelMask, frameCount, sharedBuffer, sessionId);
@@ -3550,7 +3588,8 @@
uint32_t channelMask,
int frameCount,
const sp<IMemory>& sharedBuffer,
- int sessionId)
+ int sessionId,
+ IAudioFlinger::track_flags_t flags)
: TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer, sessionId),
mMute(false),
// mFillingUpStatus ?
@@ -3561,7 +3600,8 @@
mMainBuffer(thread->mixBuffer()),
mAuxBuffer(NULL),
mAuxEffectId(0), mHasVolumeController(false),
- mPresentationCompleteFrames(0)
+ mPresentationCompleteFrames(0),
+ mFlags(flags)
{
if (mCblk != NULL) {
// NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of
@@ -3707,6 +3747,13 @@
status_t status = NO_ERROR;
ALOGV("start(%d), calling pid %d session %d tid %d",
mName, IPCThreadState::self()->getCallingPid(), mSessionId, tid);
+ // check for use case 2 with missing callback
+ if (isFastTrack() && (mSharedBuffer == 0) && (tid == 0)) {
+ ALOGW("AUDIO_POLICY_OUTPUT_FLAG_FAST denied");
+ mFlags &= ~IAudioFlinger::TRACK_FAST;
+ // FIXME the track must be invalidated and moved to another thread or
+ // attached directly to the normal mixer now
+ }
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
Mutex::Autolock _l(thread->mLock);
@@ -3922,7 +3969,7 @@
const sp<IMemory>& sharedBuffer,
int sessionId)
: Track(thread, client, streamType, sampleRate, format, channelMask,
- frameCount, sharedBuffer, sessionId),
+ frameCount, sharedBuffer, sessionId, IAudioFlinger::TRACK_TIMED),
mTimedSilenceBuffer(NULL),
mTimedSilenceBufferSize(0),
mTimedAudioOutputOnTime(false),
@@ -4400,7 +4447,8 @@
audio_format_t format,
uint32_t channelMask,
int frameCount)
- : Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount, NULL, 0),
+ : Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount,
+ NULL, 0, IAudioFlinger::TRACK_DEFAULT),
mActive(false), mSourceThread(sourceThread)
{