AudioFlinger.cpp revision c9b2e20f7c9a71e07ef398152709c76079decbcd
199e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten/*
265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**
365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Copyright 2007, The Android Open Source Project
465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**
565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Licensed under the Apache License, Version 2.0 (the "License");
665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** you may not use this file except in compliance with the License.
765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** You may obtain a copy of the License at
865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**
965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**     http://www.apache.org/licenses/LICENSE-2.0
1065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**
1165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Unless required by applicable law or agreed to in writing, software
1265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** distributed under the License is distributed on an "AS IS" BASIS,
1365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** See the License for the specific language governing permissions and
1565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** limitations under the License.
1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian*/
1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "AudioFlinger"
2065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//#define LOG_NDEBUG 0
2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
22da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <dirent.h>
2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <math.h>
2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <signal.h>
2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/time.h>
2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/resource.h>
2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
289ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang#include <binder/IPCThreadState.h>
2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h>
3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h>
31d8e6fd35ec2b59ee7d873daf1f1d9d348221c7bcGlenn Kasten#include <utils/Trace.h>
3265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/Parcel.h>
3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h>
3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/threads.h>
3538ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent#include <utils/Atomic.h>
3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <cutils/bitops.h>
3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/properties.h>
39f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten#include <cutils/compiler.h>
4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//#include <private/media/AudioTrackShared.h>
4281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//#include <private/media/AudioEffectShared.h>
43fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
4464760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h>
457394a4f358fa9908a9f0a7c954b65c399f4268e6Dima Zavin#include <hardware/audio.h>
4665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioMixer.h"
4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioFlinger.h"
4944deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten#include "ServiceUtilities.h"
5065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/EffectsFactoryApi.h>
526d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent#include <audio_effects/effect_visualizer.h>
5359bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent#include <audio_effects/effect_ns.h>
5459bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent#include <audio_effects/effect_aec.h>
5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
563b21c50ef95fe4e7ac3426ca14b365749e66ff08Glenn Kasten#include <audio_utils/primitives.h>
573b21c50ef95fe4e7ac3426ca14b365749e66ff08Glenn Kasten
58feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent#include <powermanager/PowerManager.h>
59190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
604ff14bae91075eb274eb1c2975982358946e7e63John Grossman#include <common_time/cc_helper.h>
6181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//#include <common_time/local_clock.h>
6258912562617941964939a4182cda71eaeb153d4bGlenn Kasten
639e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten#include <media/IMediaLogService.h>
649e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
65da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <media/nbaio/Pipe.h>
66da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <media/nbaio/PipeReader.h>
67da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
6965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
701c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// Note: the following macro is used for extremely verbose logging message.  In
711c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
721c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// 0; but one side effect of this is to turn all LOGV's as well.  Some messages
731c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// are so verbose that we want to suppress them even when we have ALOG_ASSERT
741c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// turned on.  Do not uncomment the #def below unless you really know what you
751c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// are doing and want to see all of the extremely verbose messages.
761c345196edc61694f29307a1826a64a0d26028dcJohn Grossman//#define VERY_VERY_VERBOSE_LOGGING
771c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#ifdef VERY_VERY_VERBOSE_LOGGING
781c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#define ALOGVV ALOGV
791c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#else
801c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#define ALOGVV(a...) do { } while(0)
811c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#endif
82de070137f11d346fba77605bd76a44c040a618fcEric Laurent
8365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
8465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
85ec1d6b5e17281a066d618f7fcd2b63b3ce11f421Glenn Kastenstatic const char kDeadlockedString[] = "AudioFlinger may be deadlocked\n";
86ec1d6b5e17281a066d618f7fcd2b63b3ce11f421Glenn Kastenstatic const char kHardwareLockedString[] = "Hardware lock is taken\n";
8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
894ff14bae91075eb274eb1c2975982358946e7e63John Grossmannsecs_t AudioFlinger::mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
907cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurent
9181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::mScreenState;
923ed292031dc50c56110cdadb1e3778117e3be76aGlenn Kasten
9346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
94da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenbool AudioFlinger::mTeeSinkInputEnabled = false;
95da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenbool AudioFlinger::mTeeSinkOutputEnabled = false;
96da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenbool AudioFlinger::mTeeSinkTrackEnabled = false;
97da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
98da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastensize_t AudioFlinger::mTeeSinkInputFrames = kTeeSinkInputFramesDefault;
99da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastensize_t AudioFlinger::mTeeSinkOutputFrames = kTeeSinkOutputFramesDefault;
100da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastensize_t AudioFlinger::mTeeSinkTrackFrames = kTeeSinkTrackFramesDefault;
10146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
102da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
10365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
10465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurentstatic int load_audio_interface(const char *if_name, audio_hw_device_t **dev)
106799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin{
107f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    const hw_module_t *mod;
108799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    int rc;
109799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
110f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
111f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    ALOGE_IF(rc, "%s couldn't load audio hw module %s.%s (%s)", __func__,
112f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent                 AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
113f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    if (rc) {
114799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        goto out;
115f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    }
116f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    rc = audio_hw_device_open(mod, dev);
117f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    ALOGE_IF(rc, "%s couldn't open audio hw device in %s.%s (%s)", __func__,
118f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent                 AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
119f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    if (rc) {
120799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        goto out;
121f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    }
122f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    if ((*dev)->common.version != AUDIO_DEVICE_API_VERSION_CURRENT) {
123f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
124f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        rc = BAD_VALUE;
125f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        goto out;
126f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    }
127799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return 0;
128799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
129799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavinout:
130799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    *dev = NULL;
131799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return rc;
132799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin}
133799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
13465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
13565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
13665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::AudioFlinger()
13765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    : BnAudioFlinger(),
1384ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mPrimaryHardwareDev(NULL),
1397d6c35bf132a46c0a8a9826491882495fc98bd8cGlenn Kasten      mHardwareStatus(AUDIO_HW_IDLE),
1404ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mMasterVolume(1.0f),
1414ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mMasterMute(false),
1424ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mNextUniqueId(1),
1434ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mMode(AUDIO_MODE_INVALID),
1444ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mBtNrecIsOff(false)
14565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1469e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    char value[PROPERTY_VALUE_MAX];
1479e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    bool doLog = (property_get("ro.test_harness", value, "0") > 0) && (atoi(value) == 1);
1489e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (doLog) {
1499e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters");
1509e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
15146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
152da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    (void) property_get("ro.debuggable", value, "0");
153da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    int debuggable = atoi(value);
154da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    int teeEnabled = 0;
155da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (debuggable) {
156da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        (void) property_get("af.tee", value, "0");
157da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        teeEnabled = atoi(value);
158da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    }
159da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (teeEnabled & 1)
160da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        mTeeSinkInputEnabled = true;
161da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (teeEnabled & 2)
162da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        mTeeSinkOutputEnabled = true;
163da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (teeEnabled & 4)
164da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        mTeeSinkTrackEnabled = true;
16546909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
1665a61d2f277af3098fc10b2881babca16391362daDima Zavin}
1675a61d2f277af3098fc10b2881babca16391362daDima Zavin
1685a61d2f277af3098fc10b2881babca16391362daDima Zavinvoid AudioFlinger::onFirstRef()
1695a61d2f277af3098fc10b2881babca16391362daDima Zavin{
170799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    int rc = 0;
171fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
172935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    Mutex::Autolock _l(mLock);
173935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent
174799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    /* TODO: move all this work into an Init() function */
1754ff14bae91075eb274eb1c2975982358946e7e63John Grossman    char val_str[PROPERTY_VALUE_MAX] = { 0 };
1764ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
1774ff14bae91075eb274eb1c2975982358946e7e63John Grossman        uint32_t int_val;
1784ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (1 == sscanf(val_str, "%u", &int_val)) {
1794ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mStandbyTimeInNsecs = milliseconds(int_val);
1804ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGI("Using %u mSec as standby time.", int_val);
1814ff14bae91075eb274eb1c2975982358946e7e63John Grossman        } else {
1824ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
1834ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGI("Using default %u mSec as standby time.",
1844ff14bae91075eb274eb1c2975982358946e7e63John Grossman                    (uint32_t)(mStandbyTimeInNsecs / 1000000));
1854ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
1864ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
18765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
188a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    mMode = AUDIO_MODE_NORMAL;
18965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
19065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
19165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::~AudioFlinger()
19265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
19365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!mRecordThreads.isEmpty()) {
194c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten        // closeInput_nonvirtual() will remove specified entry from mRecordThreads
195d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten        closeInput_nonvirtual(mRecordThreads.keyAt(0));
19665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
19765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!mPlaybackThreads.isEmpty()) {
198c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten        // closeOutput_nonvirtual() will remove specified entry from mPlaybackThreads
199d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten        closeOutput_nonvirtual(mPlaybackThreads.keyAt(0));
20065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
201799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
2022b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
2032b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten        // no mHardwareLock needed, as there are no other references to this
204a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        audio_hw_device_close(mAudioHwDevs.valueAt(i)->hwDevice());
205a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        delete mAudioHwDevs.valueAt(i);
20665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
20765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
20865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
209a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentstatic const char * const audio_interfaces[] = {
210a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_PRIMARY,
211a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_A2DP,
212a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_USB,
213a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent};
214a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent#define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0])))
215a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
216ee578c0330319f04a48bccbdb26b53fea0388d04John GrossmanAudioFlinger::AudioHwDevice* AudioFlinger::findSuitableHwDev_l(
217ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_module_handle_t module,
218ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_devices_t devices)
219799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin{
220a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    // if module is 0, the request comes from an old policy manager and we should load
221a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    // well known modules
222a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    if (module == 0) {
223a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        ALOGW("findSuitableHwDev_l() loading well know audio hw modules");
224a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) {
225a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            loadHwModule_l(audio_interfaces[i]);
226a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        }
227f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        // then try to find a module supporting the requested device.
228f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
229f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            AudioHwDevice *audioHwDevice = mAudioHwDevs.valueAt(i);
230f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            audio_hw_device_t *dev = audioHwDevice->hwDevice();
231f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            if ((dev->get_supported_devices != NULL) &&
232f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                    (dev->get_supported_devices(dev) & devices) == devices)
233f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                return audioHwDevice;
234f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        }
235a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    } else {
236a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        // check a match for the requested module handle
237ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(module);
238ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (audioHwDevice != NULL) {
239ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            return audioHwDevice;
240a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        }
241a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    }
242a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
243799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return NULL;
244799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin}
24565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
246be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
24765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
24865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
24965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
25065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
25265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("Clients:\n");
25365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mClients.size(); ++i) {
25477c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        sp<Client> client = mClients.valueAt(i).promote();
25577c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        if (client != 0) {
25677c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            snprintf(buffer, SIZE, "  pid: %d\n", client->pid());
25777c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            result.append(buffer);
25865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
25965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
2603a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
2613a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    result.append("Global session refs:\n");
262012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten    result.append(" session pid count\n");
2633a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    for (size_t i = 0; i < mAudioSessionRefs.size(); i++) {
2643a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        AudioSessionRef *r = mAudioSessionRefs[i];
265012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        snprintf(buffer, SIZE, " %7d %3d %3d\n", r->mSessionid, r->mPid, r->mCnt);
2663a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        result.append(buffer);
2673a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
26865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
26965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
27065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
27165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
272be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
27365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
27465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
27665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
277a4454b4765c5905f14186893b0688be375642283Glenn Kasten    hardware_call_state hardwareStatus = mHardwareStatus;
27865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2794ff14bae91075eb274eb1c2975982358946e7e63John Grossman    snprintf(buffer, SIZE, "Hardware status: %d\n"
2804ff14bae91075eb274eb1c2975982358946e7e63John Grossman                           "Standby Time mSec: %u\n",
2814ff14bae91075eb274eb1c2975982358946e7e63John Grossman                            hardwareStatus,
2824ff14bae91075eb274eb1c2975982358946e7e63John Grossman                            (uint32_t)(mStandbyTimeInNsecs / 1000000));
28365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
28465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
28565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
28665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
287be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
28865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
29165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Permission Denial: "
29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "can't dump AudioFlinger from pid=%d, uid=%d\n",
29465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingPid(),
29565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingUid());
29665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
29765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::dumpTryLock(Mutex& mutex)
30165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
3087dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten        usleep(kDumpLockSleepUs);
30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::dump(int fd, const Vector<String16>& args)
31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
31544deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (!dumpAllowed()) {
31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpPermissionDenial(fd, args);
31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // get state of hardware lock
31981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        bool hardwareLocked = dumpTryLock(mHardwareLock);
32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!hardwareLocked) {
32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kHardwareLockedString);
32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
32365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
32465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mHardwareLock.unlock();
32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        bool locked = dumpTryLock(mLock);
32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // failed to lock - AudioFlinger is probably deadlocked
33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kDeadlockedString);
33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpClients(fd, args);
33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpInternals(fd, args);
33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // dump playback threads
33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
34065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mPlaybackThreads.valueAt(i)->dump(fd, args);
34165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // dump record threads
34465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mRecordThreads.size(); i++) {
34565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mRecordThreads.valueAt(i)->dump(fd, args);
34665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
34765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
348799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        // dump all hardware devs
349799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
350a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
351799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            dev->dump(dev, fd);
35265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
353d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
35446909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
355d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        // dump the serially shared record tee sink
356d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        if (mRecordTeeSource != 0) {
357d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            dumpTee(fd, mRecordTeeSource);
358d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        }
35946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
360d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
361d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if (locked) {
362d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            mLock.unlock();
363d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
3649e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
3659e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // append a copy of media.log here by forwarding fd to it, but don't attempt
3669e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // to lookup the service if it's not running, as it will block for a second
3679e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        if (mLogMemoryDealer != 0) {
3689e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten            sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
3699e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten            if (binder != 0) {
3709e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten                fdprintf(fd, "\nmedia.log:\n");
3719e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten                Vector<String16> args;
3729e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten                binder->dump(fd, args);
3739e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten            }
3749e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        }
37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37998ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kastensp<AudioFlinger::Client> AudioFlinger::registerPid_l(pid_t pid)
38098ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten{
38198ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    // If pid is already in the mClients wp<> map, then use that entry
38298ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    // (for which promote() is always != 0), otherwise create a new entry and Client.
38398ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    sp<Client> client = mClients.valueFor(pid).promote();
38498ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    if (client == 0) {
38598ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        client = new Client(this, pid);
38698ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        mClients.add(pid, client);
38798ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    }
38898ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten
38998ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    return client;
39098ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten}
39165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3929e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kastensp<NBLog::Writer> AudioFlinger::newWriter_l(size_t size, const char *name)
3939e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten{
3949e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (mLogMemoryDealer == 0) {
3959e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        return new NBLog::Writer();
3969e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
3979e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<IMemory> shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size));
3989e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<NBLog::Writer> writer = new NBLog::Writer(size, shared);
3999e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
4009e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (binder != 0) {
4019e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        interface_cast<IMediaLogService>(binder)->registerWriter(shared, size, name);
4029e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
4039e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    return writer;
4049e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten}
4059e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
4069e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kastenvoid AudioFlinger::unregisterWriter(const sp<NBLog::Writer>& writer)
4079e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten{
408685ef09bcaf5de6abf2064d552296f70eaec6761Glenn Kasten    if (writer == 0) {
409685ef09bcaf5de6abf2064d552296f70eaec6761Glenn Kasten        return;
410685ef09bcaf5de6abf2064d552296f70eaec6761Glenn Kasten    }
4119e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<IMemory> iMemory(writer->getIMemory());
4129e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (iMemory == 0) {
4139e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        return;
4149e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
4159e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
4169e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (binder != 0) {
4179e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        interface_cast<IMediaLogService>(binder)->unregisterWriter(iMemory);
4189e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // Now the media.log remote reference to IMemory is gone.
4199e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // When our last local reference to IMemory also drops to zero,
4209e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // the IMemory destructor will deallocate the region from mMemoryDealer.
4219e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
4229e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten}
4239e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
42465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// IAudioFlinger interface
42565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
42665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<IAudioTrack> AudioFlinger::createTrack(
428fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten        audio_stream_type_t streamType,
42965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t sampleRate,
43058f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
431254af180475346b6186b49c297f340c9c4817511Glenn Kasten        audio_channel_mask_t channelMask,
432e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten        size_t frameCount,
433e0b07179a48ee50fda931d2aa1b3c751d167e4d7Glenn Kasten        IAudioFlinger::track_flags_t *flags,
43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const sp<IMemory>& sharedBuffer,
43572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output,
4363acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten        pid_t tid,
43765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int *sessionId,
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t *status)
43965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
44065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<PlaybackThread::Track> track;
44165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<TrackHandle> trackHandle;
44265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client;
44365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t lStatus;
44465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int lSessionId;
44565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
446263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    // client AudioTrack::set already implements AUDIO_STREAM_DEFAULT => AUDIO_STREAM_MUSIC,
447263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    // but if someone uses binder directly they could bypass that and cause us to crash
448263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {
44929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("createTrack() invalid stream type %d", streamType);
45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        lStatus = BAD_VALUE;
45165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        goto Exit;
45265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
45365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
45460a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    // client is responsible for conversion of 8-bit PCM to 16-bit PCM,
45560a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    // and we don't yet support 8.24 or 32-bit PCM
45660a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    if (audio_is_linear_pcm(format) && format != AUDIO_FORMAT_PCM_16_BIT) {
45760a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        ALOGE("createTrack() invalid format %d", format);
45860a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        lStatus = BAD_VALUE;
45960a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        goto Exit;
46060a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    }
46160a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten
46265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
46365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
46465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        PlaybackThread *thread = checkPlaybackThread_l(output);
46539e94f8f723d445447fdee0822291e664b631f60Eric Laurent        PlaybackThread *effectThread = NULL;
46665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
467c9b2e20f7c9a71e07ef398152709c76079decbcdGlenn Kasten            ALOGE("no playback thread found for output handle %d", output);
46865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lStatus = BAD_VALUE;
46965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            goto Exit;
47065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
47165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4728d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kasten        pid_t pid = IPCThreadState::self()->getCallingPid();
47398ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        client = registerPid_l(pid);
47465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("createTrack() sessionId: %d", (sessionId == NULL) ? -2 : *sessionId);
476fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) {
477f436fdcf93bd417fd3c9d2a8b19fd221d894b5e3Eric Laurent            // check if an effect chain with the same session ID is present on another
478f436fdcf93bd417fd3c9d2a8b19fd221d894b5e3Eric Laurent            // output thread and move it here.
479de070137f11d346fba77605bd76a44c040a618fcEric Laurent            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
48039e94f8f723d445447fdee0822291e664b631f60Eric Laurent                sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
48139e94f8f723d445447fdee0822291e664b631f60Eric Laurent                if (mPlaybackThreads.keyAt(i) != output) {
48239e94f8f723d445447fdee0822291e664b631f60Eric Laurent                    uint32_t sessions = t->hasAudioSession(*sessionId);
48339e94f8f723d445447fdee0822291e664b631f60Eric Laurent                    if (sessions & PlaybackThread::EFFECT_SESSION) {
48439e94f8f723d445447fdee0822291e664b631f60Eric Laurent                        effectThread = t.get();
485f436fdcf93bd417fd3c9d2a8b19fd221d894b5e3Eric Laurent                        break;
48639e94f8f723d445447fdee0822291e664b631f60Eric Laurent                    }
487de070137f11d346fba77605bd76a44c040a618fcEric Laurent                }
488de070137f11d346fba77605bd76a44c040a618fcEric Laurent            }
48965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lSessionId = *sessionId;
49065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
491de070137f11d346fba77605bd76a44c040a618fcEric Laurent            // if no audio session id is provided, create one here
4927c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            lSessionId = nextUniqueId();
49365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (sessionId != NULL) {
49465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                *sessionId = lSessionId;
49565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
49665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
4973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("createTrack() lSessionId: %d", lSessionId);
49865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
49965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track = thread->createTrack_l(client, streamType, sampleRate, format,
5003acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten                channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, &lStatus);
50139e94f8f723d445447fdee0822291e664b631f60Eric Laurent
50239e94f8f723d445447fdee0822291e664b631f60Eric Laurent        // move effect chain to this output thread if an effect on same session was waiting
50339e94f8f723d445447fdee0822291e664b631f60Eric Laurent        // for a track to be created
50439e94f8f723d445447fdee0822291e664b631f60Eric Laurent        if (lStatus == NO_ERROR && effectThread != NULL) {
50539e94f8f723d445447fdee0822291e664b631f60Eric Laurent            Mutex::Autolock _dl(thread->mLock);
50639e94f8f723d445447fdee0822291e664b631f60Eric Laurent            Mutex::Autolock _sl(effectThread->mLock);
50739e94f8f723d445447fdee0822291e664b631f60Eric Laurent            moveEffectChain_l(lSessionId, effectThread, thread, true);
50839e94f8f723d445447fdee0822291e664b631f60Eric Laurent        }
509a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
510a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        // Look for sync events awaiting for a session to be used.
511a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        for (int i = 0; i < (int)mPendingSyncEvents.size(); i++) {
512a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            if (mPendingSyncEvents[i]->triggerSession() == lSessionId) {
513a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                if (thread->isValidSyncEvent(mPendingSyncEvents[i])) {
5142986460984580833161bdaabc7f17da1005a8961Eric Laurent                    if (lStatus == NO_ERROR) {
515d23eedca9b5a1812891c05d89850ab7ee707040dGlenn Kasten                        (void) track->setSyncEvent(mPendingSyncEvents[i]);
5162986460984580833161bdaabc7f17da1005a8961Eric Laurent                    } else {
5172986460984580833161bdaabc7f17da1005a8961Eric Laurent                        mPendingSyncEvents[i]->cancel();
5182986460984580833161bdaabc7f17da1005a8961Eric Laurent                    }
519a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    mPendingSyncEvents.removeAt(i);
520a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    i--;
521a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                }
522a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            }
523a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
52465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
52565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (lStatus == NO_ERROR) {
52665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        trackHandle = new TrackHandle(track);
52765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
52865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // remove local strong reference to Client before deleting the Track so that the Client
52965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // destructor is called by the TrackBase destructor with mLock held
53065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client.clear();
53165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track.clear();
53265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
53365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
53465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianExit:
535e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (status != NULL) {
53665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        *status = lStatus;
53765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
53865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return trackHandle;
53965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
54065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
54172ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenuint32_t AudioFlinger::sampleRate(audio_io_handle_t output) const
54265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
54365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
54465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
54565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
5465ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("sampleRate() unknown thread %d", output);
54765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
54865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
54965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->sampleRate();
55065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
55165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
55272ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenint AudioFlinger::channelCount(audio_io_handle_t output) const
55365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
55465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
55565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
55665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
5575ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("channelCount() unknown thread %d", output);
55865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
55965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
56065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->channelCount();
56165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
56265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
56372ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenaudio_format_t AudioFlinger::format(audio_io_handle_t output) const
56465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
56565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
56665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
56765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
5685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("format() unknown thread %d", output);
56958f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        return AUDIO_FORMAT_INVALID;
57065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
57165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->format();
57265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
57365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
57472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastensize_t AudioFlinger::frameCount(audio_io_handle_t output) const
57565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
57665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
57765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
57865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
5795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("frameCount() unknown thread %d", output);
58065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
58165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
58258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // FIXME currently returns the normal mixer's frame count to avoid confusing legacy callers;
58358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    //       should examine all callers and fix them to handle smaller counts
58465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->frameCount();
58565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
58665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
58772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenuint32_t AudioFlinger::latency(audio_io_handle_t output) const
58865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
58965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
59065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
59165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
592c9b2e20f7c9a71e07ef398152709c76079decbcdGlenn Kasten        ALOGW("latency(): no playback thread found for output handle %d", output);
59365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
59465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
59565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->latency();
59665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
59765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
59865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setMasterVolume(float value)
59965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
600a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
601a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
602a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
603a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
604a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
60565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
60665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
60765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
60865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
60965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
610a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    Mutex::Autolock _l(mLock);
611ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    mMasterVolume = value;
612a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
613ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Set master volume in the HALs which support it.
614ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
615ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AutoMutex lock(mHardwareLock);
616ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
6174ff14bae91075eb274eb1c2975982358946e7e63John Grossman
618ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
619ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (dev->canSetMasterVolume()) {
620ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            dev->hwDevice()->set_master_volume(dev->hwDevice(), value);
621935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent        }
622ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_IDLE;
62365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
62465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
625ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Now set the master volume in each playback thread.  Playback threads
626ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // assigned to HALs which do not have master volume support will apply
627ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // master volume during the mix operation.  Threads with HALs which do
628ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // support master volume will simply ignore the setting.
6298d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i < mPlaybackThreads.size(); i++)
630ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mPlaybackThreads.valueAt(i)->setMasterVolume(value);
63165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
63265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
63365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
63465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
635f78aee70d15daf4690de7e7b4983ee68b0d1381dGlenn Kastenstatus_t AudioFlinger::setMode(audio_mode_t mode)
63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
637a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
638a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
639a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
640a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
64165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
64265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
64365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
64465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
64565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
646930f4caa1e311ef7ff538c421a324396157eb24fGlenn Kasten    if (uint32_t(mode) >= AUDIO_MODE_CNT) {
6475ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Illegal value: setMode(%d)", mode);
64865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
64965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
65065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
65165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    { // scope for the lock
65265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        AutoMutex lock(mHardwareLock);
653ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
65465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mHardwareStatus = AUDIO_HW_SET_MODE;
655ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        ret = dev->set_mode(dev, mode);
65665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mHardwareStatus = AUDIO_HW_IDLE;
65765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
65865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
65965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (NO_ERROR == ret) {
66065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
66165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mMode = mode;
6628d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        for (size_t i = 0; i < mPlaybackThreads.size(); i++)
663e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            mPlaybackThreads.valueAt(i)->setMode(mode);
66465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
66565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ret;
66765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
66865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setMicMute(bool state)
67065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
671a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
672a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
673a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
674a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
675a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
67665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
67765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
67865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
67965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
68065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
68165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mHardwareLock);
682ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
684ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    ret = dev->set_mic_mute(dev, state);
68565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_IDLE;
68665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ret;
68765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
68865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
68965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::getMicMute() const
69065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
691a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
692a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
693a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return false;
694a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
695a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
696fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    bool state = AUDIO_MODE_INVALID;
6972b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    AutoMutex lock(mHardwareLock);
698ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
69965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
700ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    dev->get_mic_mute(dev, &state);
70165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_IDLE;
70265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return state;
70365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
70465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
70565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setMasterMute(bool muted)
70665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
707d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    status_t ret = initCheck();
708d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    if (ret != NO_ERROR) {
709d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman        return ret;
710d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    }
711d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
71265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
71365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
71465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
71565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
71665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
717ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    Mutex::Autolock _l(mLock);
718ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    mMasterMute = muted;
719d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
720ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Set master mute in the HALs which support it.
721ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
722ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AutoMutex lock(mHardwareLock);
723ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
724d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
725ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
726ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (dev->canSetMasterMute()) {
727ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            dev->hwDevice()->set_master_mute(dev->hwDevice(), muted);
728d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman        }
729ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_IDLE;
730d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    }
731d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
732ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Now set the master mute in each playback thread.  Playback threads
733ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // assigned to HALs which do not have master mute support will apply master
734ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // mute during the mix operation.  Threads with HALs which do support master
735ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // mute will simply ignore the setting.
7368d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i < mPlaybackThreads.size(); i++)
737ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mPlaybackThreads.valueAt(i)->setMasterMute(muted);
73865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
73965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
74065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
74165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
74265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianfloat AudioFlinger::masterVolume() const
74365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
7449806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    Mutex::Autolock _l(mLock);
7459806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    return masterVolume_l();
74665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
74765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
74865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::masterMute() const
74965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
7509806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    Mutex::Autolock _l(mLock);
7519806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    return masterMute_l();
75265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
75365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7544ff14bae91075eb274eb1c2975982358946e7e63John Grossmanfloat AudioFlinger::masterVolume_l() const
7554ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
7564ff14bae91075eb274eb1c2975982358946e7e63John Grossman    return mMasterVolume;
7574ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
7584ff14bae91075eb274eb1c2975982358946e7e63John Grossman
759d8f178d613821c3f61a5c5e391eb275339e526a9John Grossmanbool AudioFlinger::masterMute_l() const
760d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman{
761ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    return mMasterMute;
762d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman}
763d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
76472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
76572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output)
76665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
76765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
76865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
76965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
77065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
77165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
772263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
77329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setStreamVolume() invalid stream %d", stream);
77465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
77565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
77665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
77765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mLock);
77865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = NULL;
77965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (output) {
78065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread = checkPlaybackThread_l(output);
78165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
78265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return BAD_VALUE;
78365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
78465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
78565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
78665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStreamTypes[stream].volume = value;
78765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
78865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
7898d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
790e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value);
79165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
79265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
79365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread->setStreamVolume(stream, value);
79465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
79565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
79765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
79865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
799fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatus_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)
80065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
80165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
80265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
80365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
80465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
80565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
806263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT ||
807fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) {
80829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setStreamMute() invalid stream %d", stream);
80965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
81065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
81165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
812935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    AutoMutex lock(mLock);
81365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStreamTypes[stream].mute = muted;
81465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
815e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
81665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
81865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
81965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
82072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenfloat AudioFlinger::streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const
82165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
822263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
82365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0.0f;
82465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
82565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
82665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mLock);
82765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    float volume;
82865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (output) {
82965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        PlaybackThread *thread = checkPlaybackThread_l(output);
83065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
83165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return 0.0f;
83265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
83365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        volume = thread->streamVolume(stream);
83465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
8356637baae4244aec731c4014da72418d330636ae1Glenn Kasten        volume = streamVolume_l(stream);
83665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
83765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
83865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return volume;
83965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
84065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
841fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenbool AudioFlinger::streamMute(audio_stream_type_t stream) const
84265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
843263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
84465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return true;
84565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
84665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8476637baae4244aec731c4014da72418d330636ae1Glenn Kasten    AutoMutex lock(mLock);
8486637baae4244aec731c4014da72418d330636ae1Glenn Kasten    return streamMute_l(stream);
84965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
85065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
85172ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
85265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
853827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten    ALOGV("setParameters(): io %d, keyvalue %s, calling pid %d",
854827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten            ioHandle, keyValuePairs.string(), IPCThreadState::self()->getCallingPid());
85581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
85665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
85765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
85865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
85965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
86065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
86165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // ioHandle == 0 means the parameters are global to the audio hardware interface
86265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (ioHandle == 0) {
863a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        Mutex::Autolock _l(mLock);
864799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        status_t final_result = NO_ERROR;
8658abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten        {
866a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            AutoMutex lock(mHardwareLock);
867a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            mHardwareStatus = AUDIO_HW_SET_PARAMETER;
868a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
869a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
870a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                status_t result = dev->set_parameters(dev, keyValuePairs.string());
871a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                final_result = result ?: final_result;
872a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            }
873a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            mHardwareStatus = AUDIO_HW_IDLE;
8748abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten        }
87559bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
87659bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        AudioParameter param = AudioParameter(keyValuePairs);
87759bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        String8 value;
87859bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        if (param.get(String8(AUDIO_PARAMETER_KEY_BT_NREC), value) == NO_ERROR) {
879bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent            bool btNrecIsOff = (value == AUDIO_PARAMETER_VALUE_OFF);
880bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent            if (mBtNrecIsOff != btNrecIsOff) {
88159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                for (size_t i = 0; i < mRecordThreads.size(); i++) {
88259bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                    sp<RecordThread> thread = mRecordThreads.valueAt(i);
883f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                    audio_devices_t device = thread->inDevice();
884510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    bool suspend = audio_is_bluetooth_sco_device(device) && btNrecIsOff;
885510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    // collect all of the thread's session IDs
886510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    KeyedVector<int, bool> ids = thread->sessionIds();
887510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    // suspend effects associated with those session IDs
888510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    for (size_t j = 0; j < ids.size(); ++j) {
889510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                        int sessionId = ids.keyAt(j);
89059bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                        thread->setEffectSuspended(FX_IID_AEC,
89159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                                                   suspend,
892510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                                                   sessionId);
89359bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                        thread->setEffectSuspended(FX_IID_NS,
89459bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                                                   suspend,
895510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                                                   sessionId);
89659bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                    }
89759bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                }
898bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent                mBtNrecIsOff = btNrecIsOff;
89959bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent            }
90059bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        }
90128ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        String8 screenState;
90228ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        if (param.get(String8(AudioParameter::keyScreenState), screenState) == NO_ERROR) {
90328ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten            bool isOff = screenState == "off";
90481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (isOff != (AudioFlinger::mScreenState & 1)) {
90581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                AudioFlinger::mScreenState = ((AudioFlinger::mScreenState & ~1) + 2) | isOff;
90628ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten            }
90728ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        }
908799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        return final_result;
90965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
91065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
91165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // hold a strong ref on thread in case closeOutput() or closeInput() is called
91265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // and the thread is exited once the lock is released
91365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ThreadBase> thread;
91465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
91565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
91665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread = checkPlaybackThread_l(ioHandle);
917d5903ec1332630f2992a6f0d5ca69d13a185c665Glenn Kasten        if (thread == 0) {
91865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            thread = checkRecordThread_l(ioHandle);
9197fc9a6fdf146ded90b51c52f4a05d797294dcb85Glenn Kasten        } else if (thread == primaryPlaybackThread_l()) {
9207c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            // indicate output device change to all input threads for pre processing
9217c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            AudioParameter param = AudioParameter(keyValuePairs);
9227c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            int value;
92389d94e79dad032fb18ddc655e6068e4231d3f0aaEric Laurent            if ((param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) &&
92489d94e79dad032fb18ddc655e6068e4231d3f0aaEric Laurent                    (value != 0)) {
9257c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                for (size_t i = 0; i < mRecordThreads.size(); i++) {
9267c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                    mRecordThreads.valueAt(i)->setParameters(keyValuePairs);
9277c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                }
9287c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            }
92965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
93065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
9317378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten    if (thread != 0) {
9327378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten        return thread->setParameters(keyValuePairs);
93365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
93465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BAD_VALUE;
93565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
93665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
93772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn KastenString8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& keys) const
93865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
939827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten    ALOGVV("getParameters() io %d, keys %s, calling pid %d",
940827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten            ioHandle, keys.string(), IPCThreadState::self()->getCallingPid());
94165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
942a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    Mutex::Autolock _l(mLock);
943a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
94465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (ioHandle == 0) {
945fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        String8 out_s8;
946fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
947799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
9488abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            char *s;
9498abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            {
9508abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            AutoMutex lock(mHardwareLock);
9518abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            mHardwareStatus = AUDIO_HW_GET_PARAMETER;
952a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
9538abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            s = dev->get_parameters(dev, keys.string());
9548abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            mHardwareStatus = AUDIO_HW_IDLE;
9558abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            }
956ef7740be67a4d7b6b033ebed59c3d4a9c74a2c18John Grossman            out_s8 += String8(s ? s : "");
957799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            free(s);
958799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        }
959fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return out_s8;
96065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
96165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
96265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *playbackThread = checkPlaybackThread_l(ioHandle);
96365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (playbackThread != NULL) {
96465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return playbackThread->getParameters(keys);
96565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
96665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    RecordThread *recordThread = checkRecordThread_l(ioHandle);
96765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (recordThread != NULL) {
96865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return recordThread->getParameters(keys);
96965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
97065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return String8("");
97165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
97265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
973dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kastensize_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format,
974dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten        audio_channel_mask_t channelMask) const
97565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
976a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
977a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
978a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return 0;
979a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
980a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
9812b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    AutoMutex lock(mHardwareLock);
9822b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
983f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    struct audio_config config = {
984f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        sample_rate: sampleRate,
985dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten        channel_mask: channelMask,
986f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        format: format,
987f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    };
988ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
989ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    size_t size = dev->get_input_buffer_size(dev, &config);
9902b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    mHardwareStatus = AUDIO_HW_IDLE;
9912b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    return size;
99265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
99365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
99472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenunsigned int AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const
99565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
99665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
99765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
99865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    RecordThread *recordThread = checkRecordThread_l(ioHandle);
99965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (recordThread != NULL) {
100065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return recordThread->getInputFramesLost();
100165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
100265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return 0;
100365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
100465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
100565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setVoiceVolume(float value)
100665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1007a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
1008a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
1009a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
1010a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
1011a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
101265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
101365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
101465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
101565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
101665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
101765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mHardwareLock);
1018ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
10198abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten    mHardwareStatus = AUDIO_HW_SET_VOICE_VOLUME;
1020ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    ret = dev->set_voice_volume(dev, value);
102165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_IDLE;
102265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ret;
102465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
102565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102626c77556efc30800466b60b3975bc35a70c8c28bGlenn Kastenstatus_t AudioFlinger::getRenderPosition(size_t *halFrames, size_t *dspFrames,
102772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output) const
102865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
102965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status;
103065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
103265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *playbackThread = checkPlaybackThread_l(output);
103465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (playbackThread != NULL) {
103565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return playbackThread->getRenderPosition(halFrames, dspFrames);
103665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
103765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BAD_VALUE;
103965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
104065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
104165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
104265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
104365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
104465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
104565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1046bb001926447d0b7dc71ca8bb3c9856f3136d8f4cGlenn Kasten    pid_t pid = IPCThreadState::self()->getCallingPid();
104765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mNotificationClients.indexOfKey(pid) < 0) {
104865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<NotificationClient> notificationClient = new NotificationClient(this,
104965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                                                            client,
105065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                                                            pid);
10513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("registerClient() client %p, pid %d", notificationClient.get(), pid);
105265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mNotificationClients.add(pid, notificationClient);
105465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<IBinder> binder = client->asBinder();
105665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        binder->linkToDeath(notificationClient);
105765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // the config change is always sent from playback or record threads to avoid deadlock
105965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // with AudioSystem::gLock
106065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
1061896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AudioSystem::OUTPUT_OPENED);
106265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
106365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
106465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mRecordThreads.size(); i++) {
1065896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            mRecordThreads.valueAt(i)->sendIoConfigEvent(AudioSystem::INPUT_OPENED);
106665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
106765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
106865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
106965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
107065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::removeNotificationClient(pid_t pid)
107165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
107265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
107365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1074a3b09254d44cd8d66ec947abe547538c4cfeaa89Glenn Kasten    mNotificationClients.removeItem(pid);
10753a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
10763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("%d died, releasing its sessions", pid);
10778d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    size_t num = mAudioSessionRefs.size();
10783a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    bool removed = false;
10798d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i< num; ) {
10803a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
1081012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        ALOGV(" pid %d @ %d", ref->mPid, i);
1082012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        if (ref->mPid == pid) {
1083012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten            ALOGV(" removing entry for pid %d session %d", pid, ref->mSessionid);
10843a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            mAudioSessionRefs.removeAt(i);
10853a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            delete ref;
10863a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            removed = true;
10873a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            num--;
10888d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        } else {
10898d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten            i++;
10903a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        }
10913a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
10923a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    if (removed) {
10933a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        purgeStaleEffects_l();
10943a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
109565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
109665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
109765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// audioConfigChanged_l() must be called with AudioFlinger::mLock held
1098b81cc8c6f3eec9edb255ea99b6a6f243585b1e38Glenn Kastenvoid AudioFlinger::audioConfigChanged_l(int event, audio_io_handle_t ioHandle, const void *param2)
109965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
110065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mNotificationClients.size();
110165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < size; i++) {
110284afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioHandle,
110384afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten                                                                               param2);
110465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
110565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
110665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
110765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// removeClient_l() must be called with AudioFlinger::mLock held
110865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::removeClient_l(pid_t pid)
110965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1110827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten    ALOGV("removeClient_l() pid %d, calling pid %d", pid,
111185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            IPCThreadState::self()->getCallingPid());
111265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClients.removeItem(pid);
111365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
111465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1115717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent// getEffectThread_l() must be called with AudioFlinger::mLock held
1116717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurentsp<AudioFlinger::PlaybackThread> AudioFlinger::getEffectThread_l(int sessionId, int EffectId)
1117717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent{
1118717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    sp<PlaybackThread> thread;
1119717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
1120717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
1121717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent        if (mPlaybackThreads.valueAt(i)->getEffect(sessionId, EffectId) != 0) {
1122717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            ALOG_ASSERT(thread == 0);
1123717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            thread = mPlaybackThreads.valueAt(i);
1124717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent        }
1125717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    }
1126717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
1127717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    return thread;
1128717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent}
112965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
113081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
113181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
113265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
113365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
113481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
113581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    :   RefBase(),
113681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mAudioFlinger(audioFlinger),
113781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // FIXME should be a "k" constant not hard-coded, in .h or ro. property, see 4 lines below
113881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mMemoryDealer(new MemoryDealer(1024*1024, "AudioFlinger::Client")),
113981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPid(pid),
114081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mTimedTrackCount(0)
114165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
114281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
114365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
114465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
114581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Client destructor must be called with AudioFlinger::mLock held
114681784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::Client::~Client()
114765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
114881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAudioFlinger->removeClient_l(mPid);
114965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
115065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<MemoryDealer> AudioFlinger::Client::heap() const
115265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
115381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mMemoryDealer;
115465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
115565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Reserve one of the limited slots for a timed audio track associated
115781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// with this client
115881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::Client::reserveTimedTrack()
115965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
116081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    const int kMaxTimedTracksPerClient = 4;
116165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
116281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mTimedTrackLock);
116365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
116481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mTimedTrackCount >= kMaxTimedTracksPerClient) {
116581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("can not create timed track - pid %d has exceeded the limit",
116681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent             mPid);
116781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return false;
116865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
116965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
117081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTimedTrackCount++;
117181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return true;
117265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
117365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
117481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Release a slot for a timed audio track
117581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::Client::releaseTimedTrack()
117665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
117781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mTimedTrackLock);
117881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTimedTrackCount--;
1179896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent}
1180896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent
118181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
118281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
118381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger,
118481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                     const sp<IAudioFlingerClient>& client,
118581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                     pid_t pid)
118681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    : mAudioFlinger(audioFlinger), mPid(pid), mAudioFlingerClient(client)
1187896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent{
118865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
118965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
119081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::NotificationClient::~NotificationClient()
119165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
119265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
119365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
119481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who)
119565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
119681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<NotificationClient> keep(this);
119781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAudioFlinger->removeNotificationClient(mPid);
119881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
119965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
120065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
120181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
120265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
120381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<IAudioRecord> AudioFlinger::openRecord(
120481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_io_handle_t input,
120581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        uint32_t sampleRate,
120681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_format_t format,
120781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_channel_mask_t channelMask,
120881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        size_t frameCount,
120981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        IAudioFlinger::track_flags_t flags,
121081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        pid_t tid,
121181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int *sessionId,
121281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status_t *status)
12131d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent{
121481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<RecordThread::RecordTrack> recordTrack;
121581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<RecordHandle> recordHandle;
121681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<Client> client;
121781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t lStatus;
121881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    RecordThread *thread;
121981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t inFrameCount;
122081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    int lSessionId;
12211d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
122281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // check calling permissions
122381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!recordingAllowed()) {
122481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        lStatus = PERMISSION_DENIED;
122581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
122681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
12271d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
122881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // add client to list
122981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    { // scope for mLock
123081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(mLock);
123181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread = checkRecordThread_l(input);
123281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread == NULL) {
123381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = BAD_VALUE;
123481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            goto Exit;
12351d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        }
12361d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
12378d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kasten        pid_t pid = IPCThreadState::self()->getCallingPid();
123881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        client = registerPid_l(pid);
1239feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
124081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // If no audio session id is provided, create one here
124181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) {
124281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lSessionId = *sessionId;
1243feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        } else {
124481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lSessionId = nextUniqueId();
124581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (sessionId != NULL) {
124681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                *sessionId = lSessionId;
124781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
1248feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
124981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // create new record track.
125081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // The record track uses one track in mHardwareMixerThread by convention.
125181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        recordTrack = thread->createRecordTrack_l(client, sampleRate, format, channelMask,
125281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                  frameCount, lSessionId, flags, tid, &lStatus);
1253feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
125481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (lStatus != NO_ERROR) {
125581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // remove local strong reference to Client before deleting the RecordTrack so that the
125681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Client destructor is called by the TrackBase destructor with mLock held
125781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        client.clear();
125881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        recordTrack.clear();
125981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
1260feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
1261feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
126281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // return to handle to client
126381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    recordHandle = new RecordHandle(recordTrack);
126481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    lStatus = NO_ERROR;
1265feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
126681784c37c61b09289654b979567a42bf73cd2b12Eric LaurentExit:
126781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status) {
126881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        *status = lStatus;
1269feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
127081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return recordHandle;
1271feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
1272feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1273feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
12741d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
127581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
127681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
127781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_module_handle_t AudioFlinger::loadHwModule(const char *name)
127859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
127981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!settingsAllowed()) {
128081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
128181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
128259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    Mutex::Autolock _l(mLock);
128381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return loadHwModule_l(name);
128459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
128559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
128681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// loadHwModule_l() must be called with AudioFlinger::mLock held
128781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
128859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
128981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
129081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
129181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGW("loadHwModule() module %s already loaded", name);
129281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return mAudioHwDevs.keyAt(i);
129359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
129459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
129559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
129681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_hw_device_t *dev;
129759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
129881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    int rc = load_audio_interface(name, &dev);
129981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (rc) {
130081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGI("loadHwModule() error %d loading module %s ", rc, name);
130181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
130259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
130359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
130481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mHardwareStatus = AUDIO_HW_INIT;
130581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    rc = dev->init_check(dev);
130681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mHardwareStatus = AUDIO_HW_IDLE;
130781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (rc) {
130881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGI("loadHwModule() init check error %d for module %s ", rc, name);
130981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
131059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
131159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
131281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // Check and cache this HAL's level of support for master mute and master
131381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // volume.  If this is the first HAL opened, and it supports the get
131481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // methods, use the initial values provided by the HAL as the current
131581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // master mute and volume settings.
131659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
131781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioHwDevice::Flags flags = static_cast<AudioHwDevice::Flags>(0);
131881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {  // scope for auto-lock pattern
131981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AutoMutex lock(mHardwareLock);
132059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
132181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (0 == mAudioHwDevs.size()) {
132281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
132381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (NULL != dev->get_master_volume) {
132481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                float mv;
132581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (OK == dev->get_master_volume(dev, &mv)) {
132681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    mMasterVolume = mv;
132781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                }
132881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
132981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
133081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
133181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (NULL != dev->get_master_mute) {
133281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                bool mm;
133381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (OK == dev->get_master_mute(dev, &mm)) {
133481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    mMasterMute = mm;
133581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                }
133681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
133759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
133881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
133981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
134081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((NULL != dev->set_master_volume) &&
134181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (OK == dev->set_master_volume(dev, mMasterVolume))) {
134281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            flags = static_cast<AudioHwDevice::Flags>(flags |
134381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
134459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
134559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
134681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
134781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((NULL != dev->set_master_mute) &&
134881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (OK == dev->set_master_mute(dev, mMasterMute))) {
134981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            flags = static_cast<AudioHwDevice::Flags>(flags |
135081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
135181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
135259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
135381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mHardwareStatus = AUDIO_HW_IDLE;
135459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
135559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
135681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_module_handle_t handle = nextUniqueId();
135781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAudioHwDevs.add(handle, new AudioHwDevice(name, dev, flags));
135881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
135981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGI("loadHwModule() Loaded %s audio interface from %s (%s) handle %d",
136081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent          name, dev->common.module->name, dev->common.module->id, handle);
136181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
136281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return handle;
136381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
136459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
136559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
136681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
136781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
136881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::getPrimaryOutputSamplingRate()
136959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
137059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    Mutex::Autolock _l(mLock);
137181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = primaryPlaybackThread_l();
137281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return thread != NULL ? thread->sampleRate() : 0;
1373a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent}
137459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
137581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsize_t AudioFlinger::getPrimaryOutputFrameCount()
1376a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent{
137781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
137881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = primaryPlaybackThread_l();
137981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return thread != NULL ? thread->frameCountHAL() : 0;
138059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
138159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
138265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
138365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
138481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
138581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           audio_devices_t *pDevices,
138681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           uint32_t *pSamplingRate,
138781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           audio_format_t *pFormat,
138881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           audio_channel_mask_t *pChannelMask,
138981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           uint32_t *pLatencyMs,
139081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           audio_output_flags_t flags)
139165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
139281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status;
139381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = NULL;
139481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    struct audio_config config = {
139581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sample_rate: pSamplingRate ? *pSamplingRate : 0,
139681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        channel_mask: pChannelMask ? *pChannelMask : 0,
139781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        format: pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT,
139881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    };
139981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_stream_out_t *outStream = NULL;
140081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioHwDevice *outHwDev;
1401ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
140281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %d, Channels %x, flags %x",
140381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              module,
140481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              (pDevices != NULL) ? *pDevices : 0,
140581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              config.sample_rate,
140681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              config.format,
140781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              config.channel_mask,
140881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              flags);
140981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
141081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (pDevices == NULL || *pDevices == 0) {
141181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
1412ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    }
1413ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
141481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
141565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
141681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    outHwDev = findSuitableHwDev_l(module, *pDevices);
141781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (outHwDev == NULL)
141881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
141965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
142081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_hw_device_t *hwDevHal = outHwDev->hwDevice();
142181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_io_handle_t id = nextUniqueId();
142265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
142381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
142465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
142581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status = hwDevHal->open_output_stream(hwDevHal,
142681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          id,
142781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          *pDevices,
142881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          (audio_output_flags_t)flags,
142981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          &config,
143081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          &outStream);
143165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
143281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mHardwareStatus = AUDIO_HW_IDLE;
143381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, "
143481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            "Channels %x, status %d",
143581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            outStream,
143681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.sample_rate,
143781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.format,
143881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.channel_mask,
143981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            status);
144058912562617941964939a4182cda71eaeb153d4bGlenn Kasten
144181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status == NO_ERROR && outStream != NULL) {
144281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream);
144365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
144481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) ||
144581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (config.format != AUDIO_FORMAT_PCM_16_BIT) ||
144681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (config.channel_mask != AUDIO_CHANNEL_OUT_STEREO)) {
144781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            thread = new DirectOutputThread(this, output, id, *pDevices);
144881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("openOutput() created direct output: ID %d thread %p", id, thread);
144981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
145081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            thread = new MixerThread(this, output, id, *pDevices);
145181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("openOutput() created mixer output: ID %d thread %p", id, thread);
145265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
145381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPlaybackThreads.add(id, thread);
145488cbea8a918bbaf5e06e48aadd5af5e81d58d232Glenn Kasten
145581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pSamplingRate != NULL) *pSamplingRate = config.sample_rate;
145681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pFormat != NULL) *pFormat = config.format;
145781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pChannelMask != NULL) *pChannelMask = config.channel_mask;
145881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pLatencyMs != NULL) *pLatencyMs = thread->latency();
145965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
146081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // notify client processes of the new output creation
146181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);
146265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
146381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // the first primary output opened designates the primary hw device
146481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((mPrimaryHardwareDev == NULL) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
146581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGI("Using module %d has the primary audio interface", module);
146681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mPrimaryHardwareDev = outHwDev;
146781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
146881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AutoMutex lock(mHardwareLock);
146981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mHardwareStatus = AUDIO_HW_SET_MODE;
147081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            hwDevHal->set_mode(hwDevHal, mMode);
147181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mHardwareStatus = AUDIO_HW_IDLE;
147281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
147381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return id;
147481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
147565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
147681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return 0;
147765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
147865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
147981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1,
148081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_io_handle_t output2)
148165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
148281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
148381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    MixerThread *thread1 = checkMixerThread_l(output1);
148481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    MixerThread *thread2 = checkMixerThread_l(output2);
148581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
148681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread1 == NULL || thread2 == NULL) {
148781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("openDuplicateOutput() wrong output mixer type for output %d or %d", output1,
148881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                output2);
148981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
149065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
149165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
149281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_io_handle_t id = nextUniqueId();
149381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    DuplicatingThread *thread = new DuplicatingThread(this, thread1, id);
149481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->addOutputTrack(thread2);
149581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mPlaybackThreads.add(id, thread);
149681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // notify client processes of the new output creation
149781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);
149881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return id;
149965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
150065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
150181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::closeOutput(audio_io_handle_t output)
15022bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi{
150381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return closeOutput_nonvirtual(output);
15042bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi}
15052bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi
150681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output)
150765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
150881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // keep strong reference on the playback thread so that
150981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // it is not destroyed while exit() is executed
151081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<PlaybackThread> thread;
151181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
151281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(mLock);
151381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread = checkPlaybackThread_l(output);
151481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread == NULL) {
151581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return BAD_VALUE;
151665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
151765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
151881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("closeOutput() %d", output);
1519de070137f11d346fba77605bd76a44c040a618fcEric Laurent
152081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread->type() == ThreadBase::MIXER) {
152181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
152281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (mPlaybackThreads.valueAt(i)->type() == ThreadBase::DUPLICATING) {
152381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    DuplicatingThread *dupThread =
152481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                            (DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
152581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    dupThread->removeOutputTrack((MixerThread *)thread.get());
1526de070137f11d346fba77605bd76a44c040a618fcEric Laurent                }
1527de070137f11d346fba77605bd76a44c040a618fcEric Laurent            }
1528de070137f11d346fba77605bd76a44c040a618fcEric Laurent        }
152981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, NULL);
153081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPlaybackThreads.removeItem(output);
15313acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    }
153281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->exit();
153381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // The thread entity (active unit of execution) is no longer running here,
153481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // but the ThreadBase container still exists.
15353acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten
153681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread->type() != ThreadBase::DUPLICATING) {
153781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioStreamOut *out = thread->clearOutput();
153881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOG_ASSERT(out != NULL, "out shouldn't be NULL");
153981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // from now on thread->mOutput is NULL
154081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        out->hwDev()->close_output_stream(out->hwDev(), out->stream);
154181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        delete out;
154265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
154381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
154465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
154565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
154681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::suspendOutput(audio_io_handle_t output)
1547e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent{
154881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
154981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = checkPlaybackThread_l(output);
155081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
155181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread == NULL) {
155281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
1553e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent    }
1554e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent
155581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("suspendOutput() %d", output);
155681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->suspend();
1557e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent
155881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
155965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
156065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
156181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::restoreOutput(audio_io_handle_t output)
156265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
15636637baae4244aec731c4014da72418d330636ae1Glenn Kasten    Mutex::Autolock _l(mLock);
156481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = checkPlaybackThread_l(output);
156565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
156681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread == NULL) {
156781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
1568ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    }
156965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
157081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("restoreOutput() %d", output);
157165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
157281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->restore();
157365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
157481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
157565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
157665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
157781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,
157881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          audio_devices_t *pDevices,
157981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          uint32_t *pSamplingRate,
158081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          audio_format_t *pFormat,
158181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          audio_channel_mask_t *pChannelMask)
158265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
158381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status;
158481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    RecordThread *thread = NULL;
158581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    struct audio_config config = {
158681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sample_rate: pSamplingRate ? *pSamplingRate : 0,
158781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        channel_mask: pChannelMask ? *pChannelMask : 0,
158881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        format: pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT,
158981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    };
159081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t reqSamplingRate = config.sample_rate;
159181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_format_t reqFormat = config.format;
159281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_channel_mask_t reqChannels = config.channel_mask;
159381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_stream_in_t *inStream = NULL;
159481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioHwDevice *inHwDev;
159565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
159681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (pDevices == NULL || *pDevices == 0) {
159781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
1598b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    }
1599b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent
160081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
160165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
160281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    inHwDev = findSuitableHwDev_l(module, *pDevices);
160381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (inHwDev == NULL)
160481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
1605fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
160681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_hw_device_t *inHwHal = inHwDev->hwDevice();
160781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_io_handle_t id = nextUniqueId();
1608b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
160981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config,
161081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        &inStream);
161181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, "
161281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            "status %d",
161381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            inStream,
161481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.sample_rate,
161581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.format,
161681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.channel_mask,
161781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            status);
161865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
161981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // If the input could not be opened with the requested parameters and we can handle the
162081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // conversion internally, try to open again with the proposed parameters. The AudioFlinger can
162181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // resample the input and do mono to stereo or stereo to mono conversions on 16 bit PCM inputs.
162281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status == BAD_VALUE &&
162381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        reqFormat == config.format && config.format == AUDIO_FORMAT_PCM_16_BIT &&
162481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        (config.sample_rate <= 2 * reqSamplingRate) &&
162581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        (popcount(config.channel_mask) <= FCC_2) && (popcount(reqChannels) <= FCC_2)) {
162681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("openInput() reopening with proposed sampling rate and channel mask");
162781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        inStream = NULL;
162881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config, &inStream);
162965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
163065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
163181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status == NO_ERROR && inStream != NULL) {
163258912562617941964939a4182cda71eaeb153d4bGlenn Kasten
163346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
163481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Try to re-use most recently used Pipe to archive a copy of input for dumpsys,
163581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // or (re-)create if current Pipe is idle and does not match the new format
163681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<NBAIO_Sink> teeSink;
163781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        enum {
163881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            TEE_SINK_NO,    // don't copy input
163981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            TEE_SINK_NEW,   // copy input using a new pipe
164081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            TEE_SINK_OLD,   // copy input using an existing pipe
164181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } kind;
164281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        NBAIO_Format format = Format_from_SR_C(inStream->common.get_sample_rate(&inStream->common),
164381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        popcount(inStream->common.get_channels(&inStream->common)));
1644da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        if (!mTeeSinkInputEnabled) {
1645da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            kind = TEE_SINK_NO;
1646da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        } else if (format == Format_Invalid) {
164781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_NO;
164881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else if (mRecordTeeSink == 0) {
164981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_NEW;
165081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else if (mRecordTeeSink->getStrongCount() != 1) {
165181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_NO;
165281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else if (format == mRecordTeeSink->format()) {
165381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_OLD;
16544adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        } else {
165581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_NEW;
165681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
165781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        switch (kind) {
165881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        case TEE_SINK_NEW: {
1659da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            Pipe *pipe = new Pipe(mTeeSinkInputFrames, format);
166081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t numCounterOffers = 0;
166181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const NBAIO_Format offers[1] = {format};
166281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
166381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOG_ASSERT(index == 0);
166481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PipeReader *pipeReader = new PipeReader(*pipe);
166581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            numCounterOffers = 0;
166681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
166781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOG_ASSERT(index == 0);
166881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mRecordTeeSink = pipe;
166981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mRecordTeeSource = pipeReader;
167081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            teeSink = pipe;
16714adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            }
167281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            break;
167381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        case TEE_SINK_OLD:
167481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            teeSink = mRecordTeeSink;
167581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            break;
167681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        case TEE_SINK_NO:
167781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        default:
167881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            break;
167958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
168046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
1681da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
168281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);
168365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
168481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Start record thread
168581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // RecorThread require both input and output device indication to forward to audio
168681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // pre processing modules
168781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread = new RecordThread(this,
168881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                  input,
168981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                  reqSamplingRate,
169081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                  reqChannels,
169181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                  id,
1692d3922f72601d82c6fc067a98916fda0bd1291c5fEric Laurent                                  primaryOutputDevice_l(),
169346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                                  *pDevices
169446909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
169546909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                                  , teeSink
169646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
169746909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                                  );
169881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mRecordThreads.add(id, thread);
169981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("openInput() created record thread: ID %d thread %p", id, thread);
170081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pSamplingRate != NULL) *pSamplingRate = reqSamplingRate;
170181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pFormat != NULL) *pFormat = config.format;
170281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pChannelMask != NULL) *pChannelMask = reqChannels;
170365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
170481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // notify client processes of the new input creation
170581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread->audioConfigChanged_l(AudioSystem::INPUT_OPENED);
170681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return id;
17071afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent    }
170881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
170981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return 0;
171065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
171165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
171281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::closeInput(audio_io_handle_t input)
171365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
171481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return closeInput_nonvirtual(input);
171565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
171665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
171781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input)
1718de070137f11d346fba77605bd76a44c040a618fcEric Laurent{
171981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // keep strong reference on the record thread so that
172081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // it is not destroyed while exit() is executed
172181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<RecordThread> thread;
172281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
172381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(mLock);
172481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread = checkRecordThread_l(input);
172581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread == 0) {
172681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return BAD_VALUE;
1727de070137f11d346fba77605bd76a44c040a618fcEric Laurent        }
172881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
172981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("closeInput() %d", input);
173081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audioConfigChanged_l(AudioSystem::INPUT_CLOSED, input, NULL);
173181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mRecordThreads.removeItem(input);
1732de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
173381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->exit();
173481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // The thread entity (active unit of execution) is no longer running here,
173581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // but the ThreadBase container still exists.
1736de070137f11d346fba77605bd76a44c040a618fcEric Laurent
173781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioStreamIn *in = thread->clearInput();
173881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOG_ASSERT(in != NULL, "in shouldn't be NULL");
173981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // from now on thread->mInput is NULL
174081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    in->hwDev()->close_input_stream(in->hwDev(), in->stream);
174181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    delete in;
174265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
174381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
1744b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
1745b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
174681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output)
1747b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent{
1748b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    Mutex::Autolock _l(mLock);
174981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("setStreamOutput() stream %d to output %d", stream, output);
1750b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
175181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
175281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
175381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread->invalidateTracks(stream);
1754b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    }
175581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
175681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
1757b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
1758b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
175981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
176081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentint AudioFlinger::newAudioSessionId()
1761162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent{
176281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return nextUniqueId();
1763162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent}
1764162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent
176581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::acquireAudioSessionId(int audioSession)
1766a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
1767a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    Mutex::Autolock _l(mLock);
176881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    pid_t caller = IPCThreadState::self()->getCallingPid();
176981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("acquiring %d from %d", audioSession, caller);
177081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t num = mAudioSessionRefs.size();
177181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i< num; i++) {
177281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioSessionRef *ref = mAudioSessionRefs.editItemAt(i);
177381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (ref->mSessionid == audioSession && ref->mPid == caller) {
177481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ref->mCnt++;
177581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV(" incremented refcount to %d", ref->mCnt);
177681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return;
1777a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
1778a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
177981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAudioSessionRefs.push(new AudioSessionRef(audioSession, caller));
178081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV(" added new entry for %d", audioSession);
1781a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
1782a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
178381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::releaseAudioSessionId(int audioSession)
178444a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent{
178581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
178681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    pid_t caller = IPCThreadState::self()->getCallingPid();
178781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("releasing %d from %d", audioSession, caller);
178881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t num = mAudioSessionRefs.size();
178981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i< num; i++) {
179081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
179181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (ref->mSessionid == audioSession && ref->mPid == caller) {
179281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ref->mCnt--;
179381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV(" decremented refcount to %d", ref->mCnt);
179481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (ref->mCnt == 0) {
179581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mAudioSessionRefs.removeAt(i);
179681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                delete ref;
179781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                purgeStaleEffects_l();
179844a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent            }
179981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return;
180044a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent        }
180144a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent    }
180281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGW("session id %d not found for pid %d", audioSession, caller);
180344a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent}
180444a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent
180581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::purgeStaleEffects_l() {
180665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
180781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("purging stale effects");
1808fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten
180981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Vector< sp<EffectChain> > chains;
181058912562617941964939a4182cda71eaeb153d4bGlenn Kasten
181181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
181281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
181381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        for (size_t j = 0; j < t->mEffectChains.size(); j++) {
181481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectChain> ec = t->mEffectChains[j];
181581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (ec->sessionId() > AUDIO_SESSION_OUTPUT_MIX) {
181681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                chains.push(ec);
181781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
1818c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        }
181958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
182081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mRecordThreads.size(); i++) {
182181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<RecordThread> t = mRecordThreads.valueAt(i);
182281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        for (size_t j = 0; j < t->mEffectChains.size(); j++) {
182381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectChain> ec = t->mEffectChains[j];
182481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            chains.push(ec);
182581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
1826300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    }
182765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
182881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < chains.size(); i++) {
182981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<EffectChain> ec = chains[i];
183081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int sessionid = ec->sessionId();
183181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<ThreadBase> t = ec->mThread.promote();
183281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (t == 0) {
183381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            continue;
183481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
183581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        size_t numsessionrefs = mAudioSessionRefs.size();
183681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        bool found = false;
183781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        for (size_t k = 0; k < numsessionrefs; k++) {
183881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSessionRef *ref = mAudioSessionRefs.itemAt(k);
183981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (ref->mSessionid == sessionid) {
184081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGV(" session %d still exists for %d with %d refs",
184181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    sessionid, ref->mPid, ref->mCnt);
184281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                found = true;
184381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                break;
184458912562617941964939a4182cda71eaeb153d4bGlenn Kasten            }
184558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
184681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (!found) {
184781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _l (t->mLock);
184881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // remove all effects from the chain
184981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            while (ec->mEffects.size()) {
185081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                sp<EffectModule> effect = ec->mEffects[0];
185181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                effect->unPin();
185281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                t->removeEffect_l(effect);
185381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (effect->purgeHandles()) {
185481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    t->checkSuspendOnEffectEnabled_l(effect, false, effect->sessionId());
185581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                }
185681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                AudioSystem::unregisterEffect(effect->id());
185781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
1858c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        }
185958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
186081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return;
186165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
186265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
186381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
186481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
1865190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten{
186681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mPlaybackThreads.valueFor(output).get();
1867190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten}
1868190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
186981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// checkMixerThread_l() must be called with AudioFlinger::mLock held
187081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(audio_io_handle_t output) const
187181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
187281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = checkPlaybackThread_l(output);
187381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return thread != NULL && thread->type() != ThreadBase::DIRECT ? (MixerThread *) thread : NULL;
187481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
1875190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
187681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// checkRecordThread_l() must be called with AudioFlinger::mLock held
187781784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(audio_io_handle_t input) const
187881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
187981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mRecordThreads.valueFor(input).get();
188081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
1881190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
188281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::nextUniqueId()
188381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
188481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return android_atomic_inc(&mNextUniqueId);
188581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
188683efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten
188781784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
188837d825e72a6c606553a745da1212590a425996d3Glenn Kasten{
188981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
189081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
189181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioStreamOut *output = thread->getOutput();
189281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (output != NULL && output->audioHwDev == mPrimaryHardwareDev) {
189381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return thread;
189437d825e72a6c606553a745da1212590a425996d3Glenn Kasten        }
189537d825e72a6c606553a745da1212590a425996d3Glenn Kasten    }
189681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NULL;
189737d825e72a6c606553a745da1212590a425996d3Glenn Kasten}
189837d825e72a6c606553a745da1212590a425996d3Glenn Kasten
189981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_devices_t AudioFlinger::primaryOutputDevice_l() const
190065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
190181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = primaryPlaybackThread_l();
1902000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
190381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread == NULL) {
190481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
19059f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten    }
1906000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
190781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return thread->outDevice();
1908000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
1909688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten
191081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<AudioFlinger::SyncEvent> AudioFlinger::createSyncEvent(AudioSystem::sync_event_t type,
191181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                    int triggerSession,
191281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                    int listenerSession,
191381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                    sync_event_callback_t callBack,
191481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                    void *cookie)
191581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
191681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
191773ca0f5837d5448f7a5eb159a09cd0ebe82b4de9Glenn Kasten
191881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<SyncEvent> event = new SyncEvent(type, triggerSession, listenerSession, callBack, cookie);
191981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t playStatus = NAME_NOT_FOUND;
192081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t recStatus = NAME_NOT_FOUND;
192181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
192281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        playStatus = mPlaybackThreads.valueAt(i)->setSyncEvent(event);
192381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (playStatus == NO_ERROR) {
192481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return event;
192581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
192665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
192781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mRecordThreads.size(); i++) {
192881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        recStatus = mRecordThreads.valueAt(i)->setSyncEvent(event);
192981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (recStatus == NO_ERROR) {
193081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return event;
19319f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten        }
193265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
193381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (playStatus == NAME_NOT_FOUND || recStatus == NAME_NOT_FOUND) {
193481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPendingSyncEvents.add(event);
193581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
193681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("createSyncEvent() invalid event %d", event->type());
193781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        event.clear();
193881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
193981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return event;
194065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
194165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
194281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
194381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//  Effect management
194481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
194558912562617941964939a4182cda71eaeb153d4bGlenn Kasten
194658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
194781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::queryNumberEffects(uint32_t *numEffects) const
1948000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
194981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
195081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return EffectQueryNumberEffects(numEffects);
1951000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
1952000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
195381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor) const
195458912562617941964939a4182cda71eaeb153d4bGlenn Kasten{
195581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
195681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return EffectQueryEffect(index, descriptor);
195758912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
195858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
195981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::getEffectDescriptor(const effect_uuid_t *pUuid,
196081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        effect_descriptor_t *descriptor) const
1961000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
196281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
196381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return EffectGetDescriptor(pUuid, descriptor);
1964000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
1965000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
196681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
19678d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kastensp<IEffect> AudioFlinger::createEffect(
196881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        effect_descriptor_t *pDesc,
196981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        const sp<IEffectClient>& effectClient,
197081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int32_t priority,
197181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_io_handle_t io,
197281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int sessionId,
197381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status_t *status,
197481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int *id,
197581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int *enabled)
1976000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
197781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t lStatus = NO_ERROR;
197881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<EffectHandle> handle;
197981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    effect_descriptor_t desc;
1980000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
19818d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kasten    pid_t pid = IPCThreadState::self()->getCallingPid();
198281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d",
198381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            pid, effectClient.get(), priority, sessionId, io);
1984000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
198581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (pDesc == NULL) {
198681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        lStatus = BAD_VALUE;
198781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
1988952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
1989000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
199081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // check audio settings permission for global effects
199181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (sessionId == AUDIO_SESSION_OUTPUT_MIX && !settingsAllowed()) {
199281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        lStatus = PERMISSION_DENIED;
199381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
1994952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
1995000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
199681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // Session AUDIO_SESSION_OUTPUT_STAGE is reserved for output stage effects
199781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // that can only be created by audio policy manager (running in same process)
199881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (sessionId == AUDIO_SESSION_OUTPUT_STAGE && getpid_cached != pid) {
199981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        lStatus = PERMISSION_DENIED;
200081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
2001952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
200265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
200381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (io == 0) {
200481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
200581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // output must be specified by AudioPolicyManager when using session
200681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // AUDIO_SESSION_OUTPUT_STAGE
200781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = BAD_VALUE;
200881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            goto Exit;
200981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
201081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // if the output returned by getOutputForEffect() is removed before we lock the
201181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // mutex below, the call to checkPlaybackThread_l(io) below will detect it
201281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // and we will exit safely
201381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            io = AudioSystem::getOutputForEffect(&desc);
201481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
201565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
201665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
201781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
201881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(mLock);
2019288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
202065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
202181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (!EffectIsNullUuid(&pDesc->uuid)) {
202281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // if uuid is specified, request effect descriptor
202381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = EffectGetDescriptor(&pDesc->uuid, &desc);
202481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (lStatus < 0) {
202581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("createEffect() error %d from EffectGetDescriptor", lStatus);
202681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
202781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
202881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
202981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // if uuid is not specified, look for an available implementation
203081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // of the required type in effect factory
203181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (EffectIsNullUuid(&pDesc->type)) {
203281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("createEffect() no effect type");
203381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                lStatus = BAD_VALUE;
203481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
2035288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
203681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t numEffects = 0;
203781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            effect_descriptor_t d;
203881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            d.flags = 0; // prevent compiler warning
203981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            bool found = false;
2040288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
204181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = EffectQueryNumberEffects(&numEffects);
204281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (lStatus < 0) {
204381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("createEffect() error %d from EffectQueryNumberEffects", lStatus);
204481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
204581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
204681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            for (uint32_t i = 0; i < numEffects; i++) {
204781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                lStatus = EffectQueryEffect(i, &desc);
204881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (lStatus < 0) {
204981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    ALOGW("createEffect() error %d from EffectQueryEffect", lStatus);
205081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    continue;
2051d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                }
205281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (memcmp(&desc.type, &pDesc->type, sizeof(effect_uuid_t)) == 0) {
205381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    // If matching type found save effect descriptor. If the session is
205481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    // 0 and the effect is not auxiliary, continue enumeration in case
205581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    // an auxiliary version of this effect type is available
205681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    found = true;
205781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    d = desc;
205881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    if (sessionId != AUDIO_SESSION_OUTPUT_MIX ||
205981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                            (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
2060d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                        break;
2061d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    }
2062d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                }
2063288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
206481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (!found) {
206581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                lStatus = BAD_VALUE;
206681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("createEffect() effect not found");
206781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
206881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
206981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // For same effect type, chose auxiliary version over insert version if
207081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // connect to output mix (Compliance to OpenSL ES)
207181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (sessionId == AUDIO_SESSION_OUTPUT_MIX &&
207281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    (d.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_AUXILIARY) {
207381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                desc = d;
207458912562617941964939a4182cda71eaeb153d4bGlenn Kasten            }
207558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
207658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
207781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Do not allow auxiliary effects on a session different from 0 (output mix)
207881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (sessionId != AUDIO_SESSION_OUTPUT_MIX &&
207981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent             (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
208081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = INVALID_OPERATION;
208181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            goto Exit;
20823dbe3201479828e84abe02e1fdd0a5d414c0ddb8Eric Laurent        }
208365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
208481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // check recording permission for visualizer
208581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) &&
208681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            !recordingAllowed()) {
208781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = PERMISSION_DENIED;
208881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            goto Exit;
208981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
209065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
209181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // return effect descriptor
209281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        *pDesc = desc;
209365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
209481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // If output is not specified try to find a matching audio session ID in one of the
209581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // output threads.
209681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // If output is 0 here, sessionId is neither SESSION_OUTPUT_STAGE nor SESSION_OUTPUT_MIX
209781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // because of code checking output when entering the function.
209881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Note: io is never 0 when creating an effect on an input
209981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (io == 0) {
210081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // look for the thread where the specified audio session is present
210181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
210281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
210381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    io = mPlaybackThreads.keyAt(i);
210481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    break;
210565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
2106d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            }
210781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (io == 0) {
210881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                for (size_t i = 0; i < mRecordThreads.size(); i++) {
210981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    if (mRecordThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
211081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        io = mRecordThreads.keyAt(i);
211181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        break;
21122986460984580833161bdaabc7f17da1005a8961Eric Laurent                    }
211365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
211465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
211581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // If no output thread contains the requested session ID, default to
211681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // first output. The effect chain will be moved to the correct output
211781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // thread when a track with the same session ID is created
211881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (io == 0 && mPlaybackThreads.size()) {
211981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                io = mPlaybackThreads.keyAt(0);
212081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
212181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("createEffect() got io %d for effect %s", io, desc.name);
212265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
212381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ThreadBase *thread = checkRecordThread_l(io);
212481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread == NULL) {
212581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            thread = checkPlaybackThread_l(io);
212681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (thread == NULL) {
212781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGE("createEffect() unknown output thread");
212881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                lStatus = BAD_VALUE;
212981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
2130288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
2131288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        }
2132288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
213381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<Client> client = registerPid_l(pid);
213458912562617941964939a4182cda71eaeb153d4bGlenn Kasten
213581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // create effect on selected output thread
213681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        handle = thread->createEffect_l(client, effectClient, priority, sessionId,
213781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                &desc, enabled, &lStatus);
213881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (handle != 0 && id != NULL) {
213981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            *id = handle->id();
214065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
214165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
214265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
214381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentExit:
214481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status != NULL) {
214581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        *status = lStatus;
214658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
214781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return handle;
214866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten}
214966fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
215081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::moveEffects(int sessionId, audio_io_handle_t srcOutput,
215181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_io_handle_t dstOutput)
215265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
215381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("moveEffects() session %d, srcOutput %d, dstOutput %d",
215481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sessionId, srcOutput, dstOutput);
215565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
215681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (srcOutput == dstOutput) {
215781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("moveEffects() same dst and src outputs %d", dstOutput);
215881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return NO_ERROR;
215981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
216081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *srcThread = checkPlaybackThread_l(srcOutput);
216181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (srcThread == NULL) {
216281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("moveEffects() bad srcOutput %d", srcOutput);
216381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
216481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
216581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *dstThread = checkPlaybackThread_l(dstOutput);
216681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (dstThread == NULL) {
216781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("moveEffects() bad dstOutput %d", dstOutput);
216881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
216965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
217065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
217181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _dl(dstThread->mLock);
217281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _sl(srcThread->mLock);
217381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    moveEffectChain_l(sessionId, srcThread, dstThread, false);
217465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
217581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
217665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
217765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
217881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// moveEffectChain_l must be called with both srcThread and dstThread mLocks held
217981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::moveEffectChain_l(int sessionId,
218081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                   AudioFlinger::PlaybackThread *srcThread,
218181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                   AudioFlinger::PlaybackThread *dstThread,
218281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                   bool reRegister)
218365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
218481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("moveEffectChain_l() session %d from thread %p to thread %p",
218581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sessionId, srcThread, dstThread);
218665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
218781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<EffectChain> chain = srcThread->getEffectChain_l(sessionId);
218881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (chain == 0) {
218981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("moveEffectChain_l() effect chain for session %d not on source thread %p",
219081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                sessionId, srcThread);
219181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return INVALID_OPERATION;
219281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
21939ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
219481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // remove chain first. This is useful only if reconfiguring effect chain on same output thread,
219581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // so that a new chain is created with correct parameters when first effect is added. This is
219681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // otherwise unnecessary as removeEffect_l() will remove the chain when last effect is
219781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // removed.
219881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    srcThread->removeEffectChain_l(chain);
21999ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
220081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // transfer all effects one by one so that new effect chain is created on new thread with
220181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // correct buffer sizes and audio parameters and effect engines reconfigured accordingly
220281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_io_handle_t dstOutput = dstThread->id();
220381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<EffectChain> dstChain;
220481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t strategy = 0; // prevent compiler warning
220581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<EffectModule> effect = chain->getEffectFromId_l(0);
220681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    while (effect != 0) {
220781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        srcThread->removeEffect_l(effect);
220881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        dstThread->addEffect_l(effect);
220981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // removeEffect_l() has stopped the effect if it was active so it must be restarted
221081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (effect->state() == EffectModule::ACTIVE ||
221181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                effect->state() == EffectModule::STOPPING) {
221281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            effect->start();
221365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
221481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // if the move request is not received from audio policy manager, the effect must be
221581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // re-registered with the new strategy and output
221681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (dstChain == 0) {
221781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            dstChain = effect->chain().promote();
221881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (dstChain == 0) {
221981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("moveEffectChain_l() cannot get chain from effect %p", effect.get());
222081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                srcThread->addEffect_l(effect);
222181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return NO_INIT;
222265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
222381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            strategy = dstChain->strategy();
222465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
222581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (reRegister) {
222681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSystem::unregisterEffect(effect->id());
222781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSystem::registerEffect(&effect->desc(),
222881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        dstOutput,
222981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        strategy,
223081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        sessionId,
223181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        effect->id());
223281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
223381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        effect = chain->getEffectFromId_l(0);
223458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
223558912562617941964939a4182cda71eaeb153d4bGlenn Kasten
223681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
223765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
223865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2239da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenstruct Entry {
2240da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#define MAX_NAME 32     // %Y%m%d%H%M%S_%d.wav
2241da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    char mName[MAX_NAME];
2242da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten};
2243da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
2244da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenint comparEntry(const void *p1, const void *p2)
2245da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten{
2246da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    return strcmp(((const Entry *) p1)->mName, ((const Entry *) p2)->mName);
2247da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten}
2248da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
224946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
2250d06785bebf7e43d4a011b62a252771373ada910cGlenn Kastenvoid AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_handle_t id)
225165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
2252d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    NBAIO_Source *teeSource = source.get();
2253fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten    if (teeSource != NULL) {
2254da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // .wav rotation
2255da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // There is a benign race condition if 2 threads call this simultaneously.
2256da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // They would both traverse the directory, but the result would simply be
2257da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // failures at unlink() which are ignored.  It's also unlikely since
2258da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // normally dumpsys is only done by bugreport or from the command line.
2259da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        char teePath[32+256];
2260da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        strcpy(teePath, "/data/misc/media");
2261da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        size_t teePathLen = strlen(teePath);
2262da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        DIR *dir = opendir(teePath);
2263da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        teePath[teePathLen++] = '/';
2264da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        if (dir != NULL) {
2265da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#define MAX_SORT 20 // number of entries to sort
2266da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#define MAX_KEEP 10 // number of entries to keep
2267da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            struct Entry entries[MAX_SORT];
2268da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            size_t entryCount = 0;
2269da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            while (entryCount < MAX_SORT) {
2270da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                struct dirent de;
2271da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                struct dirent *result = NULL;
2272da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                int rc = readdir_r(dir, &de, &result);
2273da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                if (rc != 0) {
2274da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    ALOGW("readdir_r failed %d", rc);
2275da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    break;
2276da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2277da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                if (result == NULL) {
2278da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    break;
2279da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2280da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                if (result != &de) {
2281da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    ALOGW("readdir_r returned unexpected result %p != %p", result, &de);
2282da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    break;
2283da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2284da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                // ignore non .wav file entries
2285da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                size_t nameLen = strlen(de.d_name);
2286da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                if (nameLen <= 4 || nameLen >= MAX_NAME ||
2287da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                        strcmp(&de.d_name[nameLen - 4], ".wav")) {
2288da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    continue;
2289da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2290da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                strcpy(entries[entryCount++].mName, de.d_name);
2291da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2292da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            (void) closedir(dir);
2293da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            if (entryCount > MAX_KEEP) {
2294da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                qsort(entries, entryCount, sizeof(Entry), comparEntry);
2295da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                for (size_t i = 0; i < entryCount - MAX_KEEP; ++i) {
2296da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    strcpy(&teePath[teePathLen], entries[i].mName);
2297da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    (void) unlink(teePath);
2298da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2299da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2300da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        } else {
2301da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            if (fd >= 0) {
2302da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                fdprintf(fd, "unable to rotate tees in %s: %s\n", teePath, strerror(errno));
2303da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2304da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        }
2305d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        char teeTime[16];
2306fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        struct timeval tv;
2307fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        gettimeofday(&tv, NULL);
2308fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        struct tm tm;
2309fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        localtime_r(&tv.tv_sec, &tm);
2310da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        strftime(teeTime, sizeof(teeTime), "%Y%m%d%H%M%S", &tm);
2311da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        snprintf(&teePath[teePathLen], sizeof(teePath) - teePathLen, "%s_%d.wav", teeTime, id);
2312da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // if 2 dumpsys are done within 1 second, and rotation didn't work, then discard 2nd
2313da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        int teeFd = open(teePath, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, S_IRUSR | S_IWUSR);
2314fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        if (teeFd >= 0) {
2315fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            char wavHeader[44];
2316fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            memcpy(wavHeader,
2317fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                "RIFF\0\0\0\0WAVEfmt \20\0\0\0\1\0\2\0\104\254\0\0\0\0\0\0\4\0\20\0data\0\0\0\0",
2318fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                sizeof(wavHeader));
2319fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            NBAIO_Format format = teeSource->format();
2320fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            unsigned channelCount = Format_channelCount(format);
2321fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            ALOG_ASSERT(channelCount <= FCC_2);
23223b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten            uint32_t sampleRate = Format_sampleRate(format);
2323fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[22] = channelCount;       // number of channels
2324fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[24] = sampleRate;         // sample rate
2325fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[25] = sampleRate >> 8;
2326fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[32] = channelCount * 2;   // block alignment
2327fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            write(teeFd, wavHeader, sizeof(wavHeader));
2328fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            size_t total = 0;
2329fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            bool firstRead = true;
2330fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            for (;;) {
2331fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten#define TEE_SINK_READ 1024
2332fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                short buffer[TEE_SINK_READ * FCC_2];
2333fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                size_t count = TEE_SINK_READ;
23342c3b2da3049627264b7c6b449a1622f002210f03John Grossman                ssize_t actual = teeSource->read(buffer, count,
23352c3b2da3049627264b7c6b449a1622f002210f03John Grossman                        AudioBufferProvider::kInvalidPTS);
2336fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                bool wasFirstRead = firstRead;
2337fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                firstRead = false;
2338fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                if (actual <= 0) {
2339fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                    if (actual == (ssize_t) OVERRUN && wasFirstRead) {
2340fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                        continue;
2341fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                    }
2342fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                    break;
2343fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                }
2344a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent                ALOG_ASSERT(actual <= (ssize_t)count);
2345fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                write(teeFd, buffer, actual * channelCount * sizeof(short));
2346fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                total += actual;
2347fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            }
2348fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            lseek(teeFd, (off_t) 4, SEEK_SET);
2349fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            uint32_t temp = 44 + total * channelCount * sizeof(short) - 8;
2350fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            write(teeFd, &temp, sizeof(temp));
2351fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            lseek(teeFd, (off_t) 40, SEEK_SET);
2352fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            temp =  total * channelCount * sizeof(short);
2353fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            write(teeFd, &temp, sizeof(temp));
2354fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            close(teeFd);
2355da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            if (fd >= 0) {
2356da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                fdprintf(fd, "tee copied to %s\n", teePath);
2357da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2358fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        } else {
2359da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            if (fd >= 0) {
2360da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                fdprintf(fd, "unable to create tee %s: %s\n", teePath, strerror(errno));
2361da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2362fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        }
2363fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten    }
2364d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten}
236546909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
2366d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
236765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
236865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
236965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::onTransact(
237065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
237165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
237265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnAudioFlinger::onTransact(code, data, reply, flags);
237365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
237465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
237565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
2376