Threads.cpp revision 4cc0a6a835c806d200ef83ef31fe5bef327c355c
13306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong/*
23306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong**
33306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong** Copyright 2012, The Android Open Source Project
43306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong**
53306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong** Licensed under the Apache License, Version 2.0 (the "License");
63306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong** you may not use this file except in compliance with the License.
73306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong** You may obtain a copy of the License at
83306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong**
93306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong**     http://www.apache.org/licenses/LICENSE-2.0
103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong**
113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong** Unless required by applicable law or agreed to in writing, software
123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong** distributed under the License is distributed on an "AS IS" BASIS,
133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong** See the License for the specific language governing permissions and
153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong** limitations under the License.
163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong*/
173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#define LOG_TAG "AudioFlinger"
203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong//#define LOG_NDEBUG 0
213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#define ATRACE_TAG ATRACE_TAG_AUDIO
223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include "Configuration.h"
243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <math.h>
253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <fcntl.h>
263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <sys/stat.h>
273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <cutils/properties.h>
283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <media/AudioParameter.h>
293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <utils/Log.h>
303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <utils/Trace.h>
313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <private/media/AudioTrackShared.h>
333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <hardware/audio.h>
343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <audio_effects/effect_ns.h>
353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <audio_effects/effect_aec.h>
363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <audio_utils/primitives.h>
373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// NBAIO implementations
393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <media/nbaio/AudioStreamOutSink.h>
403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <media/nbaio/MonoPipe.h>
413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <media/nbaio/MonoPipeReader.h>
423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <media/nbaio/Pipe.h>
433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <media/nbaio/PipeReader.h>
443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <media/nbaio/SourceAudioBufferProvider.h>
453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <powermanager/PowerManager.h>
473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <common_time/cc_helper.h>
493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <common_time/local_clock.h>
503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include "AudioFlinger.h"
523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include "AudioMixer.h"
533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include "FastMixer.h"
543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include "ServiceUtilities.h"
553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include "SchedulingPolicyService.h"
563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#ifdef ADD_BATTERY_DATA
583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <media/IMediaPlayerService.h>
593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <media/IMediaDeathNotifier.h>
603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#endif
613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#ifdef DEBUG_CPU_USAGE
633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <cpustats/CentralTendencyStatistics.h>
643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include <cpustats/ThreadCpuUsage.h>
653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#endif
663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// ----------------------------------------------------------------------------
683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// Note: the following macro is used for extremely verbose logging message.  In
703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// 0; but one side effect of this is to turn all LOGV's as well.  Some messages
723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// are so verbose that we want to suppress them even when we have ALOG_ASSERT
733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// turned on.  Do not uncomment the #def below unless you really know what you
743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// are doing and want to see all of the extremely verbose messages.
753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong//#define VERY_VERY_VERBOSE_LOGGING
763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#ifdef VERY_VERY_VERBOSE_LOGGING
773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#define ALOGVV ALOGV
783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#else
793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#define ALOGVV(a...) do { } while(0)
803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#endif
813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongnamespace android {
833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// retry counts for buffer fill timeout
853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// 50 * ~20msecs = 1 second
863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const int8_t kMaxTrackRetries = 50;
873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const int8_t kMaxTrackStartupRetries = 50;
883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// allow less retry attempts on direct output thread.
893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// direct outputs can be a scarce resource in audio hardware and should
903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// be released as quickly as possible.
913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const int8_t kMaxTrackRetriesDirect = 2;
923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// don't warn about blocked writes or record buffer overflows more often than this
943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const nsecs_t kWarningThrottleNs = seconds(5);
953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// RecordThread loop sleep time upon application overrun or audio HAL read error
973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const int kRecordThreadSleepUs = 5000;
983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// maximum time to wait for setParameters to complete
1003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const nsecs_t kSetParametersTimeoutNs = seconds(2);
1013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// minimum sleep time for the mixer thread loop when tracks are active but in underrun
1033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const uint32_t kMinThreadSleepTimeUs = 5000;
1043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// maximum divider applied to the active sleep time in the mixer thread loop
1053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const uint32_t kMaxThreadSleepTimeShift = 2;
1063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// minimum normal mix buffer size, expressed in milliseconds rather than frames
1083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const uint32_t kMinNormalMixBufferSizeMs = 20;
1093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// maximum normal mix buffer size
1103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const uint32_t kMaxNormalMixBufferSizeMs = 24;
1113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// Offloaded output thread standby delay: allows track transition without going to standby
1133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const nsecs_t kOffloadStandbyDelayNs = seconds(1);
1143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// Whether to use fast mixer
1163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const enum {
1173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    FastMixer_Never,    // never initialize or use: for debugging only
1183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    FastMixer_Always,   // always initialize and use, even if not needed: for debugging only
1193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        // normal mixer multiplier is 1
1203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    FastMixer_Static,   // initialize if needed, then use all the time if initialized,
1213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        // multiplier is calculated based on min & max normal mixer buffer size
1223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    FastMixer_Dynamic,  // initialize if needed, then use dynamically depending on track load,
1233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        // multiplier is calculated based on min & max normal mixer buffer size
1243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // FIXME for FastMixer_Dynamic:
1253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    //  Supporting this option will require fixing HALs that can't handle large writes.
1263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    //  For example, one HAL implementation returns an error from a large write,
1273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    //  and another HAL implementation corrupts memory, possibly in the sample rate converter.
1283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    //  We could either fix the HAL implementations, or provide a wrapper that breaks
1293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    //  up large writes into smaller ones, and the wrapper would need to deal with scheduler.
1303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong} kUseFastMixer = FastMixer_Static;
1313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// Priorities for requestPriority
1333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const int kPriorityAudioApp = 2;
1343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const int kPriorityFastMixer = 3;
1353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// IAudioFlinger::createTrack() reports back to client the total size of shared memory area
1373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// for the track.  The client then sub-divides this into smaller buffers for its use.
1383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// Currently the client uses N-buffering by default, but doesn't tell us about the value of N.
1393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// So for now we just assume that client is double-buffered for fast tracks.
1403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// FIXME It would be better for client to tell AudioFlinger the value of N,
1413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// so AudioFlinger could allocate the right amount of memory.
1423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// See the client's minBufCount and mNotificationFramesAct calculations for details.
1433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic const int kFastTrackMultiplier = 2;
1443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// ----------------------------------------------------------------------------
1463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#ifdef ADD_BATTERY_DATA
1483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// To collect the amplifier usage
1493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatic void addBatteryData(uint32_t params) {
1503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sp<IMediaPlayerService> service = IMediaDeathNotifier::getMediaPlayerService();
1513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (service == NULL) {
1523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // it already logged
1533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        return;
1543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
1553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    service->addBatteryData(params);
1573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
1583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#endif
1593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// ----------------------------------------------------------------------------
1623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong//      CPU Stats
1633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// ----------------------------------------------------------------------------
1643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongclass CpuStats {
1663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongpublic:
1673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    CpuStats();
1683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    void sample(const String8 &title);
1693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#ifdef DEBUG_CPU_USAGE
1703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongprivate:
1713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ThreadCpuUsage mCpuUsage;           // instantaneous thread CPU usage in wall clock ns
1723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    CentralTendencyStatistics mWcStats; // statistics on thread CPU usage in wall clock ns
1733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    CentralTendencyStatistics mHzStats; // statistics on thread CPU usage in cycles
1753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int mCpuNum;                        // thread's current CPU number
1773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int mCpukHz;                        // frequency of thread's current CPU in kHz
1783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#endif
1793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong};
1803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames DongCpuStats::CpuStats()
1823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#ifdef DEBUG_CPU_USAGE
1833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    : mCpuNum(-1), mCpukHz(-1)
1843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#endif
1853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
1863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
1873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid CpuStats::sample(const String8 &title
1893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#ifndef DEBUG_CPU_USAGE
1903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                __unused
1913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#endif
1923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ) {
1933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#ifdef DEBUG_CPU_USAGE
1943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // get current thread's delta CPU time in wall clock ns
1953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    double wcNs;
1963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    bool valid = mCpuUsage.sampleAndEnable(wcNs);
1973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // record sample for wall clock statistics
1993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (valid) {
2003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mWcStats.sample(wcNs);
2013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
2023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
2033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // get the current CPU number
2043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int cpuNum = sched_getcpu();
2053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
2063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // get the current CPU frequency in kHz
2073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int cpukHz = mCpuUsage.getCpukHz(cpuNum);
2083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
2093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // check if either CPU number or frequency changed
2103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (cpuNum != mCpuNum || cpukHz != mCpukHz) {
2113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mCpuNum = cpuNum;
2123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mCpukHz = cpukHz;
2133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // ignore sample for purposes of cycles
2143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        valid = false;
2153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
2163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
2173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // if no change in CPU number or frequency, then record sample for cycle statistics
2183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (valid && mCpukHz > 0) {
2193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        double cycles = wcNs * cpukHz * 0.000001;
2203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mHzStats.sample(cycles);
2213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
2223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
2233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    unsigned n = mWcStats.n();
2243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // mCpuUsage.elapsed() is expensive, so don't call it every loop
2253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if ((n & 127) == 1) {
2263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        long long elapsed = mCpuUsage.elapsed();
2273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (elapsed >= DEBUG_CPU_USAGE * 1000000000LL) {
2283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            double perLoop = elapsed / (double) n;
2293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            double perLoop100 = perLoop * 0.01;
2303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            double perLoop1k = perLoop * 0.001;
2313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            double mean = mWcStats.mean();
2323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            double stddev = mWcStats.stddev();
2333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            double minimum = mWcStats.minimum();
2343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            double maximum = mWcStats.maximum();
2353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            double meanCycles = mHzStats.mean();
2363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            double stddevCycles = mHzStats.stddev();
2373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            double minCycles = mHzStats.minimum();
2383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            double maxCycles = mHzStats.maximum();
2393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            mCpuUsage.resetElapsed();
2403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            mWcStats.reset();
2413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            mHzStats.reset();
2423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ALOGD("CPU usage for %s over past %.1f secs\n"
2433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                "  (%u mixer loops at %.1f mean ms per loop):\n"
2443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                "  us per mix loop: mean=%.0f stddev=%.0f min=%.0f max=%.0f\n"
2453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                "  %% of wall: mean=%.1f stddev=%.1f min=%.1f max=%.1f\n"
2463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                "  MHz: mean=%.1f, stddev=%.1f, min=%.1f max=%.1f",
2473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    title.string(),
2483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    elapsed * .000000001, n, perLoop * .000001,
2493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    mean * .001,
2503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    stddev * .001,
2513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    minimum * .001,
2523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    maximum * .001,
2533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    mean / perLoop100,
2543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    stddev / perLoop100,
2553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    minimum / perLoop100,
2563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    maximum / perLoop100,
2573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    meanCycles / perLoop1k,
2583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    stddevCycles / perLoop1k,
2593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    minCycles / perLoop1k,
2603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    maxCycles / perLoop1k);
2613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
2623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
2633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
2643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#endif
2653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong};
2663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
2673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// ----------------------------------------------------------------------------
2683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong//      ThreadBase
2693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// ----------------------------------------------------------------------------
2703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
2713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames DongAudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
2723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        audio_devices_t outDevice, audio_devices_t inDevice, type_t type)
2733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    :   Thread(false /*canCallJava*/),
2743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mType(type),
2753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mAudioFlinger(audioFlinger),
2763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // mSampleRate, mFrameCount, mChannelMask, mChannelCount, mFrameSize, mFormat, mBufferSize
2773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // are set by PlaybackThread::readOutputParameters_l() or
2783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // RecordThread::readInputParameters_l()
2793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mParamStatus(NO_ERROR),
2803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        //FIXME: mStandby should be true here. Is this some kind of hack?
2813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mStandby(false), mOutDevice(outDevice), mInDevice(inDevice),
2823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id),
2833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // mName will be set by concrete (non-virtual) subclass
2843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mDeathRecipient(new PMDeathRecipient(this))
2853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
2863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
2873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
2883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames DongAudioFlinger::ThreadBase::~ThreadBase()
2893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
2903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // mConfigEvents should be empty, but just in case it isn't, free the memory it owns
2913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    for (size_t i = 0; i < mConfigEvents.size(); i++) {
2923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        delete mConfigEvents[i];
2933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
2943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mConfigEvents.clear();
2953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
2963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mParamCond.broadcast();
2973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // do not lock the mutex in destructor
2983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    releaseWakeLock_l();
2993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (mPowerManager != 0) {
3003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        sp<IBinder> binder = mPowerManager->asBinder();
3013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        binder->unlinkToDeath(mDeathRecipient);
3023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
3033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
3043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
3053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatus_t AudioFlinger::ThreadBase::readyToRun()
3063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
3073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    status_t status = initCheck();
3083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (status == NO_ERROR) {
3093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGI("AudioFlinger's thread %p ready to run", this);
3103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else {
3113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGE("No working audio driver found.");
3123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
3133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return status;
3143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
3153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
3163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::exit()
3173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
3183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOGV("ThreadBase::exit");
3193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // do any cleanup required for exit to succeed
3203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    preExit();
3213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    {
3223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // This lock prevents the following race in thread (uniprocessor for illustration):
3233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        //  if (!exitPending()) {
3243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        //      // context switch from here to exit()
3253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        //      // exit() calls requestExit(), what exitPending() observes
3263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        //      // exit() calls signal(), which is dropped since no waiters
3273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        //      // context switch back from exit() to here
3283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        //      mWaitWorkCV.wait(...);
3293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        //      // now thread is hung
3303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        //  }
3313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        AutoMutex lock(mLock);
3323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        requestExit();
3333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mWaitWorkCV.broadcast();
3343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
3353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // When Thread::requestExitAndWait is made virtual and this method is renamed to
3363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // "virtual status_t requestExitAndWait()", replace by "return Thread::requestExitAndWait();"
3373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    requestExitAndWait();
3383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
3393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
3403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatus_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs)
3413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
3423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    status_t status;
3433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
3443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOGV("ThreadBase::setParameters() %s", keyValuePairs.string());
3453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
3463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
3473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mNewParameters.add(keyValuePairs);
3483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mWaitWorkCV.signal();
3493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // wait condition with timeout in case the thread loop has exited
3503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // before the request could be processed
3513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (mParamCond.waitRelative(mLock, kSetParametersTimeoutNs) == NO_ERROR) {
3523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        status = mParamStatus;
3533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mWaitWorkCV.signal();
3543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else {
3553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        status = TIMED_OUT;
3563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
3573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return status;
3583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
3593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
3603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::sendIoConfigEvent(int event, int param)
3613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
3623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
3633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sendIoConfigEvent_l(event, param);
3643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
3653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
3663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// sendIoConfigEvent_l() must be called with ThreadBase::mLock held
3673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::sendIoConfigEvent_l(int event, int param)
3683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
3693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    IoConfigEvent *ioEvent = new IoConfigEvent(event, param);
3703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mConfigEvents.add(static_cast<ConfigEvent *>(ioEvent));
3713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOGV("sendIoConfigEvent() num events %d event %d, param %d", mConfigEvents.size(), event,
3723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            param);
3733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mWaitWorkCV.signal();
3743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
3753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
3763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// sendPrioConfigEvent_l() must be called with ThreadBase::mLock held
3773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio)
3783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
3793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    PrioConfigEvent *prioEvent = new PrioConfigEvent(pid, tid, prio);
3803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mConfigEvents.add(static_cast<ConfigEvent *>(prioEvent));
3813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOGV("sendPrioConfigEvent_l() num events %d pid %d, tid %d prio %d",
3823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong          mConfigEvents.size(), pid, tid, prio);
3833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mWaitWorkCV.signal();
3843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
3853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
3863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::processConfigEvents()
3873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
3883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
3893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    processConfigEvents_l();
3903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
3913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
3923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// post condition: mConfigEvents.isEmpty()
3933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::processConfigEvents_l()
3943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
3953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    while (!mConfigEvents.isEmpty()) {
3963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGV("processConfigEvents() remaining events %d", mConfigEvents.size());
3973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ConfigEvent *event = mConfigEvents[0];
3983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mConfigEvents.removeAt(0);
3993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // release mLock before locking AudioFlinger mLock: lock order is always
4003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // AudioFlinger then ThreadBase to avoid cross deadlock
4013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mLock.unlock();
4023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        switch (event->type()) {
4033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        case CFG_EVENT_PRIO: {
4043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            PrioConfigEvent *prioEvent = static_cast<PrioConfigEvent *>(event);
4053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // FIXME Need to understand why this has be done asynchronously
4063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            int err = requestPriority(prioEvent->pid(), prioEvent->tid(), prioEvent->prio(),
4073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    true /*asynchronous*/);
4083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if (err != 0) {
4093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",
4103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                      prioEvent->prio(), prioEvent->pid(), prioEvent->tid(), err);
4113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
4123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        } break;
4133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        case CFG_EVENT_IO: {
4143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            IoConfigEvent *ioEvent = static_cast<IoConfigEvent *>(event);
4153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            {
4163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                Mutex::Autolock _l(mAudioFlinger->mLock);
4173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                audioConfigChanged_l(ioEvent->event(), ioEvent->param());
4183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
4193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        } break;
4203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        default:
4213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ALOGE("processConfigEvents() unknown event type %d", event->type());
4223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            break;
4233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
4243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        delete event;
4253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mLock.lock();
4263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
4273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
4283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
4293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames DongString8 channelMaskToString(audio_channel_mask_t mask, bool output) {
4303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    String8 s;
4313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (output) {
4323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_FRONT_LEFT) s.append("front-left, ");
4333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_FRONT_RIGHT) s.append("front-right, ");
4343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_FRONT_CENTER) s.append("front-center, ");
4353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_LOW_FREQUENCY) s.append("low freq, ");
4363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_BACK_LEFT) s.append("back-left, ");
4373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_BACK_RIGHT) s.append("back-right, ");
4383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER) s.append("front-left-of-center, ");
4393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER) s.append("front-right-of-center, ");
4403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_BACK_CENTER) s.append("back-center, ");
4413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_SIDE_LEFT) s.append("side-left, ");
4423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_SIDE_RIGHT) s.append("side-right, ");
4433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_TOP_CENTER) s.append("top-center ,");
4443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT) s.append("top-front-left, ");
4453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER) s.append("top-front-center, ");
4463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT) s.append("top-front-right, ");
4473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_LEFT) s.append("top-back-left, ");
4483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_CENTER) s.append("top-back-center, " );
4493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT) s.append("top-back-right, " );
4503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & ~AUDIO_CHANNEL_OUT_ALL) s.append("unknown,  ");
4513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else {
4523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_LEFT) s.append("left, ");
4533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_RIGHT) s.append("right, ");
4543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_FRONT) s.append("front, ");
4553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_BACK) s.append("back, ");
4563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_LEFT_PROCESSED) s.append("left-processed, ");
4573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_RIGHT_PROCESSED) s.append("right-processed, ");
4583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_FRONT_PROCESSED) s.append("front-processed, ");
4593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_BACK_PROCESSED) s.append("back-processed, ");
4603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_PRESSURE) s.append("pressure, ");
4613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_X_AXIS) s.append("X, ");
4623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_Y_AXIS) s.append("Y, ");
4633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_Z_AXIS) s.append("Z, ");
4643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_VOICE_UPLINK) s.append("voice-uplink, ");
4653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & AUDIO_CHANNEL_IN_VOICE_DNLINK) s.append("voice-dnlink, ");
4663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mask & ~AUDIO_CHANNEL_IN_ALL) s.append("unknown,  ");
4673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
4683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int len = s.length();
4693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (s.length() > 2) {
4703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        char *str = s.lockBuffer(len);
4713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        s.unlockBuffer(len - 2);
4723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
4733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return s;
4743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
4753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
4763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args __unused)
4773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
4783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    const size_t SIZE = 256;
4793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    char buffer[SIZE];
4803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    String8 result;
4813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
4823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    bool locked = AudioFlinger::dumpTryLock(mLock);
4833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (!locked) {
4843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        fdprintf(fd, "thread %p maybe dead locked\n", this);
4853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
4863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
4873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  I/O handle: %d\n", mId);
4883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  TID: %d\n", getTid());
4893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Standby: %s\n", mStandby ? "yes" : "no");
4903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Sample rate: %u\n", mSampleRate);
4913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  HAL frame count: %zu\n", mFrameCount);
4923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  HAL buffer size: %u bytes\n", mBufferSize);
4933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Channel Count: %u\n", mChannelCount);
4943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Channel Mask: 0x%08x (%s)\n", mChannelMask,
4953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            channelMaskToString(mChannelMask, mType != RECORD).string());
4963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Format: 0x%x (%s)\n", mFormat, formatToString(mFormat));
4973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Frame size: %zu\n", mFrameSize);
4983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Pending setParameters commands:");
4993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    size_t numParams = mNewParameters.size();
5003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (numParams) {
5013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        fdprintf(fd, "\n   Index Command");
5023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        for (size_t i = 0; i < numParams; ++i) {
5033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            fdprintf(fd, "\n   %02zu    ", i);
5043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            fdprintf(fd, mNewParameters[i]);
5053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
5063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        fdprintf(fd, "\n");
5073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else {
5083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        fdprintf(fd, " none\n");
5093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
5103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Pending config events:");
5113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    size_t numConfig = mConfigEvents.size();
5123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (numConfig) {
5133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        for (size_t i = 0; i < numConfig; i++) {
5143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            mConfigEvents[i]->dump(buffer, SIZE);
5153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            fdprintf(fd, "\n    %s", buffer);
5163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
5173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        fdprintf(fd, "\n");
5183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else {
5193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        fdprintf(fd, " none\n");
5203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
5213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
5223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (locked) {
5233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mLock.unlock();
5243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
5253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
5263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
5273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::dumpEffectChains(int fd, const Vector<String16>& args)
5283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
5293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    const size_t SIZE = 256;
5303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    char buffer[SIZE];
5313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    String8 result;
5323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
5333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    size_t numEffectChains = mEffectChains.size();
5343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    snprintf(buffer, SIZE, "  %zu Effect Chains\n", numEffectChains);
5353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    write(fd, buffer, strlen(buffer));
5363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
5373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    for (size_t i = 0; i < numEffectChains; ++i) {
5383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        sp<EffectChain> chain = mEffectChains[i];
5393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (chain != 0) {
5403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            chain->dump(fd, args);
5413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
5423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
5433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
5443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
5453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::acquireWakeLock(int uid)
5463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
5473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
5483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    acquireWakeLock_l(uid);
5493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
5503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
5513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames DongString16 AudioFlinger::ThreadBase::getWakeLockTag()
5523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
5533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    switch (mType) {
5543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        case MIXER:
5553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            return String16("AudioMix");
5563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        case DIRECT:
5573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            return String16("AudioDirectOut");
5583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        case DUPLICATING:
5593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            return String16("AudioDup");
5603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        case RECORD:
5613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            return String16("AudioIn");
5623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        case OFFLOAD:
5633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            return String16("AudioOffload");
5643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        default:
5653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ALOG_ASSERT(false);
5663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            return String16("AudioUnknown");
5673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
5683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
5693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
5703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::acquireWakeLock_l(int uid)
5713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
5723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    getPowerManager_l();
5733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (mPowerManager != 0) {
5743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        sp<IBinder> binder = new BBinder();
5753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        status_t status;
5763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (uid >= 0) {
5773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            status = mPowerManager->acquireWakeLockWithUid(POWERMANAGER_PARTIAL_WAKE_LOCK,
5783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    binder,
5793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    getWakeLockTag(),
5803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    String16("media"),
5813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    uid);
5823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        } else {
5833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK,
5843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    binder,
5853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    getWakeLockTag(),
5863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    String16("media"));
5873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
5883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (status == NO_ERROR) {
5893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            mWakeLockToken = binder;
5903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
5913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGV("acquireWakeLock_l() %s status %d", mName, status);
5923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
5933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
5943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
5953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::releaseWakeLock()
5963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
5973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
5983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    releaseWakeLock_l();
5993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
6003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::releaseWakeLock_l()
6023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
6033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (mWakeLockToken != 0) {
6043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGV("releaseWakeLock_l() %s", mName);
6053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mPowerManager != 0) {
6063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            mPowerManager->releaseWakeLock(mWakeLockToken, 0);
6073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
6083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mWakeLockToken.clear();
6093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
6103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
6113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::updateWakeLockUids(const SortedVector<int> &uids) {
6133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
6143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    updateWakeLockUids_l(uids);
6153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
6163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::getPowerManager_l() {
6183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (mPowerManager == 0) {
6203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // use checkService() to avoid blocking if power service is not up yet
6213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        sp<IBinder> binder =
6223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            defaultServiceManager()->checkService(String16("power"));
6233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (binder == 0) {
6243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ALOGW("Thread %s cannot connect to the power manager service", mName);
6253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        } else {
6263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            mPowerManager = interface_cast<IPowerManager>(binder);
6273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            binder->linkToDeath(mDeathRecipient);
6283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
6293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
6303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
6313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::updateWakeLockUids_l(const SortedVector<int> &uids) {
6333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    getPowerManager_l();
6353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (mWakeLockToken == NULL) {
6363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGE("no wake lock to update!");
6373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        return;
6383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
6393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (mPowerManager != 0) {
6403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        sp<IBinder> binder = new BBinder();
6413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        status_t status;
6423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        status = mPowerManager->updateWakeLockUids(mWakeLockToken, uids.size(), uids.array());
6433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGV("acquireWakeLock_l() %s status %d", mName, status);
6443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
6453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
6463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::clearPowerManager()
6483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
6493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
6503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    releaseWakeLock_l();
6513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mPowerManager.clear();
6523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
6533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::PMDeathRecipient::binderDied(const wp<IBinder>& who __unused)
6553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
6563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sp<ThreadBase> thread = mThread.promote();
6573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (thread != 0) {
6583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        thread->clearPowerManager();
6593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
6603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOGW("power manager service died !!!");
6613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
6623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::setEffectSuspended(
6643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        const effect_uuid_t *type, bool suspend, int sessionId)
6653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
6663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
6673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    setEffectSuspended_l(type, suspend, sessionId);
6683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
6693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::setEffectSuspended_l(
6713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        const effect_uuid_t *type, bool suspend, int sessionId)
6723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
6733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sp<EffectChain> chain = getEffectChain_l(sessionId);
6743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (chain != 0) {
6753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (type != NULL) {
6763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            chain->setEffectSuspended_l(type, suspend);
6773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        } else {
6783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            chain->setEffectSuspendedAll_l(suspend);
6793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
6803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
6813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    updateSuspendedSessions_l(type, suspend, sessionId);
6833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
6843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain)
6863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
6873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ssize_t index = mSuspendedSessions.indexOfKey(chain->sessionId());
6883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (index < 0) {
6893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        return;
6903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
6913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    const KeyedVector <int, sp<SuspendedSessionDesc> >& sessionEffects =
6933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            mSuspendedSessions.valueAt(index);
6943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
6953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    for (size_t i = 0; i < sessionEffects.size(); i++) {
6963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        sp<SuspendedSessionDesc> desc = sessionEffects.valueAt(i);
6973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        for (int j = 0; j < desc->mRefCount; j++) {
6983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if (sessionEffects.keyAt(i) == EffectChain::kKeyForSuspendAll) {
6993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                chain->setEffectSuspendedAll_l(true);
7003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            } else {
7013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ALOGV("checkSuspendOnAddEffectChain_l() suspending effects %08x",
7023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    desc->mType.timeLow);
7033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                chain->setEffectSuspended_l(&desc->mType, true);
7043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
7053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
7063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
7073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
7083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
7093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::updateSuspendedSessions_l(const effect_uuid_t *type,
7103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                                         bool suspend,
7113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                                         int sessionId)
7123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
7133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ssize_t index = mSuspendedSessions.indexOfKey(sessionId);
7143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
7153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    KeyedVector <int, sp<SuspendedSessionDesc> > sessionEffects;
7163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
7173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (suspend) {
7183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (index >= 0) {
7193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            sessionEffects = mSuspendedSessions.valueAt(index);
7203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        } else {
7213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            mSuspendedSessions.add(sessionId, sessionEffects);
7223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
7233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else {
7243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (index < 0) {
7253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            return;
7263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
7273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        sessionEffects = mSuspendedSessions.valueAt(index);
7283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
7293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
7303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
7313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int key = EffectChain::kKeyForSuspendAll;
7323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (type != NULL) {
7333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        key = type->timeLow;
7343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
7353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    index = sessionEffects.indexOfKey(key);
7363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
7373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sp<SuspendedSessionDesc> desc;
7383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (suspend) {
7393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (index >= 0) {
7403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            desc = sessionEffects.valueAt(index);
7413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        } else {
7423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            desc = new SuspendedSessionDesc();
7433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if (type != NULL) {
7443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                desc->mType = *type;
7453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
7463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            sessionEffects.add(key, desc);
7473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ALOGV("updateSuspendedSessions_l() suspend adding effect %08x", key);
7483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
7493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        desc->mRefCount++;
7503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else {
7513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (index < 0) {
7523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            return;
7533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
7543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        desc = sessionEffects.valueAt(index);
7553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (--desc->mRefCount == 0) {
7563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ALOGV("updateSuspendedSessions_l() restore removing effect %08x", key);
7573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            sessionEffects.removeItemsAt(index);
7583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if (sessionEffects.isEmpty()) {
7593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ALOGV("updateSuspendedSessions_l() restore removing session %d",
7603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                 sessionId);
7613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                mSuspendedSessions.removeItem(sessionId);
7623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
7633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
7643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
7653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (!sessionEffects.isEmpty()) {
7663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mSuspendedSessions.replaceValueFor(sessionId, sessionEffects);
7673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
7683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
7693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
7703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
7713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                                            bool enabled,
7723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                                            int sessionId)
7733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
7743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
7753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    checkSuspendOnEffectEnabled_l(effect, enabled, sessionId);
7763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
7773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
7783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled_l(const sp<EffectModule>& effect,
7793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                                            bool enabled,
7803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                                            int sessionId)
7813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
7823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (mType != RECORD) {
7833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // suspend all effects in AUDIO_SESSION_OUTPUT_MIX when enabling any effect on
7843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // another session. This gives the priority to well behaved effect control panels
7853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // and applications not using global effects.
7863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // Enabling post processing in AUDIO_SESSION_OUTPUT_STAGE session does not affect
7873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // global effects
7883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if ((sessionId != AUDIO_SESSION_OUTPUT_MIX) && (sessionId != AUDIO_SESSION_OUTPUT_STAGE)) {
7893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            setEffectSuspended_l(NULL, enabled, AUDIO_SESSION_OUTPUT_MIX);
7903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
7913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
7923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
7933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sp<EffectChain> chain = getEffectChain_l(sessionId);
7943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (chain != 0) {
7953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        chain->checkSuspendOnEffectEnabled(effect, enabled);
7963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
7973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
7983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
7993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// ThreadBase::createEffect_l() must be called with AudioFlinger::mLock held
8003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongsp<AudioFlinger::EffectHandle> AudioFlinger::ThreadBase::createEffect_l(
8013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        const sp<AudioFlinger::Client>& client,
8023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        const sp<IEffectClient>& effectClient,
8033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        int32_t priority,
8043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        int sessionId,
8053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        effect_descriptor_t *desc,
8063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        int *enabled,
8073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        status_t *status)
8083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
8093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sp<EffectModule> effect;
8103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sp<EffectHandle> handle;
8113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    status_t lStatus;
8123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sp<EffectChain> chain;
8133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    bool chainCreated = false;
8143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    bool effectCreated = false;
8153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    bool effectRegistered = false;
8163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
8173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    lStatus = initCheck();
8183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (lStatus != NO_ERROR) {
8193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGW("createEffect_l() Audio driver not initialized.");
8203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        goto Exit;
8213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
8223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
8233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // Allow global effects only on offloaded and mixer threads
8243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
8253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        switch (mType) {
8263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        case MIXER:
8273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        case OFFLOAD:
8283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            break;
8293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        case DIRECT:
8303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        case DUPLICATING:
8313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        case RECORD:
8323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        default:
8333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ALOGW("createEffect_l() Cannot add global effect %s on thread %s", desc->name, mName);
8343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            lStatus = BAD_VALUE;
8353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            goto Exit;
8363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
8373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
8383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
8393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // Only Pre processor effects are allowed on input threads and only on input threads
8403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if ((mType == RECORD) != ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC)) {
8413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGW("createEffect_l() effect %s (flags %08x) created on wrong thread type %d",
8423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                desc->name, desc->flags, mType);
8433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        lStatus = BAD_VALUE;
8443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        goto Exit;
8453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
8463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
8473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOGV("createEffect_l() thread %p effect %s on session %d", this, desc->name, sessionId);
8483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
8493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    { // scope for mLock
8503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        Mutex::Autolock _l(mLock);
8513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
8523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // check for existing effect chain with the requested audio session
8533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        chain = getEffectChain_l(sessionId);
8543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (chain == 0) {
8553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // create a new chain for this session
8563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ALOGV("createEffect_l() new effect chain for session %d", sessionId);
8573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            chain = new EffectChain(this, sessionId);
8583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            addEffectChain_l(chain);
8593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            chain->setStrategy(getStrategyForSession_l(sessionId));
8603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            chainCreated = true;
8613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        } else {
8623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            effect = chain->getEffectFromDesc_l(desc);
8633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
8643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
8653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGV("createEffect_l() got effect %p on chain %p", effect.get(), chain.get());
8663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
8673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (effect == 0) {
8683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            int id = mAudioFlinger->nextUniqueId();
8693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // Check CPU and memory usage
8703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            lStatus = AudioSystem::registerEffect(desc, mId, chain->strategy(), sessionId, id);
8713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if (lStatus != NO_ERROR) {
8723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                goto Exit;
8733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
8743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            effectRegistered = true;
8753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // create a new effect module if none present in the chain
8763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            effect = new EffectModule(this, chain, desc, id, sessionId);
8773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            lStatus = effect->status();
8783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if (lStatus != NO_ERROR) {
8793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                goto Exit;
8803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
8813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            effect->setOffloaded(mType == OFFLOAD, mId);
8823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
8833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            lStatus = chain->addEffect_l(effect);
8843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if (lStatus != NO_ERROR) {
8853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                goto Exit;
8863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
8873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            effectCreated = true;
8883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
8893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            effect->setDevice(mOutDevice);
8903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            effect->setDevice(mInDevice);
8913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            effect->setMode(mAudioFlinger->getMode());
8923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            effect->setAudioSource(mAudioSource);
8933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
8943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // create effect handle and connect it to effect module
8953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        handle = new EffectHandle(effect, client, effectClient, priority);
8963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        lStatus = handle->initCheck();
8973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (lStatus == OK) {
8983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            lStatus = effect->addHandle(handle.get());
8993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
9003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (enabled != NULL) {
9013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            *enabled = (int)effect->isEnabled();
9023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
9033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
9043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames DongExit:
9063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
9073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        Mutex::Autolock _l(mLock);
9083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (effectCreated) {
9093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            chain->removeEffect_l(effect);
9103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
9113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (effectRegistered) {
9123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            AudioSystem::unregisterEffect(effect->id());
9133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
9143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (chainCreated) {
9153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            removeEffectChain_l(chain);
9163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
9173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        handle.clear();
9183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
9193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    *status = lStatus;
9213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return handle;
9223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
9233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongsp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect(int sessionId, int effectId)
9253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
9263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
9273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return getEffect_l(sessionId, effectId);
9283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
9293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongsp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect_l(int sessionId, int effectId)
9313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
9323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sp<EffectChain> chain = getEffectChain_l(sessionId);
9333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return chain != 0 ? chain->getEffectFromId_l(effectId) : 0;
9343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
9353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// PlaybackThread::addEffect_l() must be called with AudioFlinger::mLock and
9373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// PlaybackThread::mLock held
9383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatus_t AudioFlinger::ThreadBase::addEffect_l(const sp<EffectModule>& effect)
9393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
9403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // check for existing effect chain with the requested audio session
9413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int sessionId = effect->sessionId();
9423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sp<EffectChain> chain = getEffectChain_l(sessionId);
9433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    bool chainCreated = false;
9443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOGD_IF((mType == OFFLOAD) && !effect->isOffloadable(),
9463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong             "addEffect_l() on offloaded thread %p: effect %s does not support offload flags %x",
9473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    this, effect->desc().name, effect->desc().flags);
9483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (chain == 0) {
9503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // create a new chain for this session
9513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGV("addEffect_l() new effect chain for session %d", sessionId);
9523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        chain = new EffectChain(this, sessionId);
9533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        addEffectChain_l(chain);
9543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        chain->setStrategy(getStrategyForSession_l(sessionId));
9553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        chainCreated = true;
9563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
9573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOGV("addEffect_l() %p chain %p effect %p", this, chain.get(), effect.get());
9583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (chain->getEffectFromId_l(effect->id()) != 0) {
9603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGW("addEffect_l() %p effect %s already present in chain %p",
9613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                this, effect->desc().name, chain.get());
9623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        return BAD_VALUE;
9633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
9643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    effect->setOffloaded(mType == OFFLOAD, mId);
9663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    status_t status = chain->addEffect_l(effect);
9683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (status != NO_ERROR) {
9693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (chainCreated) {
9703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            removeEffectChain_l(chain);
9713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
9723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        return status;
9733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
9743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    effect->setDevice(mOutDevice);
9763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    effect->setDevice(mInDevice);
9773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    effect->setMode(mAudioFlinger->getMode());
9783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    effect->setAudioSource(mAudioSource);
9793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return NO_ERROR;
9803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
9813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::removeEffect_l(const sp<EffectModule>& effect) {
9833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOGV("removeEffect_l() %p effect %p", this, effect.get());
9853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    effect_descriptor_t desc = effect->desc();
9863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
9873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        detachAuxEffect_l(effect->id());
9883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
9893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
9903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sp<EffectChain> chain = effect->chain().promote();
9913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (chain != 0) {
9923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // remove effect chain if removing last effect
9933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (chain->removeEffect_l(effect) == 0) {
9943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            removeEffectChain_l(chain);
9953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
9963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else {
9973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGW("removeEffect_l() %p cannot promote chain for effect %p", this, effect.get());
9983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
9993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
10003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
10013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::lockEffectChains_l(
10023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        Vector< sp<AudioFlinger::EffectChain> >& effectChains)
10033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
10043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    effectChains = mEffectChains;
10053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    for (size_t i = 0; i < mEffectChains.size(); i++) {
10063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mEffectChains[i]->lock();
10073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
10083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
10093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
10103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::unlockEffectChains(
10113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        const Vector< sp<AudioFlinger::EffectChain> >& effectChains)
10123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
10133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    for (size_t i = 0; i < effectChains.size(); i++) {
10143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        effectChains[i]->unlock();
10153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
10163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
10173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
10183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongsp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain(int sessionId)
10193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
10203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
10213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return getEffectChain_l(sessionId);
10223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
10233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
10243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongsp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain_l(int sessionId) const
10253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
10263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    size_t size = mEffectChains.size();
10273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    for (size_t i = 0; i < size; i++) {
10283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mEffectChains[i]->sessionId() == sessionId) {
10293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            return mEffectChains[i];
10303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
10313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
10323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return 0;
10333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
10343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
10353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::setMode(audio_mode_t mode)
10363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
10373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
10383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    size_t size = mEffectChains.size();
10393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    for (size_t i = 0; i < size; i++) {
10403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mEffectChains[i]->setMode_l(mode);
10413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
10423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
10433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
10443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::ThreadBase::disconnectEffect(const sp<EffectModule>& effect,
10453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                                    EffectHandle *handle,
10463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                                    bool unpinIfLast) {
10473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
10483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
10493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOGV("disconnectEffect() %p effect %p", this, effect.get());
10503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // delete the effect module if removing last handle on it
10513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (effect->removeHandle(handle) == 0) {
10523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (!effect->isPinned() || unpinIfLast) {
10533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            removeEffect_l(effect);
10543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            AudioSystem::unregisterEffect(effect->id());
10553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
10563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
10573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
10583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
10593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// ----------------------------------------------------------------------------
10603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong//      Playback
10613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// ----------------------------------------------------------------------------
10623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
10633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames DongAudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger,
10643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                             AudioStreamOut* output,
10653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                             audio_io_handle_t id,
10663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                             audio_devices_t device,
10673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                             type_t type)
10683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    :   ThreadBase(audioFlinger, id, device, AUDIO_DEVICE_NONE, type),
10693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mNormalFrameCount(0), mMixBuffer(NULL),
10703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mSuspended(0), mBytesWritten(0),
10713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mActiveTracksGeneration(0),
10723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // mStreamTypes[] initialized in constructor body
10733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mOutput(output),
10743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
10753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mMixerStatus(MIXER_IDLE),
10763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mMixerStatusIgnoringFastTracks(MIXER_IDLE),
10773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        standbyDelay(AudioFlinger::mStandbyTimeInNsecs),
10783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mBytesRemaining(0),
10793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mCurrentWriteLength(0),
10803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mUseAsyncWrite(false),
10813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mWriteAckSequence(0),
10823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mDrainSequence(0),
10833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mSignalPending(false),
10843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mScreenState(AudioFlinger::mScreenState),
10853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // index 0 is reserved for normal mixer's submix
10863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mFastTrackAvailMask(((1 << FastMixerState::kMaxFastTracks) - 1) & ~1),
10873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // mLatchD, mLatchQ,
10883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mLatchDValid(false), mLatchQValid(false)
10893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
10903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    snprintf(mName, kNameLength, "AudioOut_%X", id);
10913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mName);
10923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
10933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // Assumes constructor is called by AudioFlinger with it's mLock held, but
10943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // it would be safer to explicitly pass initial masterVolume/masterMute as
10953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // parameter.
10963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    //
10973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // If the HAL we are using has support for master volume or master mute,
10983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // then do not attenuate or mute during mixing (just leave the volume at 1.0
10993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // and the mute set to false).
11003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mMasterVolume = audioFlinger->masterVolume_l();
11013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mMasterMute = audioFlinger->masterMute_l();
11023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (mOutput && mOutput->audioHwDev) {
11033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mOutput->audioHwDev->canSetMasterVolume()) {
11043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            mMasterVolume = 1.0;
11053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
11063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
11073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (mOutput->audioHwDev->canSetMasterMute()) {
11083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            mMasterMute = false;
11093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
11103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
11113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
11123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    readOutputParameters_l();
11133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
11143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // mStreamTypes[AUDIO_STREAM_CNT] is initialized by stream_type_t default constructor
11153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // There is no AUDIO_STREAM_MIN, and ++ operator does not compile
11163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    for (audio_stream_type_t stream = (audio_stream_type_t) 0; stream < AUDIO_STREAM_CNT;
11173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            stream = (audio_stream_type_t) (stream + 1)) {
11183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mStreamTypes[stream].volume = mAudioFlinger->streamVolume_l(stream);
11193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mStreamTypes[stream].mute = mAudioFlinger->streamMute_l(stream);
11203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
11213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // mStreamTypes[AUDIO_STREAM_CNT] exists but isn't explicitly initialized here,
11223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // because mAudioFlinger doesn't have one to copy from
11233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
11243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
11253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames DongAudioFlinger::PlaybackThread::~PlaybackThread()
11263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
11273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mAudioFlinger->unregisterWriter(mNBLogWriter);
11283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    delete[] mMixBuffer;
11293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
11303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
11313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::dump(int fd, const Vector<String16>& args)
11323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
11333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    dumpInternals(fd, args);
11343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    dumpTracks(fd, args);
11353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    dumpEffectChains(fd, args);
11363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
11373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
11383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& args __unused)
11393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
11403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    const size_t SIZE = 256;
11413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    char buffer[SIZE];
11423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    String8 result;
11433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
11443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    result.appendFormat("  Stream volumes in dB: ");
11453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    for (int i = 0; i < AUDIO_STREAM_CNT; ++i) {
11463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        const stream_type_t *st = &mStreamTypes[i];
11473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (i > 0) {
11483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            result.appendFormat(", ");
11493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
11503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        result.appendFormat("%d:%.2g", i, 20.0 * log10(st->volume));
11513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (st->mute) {
11523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            result.append("M");
11533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
11543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
11553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    result.append("\n");
11563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    write(fd, result.string(), result.length());
11573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    result.clear();
11583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
11593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // These values are "raw"; they will wrap around.  See prepareTracks_l() for a better way.
11603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    FastTrackUnderruns underruns = getFastTrackUnderruns(0);
11613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Normal mixer raw underrun counters: partial=%u empty=%u\n",
11623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            underruns.mBitFields.mPartial, underruns.mBitFields.mEmpty);
11633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
11643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    size_t numtracks = mTracks.size();
11653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    size_t numactive = mActiveTracks.size();
11663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  %d Tracks", numtracks);
11673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    size_t numactiveseen = 0;
11683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (numtracks) {
11693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        fdprintf(fd, " of which %d are active\n", numactive);
11703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        Track::appendDumpHeader(result);
11713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        for (size_t i = 0; i < numtracks; ++i) {
11723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            sp<Track> track = mTracks[i];
11733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if (track != 0) {
11743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                bool active = mActiveTracks.indexOf(track) >= 0;
11753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                if (active) {
11763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    numactiveseen++;
11773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                }
11783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                track->dump(buffer, SIZE, active);
11793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                result.append(buffer);
11803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
11813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
11823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else {
11833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        result.append("\n");
11843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
11853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (numactiveseen != numactive) {
11863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // some tracks in the active list were not in the tracks list
11873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        snprintf(buffer, SIZE, "  The following tracks are in the active list but"
11883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                " not in the track list\n");
11893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        result.append(buffer);
11903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        Track::appendDumpHeader(result);
11913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        for (size_t i = 0; i < numactive; ++i) {
11923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            sp<Track> track = mActiveTracks[i].promote();
11933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if (track != 0 && mTracks.indexOf(track) < 0) {
11943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                track->dump(buffer, SIZE, true);
11953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                result.append(buffer);
11963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
11973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
11983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
11993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
12003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    write(fd, result.string(), result.size());
12013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
12023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
12033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
12043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
12053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
12063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "\nOutput thread %p:\n", this);
12073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Normal frame count: %zu\n", mNormalFrameCount);
12083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
12093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Total writes: %d\n", mNumWrites);
12103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Delayed writes: %d\n", mNumDelayedWrites);
12113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Blocked in write: %s\n", mInWrite ? "yes" : "no");
12123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Suspend count: %d\n", mSuspended);
12133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Mix buffer : %p\n", mMixBuffer);
12143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    fdprintf(fd, "  Fast track availMask=%#x\n", mFastTrackAvailMask);
12153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
12163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    dumpBase(fd, args);
12173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
12183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
12193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// Thread virtuals
12203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
12213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::onFirstRef()
12223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
12233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    run(mName, ANDROID_PRIORITY_URGENT_AUDIO);
12243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
12253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
12263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// ThreadBase virtuals
12273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::preExit()
12283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
12293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOGV("  preExit()");
12303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // FIXME this is using hard-coded strings but in the future, this functionality will be
12313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    //       converted to use audio HAL extensions required to support tunneling
12323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mOutput->stream->common.set_parameters(&mOutput->stream->common, "exiting=1");
12333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
12343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
12353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
12363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongsp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l(
12373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        const sp<AudioFlinger::Client>& client,
12383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        audio_stream_type_t streamType,
12393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        uint32_t sampleRate,
12403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        audio_format_t format,
12413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        audio_channel_mask_t channelMask,
12423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        size_t *pFrameCount,
12433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        const sp<IMemory>& sharedBuffer,
12443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        int sessionId,
12453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        IAudioFlinger::track_flags_t *flags,
12463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        pid_t tid,
12473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        int uid,
12483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        status_t *status)
12493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
12503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    size_t frameCount = *pFrameCount;
12513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sp<Track> track;
12523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    status_t lStatus;
12533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
12543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    bool isTimed = (*flags & IAudioFlinger::TRACK_TIMED) != 0;
12553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
12563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // client expresses a preference for FAST, but we get the final say
12573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (*flags & IAudioFlinger::TRACK_FAST) {
12583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong      if (
12593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // not timed
12603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            (!isTimed) &&
12613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // either of these use cases:
12623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            (
12633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong              // use case 1: shared buffer with any frame count
12643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong              (
12653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                (sharedBuffer != 0)
12663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong              ) ||
12673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong              // use case 2: callback handler and frame count is default or at least as large as HAL
12683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong              (
12693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                (tid != -1) &&
12703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ((frameCount == 0) ||
12713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                (frameCount >= mFrameCount))
12723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong              )
12733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ) &&
12743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // PCM data
12753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            audio_is_linear_pcm(format) &&
12763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // mono or stereo
12773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ( (channelMask == AUDIO_CHANNEL_OUT_MONO) ||
12783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong              (channelMask == AUDIO_CHANNEL_OUT_STEREO) ) &&
12793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // hardware sample rate
12803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            (sampleRate == mSampleRate) &&
12813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // normal mixer has an associated fast mixer
12823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            hasFastMixer() &&
12833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // there are sufficient fast track slots available
12843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            (mFastTrackAvailMask != 0)
12853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // FIXME test that MixerThread for this fast track has a capable output HAL
12863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // FIXME add a permission test also?
12873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ) {
12883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // if frameCount not specified, then it defaults to fast mixer (HAL) frame count
12893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (frameCount == 0) {
12903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            frameCount = mFrameCount * kFastTrackMultiplier;
12913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
12923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGV("AUDIO_OUTPUT_FLAG_FAST accepted: frameCount=%d mFrameCount=%d",
12933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                frameCount, mFrameCount);
12943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong      } else {
12953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGV("AUDIO_OUTPUT_FLAG_FAST denied: isTimed=%d sharedBuffer=%p frameCount=%d "
12963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                "mFrameCount=%d format=%d isLinear=%d channelMask=%#x sampleRate=%u mSampleRate=%u "
12973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                "hasFastMixer=%d tid=%d fastTrackAvailMask=%#x",
12983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                isTimed, sharedBuffer.get(), frameCount, mFrameCount, format,
12993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                audio_is_linear_pcm(format),
13003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                channelMask, sampleRate, mSampleRate, hasFastMixer(), tid, mFastTrackAvailMask);
13013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        *flags &= ~IAudioFlinger::TRACK_FAST;
13023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // For compatibility with AudioTrack calculation, buffer depth is forced
13033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // to be at least 2 x the normal mixer frame count and cover audio hardware latency.
13043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // This is probably too conservative, but legacy application code may depend on it.
13053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // If you change this calculation, also review the start threshold which is related.
13063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        uint32_t latencyMs = mOutput->stream->get_latency(mOutput->stream);
13073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        uint32_t minBufCount = latencyMs / ((1000 * mNormalFrameCount) / mSampleRate);
13083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (minBufCount < 2) {
13093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            minBufCount = 2;
13103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
13113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        size_t minFrameCount = mNormalFrameCount * minBufCount;
13123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (frameCount < minFrameCount) {
13133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            frameCount = minFrameCount;
13143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
13153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong      }
13163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
13173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    *pFrameCount = frameCount;
13183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
13193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (mType == DIRECT) {
13203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) {
13213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) {
13223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ALOGE("createTrack_l() Bad parameter: sampleRate %u format %#x, channelMask 0x%08x "
13233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        "for output %p with format %#x",
13243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        sampleRate, format, channelMask, mOutput, mFormat);
13253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                lStatus = BAD_VALUE;
13263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                goto Exit;
13273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
13283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
13293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else if (mType == OFFLOAD) {
13303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) {
13313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ALOGE("createTrack_l() Bad parameter: sampleRate %d format %#x, channelMask 0x%08x \""
13323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    "for output %p with format %#x",
13333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    sampleRate, format, channelMask, mOutput, mFormat);
13343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            lStatus = BAD_VALUE;
13353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            goto Exit;
13363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
13373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else {
13383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if ((format & AUDIO_FORMAT_MAIN_MASK) != AUDIO_FORMAT_PCM) {
13393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ALOGE("createTrack_l() Bad parameter: format %#x \""
13403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        "for output %p with format %#x",
13413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        format, mOutput, mFormat);
13423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                lStatus = BAD_VALUE;
13433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                goto Exit;
13443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
13453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // Resampler implementation limits input sampling rate to 2 x output sampling rate.
13463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (sampleRate > mSampleRate*2) {
13473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ALOGE("Sample rate out of range: %u mSampleRate %u", sampleRate, mSampleRate);
13483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            lStatus = BAD_VALUE;
13493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            goto Exit;
13503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
13513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
13523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
13533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    lStatus = initCheck();
13543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (lStatus != NO_ERROR) {
13553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOGE("Audio driver not initialized.");
13563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        goto Exit;
13573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
13583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
13593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    { // scope for mLock
13603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        Mutex::Autolock _l(mLock);
13613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
13623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // all tracks in same audio session must share the same routing strategy otherwise
13633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // conflicts will happen when tracks are moved from one output to another by audio policy
13643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // manager
13653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        uint32_t strategy = AudioSystem::getStrategyForStream(streamType);
13663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        for (size_t i = 0; i < mTracks.size(); ++i) {
13673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            sp<Track> t = mTracks[i];
13683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if (t != 0 && !t->isOutputTrack()) {
13693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                uint32_t actual = AudioSystem::getStrategyForStream(t->streamType());
13703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                if (sessionId == t->sessionId() && strategy != actual) {
13713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    ALOGE("createTrack_l() mismatched strategy; expected %u but found %u",
13723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                            strategy, actual);
13733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    lStatus = BAD_VALUE;
13743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    goto Exit;
13753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                }
13763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
13773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
13783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
13793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (!isTimed) {
13803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            track = new Track(this, client, streamType, sampleRate, format,
13813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    channelMask, frameCount, sharedBuffer, sessionId, uid, *flags);
13823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        } else {
13833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            track = TimedTrack::create(this, client, streamType, sampleRate, format,
13843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    channelMask, frameCount, sharedBuffer, sessionId, uid);
13853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
13863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
13873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // new Track always returns non-NULL,
13883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // but TimedTrack::create() is a factory that could fail by returning NULL
13893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY;
13903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (lStatus != NO_ERROR) {
13913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ALOGE("createTrack_l() initCheck failed %d; no control block?", lStatus);
13923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // track must be cleared from the caller as the caller has the AF lock
13933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            goto Exit;
13943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
13953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
13963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mTracks.add(track);
13973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
13983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        sp<EffectChain> chain = getEffectChain_l(sessionId);
13993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (chain != 0) {
14003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ALOGV("createTrack_l() setting main buffer %p", chain->inBuffer());
14013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            track->setMainBuffer(chain->inBuffer());
14023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            chain->setStrategy(AudioSystem::getStrategyForStream(track->streamType()));
14033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            chain->incTrackCnt();
14043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
14053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
14063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if ((*flags & IAudioFlinger::TRACK_FAST) && (tid != -1)) {
14073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            pid_t callingPid = IPCThreadState::self()->getCallingPid();
14083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful,
14093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // so ask activity manager to do this on our behalf
14103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            sendPrioConfigEvent_l(callingPid, tid, kPriorityAudioApp);
14113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
14123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
14133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
14143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    lStatus = NO_ERROR;
14153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
14163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames DongExit:
14173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    *status = lStatus;
14183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return track;
14193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
14203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
14213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Donguint32_t AudioFlinger::PlaybackThread::correctLatency_l(uint32_t latency) const
14223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
14233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return latency;
14243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
14253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
14263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Donguint32_t AudioFlinger::PlaybackThread::latency() const
14273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
14283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
14293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return latency_l();
14303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
14313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Donguint32_t AudioFlinger::PlaybackThread::latency_l() const
14323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
14333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (initCheck() == NO_ERROR) {
14343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        return correctLatency_l(mOutput->stream->get_latency(mOutput->stream));
14353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else {
14363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        return 0;
14373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
14383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
14393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
14403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::setMasterVolume(float value)
14413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
14423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
14433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // Don't apply master volume in SW if our HAL can do it for us.
14443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (mOutput && mOutput->audioHwDev &&
14453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mOutput->audioHwDev->canSetMasterVolume()) {
14463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mMasterVolume = 1.0;
14473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else {
14483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mMasterVolume = value;
14493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
14503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
14513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
14523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::setMasterMute(bool muted)
14533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
14543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
14553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // Don't apply master mute in SW if our HAL can do it for us.
14563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (mOutput && mOutput->audioHwDev &&
14573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mOutput->audioHwDev->canSetMasterMute()) {
14583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mMasterMute = false;
14593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else {
14603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mMasterMute = muted;
14613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
14623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
14633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
14643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
14653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
14663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
14673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mStreamTypes[stream].volume = value;
14683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    broadcast_l();
14693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
14703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
14713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
14723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
14733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
14743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mStreamTypes[stream].mute = muted;
14753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    broadcast_l();
14763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
14773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
14783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongfloat AudioFlinger::PlaybackThread::streamVolume(audio_stream_type_t stream) const
14793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
14803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
14813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return mStreamTypes[stream].volume;
14823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
14833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
14843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// addTrack_l() must be called with ThreadBase::mLock held
14853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongstatus_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
14863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
14873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    status_t status = ALREADY_EXISTS;
14883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
14893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // set retry count for buffer fill
14903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    track->mRetryCount = kMaxTrackStartupRetries;
14913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (mActiveTracks.indexOf(track) < 0) {
14923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // the track is newly added, make sure it fills up all its
14933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // buffers before playing. This is to ensure the client will
14943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // effectively get the latency it requested.
14953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (!track->isOutputTrack()) {
14963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            TrackBase::track_state state = track->mState;
14973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            mLock.unlock();
14983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            status = AudioSystem::startOutput(mId, track->streamType(), track->sessionId());
14993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            mLock.lock();
15003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // abort track was stopped/paused while we released the lock
15013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if (state != track->mState) {
15023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                if (status == NO_ERROR) {
15033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    mLock.unlock();
15043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    AudioSystem::stopOutput(mId, track->streamType(), track->sessionId());
15053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    mLock.lock();
15063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                }
15073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                return INVALID_OPERATION;
15083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
15093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // abort if start is rejected by audio policy manager
15103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if (status != NO_ERROR) {
15113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                return PERMISSION_DENIED;
15123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
15133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#ifdef ADD_BATTERY_DATA
15143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            // to track the speaker usage
15153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStart);
15163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#endif
15173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
15183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
15193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        track->mFillingUpStatus = track->sharedBuffer() != 0 ? Track::FS_FILLED : Track::FS_FILLING;
15203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        track->mResetDone = false;
15213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        track->mPresentationCompleteFrames = 0;
15223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mActiveTracks.add(track);
15233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mWakeLockUids.add(track->uid());
15243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mActiveTracksGeneration++;
15253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mLatestActiveTrack = track;
15263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        sp<EffectChain> chain = getEffectChain_l(track->sessionId());
15273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (chain != 0) {
15283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            ALOGV("addTrack_l() starting track on chain %p for session %d", chain.get(),
15293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    track->sessionId());
15303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            chain->incActiveTrackCnt();
15313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
15323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
15333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        status = NO_ERROR;
15343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
15353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
15363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    onAddNewTrack_l();
15373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return status;
15383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
15393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
15403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongbool AudioFlinger::PlaybackThread::destroyTrack_l(const sp<Track>& track)
15413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
15423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    track->terminate();
15433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // active tracks are removed by threadLoop()
15443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    bool trackActive = (mActiveTracks.indexOf(track) >= 0);
15453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    track->mState = TrackBase::STOPPED;
15463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (!trackActive) {
15473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        removeTrack_l(track);
15483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } else if (track->isFastTrack() || track->isOffloaded()) {
15493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        track->mState = TrackBase::STOPPING_1;
15503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
15513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
15523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return trackActive;
15533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
15543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
15553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::removeTrack_l(const sp<Track>& track)
15563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
15573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    track->triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
15583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mTracks.remove(track);
15593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    deleteTrackName_l(track->name());
15603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // redundant as track is about to be destroyed, for dumpsys only
15613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    track->mName = -1;
15623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (track->isFastTrack()) {
15633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        int index = track->mFastIndex;
15643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOG_ASSERT(0 < index && index < (int)FastMixerState::kMaxFastTracks);
15653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ALOG_ASSERT(!(mFastTrackAvailMask & (1 << index)));
15663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        mFastTrackAvailMask |= 1 << index;
15673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        // redundant as track is about to be destroyed, for dumpsys only
15683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        track->mFastIndex = -1;
15693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
15703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    sp<EffectChain> chain = getEffectChain_l(track->sessionId());
15713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (chain != 0) {
15723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        chain->decTrackCnt();
15733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
15743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
15753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
15763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::broadcast_l()
15773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
15783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // Thread could be blocked waiting for async
15793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // so signal it to handle state changes immediately
15803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // If threadLoop is currently unlocked a signal of mWaitWorkCV will
15813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    // be lost so we also flag to prevent it blocking on mWaitWorkCV
15823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mSignalPending = true;
15833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mWaitWorkCV.broadcast();
15843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
15853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
15863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames DongString8 AudioFlinger::PlaybackThread::getParameters(const String8& keys)
15873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
15883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    Mutex::Autolock _l(mLock);
15893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    if (initCheck() != NO_ERROR) {
15903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        return String8();
15913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
15923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
15933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    char *s = mOutput->stream->common.get_parameters(&mOutput->stream->common, keys.string());
15943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    const String8 out_s8(s);
15953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    free(s);
15963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return out_s8;
15973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
15983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
15993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong// audioConfigChanged_l() must be called with AudioFlinger::mLock held
16003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::audioConfigChanged_l(int event, int param) {
16013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    AudioSystem::OutputDescriptor desc;
16023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    void *param2 = NULL;
16033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
16043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOGV("PlaybackThread::audioConfigChanged_l, thread %p, event %d, param %d", this, event,
16053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            param);
16063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
16073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    switch (event) {
16083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    case AudioSystem::OUTPUT_OPENED:
16093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    case AudioSystem::OUTPUT_CONFIG_CHANGED:
16103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        desc.channelMask = mChannelMask;
16113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        desc.samplingRate = mSampleRate;
16123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        desc.format = mFormat;
16133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        desc.frameCount = mNormalFrameCount; // FIXME see
16143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                             // AudioFlinger::frameCount(audio_io_handle_t)
16153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        desc.latency = latency();
16163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        param2 = &desc;
16173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        break;
16183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
16193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    case AudioSystem::STREAM_CONFIG_CHANGED:
16203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        param2 = &param;
16213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    case AudioSystem::OUTPUT_CLOSED:
16223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    default:
16233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        break;
16243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
16253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mAudioFlinger->audioConfigChanged_l(event, mId, param2);
16263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
16273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
16283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::writeCallback()
16293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
16303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOG_ASSERT(mCallbackThread != 0);
16313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    mCallbackThread->resetWriteBlocked();
16323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
16333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
16343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid AudioFlinger::PlaybackThread::drainCallback()
16353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
16363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ALOG_ASSERT(mCallbackThread != 0);
1637    mCallbackThread->resetDraining();
1638}
1639
1640void AudioFlinger::PlaybackThread::resetWriteBlocked(uint32_t sequence)
1641{
1642    Mutex::Autolock _l(mLock);
1643    // reject out of sequence requests
1644    if ((mWriteAckSequence & 1) && (sequence == mWriteAckSequence)) {
1645        mWriteAckSequence &= ~1;
1646        mWaitWorkCV.signal();
1647    }
1648}
1649
1650void AudioFlinger::PlaybackThread::resetDraining(uint32_t sequence)
1651{
1652    Mutex::Autolock _l(mLock);
1653    // reject out of sequence requests
1654    if ((mDrainSequence & 1) && (sequence == mDrainSequence)) {
1655        mDrainSequence &= ~1;
1656        mWaitWorkCV.signal();
1657    }
1658}
1659
1660// static
1661int AudioFlinger::PlaybackThread::asyncCallback(stream_callback_event_t event,
1662                                                void *param __unused,
1663                                                void *cookie)
1664{
1665    AudioFlinger::PlaybackThread *me = (AudioFlinger::PlaybackThread *)cookie;
1666    ALOGV("asyncCallback() event %d", event);
1667    switch (event) {
1668    case STREAM_CBK_EVENT_WRITE_READY:
1669        me->writeCallback();
1670        break;
1671    case STREAM_CBK_EVENT_DRAIN_READY:
1672        me->drainCallback();
1673        break;
1674    default:
1675        ALOGW("asyncCallback() unknown event %d", event);
1676        break;
1677    }
1678    return 0;
1679}
1680
1681void AudioFlinger::PlaybackThread::readOutputParameters_l()
1682{
1683    // unfortunately we have no way of recovering from errors here, hence the LOG_FATAL
1684    mSampleRate = mOutput->stream->common.get_sample_rate(&mOutput->stream->common);
1685    mChannelMask = mOutput->stream->common.get_channels(&mOutput->stream->common);
1686    if (!audio_is_output_channel(mChannelMask)) {
1687        LOG_FATAL("HAL channel mask %#x not valid for output", mChannelMask);
1688    }
1689    if ((mType == MIXER || mType == DUPLICATING) && mChannelMask != AUDIO_CHANNEL_OUT_STEREO) {
1690        LOG_FATAL("HAL channel mask %#x not supported for mixed output; "
1691                "must be AUDIO_CHANNEL_OUT_STEREO", mChannelMask);
1692    }
1693    mChannelCount = popcount(mChannelMask);
1694    mFormat = mOutput->stream->common.get_format(&mOutput->stream->common);
1695    if (!audio_is_valid_format(mFormat)) {
1696        LOG_FATAL("HAL format %#x not valid for output", mFormat);
1697    }
1698    if ((mType == MIXER || mType == DUPLICATING) && mFormat != AUDIO_FORMAT_PCM_16_BIT) {
1699        LOG_FATAL("HAL format %#x not supported for mixed output; must be AUDIO_FORMAT_PCM_16_BIT",
1700                mFormat);
1701    }
1702    mFrameSize = audio_stream_frame_size(&mOutput->stream->common);
1703    mBufferSize = mOutput->stream->common.get_buffer_size(&mOutput->stream->common);
1704    mFrameCount = mBufferSize / mFrameSize;
1705    if (mFrameCount & 15) {
1706        ALOGW("HAL output buffer size is %u frames but AudioMixer requires multiples of 16 frames",
1707                mFrameCount);
1708    }
1709
1710    if ((mOutput->flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING) &&
1711            (mOutput->stream->set_callback != NULL)) {
1712        if (mOutput->stream->set_callback(mOutput->stream,
1713                                      AudioFlinger::PlaybackThread::asyncCallback, this) == 0) {
1714            mUseAsyncWrite = true;
1715            mCallbackThread = new AudioFlinger::AsyncCallbackThread(this);
1716        }
1717    }
1718
1719    // Calculate size of normal mix buffer relative to the HAL output buffer size
1720    double multiplier = 1.0;
1721    if (mType == MIXER && (kUseFastMixer == FastMixer_Static ||
1722            kUseFastMixer == FastMixer_Dynamic)) {
1723        size_t minNormalFrameCount = (kMinNormalMixBufferSizeMs * mSampleRate) / 1000;
1724        size_t maxNormalFrameCount = (kMaxNormalMixBufferSizeMs * mSampleRate) / 1000;
1725        // round up minimum and round down maximum to nearest 16 frames to satisfy AudioMixer
1726        minNormalFrameCount = (minNormalFrameCount + 15) & ~15;
1727        maxNormalFrameCount = maxNormalFrameCount & ~15;
1728        if (maxNormalFrameCount < minNormalFrameCount) {
1729            maxNormalFrameCount = minNormalFrameCount;
1730        }
1731        multiplier = (double) minNormalFrameCount / (double) mFrameCount;
1732        if (multiplier <= 1.0) {
1733            multiplier = 1.0;
1734        } else if (multiplier <= 2.0) {
1735            if (2 * mFrameCount <= maxNormalFrameCount) {
1736                multiplier = 2.0;
1737            } else {
1738                multiplier = (double) maxNormalFrameCount / (double) mFrameCount;
1739            }
1740        } else {
1741            // prefer an even multiplier, for compatibility with doubling of fast tracks due to HAL
1742            // SRC (it would be unusual for the normal mix buffer size to not be a multiple of fast
1743            // track, but we sometimes have to do this to satisfy the maximum frame count
1744            // constraint)
1745            // FIXME this rounding up should not be done if no HAL SRC
1746            uint32_t truncMult = (uint32_t) multiplier;
1747            if ((truncMult & 1)) {
1748                if ((truncMult + 1) * mFrameCount <= maxNormalFrameCount) {
1749                    ++truncMult;
1750                }
1751            }
1752            multiplier = (double) truncMult;
1753        }
1754    }
1755    mNormalFrameCount = multiplier * mFrameCount;
1756    // round up to nearest 16 frames to satisfy AudioMixer
1757    mNormalFrameCount = (mNormalFrameCount + 15) & ~15;
1758    ALOGI("HAL output buffer size %u frames, normal mix buffer size %u frames", mFrameCount,
1759            mNormalFrameCount);
1760
1761    delete[] mMixBuffer;
1762    size_t normalBufferSize = mNormalFrameCount * mFrameSize;
1763    // For historical reasons mMixBuffer is int16_t[], but mFrameSize can be odd (such as 1)
1764    mMixBuffer = new int16_t[(normalBufferSize + 1) >> 1];
1765    memset(mMixBuffer, 0, normalBufferSize);
1766
1767    // force reconfiguration of effect chains and engines to take new buffer size and audio
1768    // parameters into account
1769    // Note that mLock is not held when readOutputParameters_l() is called from the constructor
1770    // but in this case nothing is done below as no audio sessions have effect yet so it doesn't
1771    // matter.
1772    // create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains
1773    Vector< sp<EffectChain> > effectChains = mEffectChains;
1774    for (size_t i = 0; i < effectChains.size(); i ++) {
1775        mAudioFlinger->moveEffectChain_l(effectChains[i]->sessionId(), this, this, false);
1776    }
1777}
1778
1779
1780status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
1781{
1782    if (halFrames == NULL || dspFrames == NULL) {
1783        return BAD_VALUE;
1784    }
1785    Mutex::Autolock _l(mLock);
1786    if (initCheck() != NO_ERROR) {
1787        return INVALID_OPERATION;
1788    }
1789    size_t framesWritten = mBytesWritten / mFrameSize;
1790    *halFrames = framesWritten;
1791
1792    if (isSuspended()) {
1793        // return an estimation of rendered frames when the output is suspended
1794        size_t latencyFrames = (latency_l() * mSampleRate) / 1000;
1795        *dspFrames = framesWritten >= latencyFrames ? framesWritten - latencyFrames : 0;
1796        return NO_ERROR;
1797    } else {
1798        status_t status;
1799        uint32_t frames;
1800        status = mOutput->stream->get_render_position(mOutput->stream, &frames);
1801        *dspFrames = (size_t)frames;
1802        return status;
1803    }
1804}
1805
1806uint32_t AudioFlinger::PlaybackThread::hasAudioSession(int sessionId) const
1807{
1808    Mutex::Autolock _l(mLock);
1809    uint32_t result = 0;
1810    if (getEffectChain_l(sessionId) != 0) {
1811        result = EFFECT_SESSION;
1812    }
1813
1814    for (size_t i = 0; i < mTracks.size(); ++i) {
1815        sp<Track> track = mTracks[i];
1816        if (sessionId == track->sessionId() && !track->isInvalid()) {
1817            result |= TRACK_SESSION;
1818            break;
1819        }
1820    }
1821
1822    return result;
1823}
1824
1825uint32_t AudioFlinger::PlaybackThread::getStrategyForSession_l(int sessionId)
1826{
1827    // session AUDIO_SESSION_OUTPUT_MIX is placed in same strategy as MUSIC stream so that
1828    // it is moved to correct output by audio policy manager when A2DP is connected or disconnected
1829    if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
1830        return AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
1831    }
1832    for (size_t i = 0; i < mTracks.size(); i++) {
1833        sp<Track> track = mTracks[i];
1834        if (sessionId == track->sessionId() && !track->isInvalid()) {
1835            return AudioSystem::getStrategyForStream(track->streamType());
1836        }
1837    }
1838    return AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
1839}
1840
1841
1842AudioFlinger::AudioStreamOut* AudioFlinger::PlaybackThread::getOutput() const
1843{
1844    Mutex::Autolock _l(mLock);
1845    return mOutput;
1846}
1847
1848AudioFlinger::AudioStreamOut* AudioFlinger::PlaybackThread::clearOutput()
1849{
1850    Mutex::Autolock _l(mLock);
1851    AudioStreamOut *output = mOutput;
1852    mOutput = NULL;
1853    // FIXME FastMixer might also have a raw ptr to mOutputSink;
1854    //       must push a NULL and wait for ack
1855    mOutputSink.clear();
1856    mPipeSink.clear();
1857    mNormalSink.clear();
1858    return output;
1859}
1860
1861// this method must always be called either with ThreadBase mLock held or inside the thread loop
1862audio_stream_t* AudioFlinger::PlaybackThread::stream() const
1863{
1864    if (mOutput == NULL) {
1865        return NULL;
1866    }
1867    return &mOutput->stream->common;
1868}
1869
1870uint32_t AudioFlinger::PlaybackThread::activeSleepTimeUs() const
1871{
1872    return (uint32_t)((uint32_t)((mNormalFrameCount * 1000) / mSampleRate) * 1000);
1873}
1874
1875status_t AudioFlinger::PlaybackThread::setSyncEvent(const sp<SyncEvent>& event)
1876{
1877    if (!isValidSyncEvent(event)) {
1878        return BAD_VALUE;
1879    }
1880
1881    Mutex::Autolock _l(mLock);
1882
1883    for (size_t i = 0; i < mTracks.size(); ++i) {
1884        sp<Track> track = mTracks[i];
1885        if (event->triggerSession() == track->sessionId()) {
1886            (void) track->setSyncEvent(event);
1887            return NO_ERROR;
1888        }
1889    }
1890
1891    return NAME_NOT_FOUND;
1892}
1893
1894bool AudioFlinger::PlaybackThread::isValidSyncEvent(const sp<SyncEvent>& event) const
1895{
1896    return event->type() == AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE;
1897}
1898
1899void AudioFlinger::PlaybackThread::threadLoop_removeTracks(
1900        const Vector< sp<Track> >& tracksToRemove)
1901{
1902    size_t count = tracksToRemove.size();
1903    if (count > 0) {
1904        for (size_t i = 0 ; i < count ; i++) {
1905            const sp<Track>& track = tracksToRemove.itemAt(i);
1906            if (!track->isOutputTrack()) {
1907                AudioSystem::stopOutput(mId, track->streamType(), track->sessionId());
1908#ifdef ADD_BATTERY_DATA
1909                // to track the speaker usage
1910                addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);
1911#endif
1912                if (track->isTerminated()) {
1913                    AudioSystem::releaseOutput(mId);
1914                }
1915            }
1916        }
1917    }
1918}
1919
1920void AudioFlinger::PlaybackThread::checkSilentMode_l()
1921{
1922    if (!mMasterMute) {
1923        char value[PROPERTY_VALUE_MAX];
1924        if (property_get("ro.audio.silent", value, "0") > 0) {
1925            char *endptr;
1926            unsigned long ul = strtoul(value, &endptr, 0);
1927            if (*endptr == '\0' && ul != 0) {
1928                ALOGD("Silence is golden");
1929                // The setprop command will not allow a property to be changed after
1930                // the first time it is set, so we don't have to worry about un-muting.
1931                setMasterMute_l(true);
1932            }
1933        }
1934    }
1935}
1936
1937// shared by MIXER and DIRECT, overridden by DUPLICATING
1938ssize_t AudioFlinger::PlaybackThread::threadLoop_write()
1939{
1940    // FIXME rewrite to reduce number of system calls
1941    mLastWriteTime = systemTime();
1942    mInWrite = true;
1943    ssize_t bytesWritten;
1944
1945    // If an NBAIO sink is present, use it to write the normal mixer's submix
1946    if (mNormalSink != 0) {
1947#define mBitShift 2 // FIXME
1948        size_t count = mBytesRemaining >> mBitShift;
1949        size_t offset = (mCurrentWriteLength - mBytesRemaining) >> 1;
1950        ATRACE_BEGIN("write");
1951        // update the setpoint when AudioFlinger::mScreenState changes
1952        uint32_t screenState = AudioFlinger::mScreenState;
1953        if (screenState != mScreenState) {
1954            mScreenState = screenState;
1955            MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
1956            if (pipe != NULL) {
1957                pipe->setAvgFrames((mScreenState & 1) ?
1958                        (pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);
1959            }
1960        }
1961        ssize_t framesWritten = mNormalSink->write(mMixBuffer + offset, count);
1962        ATRACE_END();
1963        if (framesWritten > 0) {
1964            bytesWritten = framesWritten << mBitShift;
1965        } else {
1966            bytesWritten = framesWritten;
1967        }
1968        status_t status = mNormalSink->getTimestamp(mLatchD.mTimestamp);
1969        if (status == NO_ERROR) {
1970            size_t totalFramesWritten = mNormalSink->framesWritten();
1971            if (totalFramesWritten >= mLatchD.mTimestamp.mPosition) {
1972                mLatchD.mUnpresentedFrames = totalFramesWritten - mLatchD.mTimestamp.mPosition;
1973                mLatchDValid = true;
1974            }
1975        }
1976    // otherwise use the HAL / AudioStreamOut directly
1977    } else {
1978        // Direct output and offload threads
1979        size_t offset = (mCurrentWriteLength - mBytesRemaining);
1980        if (mUseAsyncWrite) {
1981            ALOGW_IF(mWriteAckSequence & 1, "threadLoop_write(): out of sequence write request");
1982            mWriteAckSequence += 2;
1983            mWriteAckSequence |= 1;
1984            ALOG_ASSERT(mCallbackThread != 0);
1985            mCallbackThread->setWriteBlocked(mWriteAckSequence);
1986        }
1987        // FIXME We should have an implementation of timestamps for direct output threads.
1988        // They are used e.g for multichannel PCM playback over HDMI.
1989        bytesWritten = mOutput->stream->write(mOutput->stream,
1990                                                   (char *)mMixBuffer + offset, mBytesRemaining);
1991        if (mUseAsyncWrite &&
1992                ((bytesWritten < 0) || (bytesWritten == (ssize_t)mBytesRemaining))) {
1993            // do not wait for async callback in case of error of full write
1994            mWriteAckSequence &= ~1;
1995            ALOG_ASSERT(mCallbackThread != 0);
1996            mCallbackThread->setWriteBlocked(mWriteAckSequence);
1997        }
1998    }
1999
2000    mNumWrites++;
2001    mInWrite = false;
2002    mStandby = false;
2003    return bytesWritten;
2004}
2005
2006void AudioFlinger::PlaybackThread::threadLoop_drain()
2007{
2008    if (mOutput->stream->drain) {
2009        ALOGV("draining %s", (mMixerStatus == MIXER_DRAIN_TRACK) ? "early" : "full");
2010        if (mUseAsyncWrite) {
2011            ALOGW_IF(mDrainSequence & 1, "threadLoop_drain(): out of sequence drain request");
2012            mDrainSequence |= 1;
2013            ALOG_ASSERT(mCallbackThread != 0);
2014            mCallbackThread->setDraining(mDrainSequence);
2015        }
2016        mOutput->stream->drain(mOutput->stream,
2017            (mMixerStatus == MIXER_DRAIN_TRACK) ? AUDIO_DRAIN_EARLY_NOTIFY
2018                                                : AUDIO_DRAIN_ALL);
2019    }
2020}
2021
2022void AudioFlinger::PlaybackThread::threadLoop_exit()
2023{
2024    // Default implementation has nothing to do
2025}
2026
2027/*
2028The derived values that are cached:
2029 - mixBufferSize from frame count * frame size
2030 - activeSleepTime from activeSleepTimeUs()
2031 - idleSleepTime from idleSleepTimeUs()
2032 - standbyDelay from mActiveSleepTimeUs (DIRECT only)
2033 - maxPeriod from frame count and sample rate (MIXER only)
2034
2035The parameters that affect these derived values are:
2036 - frame count
2037 - frame size
2038 - sample rate
2039 - device type: A2DP or not
2040 - device latency
2041 - format: PCM or not
2042 - active sleep time
2043 - idle sleep time
2044*/
2045
2046void AudioFlinger::PlaybackThread::cacheParameters_l()
2047{
2048    mixBufferSize = mNormalFrameCount * mFrameSize;
2049    activeSleepTime = activeSleepTimeUs();
2050    idleSleepTime = idleSleepTimeUs();
2051}
2052
2053void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
2054{
2055    ALOGV("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d",
2056            this,  streamType, mTracks.size());
2057    Mutex::Autolock _l(mLock);
2058
2059    size_t size = mTracks.size();
2060    for (size_t i = 0; i < size; i++) {
2061        sp<Track> t = mTracks[i];
2062        if (t->streamType() == streamType) {
2063            t->invalidate();
2064        }
2065    }
2066}
2067
2068status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& chain)
2069{
2070    int session = chain->sessionId();
2071    int16_t *buffer = mMixBuffer;
2072    bool ownsBuffer = false;
2073
2074    ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session);
2075    if (session > 0) {
2076        // Only one effect chain can be present in direct output thread and it uses
2077        // the mix buffer as input
2078        if (mType != DIRECT) {
2079            size_t numSamples = mNormalFrameCount * mChannelCount;
2080            buffer = new int16_t[numSamples];
2081            memset(buffer, 0, numSamples * sizeof(int16_t));
2082            ALOGV("addEffectChain_l() creating new input buffer %p session %d", buffer, session);
2083            ownsBuffer = true;
2084        }
2085
2086        // Attach all tracks with same session ID to this chain.
2087        for (size_t i = 0; i < mTracks.size(); ++i) {
2088            sp<Track> track = mTracks[i];
2089            if (session == track->sessionId()) {
2090                ALOGV("addEffectChain_l() track->setMainBuffer track %p buffer %p", track.get(),
2091                        buffer);
2092                track->setMainBuffer(buffer);
2093                chain->incTrackCnt();
2094            }
2095        }
2096
2097        // indicate all active tracks in the chain
2098        for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) {
2099            sp<Track> track = mActiveTracks[i].promote();
2100            if (track == 0) {
2101                continue;
2102            }
2103            if (session == track->sessionId()) {
2104                ALOGV("addEffectChain_l() activating track %p on session %d", track.get(), session);
2105                chain->incActiveTrackCnt();
2106            }
2107        }
2108    }
2109
2110    chain->setInBuffer(buffer, ownsBuffer);
2111    chain->setOutBuffer(mMixBuffer);
2112    // Effect chain for session AUDIO_SESSION_OUTPUT_STAGE is inserted at end of effect
2113    // chains list in order to be processed last as it contains output stage effects
2114    // Effect chain for session AUDIO_SESSION_OUTPUT_MIX is inserted before
2115    // session AUDIO_SESSION_OUTPUT_STAGE to be processed
2116    // after track specific effects and before output stage
2117    // It is therefore mandatory that AUDIO_SESSION_OUTPUT_MIX == 0 and
2118    // that AUDIO_SESSION_OUTPUT_STAGE < AUDIO_SESSION_OUTPUT_MIX
2119    // Effect chain for other sessions are inserted at beginning of effect
2120    // chains list to be processed before output mix effects. Relative order between other
2121    // sessions is not important
2122    size_t size = mEffectChains.size();
2123    size_t i = 0;
2124    for (i = 0; i < size; i++) {
2125        if (mEffectChains[i]->sessionId() < session) {
2126            break;
2127        }
2128    }
2129    mEffectChains.insertAt(chain, i);
2130    checkSuspendOnAddEffectChain_l(chain);
2131
2132    return NO_ERROR;
2133}
2134
2135size_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp<EffectChain>& chain)
2136{
2137    int session = chain->sessionId();
2138
2139    ALOGV("removeEffectChain_l() %p from thread %p for session %d", chain.get(), this, session);
2140
2141    for (size_t i = 0; i < mEffectChains.size(); i++) {
2142        if (chain == mEffectChains[i]) {
2143            mEffectChains.removeAt(i);
2144            // detach all active tracks from the chain
2145            for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) {
2146                sp<Track> track = mActiveTracks[i].promote();
2147                if (track == 0) {
2148                    continue;
2149                }
2150                if (session == track->sessionId()) {
2151                    ALOGV("removeEffectChain_l(): stopping track on chain %p for session Id: %d",
2152                            chain.get(), session);
2153                    chain->decActiveTrackCnt();
2154                }
2155            }
2156
2157            // detach all tracks with same session ID from this chain
2158            for (size_t i = 0; i < mTracks.size(); ++i) {
2159                sp<Track> track = mTracks[i];
2160                if (session == track->sessionId()) {
2161                    track->setMainBuffer(mMixBuffer);
2162                    chain->decTrackCnt();
2163                }
2164            }
2165            break;
2166        }
2167    }
2168    return mEffectChains.size();
2169}
2170
2171status_t AudioFlinger::PlaybackThread::attachAuxEffect(
2172        const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId)
2173{
2174    Mutex::Autolock _l(mLock);
2175    return attachAuxEffect_l(track, EffectId);
2176}
2177
2178status_t AudioFlinger::PlaybackThread::attachAuxEffect_l(
2179        const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId)
2180{
2181    status_t status = NO_ERROR;
2182
2183    if (EffectId == 0) {
2184        track->setAuxBuffer(0, NULL);
2185    } else {
2186        // Auxiliary effects are always in audio session AUDIO_SESSION_OUTPUT_MIX
2187        sp<EffectModule> effect = getEffect_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
2188        if (effect != 0) {
2189            if ((effect->desc().flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
2190                track->setAuxBuffer(EffectId, (int32_t *)effect->inBuffer());
2191            } else {
2192                status = INVALID_OPERATION;
2193            }
2194        } else {
2195            status = BAD_VALUE;
2196        }
2197    }
2198    return status;
2199}
2200
2201void AudioFlinger::PlaybackThread::detachAuxEffect_l(int effectId)
2202{
2203    for (size_t i = 0; i < mTracks.size(); ++i) {
2204        sp<Track> track = mTracks[i];
2205        if (track->auxEffectId() == effectId) {
2206            attachAuxEffect_l(track, 0);
2207        }
2208    }
2209}
2210
2211bool AudioFlinger::PlaybackThread::threadLoop()
2212{
2213    Vector< sp<Track> > tracksToRemove;
2214
2215    standbyTime = systemTime();
2216
2217    // MIXER
2218    nsecs_t lastWarning = 0;
2219
2220    // DUPLICATING
2221    // FIXME could this be made local to while loop?
2222    writeFrames = 0;
2223
2224    int lastGeneration = 0;
2225
2226    cacheParameters_l();
2227    sleepTime = idleSleepTime;
2228
2229    if (mType == MIXER) {
2230        sleepTimeShift = 0;
2231    }
2232
2233    CpuStats cpuStats;
2234    const String8 myName(String8::format("thread %p type %d TID %d", this, mType, gettid()));
2235
2236    acquireWakeLock();
2237
2238    // mNBLogWriter->log can only be called while thread mutex mLock is held.
2239    // So if you need to log when mutex is unlocked, set logString to a non-NULL string,
2240    // and then that string will be logged at the next convenient opportunity.
2241    const char *logString = NULL;
2242
2243    checkSilentMode_l();
2244
2245    while (!exitPending())
2246    {
2247        cpuStats.sample(myName);
2248
2249        Vector< sp<EffectChain> > effectChains;
2250
2251        processConfigEvents();
2252
2253        { // scope for mLock
2254
2255            Mutex::Autolock _l(mLock);
2256
2257            if (logString != NULL) {
2258                mNBLogWriter->logTimestamp();
2259                mNBLogWriter->log(logString);
2260                logString = NULL;
2261            }
2262
2263            if (mLatchDValid) {
2264                mLatchQ = mLatchD;
2265                mLatchDValid = false;
2266                mLatchQValid = true;
2267            }
2268
2269            if (checkForNewParameters_l()) {
2270                cacheParameters_l();
2271            }
2272
2273            saveOutputTracks();
2274            if (mSignalPending) {
2275                // A signal was raised while we were unlocked
2276                mSignalPending = false;
2277            } else if (waitingAsyncCallback_l()) {
2278                if (exitPending()) {
2279                    break;
2280                }
2281                releaseWakeLock_l();
2282                mWakeLockUids.clear();
2283                mActiveTracksGeneration++;
2284                ALOGV("wait async completion");
2285                mWaitWorkCV.wait(mLock);
2286                ALOGV("async completion/wake");
2287                acquireWakeLock_l();
2288                standbyTime = systemTime() + standbyDelay;
2289                sleepTime = 0;
2290
2291                continue;
2292            }
2293            if ((!mActiveTracks.size() && systemTime() > standbyTime) ||
2294                                   isSuspended()) {
2295                // put audio hardware into standby after short delay
2296                if (shouldStandby_l()) {
2297
2298                    threadLoop_standby();
2299
2300                    mStandby = true;
2301                }
2302
2303                if (!mActiveTracks.size() && mConfigEvents.isEmpty()) {
2304                    // we're about to wait, flush the binder command buffer
2305                    IPCThreadState::self()->flushCommands();
2306
2307                    clearOutputTracks();
2308
2309                    if (exitPending()) {
2310                        break;
2311                    }
2312
2313                    releaseWakeLock_l();
2314                    mWakeLockUids.clear();
2315                    mActiveTracksGeneration++;
2316                    // wait until we have something to do...
2317                    ALOGV("%s going to sleep", myName.string());
2318                    mWaitWorkCV.wait(mLock);
2319                    ALOGV("%s waking up", myName.string());
2320                    acquireWakeLock_l();
2321
2322                    mMixerStatus = MIXER_IDLE;
2323                    mMixerStatusIgnoringFastTracks = MIXER_IDLE;
2324                    mBytesWritten = 0;
2325                    mBytesRemaining = 0;
2326                    checkSilentMode_l();
2327
2328                    standbyTime = systemTime() + standbyDelay;
2329                    sleepTime = idleSleepTime;
2330                    if (mType == MIXER) {
2331                        sleepTimeShift = 0;
2332                    }
2333
2334                    continue;
2335                }
2336            }
2337            // mMixerStatusIgnoringFastTracks is also updated internally
2338            mMixerStatus = prepareTracks_l(&tracksToRemove);
2339
2340            // compare with previously applied list
2341            if (lastGeneration != mActiveTracksGeneration) {
2342                // update wakelock
2343                updateWakeLockUids_l(mWakeLockUids);
2344                lastGeneration = mActiveTracksGeneration;
2345            }
2346
2347            // prevent any changes in effect chain list and in each effect chain
2348            // during mixing and effect process as the audio buffers could be deleted
2349            // or modified if an effect is created or deleted
2350            lockEffectChains_l(effectChains);
2351        } // mLock scope ends
2352
2353        if (mBytesRemaining == 0) {
2354            mCurrentWriteLength = 0;
2355            if (mMixerStatus == MIXER_TRACKS_READY) {
2356                // threadLoop_mix() sets mCurrentWriteLength
2357                threadLoop_mix();
2358            } else if ((mMixerStatus != MIXER_DRAIN_TRACK)
2359                        && (mMixerStatus != MIXER_DRAIN_ALL)) {
2360                // threadLoop_sleepTime sets sleepTime to 0 if data
2361                // must be written to HAL
2362                threadLoop_sleepTime();
2363                if (sleepTime == 0) {
2364                    mCurrentWriteLength = mixBufferSize;
2365                }
2366            }
2367            mBytesRemaining = mCurrentWriteLength;
2368            if (isSuspended()) {
2369                sleepTime = suspendSleepTimeUs();
2370                // simulate write to HAL when suspended
2371                mBytesWritten += mixBufferSize;
2372                mBytesRemaining = 0;
2373            }
2374
2375            // only process effects if we're going to write
2376            if (sleepTime == 0 && mType != OFFLOAD) {
2377                for (size_t i = 0; i < effectChains.size(); i ++) {
2378                    effectChains[i]->process_l();
2379                }
2380            }
2381        }
2382        // Process effect chains for offloaded thread even if no audio
2383        // was read from audio track: process only updates effect state
2384        // and thus does have to be synchronized with audio writes but may have
2385        // to be called while waiting for async write callback
2386        if (mType == OFFLOAD) {
2387            for (size_t i = 0; i < effectChains.size(); i ++) {
2388                effectChains[i]->process_l();
2389            }
2390        }
2391
2392        // enable changes in effect chain
2393        unlockEffectChains(effectChains);
2394
2395        if (!waitingAsyncCallback()) {
2396            // sleepTime == 0 means we must write to audio hardware
2397            if (sleepTime == 0) {
2398                if (mBytesRemaining) {
2399                    ssize_t ret = threadLoop_write();
2400                    if (ret < 0) {
2401                        mBytesRemaining = 0;
2402                    } else {
2403                        mBytesWritten += ret;
2404                        mBytesRemaining -= ret;
2405                    }
2406                } else if ((mMixerStatus == MIXER_DRAIN_TRACK) ||
2407                        (mMixerStatus == MIXER_DRAIN_ALL)) {
2408                    threadLoop_drain();
2409                }
2410                if (mType == MIXER) {
2411                    // write blocked detection
2412                    nsecs_t now = systemTime();
2413                    nsecs_t delta = now - mLastWriteTime;
2414                    if (!mStandby && delta > maxPeriod) {
2415                        mNumDelayedWrites++;
2416                        if ((now - lastWarning) > kWarningThrottleNs) {
2417                            ATRACE_NAME("underrun");
2418                            ALOGW("write blocked for %llu msecs, %d delayed writes, thread %p",
2419                                    ns2ms(delta), mNumDelayedWrites, this);
2420                            lastWarning = now;
2421                        }
2422                    }
2423                }
2424
2425            } else {
2426                usleep(sleepTime);
2427            }
2428        }
2429
2430        // Finally let go of removed track(s), without the lock held
2431        // since we can't guarantee the destructors won't acquire that
2432        // same lock.  This will also mutate and push a new fast mixer state.
2433        threadLoop_removeTracks(tracksToRemove);
2434        tracksToRemove.clear();
2435
2436        // FIXME I don't understand the need for this here;
2437        //       it was in the original code but maybe the
2438        //       assignment in saveOutputTracks() makes this unnecessary?
2439        clearOutputTracks();
2440
2441        // Effect chains will be actually deleted here if they were removed from
2442        // mEffectChains list during mixing or effects processing
2443        effectChains.clear();
2444
2445        // FIXME Note that the above .clear() is no longer necessary since effectChains
2446        // is now local to this block, but will keep it for now (at least until merge done).
2447    }
2448
2449    threadLoop_exit();
2450
2451    // for DuplicatingThread, standby mode is handled by the outputTracks, otherwise ...
2452    if (mType == MIXER || mType == DIRECT || mType == OFFLOAD) {
2453        // put output stream into standby mode
2454        if (!mStandby) {
2455            mOutput->stream->common.standby(&mOutput->stream->common);
2456        }
2457    }
2458
2459    releaseWakeLock();
2460    mWakeLockUids.clear();
2461    mActiveTracksGeneration++;
2462
2463    ALOGV("Thread %p type %d exiting", this, mType);
2464    return false;
2465}
2466
2467// removeTracks_l() must be called with ThreadBase::mLock held
2468void AudioFlinger::PlaybackThread::removeTracks_l(const Vector< sp<Track> >& tracksToRemove)
2469{
2470    size_t count = tracksToRemove.size();
2471    if (count > 0) {
2472        for (size_t i=0 ; i<count ; i++) {
2473            const sp<Track>& track = tracksToRemove.itemAt(i);
2474            mActiveTracks.remove(track);
2475            mWakeLockUids.remove(track->uid());
2476            mActiveTracksGeneration++;
2477            ALOGV("removeTracks_l removing track on session %d", track->sessionId());
2478            sp<EffectChain> chain = getEffectChain_l(track->sessionId());
2479            if (chain != 0) {
2480                ALOGV("stopping track on chain %p for session Id: %d", chain.get(),
2481                        track->sessionId());
2482                chain->decActiveTrackCnt();
2483            }
2484            if (track->isTerminated()) {
2485                removeTrack_l(track);
2486            }
2487        }
2488    }
2489
2490}
2491
2492status_t AudioFlinger::PlaybackThread::getTimestamp_l(AudioTimestamp& timestamp)
2493{
2494    if (mNormalSink != 0) {
2495        return mNormalSink->getTimestamp(timestamp);
2496    }
2497    if (mType == OFFLOAD && mOutput->stream->get_presentation_position) {
2498        uint64_t position64;
2499        int ret = mOutput->stream->get_presentation_position(
2500                                                mOutput->stream, &position64, &timestamp.mTime);
2501        if (ret == 0) {
2502            timestamp.mPosition = (uint32_t)position64;
2503            return NO_ERROR;
2504        }
2505    }
2506    return INVALID_OPERATION;
2507}
2508// ----------------------------------------------------------------------------
2509
2510AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
2511        audio_io_handle_t id, audio_devices_t device, type_t type)
2512    :   PlaybackThread(audioFlinger, output, id, device, type),
2513        // mAudioMixer below
2514        // mFastMixer below
2515        mFastMixerFutex(0)
2516        // mOutputSink below
2517        // mPipeSink below
2518        // mNormalSink below
2519{
2520    ALOGV("MixerThread() id=%d device=%#x type=%d", id, device, type);
2521    ALOGV("mSampleRate=%u, mChannelMask=%#x, mChannelCount=%u, mFormat=%d, mFrameSize=%u, "
2522            "mFrameCount=%d, mNormalFrameCount=%d",
2523            mSampleRate, mChannelMask, mChannelCount, mFormat, mFrameSize, mFrameCount,
2524            mNormalFrameCount);
2525    mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate);
2526
2527    // FIXME - Current mixer implementation only supports stereo output
2528    if (mChannelCount != FCC_2) {
2529        ALOGE("Invalid audio hardware channel count %d", mChannelCount);
2530    }
2531
2532    // create an NBAIO sink for the HAL output stream, and negotiate
2533    mOutputSink = new AudioStreamOutSink(output->stream);
2534    size_t numCounterOffers = 0;
2535    const NBAIO_Format offers[1] = {Format_from_SR_C(mSampleRate, mChannelCount)};
2536    ssize_t index = mOutputSink->negotiate(offers, 1, NULL, numCounterOffers);
2537    ALOG_ASSERT(index == 0);
2538
2539    // initialize fast mixer depending on configuration
2540    bool initFastMixer;
2541    switch (kUseFastMixer) {
2542    case FastMixer_Never:
2543        initFastMixer = false;
2544        break;
2545    case FastMixer_Always:
2546        initFastMixer = true;
2547        break;
2548    case FastMixer_Static:
2549    case FastMixer_Dynamic:
2550        initFastMixer = mFrameCount < mNormalFrameCount;
2551        break;
2552    }
2553    if (initFastMixer) {
2554
2555        // create a MonoPipe to connect our submix to FastMixer
2556        NBAIO_Format format = mOutputSink->format();
2557        // This pipe depth compensates for scheduling latency of the normal mixer thread.
2558        // When it wakes up after a maximum latency, it runs a few cycles quickly before
2559        // finally blocking.  Note the pipe implementation rounds up the request to a power of 2.
2560        MonoPipe *monoPipe = new MonoPipe(mNormalFrameCount * 4, format, true /*writeCanBlock*/);
2561        const NBAIO_Format offers[1] = {format};
2562        size_t numCounterOffers = 0;
2563        ssize_t index = monoPipe->negotiate(offers, 1, NULL, numCounterOffers);
2564        ALOG_ASSERT(index == 0);
2565        monoPipe->setAvgFrames((mScreenState & 1) ?
2566                (monoPipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);
2567        mPipeSink = monoPipe;
2568
2569#ifdef TEE_SINK
2570        if (mTeeSinkOutputEnabled) {
2571            // create a Pipe to archive a copy of FastMixer's output for dumpsys
2572            Pipe *teeSink = new Pipe(mTeeSinkOutputFrames, format);
2573            numCounterOffers = 0;
2574            index = teeSink->negotiate(offers, 1, NULL, numCounterOffers);
2575            ALOG_ASSERT(index == 0);
2576            mTeeSink = teeSink;
2577            PipeReader *teeSource = new PipeReader(*teeSink);
2578            numCounterOffers = 0;
2579            index = teeSource->negotiate(offers, 1, NULL, numCounterOffers);
2580            ALOG_ASSERT(index == 0);
2581            mTeeSource = teeSource;
2582        }
2583#endif
2584
2585        // create fast mixer and configure it initially with just one fast track for our submix
2586        mFastMixer = new FastMixer();
2587        FastMixerStateQueue *sq = mFastMixer->sq();
2588#ifdef STATE_QUEUE_DUMP
2589        sq->setObserverDump(&mStateQueueObserverDump);
2590        sq->setMutatorDump(&mStateQueueMutatorDump);
2591#endif
2592        FastMixerState *state = sq->begin();
2593        FastTrack *fastTrack = &state->mFastTracks[0];
2594        // wrap the source side of the MonoPipe to make it an AudioBufferProvider
2595        fastTrack->mBufferProvider = new SourceAudioBufferProvider(new MonoPipeReader(monoPipe));
2596        fastTrack->mVolumeProvider = NULL;
2597        fastTrack->mGeneration++;
2598        state->mFastTracksGen++;
2599        state->mTrackMask = 1;
2600        // fast mixer will use the HAL output sink
2601        state->mOutputSink = mOutputSink.get();
2602        state->mOutputSinkGen++;
2603        state->mFrameCount = mFrameCount;
2604        state->mCommand = FastMixerState::COLD_IDLE;
2605        // already done in constructor initialization list
2606        //mFastMixerFutex = 0;
2607        state->mColdFutexAddr = &mFastMixerFutex;
2608        state->mColdGen++;
2609        state->mDumpState = &mFastMixerDumpState;
2610#ifdef TEE_SINK
2611        state->mTeeSink = mTeeSink.get();
2612#endif
2613        mFastMixerNBLogWriter = audioFlinger->newWriter_l(kFastMixerLogSize, "FastMixer");
2614        state->mNBLogWriter = mFastMixerNBLogWriter.get();
2615        sq->end();
2616        sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
2617
2618        // start the fast mixer
2619        mFastMixer->run("FastMixer", PRIORITY_URGENT_AUDIO);
2620        pid_t tid = mFastMixer->getTid();
2621        int err = requestPriority(getpid_cached, tid, kPriorityFastMixer);
2622        if (err != 0) {
2623            ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",
2624                    kPriorityFastMixer, getpid_cached, tid, err);
2625        }
2626
2627#ifdef AUDIO_WATCHDOG
2628        // create and start the watchdog
2629        mAudioWatchdog = new AudioWatchdog();
2630        mAudioWatchdog->setDump(&mAudioWatchdogDump);
2631        mAudioWatchdog->run("AudioWatchdog", PRIORITY_URGENT_AUDIO);
2632        tid = mAudioWatchdog->getTid();
2633        err = requestPriority(getpid_cached, tid, kPriorityFastMixer);
2634        if (err != 0) {
2635            ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",
2636                    kPriorityFastMixer, getpid_cached, tid, err);
2637        }
2638#endif
2639
2640    } else {
2641        mFastMixer = NULL;
2642    }
2643
2644    switch (kUseFastMixer) {
2645    case FastMixer_Never:
2646    case FastMixer_Dynamic:
2647        mNormalSink = mOutputSink;
2648        break;
2649    case FastMixer_Always:
2650        mNormalSink = mPipeSink;
2651        break;
2652    case FastMixer_Static:
2653        mNormalSink = initFastMixer ? mPipeSink : mOutputSink;
2654        break;
2655    }
2656}
2657
2658AudioFlinger::MixerThread::~MixerThread()
2659{
2660    if (mFastMixer != NULL) {
2661        FastMixerStateQueue *sq = mFastMixer->sq();
2662        FastMixerState *state = sq->begin();
2663        if (state->mCommand == FastMixerState::COLD_IDLE) {
2664            int32_t old = android_atomic_inc(&mFastMixerFutex);
2665            if (old == -1) {
2666                __futex_syscall3(&mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1);
2667            }
2668        }
2669        state->mCommand = FastMixerState::EXIT;
2670        sq->end();
2671        sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
2672        mFastMixer->join();
2673        // Though the fast mixer thread has exited, it's state queue is still valid.
2674        // We'll use that extract the final state which contains one remaining fast track
2675        // corresponding to our sub-mix.
2676        state = sq->begin();
2677        ALOG_ASSERT(state->mTrackMask == 1);
2678        FastTrack *fastTrack = &state->mFastTracks[0];
2679        ALOG_ASSERT(fastTrack->mBufferProvider != NULL);
2680        delete fastTrack->mBufferProvider;
2681        sq->end(false /*didModify*/);
2682        delete mFastMixer;
2683#ifdef AUDIO_WATCHDOG
2684        if (mAudioWatchdog != 0) {
2685            mAudioWatchdog->requestExit();
2686            mAudioWatchdog->requestExitAndWait();
2687            mAudioWatchdog.clear();
2688        }
2689#endif
2690    }
2691    mAudioFlinger->unregisterWriter(mFastMixerNBLogWriter);
2692    delete mAudioMixer;
2693}
2694
2695
2696uint32_t AudioFlinger::MixerThread::correctLatency_l(uint32_t latency) const
2697{
2698    if (mFastMixer != NULL) {
2699        MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
2700        latency += (pipe->getAvgFrames() * 1000) / mSampleRate;
2701    }
2702    return latency;
2703}
2704
2705
2706void AudioFlinger::MixerThread::threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove)
2707{
2708    PlaybackThread::threadLoop_removeTracks(tracksToRemove);
2709}
2710
2711ssize_t AudioFlinger::MixerThread::threadLoop_write()
2712{
2713    // FIXME we should only do one push per cycle; confirm this is true
2714    // Start the fast mixer if it's not already running
2715    if (mFastMixer != NULL) {
2716        FastMixerStateQueue *sq = mFastMixer->sq();
2717        FastMixerState *state = sq->begin();
2718        if (state->mCommand != FastMixerState::MIX_WRITE &&
2719                (kUseFastMixer != FastMixer_Dynamic || state->mTrackMask > 1)) {
2720            if (state->mCommand == FastMixerState::COLD_IDLE) {
2721                int32_t old = android_atomic_inc(&mFastMixerFutex);
2722                if (old == -1) {
2723                    __futex_syscall3(&mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1);
2724                }
2725#ifdef AUDIO_WATCHDOG
2726                if (mAudioWatchdog != 0) {
2727                    mAudioWatchdog->resume();
2728                }
2729#endif
2730            }
2731            state->mCommand = FastMixerState::MIX_WRITE;
2732            mFastMixerDumpState.increaseSamplingN(mAudioFlinger->isLowRamDevice() ?
2733                    FastMixerDumpState::kSamplingNforLowRamDevice : FastMixerDumpState::kSamplingN);
2734            sq->end();
2735            sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
2736            if (kUseFastMixer == FastMixer_Dynamic) {
2737                mNormalSink = mPipeSink;
2738            }
2739        } else {
2740            sq->end(false /*didModify*/);
2741        }
2742    }
2743    return PlaybackThread::threadLoop_write();
2744}
2745
2746void AudioFlinger::MixerThread::threadLoop_standby()
2747{
2748    // Idle the fast mixer if it's currently running
2749    if (mFastMixer != NULL) {
2750        FastMixerStateQueue *sq = mFastMixer->sq();
2751        FastMixerState *state = sq->begin();
2752        if (!(state->mCommand & FastMixerState::IDLE)) {
2753            state->mCommand = FastMixerState::COLD_IDLE;
2754            state->mColdFutexAddr = &mFastMixerFutex;
2755            state->mColdGen++;
2756            mFastMixerFutex = 0;
2757            sq->end();
2758            // BLOCK_UNTIL_PUSHED would be insufficient, as we need it to stop doing I/O now
2759            sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED);
2760            if (kUseFastMixer == FastMixer_Dynamic) {
2761                mNormalSink = mOutputSink;
2762            }
2763#ifdef AUDIO_WATCHDOG
2764            if (mAudioWatchdog != 0) {
2765                mAudioWatchdog->pause();
2766            }
2767#endif
2768        } else {
2769            sq->end(false /*didModify*/);
2770        }
2771    }
2772    PlaybackThread::threadLoop_standby();
2773}
2774
2775bool AudioFlinger::PlaybackThread::waitingAsyncCallback_l()
2776{
2777    return false;
2778}
2779
2780bool AudioFlinger::PlaybackThread::shouldStandby_l()
2781{
2782    return !mStandby;
2783}
2784
2785bool AudioFlinger::PlaybackThread::waitingAsyncCallback()
2786{
2787    Mutex::Autolock _l(mLock);
2788    return waitingAsyncCallback_l();
2789}
2790
2791// shared by MIXER and DIRECT, overridden by DUPLICATING
2792void AudioFlinger::PlaybackThread::threadLoop_standby()
2793{
2794    ALOGV("Audio hardware entering standby, mixer %p, suspend count %d", this, mSuspended);
2795    mOutput->stream->common.standby(&mOutput->stream->common);
2796    if (mUseAsyncWrite != 0) {
2797        // discard any pending drain or write ack by incrementing sequence
2798        mWriteAckSequence = (mWriteAckSequence + 2) & ~1;
2799        mDrainSequence = (mDrainSequence + 2) & ~1;
2800        ALOG_ASSERT(mCallbackThread != 0);
2801        mCallbackThread->setWriteBlocked(mWriteAckSequence);
2802        mCallbackThread->setDraining(mDrainSequence);
2803    }
2804}
2805
2806void AudioFlinger::PlaybackThread::onAddNewTrack_l()
2807{
2808    ALOGV("signal playback thread");
2809    broadcast_l();
2810}
2811
2812void AudioFlinger::MixerThread::threadLoop_mix()
2813{
2814    // obtain the presentation timestamp of the next output buffer
2815    int64_t pts;
2816    status_t status = INVALID_OPERATION;
2817
2818    if (mNormalSink != 0) {
2819        status = mNormalSink->getNextWriteTimestamp(&pts);
2820    } else {
2821        status = mOutputSink->getNextWriteTimestamp(&pts);
2822    }
2823
2824    if (status != NO_ERROR) {
2825        pts = AudioBufferProvider::kInvalidPTS;
2826    }
2827
2828    // mix buffers...
2829    mAudioMixer->process(pts);
2830    mCurrentWriteLength = mixBufferSize;
2831    // increase sleep time progressively when application underrun condition clears.
2832    // Only increase sleep time if the mixer is ready for two consecutive times to avoid
2833    // that a steady state of alternating ready/not ready conditions keeps the sleep time
2834    // such that we would underrun the audio HAL.
2835    if ((sleepTime == 0) && (sleepTimeShift > 0)) {
2836        sleepTimeShift--;
2837    }
2838    sleepTime = 0;
2839    standbyTime = systemTime() + standbyDelay;
2840    //TODO: delay standby when effects have a tail
2841}
2842
2843void AudioFlinger::MixerThread::threadLoop_sleepTime()
2844{
2845    // If no tracks are ready, sleep once for the duration of an output
2846    // buffer size, then write 0s to the output
2847    if (sleepTime == 0) {
2848        if (mMixerStatus == MIXER_TRACKS_ENABLED) {
2849            sleepTime = activeSleepTime >> sleepTimeShift;
2850            if (sleepTime < kMinThreadSleepTimeUs) {
2851                sleepTime = kMinThreadSleepTimeUs;
2852            }
2853            // reduce sleep time in case of consecutive application underruns to avoid
2854            // starving the audio HAL. As activeSleepTimeUs() is larger than a buffer
2855            // duration we would end up writing less data than needed by the audio HAL if
2856            // the condition persists.
2857            if (sleepTimeShift < kMaxThreadSleepTimeShift) {
2858                sleepTimeShift++;
2859            }
2860        } else {
2861            sleepTime = idleSleepTime;
2862        }
2863    } else if (mBytesWritten != 0 || (mMixerStatus == MIXER_TRACKS_ENABLED)) {
2864        memset(mMixBuffer, 0, mixBufferSize);
2865        sleepTime = 0;
2866        ALOGV_IF(mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED),
2867                "anticipated start");
2868    }
2869    // TODO add standby time extension fct of effect tail
2870}
2871
2872// prepareTracks_l() must be called with ThreadBase::mLock held
2873AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l(
2874        Vector< sp<Track> > *tracksToRemove)
2875{
2876
2877    mixer_state mixerStatus = MIXER_IDLE;
2878    // find out which tracks need to be processed
2879    size_t count = mActiveTracks.size();
2880    size_t mixedTracks = 0;
2881    size_t tracksWithEffect = 0;
2882    // counts only _active_ fast tracks
2883    size_t fastTracks = 0;
2884    uint32_t resetMask = 0; // bit mask of fast tracks that need to be reset
2885
2886    float masterVolume = mMasterVolume;
2887    bool masterMute = mMasterMute;
2888
2889    if (masterMute) {
2890        masterVolume = 0;
2891    }
2892    // Delegate master volume control to effect in output mix effect chain if needed
2893    sp<EffectChain> chain = getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
2894    if (chain != 0) {
2895        uint32_t v = (uint32_t)(masterVolume * (1 << 24));
2896        chain->setVolume_l(&v, &v);
2897        masterVolume = (float)((v + (1 << 23)) >> 24);
2898        chain.clear();
2899    }
2900
2901    // prepare a new state to push
2902    FastMixerStateQueue *sq = NULL;
2903    FastMixerState *state = NULL;
2904    bool didModify = false;
2905    FastMixerStateQueue::block_t block = FastMixerStateQueue::BLOCK_UNTIL_PUSHED;
2906    if (mFastMixer != NULL) {
2907        sq = mFastMixer->sq();
2908        state = sq->begin();
2909    }
2910
2911    for (size_t i=0 ; i<count ; i++) {
2912        const sp<Track> t = mActiveTracks[i].promote();
2913        if (t == 0) {
2914            continue;
2915        }
2916
2917        // this const just means the local variable doesn't change
2918        Track* const track = t.get();
2919
2920        // process fast tracks
2921        if (track->isFastTrack()) {
2922
2923            // It's theoretically possible (though unlikely) for a fast track to be created
2924            // and then removed within the same normal mix cycle.  This is not a problem, as
2925            // the track never becomes active so it's fast mixer slot is never touched.
2926            // The converse, of removing an (active) track and then creating a new track
2927            // at the identical fast mixer slot within the same normal mix cycle,
2928            // is impossible because the slot isn't marked available until the end of each cycle.
2929            int j = track->mFastIndex;
2930            ALOG_ASSERT(0 < j && j < (int)FastMixerState::kMaxFastTracks);
2931            ALOG_ASSERT(!(mFastTrackAvailMask & (1 << j)));
2932            FastTrack *fastTrack = &state->mFastTracks[j];
2933
2934            // Determine whether the track is currently in underrun condition,
2935            // and whether it had a recent underrun.
2936            FastTrackDump *ftDump = &mFastMixerDumpState.mTracks[j];
2937            FastTrackUnderruns underruns = ftDump->mUnderruns;
2938            uint32_t recentFull = (underruns.mBitFields.mFull -
2939                    track->mObservedUnderruns.mBitFields.mFull) & UNDERRUN_MASK;
2940            uint32_t recentPartial = (underruns.mBitFields.mPartial -
2941                    track->mObservedUnderruns.mBitFields.mPartial) & UNDERRUN_MASK;
2942            uint32_t recentEmpty = (underruns.mBitFields.mEmpty -
2943                    track->mObservedUnderruns.mBitFields.mEmpty) & UNDERRUN_MASK;
2944            uint32_t recentUnderruns = recentPartial + recentEmpty;
2945            track->mObservedUnderruns = underruns;
2946            // don't count underruns that occur while stopping or pausing
2947            // or stopped which can occur when flush() is called while active
2948            if (!(track->isStopping() || track->isPausing() || track->isStopped()) &&
2949                    recentUnderruns > 0) {
2950                // FIXME fast mixer will pull & mix partial buffers, but we count as a full underrun
2951                track->mAudioTrackServerProxy->tallyUnderrunFrames(recentUnderruns * mFrameCount);
2952            }
2953
2954            // This is similar to the state machine for normal tracks,
2955            // with a few modifications for fast tracks.
2956            bool isActive = true;
2957            switch (track->mState) {
2958            case TrackBase::STOPPING_1:
2959                // track stays active in STOPPING_1 state until first underrun
2960                if (recentUnderruns > 0 || track->isTerminated()) {
2961                    track->mState = TrackBase::STOPPING_2;
2962                }
2963                break;
2964            case TrackBase::PAUSING:
2965                // ramp down is not yet implemented
2966                track->setPaused();
2967                break;
2968            case TrackBase::RESUMING:
2969                // ramp up is not yet implemented
2970                track->mState = TrackBase::ACTIVE;
2971                break;
2972            case TrackBase::ACTIVE:
2973                if (recentFull > 0 || recentPartial > 0) {
2974                    // track has provided at least some frames recently: reset retry count
2975                    track->mRetryCount = kMaxTrackRetries;
2976                }
2977                if (recentUnderruns == 0) {
2978                    // no recent underruns: stay active
2979                    break;
2980                }
2981                // there has recently been an underrun of some kind
2982                if (track->sharedBuffer() == 0) {
2983                    // were any of the recent underruns "empty" (no frames available)?
2984                    if (recentEmpty == 0) {
2985                        // no, then ignore the partial underruns as they are allowed indefinitely
2986                        break;
2987                    }
2988                    // there has recently been an "empty" underrun: decrement the retry counter
2989                    if (--(track->mRetryCount) > 0) {
2990                        break;
2991                    }
2992                    // indicate to client process that the track was disabled because of underrun;
2993                    // it will then automatically call start() when data is available
2994                    android_atomic_or(CBLK_DISABLED, &track->mCblk->mFlags);
2995                    // remove from active list, but state remains ACTIVE [confusing but true]
2996                    isActive = false;
2997                    break;
2998                }
2999                // fall through
3000            case TrackBase::STOPPING_2:
3001            case TrackBase::PAUSED:
3002            case TrackBase::STOPPED:
3003            case TrackBase::FLUSHED:   // flush() while active
3004                // Check for presentation complete if track is inactive
3005                // We have consumed all the buffers of this track.
3006                // This would be incomplete if we auto-paused on underrun
3007                {
3008                    size_t audioHALFrames =
3009                            (mOutput->stream->get_latency(mOutput->stream)*mSampleRate) / 1000;
3010                    size_t framesWritten = mBytesWritten / mFrameSize;
3011                    if (!(mStandby || track->presentationComplete(framesWritten, audioHALFrames))) {
3012                        // track stays in active list until presentation is complete
3013                        break;
3014                    }
3015                }
3016                if (track->isStopping_2()) {
3017                    track->mState = TrackBase::STOPPED;
3018                }
3019                if (track->isStopped()) {
3020                    // Can't reset directly, as fast mixer is still polling this track
3021                    //   track->reset();
3022                    // So instead mark this track as needing to be reset after push with ack
3023                    resetMask |= 1 << i;
3024                }
3025                isActive = false;
3026                break;
3027            case TrackBase::IDLE:
3028            default:
3029                LOG_FATAL("unexpected track state %d", track->mState);
3030            }
3031
3032            if (isActive) {
3033                // was it previously inactive?
3034                if (!(state->mTrackMask & (1 << j))) {
3035                    ExtendedAudioBufferProvider *eabp = track;
3036                    VolumeProvider *vp = track;
3037                    fastTrack->mBufferProvider = eabp;
3038                    fastTrack->mVolumeProvider = vp;
3039                    fastTrack->mChannelMask = track->mChannelMask;
3040                    fastTrack->mGeneration++;
3041                    state->mTrackMask |= 1 << j;
3042                    didModify = true;
3043                    // no acknowledgement required for newly active tracks
3044                }
3045                // cache the combined master volume and stream type volume for fast mixer; this
3046                // lacks any synchronization or barrier so VolumeProvider may read a stale value
3047                track->mCachedVolume = masterVolume * mStreamTypes[track->streamType()].volume;
3048                ++fastTracks;
3049            } else {
3050                // was it previously active?
3051                if (state->mTrackMask & (1 << j)) {
3052                    fastTrack->mBufferProvider = NULL;
3053                    fastTrack->mGeneration++;
3054                    state->mTrackMask &= ~(1 << j);
3055                    didModify = true;
3056                    // If any fast tracks were removed, we must wait for acknowledgement
3057                    // because we're about to decrement the last sp<> on those tracks.
3058                    block = FastMixerStateQueue::BLOCK_UNTIL_ACKED;
3059                } else {
3060                    LOG_FATAL("fast track %d should have been active", j);
3061                }
3062                tracksToRemove->add(track);
3063                // Avoids a misleading display in dumpsys
3064                track->mObservedUnderruns.mBitFields.mMostRecent = UNDERRUN_FULL;
3065            }
3066            continue;
3067        }
3068
3069        {   // local variable scope to avoid goto warning
3070
3071        audio_track_cblk_t* cblk = track->cblk();
3072
3073        // The first time a track is added we wait
3074        // for all its buffers to be filled before processing it
3075        int name = track->name();
3076        // make sure that we have enough frames to mix one full buffer.
3077        // enforce this condition only once to enable draining the buffer in case the client
3078        // app does not call stop() and relies on underrun to stop:
3079        // hence the test on (mMixerStatus == MIXER_TRACKS_READY) meaning the track was mixed
3080        // during last round
3081        size_t desiredFrames;
3082        uint32_t sr = track->sampleRate();
3083        if (sr == mSampleRate) {
3084            desiredFrames = mNormalFrameCount;
3085        } else {
3086            // +1 for rounding and +1 for additional sample needed for interpolation
3087            desiredFrames = (mNormalFrameCount * sr) / mSampleRate + 1 + 1;
3088            // add frames already consumed but not yet released by the resampler
3089            // because mAudioTrackServerProxy->framesReady() will include these frames
3090            desiredFrames += mAudioMixer->getUnreleasedFrames(track->name());
3091#if 0
3092            // the minimum track buffer size is normally twice the number of frames necessary
3093            // to fill one buffer and the resampler should not leave more than one buffer worth
3094            // of unreleased frames after each pass, but just in case...
3095            ALOG_ASSERT(desiredFrames <= cblk->frameCount_);
3096#endif
3097        }
3098        uint32_t minFrames = 1;
3099        if ((track->sharedBuffer() == 0) && !track->isStopped() && !track->isPausing() &&
3100                (mMixerStatusIgnoringFastTracks == MIXER_TRACKS_READY)) {
3101            minFrames = desiredFrames;
3102        }
3103
3104        size_t framesReady = track->framesReady();
3105        if ((framesReady >= minFrames) && track->isReady() &&
3106                !track->isPaused() && !track->isTerminated())
3107        {
3108            ALOGVV("track %d s=%08x [OK] on thread %p", name, cblk->mServer, this);
3109
3110            mixedTracks++;
3111
3112            // track->mainBuffer() != mMixBuffer means there is an effect chain
3113            // connected to the track
3114            chain.clear();
3115            if (track->mainBuffer() != mMixBuffer) {
3116                chain = getEffectChain_l(track->sessionId());
3117                // Delegate volume control to effect in track effect chain if needed
3118                if (chain != 0) {
3119                    tracksWithEffect++;
3120                } else {
3121                    ALOGW("prepareTracks_l(): track %d attached to effect but no chain found on "
3122                            "session %d",
3123                            name, track->sessionId());
3124                }
3125            }
3126
3127
3128            int param = AudioMixer::VOLUME;
3129            if (track->mFillingUpStatus == Track::FS_FILLED) {
3130                // no ramp for the first volume setting
3131                track->mFillingUpStatus = Track::FS_ACTIVE;
3132                if (track->mState == TrackBase::RESUMING) {
3133                    track->mState = TrackBase::ACTIVE;
3134                    param = AudioMixer::RAMP_VOLUME;
3135                }
3136                mAudioMixer->setParameter(name, AudioMixer::RESAMPLE, AudioMixer::RESET, NULL);
3137            // FIXME should not make a decision based on mServer
3138            } else if (cblk->mServer != 0) {
3139                // If the track is stopped before the first frame was mixed,
3140                // do not apply ramp
3141                param = AudioMixer::RAMP_VOLUME;
3142            }
3143
3144            // compute volume for this track
3145            uint32_t vl, vr, va;
3146            if (track->isPausing() || mStreamTypes[track->streamType()].mute) {
3147                vl = vr = va = 0;
3148                if (track->isPausing()) {
3149                    track->setPaused();
3150                }
3151            } else {
3152
3153                // read original volumes with volume control
3154                float typeVolume = mStreamTypes[track->streamType()].volume;
3155                float v = masterVolume * typeVolume;
3156                AudioTrackServerProxy *proxy = track->mAudioTrackServerProxy;
3157                uint32_t vlr = proxy->getVolumeLR();
3158                vl = vlr & 0xFFFF;
3159                vr = vlr >> 16;
3160                // track volumes come from shared memory, so can't be trusted and must be clamped
3161                if (vl > MAX_GAIN_INT) {
3162                    ALOGV("Track left volume out of range: %04X", vl);
3163                    vl = MAX_GAIN_INT;
3164                }
3165                if (vr > MAX_GAIN_INT) {
3166                    ALOGV("Track right volume out of range: %04X", vr);
3167                    vr = MAX_GAIN_INT;
3168                }
3169                // now apply the master volume and stream type volume
3170                vl = (uint32_t)(v * vl) << 12;
3171                vr = (uint32_t)(v * vr) << 12;
3172                // assuming master volume and stream type volume each go up to 1.0,
3173                // vl and vr are now in 8.24 format
3174
3175                uint16_t sendLevel = proxy->getSendLevel_U4_12();
3176                // send level comes from shared memory and so may be corrupt
3177                if (sendLevel > MAX_GAIN_INT) {
3178                    ALOGV("Track send level out of range: %04X", sendLevel);
3179                    sendLevel = MAX_GAIN_INT;
3180                }
3181                va = (uint32_t)(v * sendLevel);
3182            }
3183
3184            // Delegate volume control to effect in track effect chain if needed
3185            if (chain != 0 && chain->setVolume_l(&vl, &vr)) {
3186                // Do not ramp volume if volume is controlled by effect
3187                param = AudioMixer::VOLUME;
3188                track->mHasVolumeController = true;
3189            } else {
3190                // force no volume ramp when volume controller was just disabled or removed
3191                // from effect chain to avoid volume spike
3192                if (track->mHasVolumeController) {
3193                    param = AudioMixer::VOLUME;
3194                }
3195                track->mHasVolumeController = false;
3196            }
3197
3198            // Convert volumes from 8.24 to 4.12 format
3199            // This additional clamping is needed in case chain->setVolume_l() overshot
3200            vl = (vl + (1 << 11)) >> 12;
3201            if (vl > MAX_GAIN_INT) {
3202                vl = MAX_GAIN_INT;
3203            }
3204            vr = (vr + (1 << 11)) >> 12;
3205            if (vr > MAX_GAIN_INT) {
3206                vr = MAX_GAIN_INT;
3207            }
3208
3209            if (va > MAX_GAIN_INT) {
3210                va = MAX_GAIN_INT;   // va is uint32_t, so no need to check for -
3211            }
3212
3213            // XXX: these things DON'T need to be done each time
3214            mAudioMixer->setBufferProvider(name, track);
3215            mAudioMixer->enable(name);
3216
3217            mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, (void *)(uintptr_t)vl);
3218            mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, (void *)(uintptr_t)vr);
3219            mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, (void *)(uintptr_t)va);
3220            mAudioMixer->setParameter(
3221                name,
3222                AudioMixer::TRACK,
3223                AudioMixer::FORMAT, (void *)track->format());
3224            mAudioMixer->setParameter(
3225                name,
3226                AudioMixer::TRACK,
3227                AudioMixer::CHANNEL_MASK, (void *)(uintptr_t)track->channelMask());
3228            // limit track sample rate to 2 x output sample rate, which changes at re-configuration
3229            uint32_t maxSampleRate = mSampleRate * 2;
3230            uint32_t reqSampleRate = track->mAudioTrackServerProxy->getSampleRate();
3231            if (reqSampleRate == 0) {
3232                reqSampleRate = mSampleRate;
3233            } else if (reqSampleRate > maxSampleRate) {
3234                reqSampleRate = maxSampleRate;
3235            }
3236            mAudioMixer->setParameter(
3237                name,
3238                AudioMixer::RESAMPLE,
3239                AudioMixer::SAMPLE_RATE,
3240                (void *)(uintptr_t)reqSampleRate);
3241            mAudioMixer->setParameter(
3242                name,
3243                AudioMixer::TRACK,
3244                AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer());
3245            mAudioMixer->setParameter(
3246                name,
3247                AudioMixer::TRACK,
3248                AudioMixer::AUX_BUFFER, (void *)track->auxBuffer());
3249
3250            // reset retry count
3251            track->mRetryCount = kMaxTrackRetries;
3252
3253            // If one track is ready, set the mixer ready if:
3254            //  - the mixer was not ready during previous round OR
3255            //  - no other track is not ready
3256            if (mMixerStatusIgnoringFastTracks != MIXER_TRACKS_READY ||
3257                    mixerStatus != MIXER_TRACKS_ENABLED) {
3258                mixerStatus = MIXER_TRACKS_READY;
3259            }
3260        } else {
3261            if (framesReady < desiredFrames && !track->isStopped() && !track->isPaused()) {
3262                track->mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames);
3263            }
3264            // clear effect chain input buffer if an active track underruns to avoid sending
3265            // previous audio buffer again to effects
3266            chain = getEffectChain_l(track->sessionId());
3267            if (chain != 0) {
3268                chain->clearInputBuffer();
3269            }
3270
3271            ALOGVV("track %d s=%08x [NOT READY] on thread %p", name, cblk->mServer, this);
3272            if ((track->sharedBuffer() != 0) || track->isTerminated() ||
3273                    track->isStopped() || track->isPaused()) {
3274                // We have consumed all the buffers of this track.
3275                // Remove it from the list of active tracks.
3276                // TODO: use actual buffer filling status instead of latency when available from
3277                // audio HAL
3278                size_t audioHALFrames = (latency_l() * mSampleRate) / 1000;
3279                size_t framesWritten = mBytesWritten / mFrameSize;
3280                if (mStandby || track->presentationComplete(framesWritten, audioHALFrames)) {
3281                    if (track->isStopped()) {
3282                        track->reset();
3283                    }
3284                    tracksToRemove->add(track);
3285                }
3286            } else {
3287                // No buffers for this track. Give it a few chances to
3288                // fill a buffer, then remove it from active list.
3289                if (--(track->mRetryCount) <= 0) {
3290                    ALOGI("BUFFER TIMEOUT: remove(%d) from active list on thread %p", name, this);
3291                    tracksToRemove->add(track);
3292                    // indicate to client process that the track was disabled because of underrun;
3293                    // it will then automatically call start() when data is available
3294                    android_atomic_or(CBLK_DISABLED, &cblk->mFlags);
3295                // If one track is not ready, mark the mixer also not ready if:
3296                //  - the mixer was ready during previous round OR
3297                //  - no other track is ready
3298                } else if (mMixerStatusIgnoringFastTracks == MIXER_TRACKS_READY ||
3299                                mixerStatus != MIXER_TRACKS_READY) {
3300                    mixerStatus = MIXER_TRACKS_ENABLED;
3301                }
3302            }
3303            mAudioMixer->disable(name);
3304        }
3305
3306        }   // local variable scope to avoid goto warning
3307track_is_ready: ;
3308
3309    }
3310
3311    // Push the new FastMixer state if necessary
3312    bool pauseAudioWatchdog = false;
3313    if (didModify) {
3314        state->mFastTracksGen++;
3315        // if the fast mixer was active, but now there are no fast tracks, then put it in cold idle
3316        if (kUseFastMixer == FastMixer_Dynamic &&
3317                state->mCommand == FastMixerState::MIX_WRITE && state->mTrackMask <= 1) {
3318            state->mCommand = FastMixerState::COLD_IDLE;
3319            state->mColdFutexAddr = &mFastMixerFutex;
3320            state->mColdGen++;
3321            mFastMixerFutex = 0;
3322            if (kUseFastMixer == FastMixer_Dynamic) {
3323                mNormalSink = mOutputSink;
3324            }
3325            // If we go into cold idle, need to wait for acknowledgement
3326            // so that fast mixer stops doing I/O.
3327            block = FastMixerStateQueue::BLOCK_UNTIL_ACKED;
3328            pauseAudioWatchdog = true;
3329        }
3330    }
3331    if (sq != NULL) {
3332        sq->end(didModify);
3333        sq->push(block);
3334    }
3335#ifdef AUDIO_WATCHDOG
3336    if (pauseAudioWatchdog && mAudioWatchdog != 0) {
3337        mAudioWatchdog->pause();
3338    }
3339#endif
3340
3341    // Now perform the deferred reset on fast tracks that have stopped
3342    while (resetMask != 0) {
3343        size_t i = __builtin_ctz(resetMask);
3344        ALOG_ASSERT(i < count);
3345        resetMask &= ~(1 << i);
3346        sp<Track> t = mActiveTracks[i].promote();
3347        if (t == 0) {
3348            continue;
3349        }
3350        Track* track = t.get();
3351        ALOG_ASSERT(track->isFastTrack() && track->isStopped());
3352        track->reset();
3353    }
3354
3355    // remove all the tracks that need to be...
3356    removeTracks_l(*tracksToRemove);
3357
3358    // mix buffer must be cleared if all tracks are connected to an
3359    // effect chain as in this case the mixer will not write to
3360    // mix buffer and track effects will accumulate into it
3361    if ((mBytesRemaining == 0) && ((mixedTracks != 0 && mixedTracks == tracksWithEffect) ||
3362            (mixedTracks == 0 && fastTracks > 0))) {
3363        // FIXME as a performance optimization, should remember previous zero status
3364        memset(mMixBuffer, 0, mNormalFrameCount * mChannelCount * sizeof(int16_t));
3365    }
3366
3367    // if any fast tracks, then status is ready
3368    mMixerStatusIgnoringFastTracks = mixerStatus;
3369    if (fastTracks > 0) {
3370        mixerStatus = MIXER_TRACKS_READY;
3371    }
3372    return mixerStatus;
3373}
3374
3375// getTrackName_l() must be called with ThreadBase::mLock held
3376int AudioFlinger::MixerThread::getTrackName_l(audio_channel_mask_t channelMask, int sessionId)
3377{
3378    return mAudioMixer->getTrackName(channelMask, sessionId);
3379}
3380
3381// deleteTrackName_l() must be called with ThreadBase::mLock held
3382void AudioFlinger::MixerThread::deleteTrackName_l(int name)
3383{
3384    ALOGV("remove track (%d) and delete from mixer", name);
3385    mAudioMixer->deleteTrackName(name);
3386}
3387
3388// checkForNewParameters_l() must be called with ThreadBase::mLock held
3389bool AudioFlinger::MixerThread::checkForNewParameters_l()
3390{
3391    // if !&IDLE, holds the FastMixer state to restore after new parameters processed
3392    FastMixerState::Command previousCommand = FastMixerState::HOT_IDLE;
3393    bool reconfig = false;
3394
3395    while (!mNewParameters.isEmpty()) {
3396
3397        if (mFastMixer != NULL) {
3398            FastMixerStateQueue *sq = mFastMixer->sq();
3399            FastMixerState *state = sq->begin();
3400            if (!(state->mCommand & FastMixerState::IDLE)) {
3401                previousCommand = state->mCommand;
3402                state->mCommand = FastMixerState::HOT_IDLE;
3403                sq->end();
3404                sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED);
3405            } else {
3406                sq->end(false /*didModify*/);
3407            }
3408        }
3409
3410        status_t status = NO_ERROR;
3411        String8 keyValuePair = mNewParameters[0];
3412        AudioParameter param = AudioParameter(keyValuePair);
3413        int value;
3414
3415        if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) {
3416            reconfig = true;
3417        }
3418        if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) {
3419            if ((audio_format_t) value != AUDIO_FORMAT_PCM_16_BIT) {
3420                status = BAD_VALUE;
3421            } else {
3422                // no need to save value, since it's constant
3423                reconfig = true;
3424            }
3425        }
3426        if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
3427            if ((audio_channel_mask_t) value != AUDIO_CHANNEL_OUT_STEREO) {
3428                status = BAD_VALUE;
3429            } else {
3430                // no need to save value, since it's constant
3431                reconfig = true;
3432            }
3433        }
3434        if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
3435            // do not accept frame count changes if tracks are open as the track buffer
3436            // size depends on frame count and correct behavior would not be guaranteed
3437            // if frame count is changed after track creation
3438            if (!mTracks.isEmpty()) {
3439                status = INVALID_OPERATION;
3440            } else {
3441                reconfig = true;
3442            }
3443        }
3444        if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
3445#ifdef ADD_BATTERY_DATA
3446            // when changing the audio output device, call addBatteryData to notify
3447            // the change
3448            if (mOutDevice != value) {
3449                uint32_t params = 0;
3450                // check whether speaker is on
3451                if (value & AUDIO_DEVICE_OUT_SPEAKER) {
3452                    params |= IMediaPlayerService::kBatteryDataSpeakerOn;
3453                }
3454
3455                audio_devices_t deviceWithoutSpeaker
3456                    = AUDIO_DEVICE_OUT_ALL & ~AUDIO_DEVICE_OUT_SPEAKER;
3457                // check if any other device (except speaker) is on
3458                if (value & deviceWithoutSpeaker ) {
3459                    params |= IMediaPlayerService::kBatteryDataOtherAudioDeviceOn;
3460                }
3461
3462                if (params != 0) {
3463                    addBatteryData(params);
3464                }
3465            }
3466#endif
3467
3468            // forward device change to effects that have requested to be
3469            // aware of attached audio device.
3470            if (value != AUDIO_DEVICE_NONE) {
3471                mOutDevice = value;
3472                for (size_t i = 0; i < mEffectChains.size(); i++) {
3473                    mEffectChains[i]->setDevice_l(mOutDevice);
3474                }
3475            }
3476        }
3477
3478        if (status == NO_ERROR) {
3479            status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
3480                                                    keyValuePair.string());
3481            if (!mStandby && status == INVALID_OPERATION) {
3482                mOutput->stream->common.standby(&mOutput->stream->common);
3483                mStandby = true;
3484                mBytesWritten = 0;
3485                status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
3486                                                       keyValuePair.string());
3487            }
3488            if (status == NO_ERROR && reconfig) {
3489                readOutputParameters_l();
3490                delete mAudioMixer;
3491                mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate);
3492                for (size_t i = 0; i < mTracks.size() ; i++) {
3493                    int name = getTrackName_l(mTracks[i]->mChannelMask, mTracks[i]->mSessionId);
3494                    if (name < 0) {
3495                        break;
3496                    }
3497                    mTracks[i]->mName = name;
3498                }
3499                sendIoConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
3500            }
3501        }
3502
3503        mNewParameters.removeAt(0);
3504
3505        mParamStatus = status;
3506        mParamCond.signal();
3507        // wait for condition with time out in case the thread calling ThreadBase::setParameters()
3508        // already timed out waiting for the status and will never signal the condition.
3509        mWaitWorkCV.waitRelative(mLock, kSetParametersTimeoutNs);
3510    }
3511
3512    if (!(previousCommand & FastMixerState::IDLE)) {
3513        ALOG_ASSERT(mFastMixer != NULL);
3514        FastMixerStateQueue *sq = mFastMixer->sq();
3515        FastMixerState *state = sq->begin();
3516        ALOG_ASSERT(state->mCommand == FastMixerState::HOT_IDLE);
3517        state->mCommand = previousCommand;
3518        sq->end();
3519        sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
3520    }
3521
3522    return reconfig;
3523}
3524
3525
3526void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
3527{
3528    const size_t SIZE = 256;
3529    char buffer[SIZE];
3530    String8 result;
3531
3532    PlaybackThread::dumpInternals(fd, args);
3533
3534    fdprintf(fd, "  AudioMixer tracks: 0x%08x\n", mAudioMixer->trackNames());
3535
3536    // Make a non-atomic copy of fast mixer dump state so it won't change underneath us
3537    const FastMixerDumpState copy(mFastMixerDumpState);
3538    copy.dump(fd);
3539
3540#ifdef STATE_QUEUE_DUMP
3541    // Similar for state queue
3542    StateQueueObserverDump observerCopy = mStateQueueObserverDump;
3543    observerCopy.dump(fd);
3544    StateQueueMutatorDump mutatorCopy = mStateQueueMutatorDump;
3545    mutatorCopy.dump(fd);
3546#endif
3547
3548#ifdef TEE_SINK
3549    // Write the tee output to a .wav file
3550    dumpTee(fd, mTeeSource, mId);
3551#endif
3552
3553#ifdef AUDIO_WATCHDOG
3554    if (mAudioWatchdog != 0) {
3555        // Make a non-atomic copy of audio watchdog dump so it won't change underneath us
3556        AudioWatchdogDump wdCopy = mAudioWatchdogDump;
3557        wdCopy.dump(fd);
3558    }
3559#endif
3560}
3561
3562uint32_t AudioFlinger::MixerThread::idleSleepTimeUs() const
3563{
3564    return (uint32_t)(((mNormalFrameCount * 1000) / mSampleRate) * 1000) / 2;
3565}
3566
3567uint32_t AudioFlinger::MixerThread::suspendSleepTimeUs() const
3568{
3569    return (uint32_t)(((mNormalFrameCount * 1000) / mSampleRate) * 1000);
3570}
3571
3572void AudioFlinger::MixerThread::cacheParameters_l()
3573{
3574    PlaybackThread::cacheParameters_l();
3575
3576    // FIXME: Relaxed timing because of a certain device that can't meet latency
3577    // Should be reduced to 2x after the vendor fixes the driver issue
3578    // increase threshold again due to low power audio mode. The way this warning
3579    // threshold is calculated and its usefulness should be reconsidered anyway.
3580    maxPeriod = seconds(mNormalFrameCount) / mSampleRate * 15;
3581}
3582
3583// ----------------------------------------------------------------------------
3584
3585AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
3586        AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device)
3587    :   PlaybackThread(audioFlinger, output, id, device, DIRECT)
3588        // mLeftVolFloat, mRightVolFloat
3589{
3590}
3591
3592AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
3593        AudioStreamOut* output, audio_io_handle_t id, uint32_t device,
3594        ThreadBase::type_t type)
3595    :   PlaybackThread(audioFlinger, output, id, device, type)
3596        // mLeftVolFloat, mRightVolFloat
3597{
3598}
3599
3600AudioFlinger::DirectOutputThread::~DirectOutputThread()
3601{
3602}
3603
3604void AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTrack)
3605{
3606    audio_track_cblk_t* cblk = track->cblk();
3607    float left, right;
3608
3609    if (mMasterMute || mStreamTypes[track->streamType()].mute) {
3610        left = right = 0;
3611    } else {
3612        float typeVolume = mStreamTypes[track->streamType()].volume;
3613        float v = mMasterVolume * typeVolume;
3614        AudioTrackServerProxy *proxy = track->mAudioTrackServerProxy;
3615        uint32_t vlr = proxy->getVolumeLR();
3616        float v_clamped = v * (vlr & 0xFFFF);
3617        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
3618        left = v_clamped/MAX_GAIN;
3619        v_clamped = v * (vlr >> 16);
3620        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
3621        right = v_clamped/MAX_GAIN;
3622    }
3623
3624    if (lastTrack) {
3625        if (left != mLeftVolFloat || right != mRightVolFloat) {
3626            mLeftVolFloat = left;
3627            mRightVolFloat = right;
3628
3629            // Convert volumes from float to 8.24
3630            uint32_t vl = (uint32_t)(left * (1 << 24));
3631            uint32_t vr = (uint32_t)(right * (1 << 24));
3632
3633            // Delegate volume control to effect in track effect chain if needed
3634            // only one effect chain can be present on DirectOutputThread, so if
3635            // there is one, the track is connected to it
3636            if (!mEffectChains.isEmpty()) {
3637                mEffectChains[0]->setVolume_l(&vl, &vr);
3638                left = (float)vl / (1 << 24);
3639                right = (float)vr / (1 << 24);
3640            }
3641            if (mOutput->stream->set_volume) {
3642                mOutput->stream->set_volume(mOutput->stream, left, right);
3643            }
3644        }
3645    }
3646}
3647
3648
3649AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prepareTracks_l(
3650    Vector< sp<Track> > *tracksToRemove
3651)
3652{
3653    size_t count = mActiveTracks.size();
3654    mixer_state mixerStatus = MIXER_IDLE;
3655
3656    // find out which tracks need to be processed
3657    for (size_t i = 0; i < count; i++) {
3658        sp<Track> t = mActiveTracks[i].promote();
3659        // The track died recently
3660        if (t == 0) {
3661            continue;
3662        }
3663
3664        Track* const track = t.get();
3665        audio_track_cblk_t* cblk = track->cblk();
3666        // Only consider last track started for volume and mixer state control.
3667        // In theory an older track could underrun and restart after the new one starts
3668        // but as we only care about the transition phase between two tracks on a
3669        // direct output, it is not a problem to ignore the underrun case.
3670        sp<Track> l = mLatestActiveTrack.promote();
3671        bool last = l.get() == track;
3672
3673        // The first time a track is added we wait
3674        // for all its buffers to be filled before processing it
3675        uint32_t minFrames;
3676        if ((track->sharedBuffer() == 0) && !track->isStopped() && !track->isPausing()) {
3677            minFrames = mNormalFrameCount;
3678        } else {
3679            minFrames = 1;
3680        }
3681
3682        if ((track->framesReady() >= minFrames) && track->isReady() &&
3683                !track->isPaused() && !track->isTerminated())
3684        {
3685            ALOGVV("track %d s=%08x [OK]", track->name(), cblk->mServer);
3686
3687            if (track->mFillingUpStatus == Track::FS_FILLED) {
3688                track->mFillingUpStatus = Track::FS_ACTIVE;
3689                // make sure processVolume_l() will apply new volume even if 0
3690                mLeftVolFloat = mRightVolFloat = -1.0;
3691                if (track->mState == TrackBase::RESUMING) {
3692                    track->mState = TrackBase::ACTIVE;
3693                }
3694            }
3695
3696            // compute volume for this track
3697            processVolume_l(track, last);
3698            if (last) {
3699                // reset retry count
3700                track->mRetryCount = kMaxTrackRetriesDirect;
3701                mActiveTrack = t;
3702                mixerStatus = MIXER_TRACKS_READY;
3703            }
3704        } else {
3705            // clear effect chain input buffer if the last active track started underruns
3706            // to avoid sending previous audio buffer again to effects
3707            if (!mEffectChains.isEmpty() && last) {
3708                mEffectChains[0]->clearInputBuffer();
3709            }
3710
3711            ALOGVV("track %d s=%08x [NOT READY]", track->name(), cblk->mServer);
3712            if ((track->sharedBuffer() != 0) || track->isTerminated() ||
3713                    track->isStopped() || track->isPaused()) {
3714                // We have consumed all the buffers of this track.
3715                // Remove it from the list of active tracks.
3716                // TODO: implement behavior for compressed audio
3717                size_t audioHALFrames = (latency_l() * mSampleRate) / 1000;
3718                size_t framesWritten = mBytesWritten / mFrameSize;
3719                if (mStandby || !last ||
3720                        track->presentationComplete(framesWritten, audioHALFrames)) {
3721                    if (track->isStopped()) {
3722                        track->reset();
3723                    }
3724                    tracksToRemove->add(track);
3725                }
3726            } else {
3727                // No buffers for this track. Give it a few chances to
3728                // fill a buffer, then remove it from active list.
3729                // Only consider last track started for mixer state control
3730                if (--(track->mRetryCount) <= 0) {
3731                    ALOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
3732                    tracksToRemove->add(track);
3733                    // indicate to client process that the track was disabled because of underrun;
3734                    // it will then automatically call start() when data is available
3735                    android_atomic_or(CBLK_DISABLED, &cblk->mFlags);
3736                } else if (last) {
3737                    mixerStatus = MIXER_TRACKS_ENABLED;
3738                }
3739            }
3740        }
3741    }
3742
3743    // remove all the tracks that need to be...
3744    removeTracks_l(*tracksToRemove);
3745
3746    return mixerStatus;
3747}
3748
3749void AudioFlinger::DirectOutputThread::threadLoop_mix()
3750{
3751    size_t frameCount = mFrameCount;
3752    int8_t *curBuf = (int8_t *)mMixBuffer;
3753    // output audio to hardware
3754    while (frameCount) {
3755        AudioBufferProvider::Buffer buffer;
3756        buffer.frameCount = frameCount;
3757        mActiveTrack->getNextBuffer(&buffer);
3758        if (buffer.raw == NULL) {
3759            memset(curBuf, 0, frameCount * mFrameSize);
3760            break;
3761        }
3762        memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
3763        frameCount -= buffer.frameCount;
3764        curBuf += buffer.frameCount * mFrameSize;
3765        mActiveTrack->releaseBuffer(&buffer);
3766    }
3767    mCurrentWriteLength = curBuf - (int8_t *)mMixBuffer;
3768    sleepTime = 0;
3769    standbyTime = systemTime() + standbyDelay;
3770    mActiveTrack.clear();
3771}
3772
3773void AudioFlinger::DirectOutputThread::threadLoop_sleepTime()
3774{
3775    if (sleepTime == 0) {
3776        if (mMixerStatus == MIXER_TRACKS_ENABLED) {
3777            sleepTime = activeSleepTime;
3778        } else {
3779            sleepTime = idleSleepTime;
3780        }
3781    } else if (mBytesWritten != 0 && audio_is_linear_pcm(mFormat)) {
3782        memset(mMixBuffer, 0, mFrameCount * mFrameSize);
3783        sleepTime = 0;
3784    }
3785}
3786
3787// getTrackName_l() must be called with ThreadBase::mLock held
3788int AudioFlinger::DirectOutputThread::getTrackName_l(audio_channel_mask_t channelMask __unused,
3789        int sessionId __unused)
3790{
3791    return 0;
3792}
3793
3794// deleteTrackName_l() must be called with ThreadBase::mLock held
3795void AudioFlinger::DirectOutputThread::deleteTrackName_l(int name __unused)
3796{
3797}
3798
3799// checkForNewParameters_l() must be called with ThreadBase::mLock held
3800bool AudioFlinger::DirectOutputThread::checkForNewParameters_l()
3801{
3802    bool reconfig = false;
3803
3804    while (!mNewParameters.isEmpty()) {
3805        status_t status = NO_ERROR;
3806        String8 keyValuePair = mNewParameters[0];
3807        AudioParameter param = AudioParameter(keyValuePair);
3808        int value;
3809
3810        if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
3811            // do not accept frame count changes if tracks are open as the track buffer
3812            // size depends on frame count and correct behavior would not be garantied
3813            // if frame count is changed after track creation
3814            if (!mTracks.isEmpty()) {
3815                status = INVALID_OPERATION;
3816            } else {
3817                reconfig = true;
3818            }
3819        }
3820        if (status == NO_ERROR) {
3821            status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
3822                                                    keyValuePair.string());
3823            if (!mStandby && status == INVALID_OPERATION) {
3824                mOutput->stream->common.standby(&mOutput->stream->common);
3825                mStandby = true;
3826                mBytesWritten = 0;
3827                status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
3828                                                       keyValuePair.string());
3829            }
3830            if (status == NO_ERROR && reconfig) {
3831                readOutputParameters_l();
3832                sendIoConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
3833            }
3834        }
3835
3836        mNewParameters.removeAt(0);
3837
3838        mParamStatus = status;
3839        mParamCond.signal();
3840        // wait for condition with time out in case the thread calling ThreadBase::setParameters()
3841        // already timed out waiting for the status and will never signal the condition.
3842        mWaitWorkCV.waitRelative(mLock, kSetParametersTimeoutNs);
3843    }
3844    return reconfig;
3845}
3846
3847uint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs() const
3848{
3849    uint32_t time;
3850    if (audio_is_linear_pcm(mFormat)) {
3851        time = PlaybackThread::activeSleepTimeUs();
3852    } else {
3853        time = 10000;
3854    }
3855    return time;
3856}
3857
3858uint32_t AudioFlinger::DirectOutputThread::idleSleepTimeUs() const
3859{
3860    uint32_t time;
3861    if (audio_is_linear_pcm(mFormat)) {
3862        time = (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000) / 2;
3863    } else {
3864        time = 10000;
3865    }
3866    return time;
3867}
3868
3869uint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs() const
3870{
3871    uint32_t time;
3872    if (audio_is_linear_pcm(mFormat)) {
3873        time = (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000);
3874    } else {
3875        time = 10000;
3876    }
3877    return time;
3878}
3879
3880void AudioFlinger::DirectOutputThread::cacheParameters_l()
3881{
3882    PlaybackThread::cacheParameters_l();
3883
3884    // use shorter standby delay as on normal output to release
3885    // hardware resources as soon as possible
3886    if (audio_is_linear_pcm(mFormat)) {
3887        standbyDelay = microseconds(activeSleepTime*2);
3888    } else {
3889        standbyDelay = kOffloadStandbyDelayNs;
3890    }
3891}
3892
3893// ----------------------------------------------------------------------------
3894
3895AudioFlinger::AsyncCallbackThread::AsyncCallbackThread(
3896        const wp<AudioFlinger::PlaybackThread>& playbackThread)
3897    :   Thread(false /*canCallJava*/),
3898        mPlaybackThread(playbackThread),
3899        mWriteAckSequence(0),
3900        mDrainSequence(0)
3901{
3902}
3903
3904AudioFlinger::AsyncCallbackThread::~AsyncCallbackThread()
3905{
3906}
3907
3908void AudioFlinger::AsyncCallbackThread::onFirstRef()
3909{
3910    run("Offload Cbk", ANDROID_PRIORITY_URGENT_AUDIO);
3911}
3912
3913bool AudioFlinger::AsyncCallbackThread::threadLoop()
3914{
3915    while (!exitPending()) {
3916        uint32_t writeAckSequence;
3917        uint32_t drainSequence;
3918
3919        {
3920            Mutex::Autolock _l(mLock);
3921            while (!((mWriteAckSequence & 1) ||
3922                     (mDrainSequence & 1) ||
3923                     exitPending())) {
3924                mWaitWorkCV.wait(mLock);
3925            }
3926
3927            if (exitPending()) {
3928                break;
3929            }
3930            ALOGV("AsyncCallbackThread mWriteAckSequence %d mDrainSequence %d",
3931                  mWriteAckSequence, mDrainSequence);
3932            writeAckSequence = mWriteAckSequence;
3933            mWriteAckSequence &= ~1;
3934            drainSequence = mDrainSequence;
3935            mDrainSequence &= ~1;
3936        }
3937        {
3938            sp<AudioFlinger::PlaybackThread> playbackThread = mPlaybackThread.promote();
3939            if (playbackThread != 0) {
3940                if (writeAckSequence & 1) {
3941                    playbackThread->resetWriteBlocked(writeAckSequence >> 1);
3942                }
3943                if (drainSequence & 1) {
3944                    playbackThread->resetDraining(drainSequence >> 1);
3945                }
3946            }
3947        }
3948    }
3949    return false;
3950}
3951
3952void AudioFlinger::AsyncCallbackThread::exit()
3953{
3954    ALOGV("AsyncCallbackThread::exit");
3955    Mutex::Autolock _l(mLock);
3956    requestExit();
3957    mWaitWorkCV.broadcast();
3958}
3959
3960void AudioFlinger::AsyncCallbackThread::setWriteBlocked(uint32_t sequence)
3961{
3962    Mutex::Autolock _l(mLock);
3963    // bit 0 is cleared
3964    mWriteAckSequence = sequence << 1;
3965}
3966
3967void AudioFlinger::AsyncCallbackThread::resetWriteBlocked()
3968{
3969    Mutex::Autolock _l(mLock);
3970    // ignore unexpected callbacks
3971    if (mWriteAckSequence & 2) {
3972        mWriteAckSequence |= 1;
3973        mWaitWorkCV.signal();
3974    }
3975}
3976
3977void AudioFlinger::AsyncCallbackThread::setDraining(uint32_t sequence)
3978{
3979    Mutex::Autolock _l(mLock);
3980    // bit 0 is cleared
3981    mDrainSequence = sequence << 1;
3982}
3983
3984void AudioFlinger::AsyncCallbackThread::resetDraining()
3985{
3986    Mutex::Autolock _l(mLock);
3987    // ignore unexpected callbacks
3988    if (mDrainSequence & 2) {
3989        mDrainSequence |= 1;
3990        mWaitWorkCV.signal();
3991    }
3992}
3993
3994
3995// ----------------------------------------------------------------------------
3996AudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger,
3997        AudioStreamOut* output, audio_io_handle_t id, uint32_t device)
3998    :   DirectOutputThread(audioFlinger, output, id, device, OFFLOAD),
3999        mHwPaused(false),
4000        mFlushPending(false),
4001        mPausedBytesRemaining(0)
4002{
4003    //FIXME: mStandby should be set to true by ThreadBase constructor
4004    mStandby = true;
4005}
4006
4007void AudioFlinger::OffloadThread::threadLoop_exit()
4008{
4009    if (mFlushPending || mHwPaused) {
4010        // If a flush is pending or track was paused, just discard buffered data
4011        flushHw_l();
4012    } else {
4013        mMixerStatus = MIXER_DRAIN_ALL;
4014        threadLoop_drain();
4015    }
4016    mCallbackThread->exit();
4017    PlaybackThread::threadLoop_exit();
4018}
4019
4020AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTracks_l(
4021    Vector< sp<Track> > *tracksToRemove
4022)
4023{
4024    size_t count = mActiveTracks.size();
4025
4026    mixer_state mixerStatus = MIXER_IDLE;
4027    bool doHwPause = false;
4028    bool doHwResume = false;
4029
4030    ALOGV("OffloadThread::prepareTracks_l active tracks %d", count);
4031
4032    // find out which tracks need to be processed
4033    for (size_t i = 0; i < count; i++) {
4034        sp<Track> t = mActiveTracks[i].promote();
4035        // The track died recently
4036        if (t == 0) {
4037            continue;
4038        }
4039        Track* const track = t.get();
4040        audio_track_cblk_t* cblk = track->cblk();
4041        // Only consider last track started for volume and mixer state control.
4042        // In theory an older track could underrun and restart after the new one starts
4043        // but as we only care about the transition phase between two tracks on a
4044        // direct output, it is not a problem to ignore the underrun case.
4045        sp<Track> l = mLatestActiveTrack.promote();
4046        bool last = l.get() == track;
4047
4048        if (track->isInvalid()) {
4049            ALOGW("An invalidated track shouldn't be in active list");
4050            tracksToRemove->add(track);
4051            continue;
4052        }
4053
4054        if (track->mState == TrackBase::IDLE) {
4055            ALOGW("An idle track shouldn't be in active list");
4056            continue;
4057        }
4058
4059        if (track->isPausing()) {
4060            track->setPaused();
4061            if (last) {
4062                if (!mHwPaused) {
4063                    doHwPause = true;
4064                    mHwPaused = true;
4065                }
4066                // If we were part way through writing the mixbuffer to
4067                // the HAL we must save this until we resume
4068                // BUG - this will be wrong if a different track is made active,
4069                // in that case we want to discard the pending data in the
4070                // mixbuffer and tell the client to present it again when the
4071                // track is resumed
4072                mPausedWriteLength = mCurrentWriteLength;
4073                mPausedBytesRemaining = mBytesRemaining;
4074                mBytesRemaining = 0;    // stop writing
4075            }
4076            tracksToRemove->add(track);
4077        } else if (track->isFlushPending()) {
4078            track->flushAck();
4079            if (last) {
4080                mFlushPending = true;
4081            }
4082        } else if (track->framesReady() && track->isReady() &&
4083                !track->isPaused() && !track->isTerminated() && !track->isStopping_2()) {
4084            ALOGVV("OffloadThread: track %d s=%08x [OK]", track->name(), cblk->mServer);
4085            if (track->mFillingUpStatus == Track::FS_FILLED) {
4086                track->mFillingUpStatus = Track::FS_ACTIVE;
4087                // make sure processVolume_l() will apply new volume even if 0
4088                mLeftVolFloat = mRightVolFloat = -1.0;
4089                if (track->mState == TrackBase::RESUMING) {
4090                    track->mState = TrackBase::ACTIVE;
4091                    if (last) {
4092                        if (mPausedBytesRemaining) {
4093                            // Need to continue write that was interrupted
4094                            mCurrentWriteLength = mPausedWriteLength;
4095                            mBytesRemaining = mPausedBytesRemaining;
4096                            mPausedBytesRemaining = 0;
4097                        }
4098                        if (mHwPaused) {
4099                            doHwResume = true;
4100                            mHwPaused = false;
4101                            // threadLoop_mix() will handle the case that we need to
4102                            // resume an interrupted write
4103                        }
4104                        // enable write to audio HAL
4105                        sleepTime = 0;
4106                    }
4107                }
4108            }
4109
4110            if (last) {
4111                sp<Track> previousTrack = mPreviousTrack.promote();
4112                if (previousTrack != 0) {
4113                    if (track != previousTrack.get()) {
4114                        // Flush any data still being written from last track
4115                        mBytesRemaining = 0;
4116                        if (mPausedBytesRemaining) {
4117                            // Last track was paused so we also need to flush saved
4118                            // mixbuffer state and invalidate track so that it will
4119                            // re-submit that unwritten data when it is next resumed
4120                            mPausedBytesRemaining = 0;
4121                            // Invalidate is a bit drastic - would be more efficient
4122                            // to have a flag to tell client that some of the
4123                            // previously written data was lost
4124                            previousTrack->invalidate();
4125                        }
4126                        // flush data already sent to the DSP if changing audio session as audio
4127                        // comes from a different source. Also invalidate previous track to force a
4128                        // seek when resuming.
4129                        if (previousTrack->sessionId() != track->sessionId()) {
4130                            previousTrack->invalidate();
4131                        }
4132                    }
4133                }
4134                mPreviousTrack = track;
4135                // reset retry count
4136                track->mRetryCount = kMaxTrackRetriesOffload;
4137                mActiveTrack = t;
4138                mixerStatus = MIXER_TRACKS_READY;
4139            }
4140        } else {
4141            ALOGVV("OffloadThread: track %d s=%08x [NOT READY]", track->name(), cblk->mServer);
4142            if (track->isStopping_1()) {
4143                // Hardware buffer can hold a large amount of audio so we must
4144                // wait for all current track's data to drain before we say
4145                // that the track is stopped.
4146                if (mBytesRemaining == 0) {
4147                    // Only start draining when all data in mixbuffer
4148                    // has been written
4149                    ALOGV("OffloadThread: underrun and STOPPING_1 -> draining, STOPPING_2");
4150                    track->mState = TrackBase::STOPPING_2; // so presentation completes after drain
4151                    // do not drain if no data was ever sent to HAL (mStandby == true)
4152                    if (last && !mStandby) {
4153                        // do not modify drain sequence if we are already draining. This happens
4154                        // when resuming from pause after drain.
4155                        if ((mDrainSequence & 1) == 0) {
4156                            sleepTime = 0;
4157                            standbyTime = systemTime() + standbyDelay;
4158                            mixerStatus = MIXER_DRAIN_TRACK;
4159                            mDrainSequence += 2;
4160                        }
4161                        if (mHwPaused) {
4162                            // It is possible to move from PAUSED to STOPPING_1 without
4163                            // a resume so we must ensure hardware is running
4164                            doHwResume = true;
4165                            mHwPaused = false;
4166                        }
4167                    }
4168                }
4169            } else if (track->isStopping_2()) {
4170                // Drain has completed or we are in standby, signal presentation complete
4171                if (!(mDrainSequence & 1) || !last || mStandby) {
4172                    track->mState = TrackBase::STOPPED;
4173                    size_t audioHALFrames =
4174                            (mOutput->stream->get_latency(mOutput->stream)*mSampleRate) / 1000;
4175                    size_t framesWritten =
4176                            mBytesWritten / audio_stream_frame_size(&mOutput->stream->common);
4177                    track->presentationComplete(framesWritten, audioHALFrames);
4178                    track->reset();
4179                    tracksToRemove->add(track);
4180                }
4181            } else {
4182                // No buffers for this track. Give it a few chances to
4183                // fill a buffer, then remove it from active list.
4184                if (--(track->mRetryCount) <= 0) {
4185                    ALOGV("OffloadThread: BUFFER TIMEOUT: remove(%d) from active list",
4186                          track->name());
4187                    tracksToRemove->add(track);
4188                    // indicate to client process that the track was disabled because of underrun;
4189                    // it will then automatically call start() when data is available
4190                    android_atomic_or(CBLK_DISABLED, &cblk->mFlags);
4191                } else if (last){
4192                    mixerStatus = MIXER_TRACKS_ENABLED;
4193                }
4194            }
4195        }
4196        // compute volume for this track
4197        processVolume_l(track, last);
4198    }
4199
4200    // make sure the pause/flush/resume sequence is executed in the right order.
4201    // If a flush is pending and a track is active but the HW is not paused, force a HW pause
4202    // before flush and then resume HW. This can happen in case of pause/flush/resume
4203    // if resume is received before pause is executed.
4204    if (!mStandby && (doHwPause || (mFlushPending && !mHwPaused && (count != 0)))) {
4205        mOutput->stream->pause(mOutput->stream);
4206    }
4207    if (mFlushPending) {
4208        flushHw_l();
4209        mFlushPending = false;
4210    }
4211    if (!mStandby && doHwResume) {
4212        mOutput->stream->resume(mOutput->stream);
4213    }
4214
4215    // remove all the tracks that need to be...
4216    removeTracks_l(*tracksToRemove);
4217
4218    return mixerStatus;
4219}
4220
4221// must be called with thread mutex locked
4222bool AudioFlinger::OffloadThread::waitingAsyncCallback_l()
4223{
4224    ALOGVV("waitingAsyncCallback_l mWriteAckSequence %d mDrainSequence %d",
4225          mWriteAckSequence, mDrainSequence);
4226    if (mUseAsyncWrite && ((mWriteAckSequence & 1) || (mDrainSequence & 1))) {
4227        return true;
4228    }
4229    return false;
4230}
4231
4232// must be called with thread mutex locked
4233bool AudioFlinger::OffloadThread::shouldStandby_l()
4234{
4235    bool trackPaused = false;
4236
4237    // do not put the HAL in standby when paused. AwesomePlayer clear the offloaded AudioTrack
4238    // after a timeout and we will enter standby then.
4239    if (mTracks.size() > 0) {
4240        trackPaused = mTracks[mTracks.size() - 1]->isPaused();
4241    }
4242
4243    return !mStandby && !trackPaused;
4244}
4245
4246
4247bool AudioFlinger::OffloadThread::waitingAsyncCallback()
4248{
4249    Mutex::Autolock _l(mLock);
4250    return waitingAsyncCallback_l();
4251}
4252
4253void AudioFlinger::OffloadThread::flushHw_l()
4254{
4255    mOutput->stream->flush(mOutput->stream);
4256    // Flush anything still waiting in the mixbuffer
4257    mCurrentWriteLength = 0;
4258    mBytesRemaining = 0;
4259    mPausedWriteLength = 0;
4260    mPausedBytesRemaining = 0;
4261    mHwPaused = false;
4262
4263    if (mUseAsyncWrite) {
4264        // discard any pending drain or write ack by incrementing sequence
4265        mWriteAckSequence = (mWriteAckSequence + 2) & ~1;
4266        mDrainSequence = (mDrainSequence + 2) & ~1;
4267        ALOG_ASSERT(mCallbackThread != 0);
4268        mCallbackThread->setWriteBlocked(mWriteAckSequence);
4269        mCallbackThread->setDraining(mDrainSequence);
4270    }
4271}
4272
4273void AudioFlinger::OffloadThread::onAddNewTrack_l()
4274{
4275    sp<Track> previousTrack = mPreviousTrack.promote();
4276    sp<Track> latestTrack = mLatestActiveTrack.promote();
4277
4278    if (previousTrack != 0 && latestTrack != 0 &&
4279        (previousTrack->sessionId() != latestTrack->sessionId())) {
4280        mFlushPending = true;
4281    }
4282    PlaybackThread::onAddNewTrack_l();
4283}
4284
4285// ----------------------------------------------------------------------------
4286
4287AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger,
4288        AudioFlinger::MixerThread* mainThread, audio_io_handle_t id)
4289    :   MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->outDevice(),
4290                DUPLICATING),
4291        mWaitTimeMs(UINT_MAX)
4292{
4293    addOutputTrack(mainThread);
4294}
4295
4296AudioFlinger::DuplicatingThread::~DuplicatingThread()
4297{
4298    for (size_t i = 0; i < mOutputTracks.size(); i++) {
4299        mOutputTracks[i]->destroy();
4300    }
4301}
4302
4303void AudioFlinger::DuplicatingThread::threadLoop_mix()
4304{
4305    // mix buffers...
4306    if (outputsReady(outputTracks)) {
4307        mAudioMixer->process(AudioBufferProvider::kInvalidPTS);
4308    } else {
4309        memset(mMixBuffer, 0, mixBufferSize);
4310    }
4311    sleepTime = 0;
4312    writeFrames = mNormalFrameCount;
4313    mCurrentWriteLength = mixBufferSize;
4314    standbyTime = systemTime() + standbyDelay;
4315}
4316
4317void AudioFlinger::DuplicatingThread::threadLoop_sleepTime()
4318{
4319    if (sleepTime == 0) {
4320        if (mMixerStatus == MIXER_TRACKS_ENABLED) {
4321            sleepTime = activeSleepTime;
4322        } else {
4323            sleepTime = idleSleepTime;
4324        }
4325    } else if (mBytesWritten != 0) {
4326        if (mMixerStatus == MIXER_TRACKS_ENABLED) {
4327            writeFrames = mNormalFrameCount;
4328            memset(mMixBuffer, 0, mixBufferSize);
4329        } else {
4330            // flush remaining overflow buffers in output tracks
4331            writeFrames = 0;
4332        }
4333        sleepTime = 0;
4334    }
4335}
4336
4337ssize_t AudioFlinger::DuplicatingThread::threadLoop_write()
4338{
4339    for (size_t i = 0; i < outputTracks.size(); i++) {
4340        outputTracks[i]->write(mMixBuffer, writeFrames);
4341    }
4342    mStandby = false;
4343    return (ssize_t)mixBufferSize;
4344}
4345
4346void AudioFlinger::DuplicatingThread::threadLoop_standby()
4347{
4348    // DuplicatingThread implements standby by stopping all tracks
4349    for (size_t i = 0; i < outputTracks.size(); i++) {
4350        outputTracks[i]->stop();
4351    }
4352}
4353
4354void AudioFlinger::DuplicatingThread::saveOutputTracks()
4355{
4356    outputTracks = mOutputTracks;
4357}
4358
4359void AudioFlinger::DuplicatingThread::clearOutputTracks()
4360{
4361    outputTracks.clear();
4362}
4363
4364void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
4365{
4366    Mutex::Autolock _l(mLock);
4367    // FIXME explain this formula
4368    size_t frameCount = (3 * mNormalFrameCount * mSampleRate) / thread->sampleRate();
4369    OutputTrack *outputTrack = new OutputTrack(thread,
4370                                            this,
4371                                            mSampleRate,
4372                                            mFormat,
4373                                            mChannelMask,
4374                                            frameCount,
4375                                            IPCThreadState::self()->getCallingUid());
4376    if (outputTrack->cblk() != NULL) {
4377        thread->setStreamVolume(AUDIO_STREAM_CNT, 1.0f);
4378        mOutputTracks.add(outputTrack);
4379        ALOGV("addOutputTrack() track %p, on thread %p", outputTrack, thread);
4380        updateWaitTime_l();
4381    }
4382}
4383
4384void AudioFlinger::DuplicatingThread::removeOutputTrack(MixerThread *thread)
4385{
4386    Mutex::Autolock _l(mLock);
4387    for (size_t i = 0; i < mOutputTracks.size(); i++) {
4388        if (mOutputTracks[i]->thread() == thread) {
4389            mOutputTracks[i]->destroy();
4390            mOutputTracks.removeAt(i);
4391            updateWaitTime_l();
4392            return;
4393        }
4394    }
4395    ALOGV("removeOutputTrack(): unkonwn thread: %p", thread);
4396}
4397
4398// caller must hold mLock
4399void AudioFlinger::DuplicatingThread::updateWaitTime_l()
4400{
4401    mWaitTimeMs = UINT_MAX;
4402    for (size_t i = 0; i < mOutputTracks.size(); i++) {
4403        sp<ThreadBase> strong = mOutputTracks[i]->thread().promote();
4404        if (strong != 0) {
4405            uint32_t waitTimeMs = (strong->frameCount() * 2 * 1000) / strong->sampleRate();
4406            if (waitTimeMs < mWaitTimeMs) {
4407                mWaitTimeMs = waitTimeMs;
4408            }
4409        }
4410    }
4411}
4412
4413
4414bool AudioFlinger::DuplicatingThread::outputsReady(
4415        const SortedVector< sp<OutputTrack> > &outputTracks)
4416{
4417    for (size_t i = 0; i < outputTracks.size(); i++) {
4418        sp<ThreadBase> thread = outputTracks[i]->thread().promote();
4419        if (thread == 0) {
4420            ALOGW("DuplicatingThread::outputsReady() could not promote thread on output track %p",
4421                    outputTracks[i].get());
4422            return false;
4423        }
4424        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
4425        // see note at standby() declaration
4426        if (playbackThread->standby() && !playbackThread->isSuspended()) {
4427            ALOGV("DuplicatingThread output track %p on thread %p Not Ready", outputTracks[i].get(),
4428                    thread.get());
4429            return false;
4430        }
4431    }
4432    return true;
4433}
4434
4435uint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs() const
4436{
4437    return (mWaitTimeMs * 1000) / 2;
4438}
4439
4440void AudioFlinger::DuplicatingThread::cacheParameters_l()
4441{
4442    // updateWaitTime_l() sets mWaitTimeMs, which affects activeSleepTimeUs(), so call it first
4443    updateWaitTime_l();
4444
4445    MixerThread::cacheParameters_l();
4446}
4447
4448// ----------------------------------------------------------------------------
4449//      Record
4450// ----------------------------------------------------------------------------
4451
4452AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
4453                                         AudioStreamIn *input,
4454                                         audio_io_handle_t id,
4455                                         audio_devices_t outDevice,
4456                                         audio_devices_t inDevice
4457#ifdef TEE_SINK
4458                                         , const sp<NBAIO_Sink>& teeSink
4459#endif
4460                                         ) :
4461    ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD),
4462    mInput(input), mActiveTracksGen(0), mRsmpInBuffer(NULL),
4463    // mRsmpInFrames and mRsmpInFramesP2 are set by readInputParameters_l()
4464    mRsmpInRear(0)
4465#ifdef TEE_SINK
4466    , mTeeSink(teeSink)
4467#endif
4468{
4469    snprintf(mName, kNameLength, "AudioIn_%X", id);
4470    mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mName);
4471
4472    readInputParameters_l();
4473}
4474
4475
4476AudioFlinger::RecordThread::~RecordThread()
4477{
4478    mAudioFlinger->unregisterWriter(mNBLogWriter);
4479    delete[] mRsmpInBuffer;
4480}
4481
4482void AudioFlinger::RecordThread::onFirstRef()
4483{
4484    run(mName, PRIORITY_URGENT_AUDIO);
4485}
4486
4487bool AudioFlinger::RecordThread::threadLoop()
4488{
4489    nsecs_t lastWarning = 0;
4490
4491    inputStandBy();
4492
4493reacquire_wakelock:
4494    sp<RecordTrack> activeTrack;
4495    int activeTracksGen;
4496    {
4497        Mutex::Autolock _l(mLock);
4498        size_t size = mActiveTracks.size();
4499        activeTracksGen = mActiveTracksGen;
4500        if (size > 0) {
4501            // FIXME an arbitrary choice
4502            activeTrack = mActiveTracks[0];
4503            acquireWakeLock_l(activeTrack->uid());
4504            if (size > 1) {
4505                SortedVector<int> tmp;
4506                for (size_t i = 0; i < size; i++) {
4507                    tmp.add(mActiveTracks[i]->uid());
4508                }
4509                updateWakeLockUids_l(tmp);
4510            }
4511        } else {
4512            acquireWakeLock_l(-1);
4513        }
4514    }
4515
4516    // used to request a deferred sleep, to be executed later while mutex is unlocked
4517    uint32_t sleepUs = 0;
4518
4519    // loop while there is work to do
4520    for (;;) {
4521        Vector< sp<EffectChain> > effectChains;
4522
4523        // sleep with mutex unlocked
4524        if (sleepUs > 0) {
4525            usleep(sleepUs);
4526            sleepUs = 0;
4527        }
4528
4529        // activeTracks accumulates a copy of a subset of mActiveTracks
4530        Vector< sp<RecordTrack> > activeTracks;
4531
4532        { // scope for mLock
4533            Mutex::Autolock _l(mLock);
4534
4535            processConfigEvents_l();
4536            // return value 'reconfig' is currently unused
4537            bool reconfig = checkForNewParameters_l();
4538
4539            // check exitPending here because checkForNewParameters_l() and
4540            // checkForNewParameters_l() can temporarily release mLock
4541            if (exitPending()) {
4542                break;
4543            }
4544
4545            // if no active track(s), then standby and release wakelock
4546            size_t size = mActiveTracks.size();
4547            if (size == 0) {
4548                standbyIfNotAlreadyInStandby();
4549                // exitPending() can't become true here
4550                releaseWakeLock_l();
4551                ALOGV("RecordThread: loop stopping");
4552                // go to sleep
4553                mWaitWorkCV.wait(mLock);
4554                ALOGV("RecordThread: loop starting");
4555                goto reacquire_wakelock;
4556            }
4557
4558            if (mActiveTracksGen != activeTracksGen) {
4559                activeTracksGen = mActiveTracksGen;
4560                SortedVector<int> tmp;
4561                for (size_t i = 0; i < size; i++) {
4562                    tmp.add(mActiveTracks[i]->uid());
4563                }
4564                updateWakeLockUids_l(tmp);
4565            }
4566
4567            bool doBroadcast = false;
4568            for (size_t i = 0; i < size; ) {
4569
4570                activeTrack = mActiveTracks[i];
4571                if (activeTrack->isTerminated()) {
4572                    removeTrack_l(activeTrack);
4573                    mActiveTracks.remove(activeTrack);
4574                    mActiveTracksGen++;
4575                    size--;
4576                    continue;
4577                }
4578
4579                TrackBase::track_state activeTrackState = activeTrack->mState;
4580                switch (activeTrackState) {
4581
4582                case TrackBase::PAUSING:
4583                    mActiveTracks.remove(activeTrack);
4584                    mActiveTracksGen++;
4585                    doBroadcast = true;
4586                    size--;
4587                    continue;
4588
4589                case TrackBase::STARTING_1:
4590                    sleepUs = 10000;
4591                    i++;
4592                    continue;
4593
4594                case TrackBase::STARTING_2:
4595                    doBroadcast = true;
4596                    mStandby = false;
4597                    activeTrack->mState = TrackBase::ACTIVE;
4598                    break;
4599
4600                case TrackBase::ACTIVE:
4601                    break;
4602
4603                case TrackBase::IDLE:
4604                    i++;
4605                    continue;
4606
4607                default:
4608                    LOG_FATAL("Unexpected activeTrackState %d", activeTrackState);
4609                }
4610
4611                activeTracks.add(activeTrack);
4612                i++;
4613
4614            }
4615            if (doBroadcast) {
4616                mStartStopCond.broadcast();
4617            }
4618
4619            // sleep if there are no active tracks to process
4620            if (activeTracks.size() == 0) {
4621                if (sleepUs == 0) {
4622                    sleepUs = kRecordThreadSleepUs;
4623                }
4624                continue;
4625            }
4626            sleepUs = 0;
4627
4628            lockEffectChains_l(effectChains);
4629        }
4630
4631        // thread mutex is now unlocked, mActiveTracks unknown, activeTracks.size() > 0
4632
4633        size_t size = effectChains.size();
4634        for (size_t i = 0; i < size; i++) {
4635            // thread mutex is not locked, but effect chain is locked
4636            effectChains[i]->process_l();
4637        }
4638
4639        // Read from HAL to keep up with fastest client if multiple active tracks, not slowest one.
4640        // Only the client(s) that are too slow will overrun. But if even the fastest client is too
4641        // slow, then this RecordThread will overrun by not calling HAL read often enough.
4642        // If destination is non-contiguous, first read past the nominal end of buffer, then
4643        // copy to the right place.  Permitted because mRsmpInBuffer was over-allocated.
4644
4645        int32_t rear = mRsmpInRear & (mRsmpInFramesP2 - 1);
4646        ssize_t bytesRead = mInput->stream->read(mInput->stream,
4647                &mRsmpInBuffer[rear * mChannelCount], mBufferSize);
4648        if (bytesRead <= 0) {
4649            ALOGE("read failed: bytesRead=%d < %u", bytesRead, mBufferSize);
4650            // Force input into standby so that it tries to recover at next read attempt
4651            inputStandBy();
4652            sleepUs = kRecordThreadSleepUs;
4653            continue;
4654        }
4655        ALOG_ASSERT((size_t) bytesRead <= mBufferSize);
4656        size_t framesRead = bytesRead / mFrameSize;
4657        ALOG_ASSERT(framesRead > 0);
4658        if (mTeeSink != 0) {
4659            (void) mTeeSink->write(&mRsmpInBuffer[rear * mChannelCount], framesRead);
4660        }
4661        // If destination is non-contiguous, we now correct for reading past end of buffer.
4662        size_t part1 = mRsmpInFramesP2 - rear;
4663        if (framesRead > part1) {
4664            memcpy(mRsmpInBuffer, &mRsmpInBuffer[mRsmpInFramesP2 * mChannelCount],
4665                    (framesRead - part1) * mFrameSize);
4666        }
4667        rear = mRsmpInRear += framesRead;
4668
4669        size = activeTracks.size();
4670        // loop over each active track
4671        for (size_t i = 0; i < size; i++) {
4672            activeTrack = activeTracks[i];
4673
4674            enum {
4675                OVERRUN_UNKNOWN,
4676                OVERRUN_TRUE,
4677                OVERRUN_FALSE
4678            } overrun = OVERRUN_UNKNOWN;
4679
4680            // loop over getNextBuffer to handle circular sink
4681            for (;;) {
4682
4683                activeTrack->mSink.frameCount = ~0;
4684                status_t status = activeTrack->getNextBuffer(&activeTrack->mSink);
4685                size_t framesOut = activeTrack->mSink.frameCount;
4686                LOG_ALWAYS_FATAL_IF((status == OK) != (framesOut > 0));
4687
4688                int32_t front = activeTrack->mRsmpInFront;
4689                ssize_t filled = rear - front;
4690                size_t framesIn;
4691
4692                if (filled < 0) {
4693                    // should not happen, but treat like a massive overrun and re-sync
4694                    framesIn = 0;
4695                    activeTrack->mRsmpInFront = rear;
4696                    overrun = OVERRUN_TRUE;
4697                } else if ((size_t) filled <= mRsmpInFramesP2) {
4698                    framesIn = (size_t) filled;
4699                } else {
4700                    // client is not keeping up with server, but give it latest data
4701                    framesIn = mRsmpInFramesP2;
4702                    activeTrack->mRsmpInFront = rear - framesIn;
4703                    overrun = OVERRUN_TRUE;
4704                }
4705
4706                if (framesOut == 0 || framesIn == 0) {
4707                    break;
4708                }
4709
4710                if (activeTrack->mResampler == NULL) {
4711                    // no resampling
4712                    if (framesIn > framesOut) {
4713                        framesIn = framesOut;
4714                    } else {
4715                        framesOut = framesIn;
4716                    }
4717                    int8_t *dst = activeTrack->mSink.i8;
4718                    while (framesIn > 0) {
4719                        front &= mRsmpInFramesP2 - 1;
4720                        size_t part1 = mRsmpInFramesP2 - front;
4721                        if (part1 > framesIn) {
4722                            part1 = framesIn;
4723                        }
4724                        int8_t *src = (int8_t *)mRsmpInBuffer + (front * mFrameSize);
4725                        if (mChannelCount == activeTrack->mChannelCount) {
4726                            memcpy(dst, src, part1 * mFrameSize);
4727                        } else if (mChannelCount == 1) {
4728                            upmix_to_stereo_i16_from_mono_i16((int16_t *)dst, (int16_t *)src,
4729                                    part1);
4730                        } else {
4731                            downmix_to_mono_i16_from_stereo_i16((int16_t *)dst, (int16_t *)src,
4732                                    part1);
4733                        }
4734                        dst += part1 * activeTrack->mFrameSize;
4735                        front += part1;
4736                        framesIn -= part1;
4737                    }
4738                    activeTrack->mRsmpInFront += framesOut;
4739
4740                } else {
4741                    // resampling
4742                    // FIXME framesInNeeded should really be part of resampler API, and should
4743                    //       depend on the SRC ratio
4744                    //       to keep mRsmpInBuffer full so resampler always has sufficient input
4745                    size_t framesInNeeded;
4746                    // FIXME only re-calculate when it changes, and optimize for common ratios
4747                    double inOverOut = (double) mSampleRate / activeTrack->mSampleRate;
4748                    double outOverIn = (double) activeTrack->mSampleRate / mSampleRate;
4749                    framesInNeeded = ceil(framesOut * inOverOut) + 1;
4750                    if (framesIn < framesInNeeded) {
4751                        ALOGV("not enough to resample: have %u but need %u to produce %u "
4752                                "given in/out ratio of %.4g",
4753                                framesIn, framesInNeeded, framesOut, inOverOut);
4754                        size_t newFramesOut = framesIn > 0 ? floor((framesIn - 1) * outOverIn) : 0;
4755                        size_t newFramesInNeeded = ceil(newFramesOut * inOverOut) + 1;
4756                        ALOGV("now need %u frames to produce %u given out/in ratio of %.4g",
4757                                newFramesInNeeded, newFramesOut, outOverIn);
4758                        if (framesIn < newFramesInNeeded) {
4759                            ALOGE("failure: have %u but need %u", framesIn, newFramesInNeeded);
4760                            framesOut = 0;
4761                        } else {
4762                            ALOGV("success 2: have %u and need %u to produce %u "
4763                                  "given in/out ratio of %.4g",
4764                                  framesIn, newFramesInNeeded, newFramesOut, inOverOut);
4765                            LOG_ALWAYS_FATAL_IF(newFramesOut > framesOut);
4766                            framesOut = newFramesOut;
4767                        }
4768                    } else {
4769                        ALOGI("success 1: have %u and need %u to produce %u "
4770                            "given in/out ratio of %.4g",
4771                            framesIn, framesInNeeded, framesOut, inOverOut);
4772                    }
4773
4774                    // reallocate mRsmpOutBuffer as needed; we will grow but never shrink
4775                    if (activeTrack->mRsmpOutFrameCount < framesOut) {
4776                        delete[] activeTrack->mRsmpOutBuffer;
4777                        // resampler always outputs stereo
4778                        activeTrack->mRsmpOutBuffer = new int32_t[framesOut * FCC_2];
4779                        activeTrack->mRsmpOutFrameCount = framesOut;
4780                    }
4781
4782                    // resampler accumulates, but we only have one source track
4783                    memset(activeTrack->mRsmpOutBuffer, 0, framesOut * FCC_2 * sizeof(int32_t));
4784                    activeTrack->mResampler->resample(activeTrack->mRsmpOutBuffer, framesOut,
4785                            activeTrack->mResamplerBufferProvider
4786                            /*this*/ /* AudioBufferProvider* */);
4787                    // ditherAndClamp() works as long as all buffers returned by
4788                    // activeTrack->getNextBuffer() are 32 bit aligned which should be always true.
4789                    if (activeTrack->mChannelCount == 1) {
4790                        // temporarily type pun mRsmpOutBuffer from Q19.12 to int16_t
4791                        ditherAndClamp(activeTrack->mRsmpOutBuffer, activeTrack->mRsmpOutBuffer,
4792                                framesOut);
4793                        // the resampler always outputs stereo samples:
4794                        // do post stereo to mono conversion
4795                        downmix_to_mono_i16_from_stereo_i16(activeTrack->mSink.i16,
4796                                (int16_t *)activeTrack->mRsmpOutBuffer, framesOut);
4797                    } else {
4798                        ditherAndClamp((int32_t *)activeTrack->mSink.raw,
4799                                activeTrack->mRsmpOutBuffer, framesOut);
4800                    }
4801                    // now done with mRsmpOutBuffer
4802
4803                }
4804
4805                if (framesOut > 0 && (overrun == OVERRUN_UNKNOWN)) {
4806                    overrun = OVERRUN_FALSE;
4807                }
4808
4809                if (activeTrack->mFramesToDrop == 0) {
4810                    if (framesOut > 0) {
4811                        activeTrack->mSink.frameCount = framesOut;
4812                        activeTrack->releaseBuffer(&activeTrack->mSink);
4813                    }
4814                } else {
4815                    // FIXME could do a partial drop of framesOut
4816                    if (activeTrack->mFramesToDrop > 0) {
4817                        activeTrack->mFramesToDrop -= framesOut;
4818                        if (activeTrack->mFramesToDrop <= 0) {
4819                            activeTrack->clearSyncStartEvent();
4820                        }
4821                    } else {
4822                        activeTrack->mFramesToDrop += framesOut;
4823                        if (activeTrack->mFramesToDrop >= 0 || activeTrack->mSyncStartEvent == 0 ||
4824                                activeTrack->mSyncStartEvent->isCancelled()) {
4825                            ALOGW("Synced record %s, session %d, trigger session %d",
4826                                  (activeTrack->mFramesToDrop >= 0) ? "timed out" : "cancelled",
4827                                  activeTrack->sessionId(),
4828                                  (activeTrack->mSyncStartEvent != 0) ?
4829                                          activeTrack->mSyncStartEvent->triggerSession() : 0);
4830                            activeTrack->clearSyncStartEvent();
4831                        }
4832                    }
4833                }
4834
4835                if (framesOut == 0) {
4836                    break;
4837                }
4838            }
4839
4840            switch (overrun) {
4841            case OVERRUN_TRUE:
4842                // client isn't retrieving buffers fast enough
4843                if (!activeTrack->setOverflow()) {
4844                    nsecs_t now = systemTime();
4845                    // FIXME should lastWarning per track?
4846                    if ((now - lastWarning) > kWarningThrottleNs) {
4847                        ALOGW("RecordThread: buffer overflow");
4848                        lastWarning = now;
4849                    }
4850                }
4851                break;
4852            case OVERRUN_FALSE:
4853                activeTrack->clearOverflow();
4854                break;
4855            case OVERRUN_UNKNOWN:
4856                break;
4857            }
4858
4859        }
4860
4861        // enable changes in effect chain
4862        unlockEffectChains(effectChains);
4863        // effectChains doesn't need to be cleared, since it is cleared by destructor at scope end
4864    }
4865
4866    standbyIfNotAlreadyInStandby();
4867
4868    {
4869        Mutex::Autolock _l(mLock);
4870        for (size_t i = 0; i < mTracks.size(); i++) {
4871            sp<RecordTrack> track = mTracks[i];
4872            track->invalidate();
4873        }
4874        mActiveTracks.clear();
4875        mActiveTracksGen++;
4876        mStartStopCond.broadcast();
4877    }
4878
4879    releaseWakeLock();
4880
4881    ALOGV("RecordThread %p exiting", this);
4882    return false;
4883}
4884
4885void AudioFlinger::RecordThread::standbyIfNotAlreadyInStandby()
4886{
4887    if (!mStandby) {
4888        inputStandBy();
4889        mStandby = true;
4890    }
4891}
4892
4893void AudioFlinger::RecordThread::inputStandBy()
4894{
4895    mInput->stream->common.standby(&mInput->stream->common);
4896}
4897
4898sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRecordTrack_l(
4899        const sp<AudioFlinger::Client>& client,
4900        uint32_t sampleRate,
4901        audio_format_t format,
4902        audio_channel_mask_t channelMask,
4903        size_t *pFrameCount,
4904        int sessionId,
4905        int uid,
4906        IAudioFlinger::track_flags_t *flags,
4907        pid_t tid,
4908        status_t *status)
4909{
4910    size_t frameCount = *pFrameCount;
4911    sp<RecordTrack> track;
4912    status_t lStatus;
4913
4914    lStatus = initCheck();
4915    if (lStatus != NO_ERROR) {
4916        ALOGE("createRecordTrack_l() audio driver not initialized");
4917        goto Exit;
4918    }
4919
4920    // client expresses a preference for FAST, but we get the final say
4921    if (*flags & IAudioFlinger::TRACK_FAST) {
4922      if (
4923            // use case: callback handler and frame count is default or at least as large as HAL
4924            (
4925                (tid != -1) &&
4926                ((frameCount == 0) ||
4927                (frameCount >= mFrameCount))
4928            ) &&
4929            // FIXME when record supports non-PCM data, also check for audio_is_linear_pcm(format)
4930            // mono or stereo
4931            ( (channelMask == AUDIO_CHANNEL_OUT_MONO) ||
4932              (channelMask == AUDIO_CHANNEL_OUT_STEREO) ) &&
4933            // hardware sample rate
4934            (sampleRate == mSampleRate) &&
4935            // record thread has an associated fast recorder
4936            hasFastRecorder()
4937            // FIXME test that RecordThread for this fast track has a capable output HAL
4938            // FIXME add a permission test also?
4939        ) {
4940        // if frameCount not specified, then it defaults to fast recorder (HAL) frame count
4941        if (frameCount == 0) {
4942            frameCount = mFrameCount * kFastTrackMultiplier;
4943        }
4944        ALOGV("AUDIO_INPUT_FLAG_FAST accepted: frameCount=%d mFrameCount=%d",
4945                frameCount, mFrameCount);
4946      } else {
4947        ALOGV("AUDIO_INPUT_FLAG_FAST denied: frameCount=%d "
4948                "mFrameCount=%d format=%d isLinear=%d channelMask=%#x sampleRate=%u mSampleRate=%u "
4949                "hasFastRecorder=%d tid=%d",
4950                frameCount, mFrameCount, format,
4951                audio_is_linear_pcm(format),
4952                channelMask, sampleRate, mSampleRate, hasFastRecorder(), tid);
4953        *flags &= ~IAudioFlinger::TRACK_FAST;
4954        // For compatibility with AudioRecord calculation, buffer depth is forced
4955        // to be at least 2 x the record thread frame count and cover audio hardware latency.
4956        // This is probably too conservative, but legacy application code may depend on it.
4957        // If you change this calculation, also review the start threshold which is related.
4958        uint32_t latencyMs = 50; // FIXME mInput->stream->get_latency(mInput->stream);
4959        size_t mNormalFrameCount = 2048; // FIXME
4960        uint32_t minBufCount = latencyMs / ((1000 * mNormalFrameCount) / mSampleRate);
4961        if (minBufCount < 2) {
4962            minBufCount = 2;
4963        }
4964        size_t minFrameCount = mNormalFrameCount * minBufCount;
4965        if (frameCount < minFrameCount) {
4966            frameCount = minFrameCount;
4967        }
4968      }
4969    }
4970    *pFrameCount = frameCount;
4971
4972    // FIXME use flags and tid similar to createTrack_l()
4973
4974    { // scope for mLock
4975        Mutex::Autolock _l(mLock);
4976
4977        track = new RecordTrack(this, client, sampleRate,
4978                      format, channelMask, frameCount, sessionId, uid);
4979
4980        lStatus = track->initCheck();
4981        if (lStatus != NO_ERROR) {
4982            ALOGE("createRecordTrack_l() initCheck failed %d; no control block?", lStatus);
4983            // track must be cleared from the caller as the caller has the AF lock
4984            goto Exit;
4985        }
4986        mTracks.add(track);
4987
4988        // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
4989        bool suspend = audio_is_bluetooth_sco_device(mInDevice) &&
4990                        mAudioFlinger->btNrecIsOff();
4991        setEffectSuspended_l(FX_IID_AEC, suspend, sessionId);
4992        setEffectSuspended_l(FX_IID_NS, suspend, sessionId);
4993
4994        if ((*flags & IAudioFlinger::TRACK_FAST) && (tid != -1)) {
4995            pid_t callingPid = IPCThreadState::self()->getCallingPid();
4996            // we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful,
4997            // so ask activity manager to do this on our behalf
4998            sendPrioConfigEvent_l(callingPid, tid, kPriorityAudioApp);
4999        }
5000    }
5001    lStatus = NO_ERROR;
5002
5003Exit:
5004    *status = lStatus;
5005    return track;
5006}
5007
5008status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack,
5009                                           AudioSystem::sync_event_t event,
5010                                           int triggerSession)
5011{
5012    ALOGV("RecordThread::start event %d, triggerSession %d", event, triggerSession);
5013    sp<ThreadBase> strongMe = this;
5014    status_t status = NO_ERROR;
5015
5016    if (event == AudioSystem::SYNC_EVENT_NONE) {
5017        recordTrack->clearSyncStartEvent();
5018    } else if (event != AudioSystem::SYNC_EVENT_SAME) {
5019        recordTrack->mSyncStartEvent = mAudioFlinger->createSyncEvent(event,
5020                                       triggerSession,
5021                                       recordTrack->sessionId(),
5022                                       syncStartEventCallback,
5023                                       recordTrack);
5024        // Sync event can be cancelled by the trigger session if the track is not in a
5025        // compatible state in which case we start record immediately
5026        if (recordTrack->mSyncStartEvent->isCancelled()) {
5027            recordTrack->clearSyncStartEvent();
5028        } else {
5029            // do not wait for the event for more than AudioSystem::kSyncRecordStartTimeOutMs
5030            recordTrack->mFramesToDrop = -
5031                    ((AudioSystem::kSyncRecordStartTimeOutMs * recordTrack->mSampleRate) / 1000);
5032        }
5033    }
5034
5035    {
5036        // This section is a rendezvous between binder thread executing start() and RecordThread
5037        AutoMutex lock(mLock);
5038        if (mActiveTracks.indexOf(recordTrack) >= 0) {
5039            if (recordTrack->mState == TrackBase::PAUSING) {
5040                ALOGV("active record track PAUSING -> ACTIVE");
5041                recordTrack->mState = TrackBase::ACTIVE;
5042            } else {
5043                ALOGV("active record track state %d", recordTrack->mState);
5044            }
5045            return status;
5046        }
5047
5048        // TODO consider other ways of handling this, such as changing the state to :STARTING and
5049        //      adding the track to mActiveTracks after returning from AudioSystem::startInput(),
5050        //      or using a separate command thread
5051        recordTrack->mState = TrackBase::STARTING_1;
5052        mActiveTracks.add(recordTrack);
5053        mActiveTracksGen++;
5054        mLock.unlock();
5055        status_t status = AudioSystem::startInput(mId);
5056        mLock.lock();
5057        // FIXME should verify that recordTrack is still in mActiveTracks
5058        if (status != NO_ERROR) {
5059            mActiveTracks.remove(recordTrack);
5060            mActiveTracksGen++;
5061            recordTrack->clearSyncStartEvent();
5062            return status;
5063        }
5064        // Catch up with current buffer indices if thread is already running.
5065        // This is what makes a new client discard all buffered data.  If the track's mRsmpInFront
5066        // was initialized to some value closer to the thread's mRsmpInFront, then the track could
5067        // see previously buffered data before it called start(), but with greater risk of overrun.
5068
5069        recordTrack->mRsmpInFront = mRsmpInRear;
5070        recordTrack->mRsmpInUnrel = 0;
5071        // FIXME why reset?
5072        if (recordTrack->mResampler != NULL) {
5073            recordTrack->mResampler->reset();
5074        }
5075        recordTrack->mState = TrackBase::STARTING_2;
5076        // signal thread to start
5077        mWaitWorkCV.broadcast();
5078        if (mActiveTracks.indexOf(recordTrack) < 0) {
5079            ALOGV("Record failed to start");
5080            status = BAD_VALUE;
5081            goto startError;
5082        }
5083        return status;
5084    }
5085
5086startError:
5087    AudioSystem::stopInput(mId);
5088    recordTrack->clearSyncStartEvent();
5089    // FIXME I wonder why we do not reset the state here?
5090    return status;
5091}
5092
5093void AudioFlinger::RecordThread::syncStartEventCallback(const wp<SyncEvent>& event)
5094{
5095    sp<SyncEvent> strongEvent = event.promote();
5096
5097    if (strongEvent != 0) {
5098        RecordTrack *recordTrack = (RecordTrack *)strongEvent->cookie();
5099        recordTrack->handleSyncStartEvent(strongEvent);
5100    }
5101}
5102
5103bool AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
5104    ALOGV("RecordThread::stop");
5105    AutoMutex _l(mLock);
5106    if (mActiveTracks.indexOf(recordTrack) != 0 || recordTrack->mState == TrackBase::PAUSING) {
5107        return false;
5108    }
5109    // note that threadLoop may still be processing the track at this point [without lock]
5110    recordTrack->mState = TrackBase::PAUSING;
5111    // do not wait for mStartStopCond if exiting
5112    if (exitPending()) {
5113        return true;
5114    }
5115    // FIXME incorrect usage of wait: no explicit predicate or loop
5116    mStartStopCond.wait(mLock);
5117    // if we have been restarted, recordTrack is in mActiveTracks here
5118    if (exitPending() || mActiveTracks.indexOf(recordTrack) != 0) {
5119        ALOGV("Record stopped OK");
5120        return true;
5121    }
5122    return false;
5123}
5124
5125bool AudioFlinger::RecordThread::isValidSyncEvent(const sp<SyncEvent>& event __unused) const
5126{
5127    return false;
5128}
5129
5130status_t AudioFlinger::RecordThread::setSyncEvent(const sp<SyncEvent>& event __unused)
5131{
5132#if 0   // This branch is currently dead code, but is preserved in case it will be needed in future
5133    if (!isValidSyncEvent(event)) {
5134        return BAD_VALUE;
5135    }
5136
5137    int eventSession = event->triggerSession();
5138    status_t ret = NAME_NOT_FOUND;
5139
5140    Mutex::Autolock _l(mLock);
5141
5142    for (size_t i = 0; i < mTracks.size(); i++) {
5143        sp<RecordTrack> track = mTracks[i];
5144        if (eventSession == track->sessionId()) {
5145            (void) track->setSyncEvent(event);
5146            ret = NO_ERROR;
5147        }
5148    }
5149    return ret;
5150#else
5151    return BAD_VALUE;
5152#endif
5153}
5154
5155// destroyTrack_l() must be called with ThreadBase::mLock held
5156void AudioFlinger::RecordThread::destroyTrack_l(const sp<RecordTrack>& track)
5157{
5158    track->terminate();
5159    track->mState = TrackBase::STOPPED;
5160    // active tracks are removed by threadLoop()
5161    if (mActiveTracks.indexOf(track) < 0) {
5162        removeTrack_l(track);
5163    }
5164}
5165
5166void AudioFlinger::RecordThread::removeTrack_l(const sp<RecordTrack>& track)
5167{
5168    mTracks.remove(track);
5169    // need anything related to effects here?
5170}
5171
5172void AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args)
5173{
5174    dumpInternals(fd, args);
5175    dumpTracks(fd, args);
5176    dumpEffectChains(fd, args);
5177}
5178
5179void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& args)
5180{
5181    fdprintf(fd, "\nInput thread %p:\n", this);
5182
5183    if (mActiveTracks.size() > 0) {
5184        fdprintf(fd, "  Buffer size: %zu bytes\n", mBufferSize);
5185    } else {
5186        fdprintf(fd, "  No active record clients\n");
5187    }
5188
5189    dumpBase(fd, args);
5190}
5191
5192void AudioFlinger::RecordThread::dumpTracks(int fd, const Vector<String16>& args __unused)
5193{
5194    const size_t SIZE = 256;
5195    char buffer[SIZE];
5196    String8 result;
5197
5198    size_t numtracks = mTracks.size();
5199    size_t numactive = mActiveTracks.size();
5200    size_t numactiveseen = 0;
5201    fdprintf(fd, "  %d Tracks", numtracks);
5202    if (numtracks) {
5203        fdprintf(fd, " of which %d are active\n", numactive);
5204        RecordTrack::appendDumpHeader(result);
5205        for (size_t i = 0; i < numtracks ; ++i) {
5206            sp<RecordTrack> track = mTracks[i];
5207            if (track != 0) {
5208                bool active = mActiveTracks.indexOf(track) >= 0;
5209                if (active) {
5210                    numactiveseen++;
5211                }
5212                track->dump(buffer, SIZE, active);
5213                result.append(buffer);
5214            }
5215        }
5216    } else {
5217        fdprintf(fd, "\n");
5218    }
5219
5220    if (numactiveseen != numactive) {
5221        snprintf(buffer, SIZE, "  The following tracks are in the active list but"
5222                " not in the track list\n");
5223        result.append(buffer);
5224        RecordTrack::appendDumpHeader(result);
5225        for (size_t i = 0; i < numactive; ++i) {
5226            sp<RecordTrack> track = mActiveTracks[i];
5227            if (mTracks.indexOf(track) < 0) {
5228                track->dump(buffer, SIZE, true);
5229                result.append(buffer);
5230            }
5231        }
5232
5233    }
5234    write(fd, result.string(), result.size());
5235}
5236
5237// AudioBufferProvider interface
5238status_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer(
5239        AudioBufferProvider::Buffer* buffer, int64_t pts __unused)
5240{
5241    RecordTrack *activeTrack = mRecordTrack;
5242    sp<ThreadBase> threadBase = activeTrack->mThread.promote();
5243    if (threadBase == 0) {
5244        buffer->frameCount = 0;
5245        return NOT_ENOUGH_DATA;
5246    }
5247    RecordThread *recordThread = (RecordThread *) threadBase.get();
5248    int32_t rear = recordThread->mRsmpInRear;
5249    int32_t front = activeTrack->mRsmpInFront;
5250    ssize_t filled = rear - front;
5251    // FIXME should not be P2 (don't want to increase latency)
5252    // FIXME if client not keeping up, discard
5253    ALOG_ASSERT(0 <= filled && (size_t) filled <= recordThread->mRsmpInFramesP2);
5254    // 'filled' may be non-contiguous, so return only the first contiguous chunk
5255    front &= recordThread->mRsmpInFramesP2 - 1;
5256    size_t part1 = recordThread->mRsmpInFramesP2 - front;
5257    if (part1 > (size_t) filled) {
5258        part1 = filled;
5259    }
5260    size_t ask = buffer->frameCount;
5261    ALOG_ASSERT(ask > 0);
5262    if (part1 > ask) {
5263        part1 = ask;
5264    }
5265    if (part1 == 0) {
5266        // Higher-level should keep mRsmpInBuffer full, and not call resampler if empty
5267        LOG_FATAL("RecordThread::getNextBuffer() starved");
5268        buffer->raw = NULL;
5269        buffer->frameCount = 0;
5270        activeTrack->mRsmpInUnrel = 0;
5271        return NOT_ENOUGH_DATA;
5272    }
5273
5274    buffer->raw = recordThread->mRsmpInBuffer + front * recordThread->mChannelCount;
5275    buffer->frameCount = part1;
5276    activeTrack->mRsmpInUnrel = part1;
5277    return NO_ERROR;
5278}
5279
5280// AudioBufferProvider interface
5281void AudioFlinger::RecordThread::ResamplerBufferProvider::releaseBuffer(
5282        AudioBufferProvider::Buffer* buffer)
5283{
5284    RecordTrack *activeTrack = mRecordTrack;
5285    size_t stepCount = buffer->frameCount;
5286    if (stepCount == 0) {
5287        return;
5288    }
5289    ALOG_ASSERT(stepCount <= activeTrack->mRsmpInUnrel);
5290    activeTrack->mRsmpInUnrel -= stepCount;
5291    activeTrack->mRsmpInFront += stepCount;
5292    buffer->raw = NULL;
5293    buffer->frameCount = 0;
5294}
5295
5296bool AudioFlinger::RecordThread::checkForNewParameters_l()
5297{
5298    bool reconfig = false;
5299
5300    while (!mNewParameters.isEmpty()) {
5301        status_t status = NO_ERROR;
5302        String8 keyValuePair = mNewParameters[0];
5303        AudioParameter param = AudioParameter(keyValuePair);
5304        int value;
5305        audio_format_t reqFormat = mFormat;
5306        uint32_t samplingRate = mSampleRate;
5307        audio_channel_mask_t channelMask = audio_channel_in_mask_from_count(mChannelCount);
5308
5309        // TODO Investigate when this code runs. Check with audio policy when a sample rate and
5310        //      channel count change can be requested. Do we mandate the first client defines the
5311        //      HAL sampling rate and channel count or do we allow changes on the fly?
5312        if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) {
5313            samplingRate = value;
5314            reconfig = true;
5315        }
5316        if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) {
5317            if ((audio_format_t) value != AUDIO_FORMAT_PCM_16_BIT) {
5318                status = BAD_VALUE;
5319            } else {
5320                reqFormat = (audio_format_t) value;
5321                reconfig = true;
5322            }
5323        }
5324        if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
5325            audio_channel_mask_t mask = (audio_channel_mask_t) value;
5326            if (mask != AUDIO_CHANNEL_IN_MONO && mask != AUDIO_CHANNEL_IN_STEREO) {
5327                status = BAD_VALUE;
5328            } else {
5329                channelMask = mask;
5330                reconfig = true;
5331            }
5332        }
5333        if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
5334            // do not accept frame count changes if tracks are open as the track buffer
5335            // size depends on frame count and correct behavior would not be guaranteed
5336            // if frame count is changed after track creation
5337            if (mActiveTracks.size() > 0) {
5338                status = INVALID_OPERATION;
5339            } else {
5340                reconfig = true;
5341            }
5342        }
5343        if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
5344            // forward device change to effects that have requested to be
5345            // aware of attached audio device.
5346            for (size_t i = 0; i < mEffectChains.size(); i++) {
5347                mEffectChains[i]->setDevice_l(value);
5348            }
5349
5350            // store input device and output device but do not forward output device to audio HAL.
5351            // Note that status is ignored by the caller for output device
5352            // (see AudioFlinger::setParameters()
5353            if (audio_is_output_devices(value)) {
5354                mOutDevice = value;
5355                status = BAD_VALUE;
5356            } else {
5357                mInDevice = value;
5358                // disable AEC and NS if the device is a BT SCO headset supporting those
5359                // pre processings
5360                if (mTracks.size() > 0) {
5361                    bool suspend = audio_is_bluetooth_sco_device(mInDevice) &&
5362                                        mAudioFlinger->btNrecIsOff();
5363                    for (size_t i = 0; i < mTracks.size(); i++) {
5364                        sp<RecordTrack> track = mTracks[i];
5365                        setEffectSuspended_l(FX_IID_AEC, suspend, track->sessionId());
5366                        setEffectSuspended_l(FX_IID_NS, suspend, track->sessionId());
5367                    }
5368                }
5369            }
5370        }
5371        if (param.getInt(String8(AudioParameter::keyInputSource), value) == NO_ERROR &&
5372                mAudioSource != (audio_source_t)value) {
5373            // forward device change to effects that have requested to be
5374            // aware of attached audio device.
5375            for (size_t i = 0; i < mEffectChains.size(); i++) {
5376                mEffectChains[i]->setAudioSource_l((audio_source_t)value);
5377            }
5378            mAudioSource = (audio_source_t)value;
5379        }
5380
5381        if (status == NO_ERROR) {
5382            status = mInput->stream->common.set_parameters(&mInput->stream->common,
5383                    keyValuePair.string());
5384            if (status == INVALID_OPERATION) {
5385                inputStandBy();
5386                status = mInput->stream->common.set_parameters(&mInput->stream->common,
5387                        keyValuePair.string());
5388            }
5389            if (reconfig) {
5390                if (status == BAD_VALUE &&
5391                    reqFormat == mInput->stream->common.get_format(&mInput->stream->common) &&
5392                    reqFormat == AUDIO_FORMAT_PCM_16_BIT &&
5393                    (mInput->stream->common.get_sample_rate(&mInput->stream->common)
5394                            <= (2 * samplingRate)) &&
5395                    popcount(mInput->stream->common.get_channels(&mInput->stream->common))
5396                            <= FCC_2 &&
5397                    (channelMask == AUDIO_CHANNEL_IN_MONO ||
5398                            channelMask == AUDIO_CHANNEL_IN_STEREO)) {
5399                    status = NO_ERROR;
5400                }
5401                if (status == NO_ERROR) {
5402                    readInputParameters_l();
5403                    sendIoConfigEvent_l(AudioSystem::INPUT_CONFIG_CHANGED);
5404                }
5405            }
5406        }
5407
5408        mNewParameters.removeAt(0);
5409
5410        mParamStatus = status;
5411        mParamCond.signal();
5412        // wait for condition with time out in case the thread calling ThreadBase::setParameters()
5413        // already timed out waiting for the status and will never signal the condition.
5414        mWaitWorkCV.waitRelative(mLock, kSetParametersTimeoutNs);
5415    }
5416    return reconfig;
5417}
5418
5419String8 AudioFlinger::RecordThread::getParameters(const String8& keys)
5420{
5421    Mutex::Autolock _l(mLock);
5422    if (initCheck() != NO_ERROR) {
5423        return String8();
5424    }
5425
5426    char *s = mInput->stream->common.get_parameters(&mInput->stream->common, keys.string());
5427    const String8 out_s8(s);
5428    free(s);
5429    return out_s8;
5430}
5431
5432void AudioFlinger::RecordThread::audioConfigChanged_l(int event, int param __unused) {
5433    AudioSystem::OutputDescriptor desc;
5434    const void *param2 = NULL;
5435
5436    switch (event) {
5437    case AudioSystem::INPUT_OPENED:
5438    case AudioSystem::INPUT_CONFIG_CHANGED:
5439        desc.channelMask = mChannelMask;
5440        desc.samplingRate = mSampleRate;
5441        desc.format = mFormat;
5442        desc.frameCount = mFrameCount;
5443        desc.latency = 0;
5444        param2 = &desc;
5445        break;
5446
5447    case AudioSystem::INPUT_CLOSED:
5448    default:
5449        break;
5450    }
5451    mAudioFlinger->audioConfigChanged_l(event, mId, param2);
5452}
5453
5454void AudioFlinger::RecordThread::readInputParameters_l()
5455{
5456    mSampleRate = mInput->stream->common.get_sample_rate(&mInput->stream->common);
5457    mChannelMask = mInput->stream->common.get_channels(&mInput->stream->common);
5458    mChannelCount = popcount(mChannelMask);
5459    mFormat = mInput->stream->common.get_format(&mInput->stream->common);
5460    if (mFormat != AUDIO_FORMAT_PCM_16_BIT) {
5461        ALOGE("HAL format %#x not supported; must be AUDIO_FORMAT_PCM_16_BIT", mFormat);
5462    }
5463    mFrameSize = audio_stream_frame_size(&mInput->stream->common);
5464    mBufferSize = mInput->stream->common.get_buffer_size(&mInput->stream->common);
5465    mFrameCount = mBufferSize / mFrameSize;
5466    // This is the formula for calculating the temporary buffer size.
5467    // With 3 HAL buffers, we can guarantee ability to down-sample the input by ratio of 2:1 to
5468    // 1 full output buffer, regardless of the alignment of the available input.
5469    // The "3" is somewhat arbitrary, and could probably be larger.
5470    // A larger value should allow more old data to be read after a track calls start(),
5471    // without increasing latency.
5472    mRsmpInFrames = mFrameCount * 3;
5473    mRsmpInFramesP2 = roundup(mRsmpInFrames);
5474    delete[] mRsmpInBuffer;
5475    // Over-allocate beyond mRsmpInFramesP2 to permit a HAL read past end of buffer
5476    mRsmpInBuffer = new int16_t[(mRsmpInFramesP2 + mFrameCount - 1) * mChannelCount];
5477
5478    // AudioRecord mSampleRate and mChannelCount are constant due to AudioRecord API constraints.
5479    // But if thread's mSampleRate or mChannelCount changes, how will that affect active tracks?
5480}
5481
5482uint32_t AudioFlinger::RecordThread::getInputFramesLost()
5483{
5484    Mutex::Autolock _l(mLock);
5485    if (initCheck() != NO_ERROR) {
5486        return 0;
5487    }
5488
5489    return mInput->stream->get_input_frames_lost(mInput->stream);
5490}
5491
5492uint32_t AudioFlinger::RecordThread::hasAudioSession(int sessionId) const
5493{
5494    Mutex::Autolock _l(mLock);
5495    uint32_t result = 0;
5496    if (getEffectChain_l(sessionId) != 0) {
5497        result = EFFECT_SESSION;
5498    }
5499
5500    for (size_t i = 0; i < mTracks.size(); ++i) {
5501        if (sessionId == mTracks[i]->sessionId()) {
5502            result |= TRACK_SESSION;
5503            break;
5504        }
5505    }
5506
5507    return result;
5508}
5509
5510KeyedVector<int, bool> AudioFlinger::RecordThread::sessionIds() const
5511{
5512    KeyedVector<int, bool> ids;
5513    Mutex::Autolock _l(mLock);
5514    for (size_t j = 0; j < mTracks.size(); ++j) {
5515        sp<RecordThread::RecordTrack> track = mTracks[j];
5516        int sessionId = track->sessionId();
5517        if (ids.indexOfKey(sessionId) < 0) {
5518            ids.add(sessionId, true);
5519        }
5520    }
5521    return ids;
5522}
5523
5524AudioFlinger::AudioStreamIn* AudioFlinger::RecordThread::clearInput()
5525{
5526    Mutex::Autolock _l(mLock);
5527    AudioStreamIn *input = mInput;
5528    mInput = NULL;
5529    return input;
5530}
5531
5532// this method must always be called either with ThreadBase mLock held or inside the thread loop
5533audio_stream_t* AudioFlinger::RecordThread::stream() const
5534{
5535    if (mInput == NULL) {
5536        return NULL;
5537    }
5538    return &mInput->stream->common;
5539}
5540
5541status_t AudioFlinger::RecordThread::addEffectChain_l(const sp<EffectChain>& chain)
5542{
5543    // only one chain per input thread
5544    if (mEffectChains.size() != 0) {
5545        return INVALID_OPERATION;
5546    }
5547    ALOGV("addEffectChain_l() %p on thread %p", chain.get(), this);
5548
5549    chain->setInBuffer(NULL);
5550    chain->setOutBuffer(NULL);
5551
5552    checkSuspendOnAddEffectChain_l(chain);
5553
5554    mEffectChains.add(chain);
5555
5556    return NO_ERROR;
5557}
5558
5559size_t AudioFlinger::RecordThread::removeEffectChain_l(const sp<EffectChain>& chain)
5560{
5561    ALOGV("removeEffectChain_l() %p from thread %p", chain.get(), this);
5562    ALOGW_IF(mEffectChains.size() != 1,
5563            "removeEffectChain_l() %p invalid chain size %d on thread %p",
5564            chain.get(), mEffectChains.size(), this);
5565    if (mEffectChains.size() == 1) {
5566        mEffectChains.removeAt(0);
5567    }
5568    return 0;
5569}
5570
5571}; // namespace android
5572