AudioFlinger.cpp revision da6ef1320d0161b1640dc84d7a9c5a25860c3619
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
93da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenbool AudioFlinger::mTeeSinkInputEnabled = false;
94da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenbool AudioFlinger::mTeeSinkOutputEnabled = false;
95da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenbool AudioFlinger::mTeeSinkTrackEnabled = false;
96da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
97da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastensize_t AudioFlinger::mTeeSinkInputFrames = kTeeSinkInputFramesDefault;
98da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastensize_t AudioFlinger::mTeeSinkOutputFrames = kTeeSinkOutputFramesDefault;
99da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastensize_t AudioFlinger::mTeeSinkTrackFrames = kTeeSinkTrackFramesDefault;
100da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
10165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
10265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurentstatic int load_audio_interface(const char *if_name, audio_hw_device_t **dev)
104799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin{
105f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    const hw_module_t *mod;
106799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    int rc;
107799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
108f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
109f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    ALOGE_IF(rc, "%s couldn't load audio hw module %s.%s (%s)", __func__,
110f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent                 AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
111f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    if (rc) {
112799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        goto out;
113f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    }
114f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    rc = audio_hw_device_open(mod, dev);
115f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    ALOGE_IF(rc, "%s couldn't open audio hw device in %s.%s (%s)", __func__,
116f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent                 AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
117f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    if (rc) {
118799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        goto out;
119f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    }
120f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    if ((*dev)->common.version != AUDIO_DEVICE_API_VERSION_CURRENT) {
121f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
122f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        rc = BAD_VALUE;
123f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        goto out;
124f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    }
125799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return 0;
126799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
127799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavinout:
128799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    *dev = NULL;
129799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return rc;
130799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin}
131799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
13265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
13365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
13465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::AudioFlinger()
13565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    : BnAudioFlinger(),
1364ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mPrimaryHardwareDev(NULL),
1377d6c35bf132a46c0a8a9826491882495fc98bd8cGlenn Kasten      mHardwareStatus(AUDIO_HW_IDLE),
1384ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mMasterVolume(1.0f),
1394ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mMasterMute(false),
1404ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mNextUniqueId(1),
1414ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mMode(AUDIO_MODE_INVALID),
1424ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mBtNrecIsOff(false)
14365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1449e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    char value[PROPERTY_VALUE_MAX];
1459e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    bool doLog = (property_get("ro.test_harness", value, "0") > 0) && (atoi(value) == 1);
1469e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (doLog) {
1479e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters");
1489e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
149da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    (void) property_get("ro.debuggable", value, "0");
150da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    int debuggable = atoi(value);
151da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    int teeEnabled = 0;
152da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (debuggable) {
153da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        (void) property_get("af.tee", value, "0");
154da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        teeEnabled = atoi(value);
155da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    }
156da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (teeEnabled & 1)
157da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        mTeeSinkInputEnabled = true;
158da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (teeEnabled & 2)
159da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        mTeeSinkOutputEnabled = true;
160da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (teeEnabled & 4)
161da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        mTeeSinkTrackEnabled = true;
1625a61d2f277af3098fc10b2881babca16391362daDima Zavin}
1635a61d2f277af3098fc10b2881babca16391362daDima Zavin
1645a61d2f277af3098fc10b2881babca16391362daDima Zavinvoid AudioFlinger::onFirstRef()
1655a61d2f277af3098fc10b2881babca16391362daDima Zavin{
166799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    int rc = 0;
167fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
168935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    Mutex::Autolock _l(mLock);
169935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent
170799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    /* TODO: move all this work into an Init() function */
1714ff14bae91075eb274eb1c2975982358946e7e63John Grossman    char val_str[PROPERTY_VALUE_MAX] = { 0 };
1724ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
1734ff14bae91075eb274eb1c2975982358946e7e63John Grossman        uint32_t int_val;
1744ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (1 == sscanf(val_str, "%u", &int_val)) {
1754ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mStandbyTimeInNsecs = milliseconds(int_val);
1764ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGI("Using %u mSec as standby time.", int_val);
1774ff14bae91075eb274eb1c2975982358946e7e63John Grossman        } else {
1784ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
1794ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGI("Using default %u mSec as standby time.",
1804ff14bae91075eb274eb1c2975982358946e7e63John Grossman                    (uint32_t)(mStandbyTimeInNsecs / 1000000));
1814ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
1824ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
18365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
184a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    mMode = AUDIO_MODE_NORMAL;
18565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
18665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
18765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::~AudioFlinger()
18865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
18965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!mRecordThreads.isEmpty()) {
190c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten        // closeInput_nonvirtual() will remove specified entry from mRecordThreads
191d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten        closeInput_nonvirtual(mRecordThreads.keyAt(0));
19265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
19365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!mPlaybackThreads.isEmpty()) {
194c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten        // closeOutput_nonvirtual() will remove specified entry from mPlaybackThreads
195d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten        closeOutput_nonvirtual(mPlaybackThreads.keyAt(0));
19665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
197799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
1982b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
1992b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten        // no mHardwareLock needed, as there are no other references to this
200a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        audio_hw_device_close(mAudioHwDevs.valueAt(i)->hwDevice());
201a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        delete mAudioHwDevs.valueAt(i);
20265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
20365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
20465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
205a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentstatic const char * const audio_interfaces[] = {
206a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_PRIMARY,
207a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_A2DP,
208a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_USB,
209a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent};
210a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent#define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0])))
211a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
212ee578c0330319f04a48bccbdb26b53fea0388d04John GrossmanAudioFlinger::AudioHwDevice* AudioFlinger::findSuitableHwDev_l(
213ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_module_handle_t module,
214ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_devices_t devices)
215799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin{
216a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    // if module is 0, the request comes from an old policy manager and we should load
217a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    // well known modules
218a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    if (module == 0) {
219a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        ALOGW("findSuitableHwDev_l() loading well know audio hw modules");
220a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) {
221a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            loadHwModule_l(audio_interfaces[i]);
222a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        }
223f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        // then try to find a module supporting the requested device.
224f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
225f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            AudioHwDevice *audioHwDevice = mAudioHwDevs.valueAt(i);
226f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            audio_hw_device_t *dev = audioHwDevice->hwDevice();
227f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            if ((dev->get_supported_devices != NULL) &&
228f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                    (dev->get_supported_devices(dev) & devices) == devices)
229f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                return audioHwDevice;
230f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        }
231a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    } else {
232a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        // check a match for the requested module handle
233ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(module);
234ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (audioHwDevice != NULL) {
235ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            return audioHwDevice;
236a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        }
237a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    }
238a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
239799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return NULL;
240799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin}
24165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
242be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
24365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
24465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
24565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
24665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
24765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
24865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("Clients:\n");
24965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mClients.size(); ++i) {
25077c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        sp<Client> client = mClients.valueAt(i).promote();
25177c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        if (client != 0) {
25277c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            snprintf(buffer, SIZE, "  pid: %d\n", client->pid());
25377c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            result.append(buffer);
25465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
25565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
2563a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
2573a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    result.append("Global session refs:\n");
258012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten    result.append(" session pid count\n");
2593a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    for (size_t i = 0; i < mAudioSessionRefs.size(); i++) {
2603a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        AudioSessionRef *r = mAudioSessionRefs[i];
261012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        snprintf(buffer, SIZE, " %7d %3d %3d\n", r->mSessionid, r->mPid, r->mCnt);
2623a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        result.append(buffer);
2633a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
26465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
26565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
26665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
26765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
268be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
26965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
27065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
27165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
27265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
273a4454b4765c5905f14186893b0688be375642283Glenn Kasten    hardware_call_state hardwareStatus = mHardwareStatus;
27465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2754ff14bae91075eb274eb1c2975982358946e7e63John Grossman    snprintf(buffer, SIZE, "Hardware status: %d\n"
2764ff14bae91075eb274eb1c2975982358946e7e63John Grossman                           "Standby Time mSec: %u\n",
2774ff14bae91075eb274eb1c2975982358946e7e63John Grossman                            hardwareStatus,
2784ff14bae91075eb274eb1c2975982358946e7e63John Grossman                            (uint32_t)(mStandbyTimeInNsecs / 1000000));
27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
28065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
28165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
28265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
283be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
28465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
28565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
28665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
28765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
28865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Permission Denial: "
28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "can't dump AudioFlinger from pid=%d, uid=%d\n",
29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingPid(),
29165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingUid());
29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
29465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
29565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
29681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::dumpTryLock(Mutex& mutex)
29765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
30165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
3047dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten        usleep(kDumpLockSleepUs);
30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::dump(int fd, const Vector<String16>& args)
31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
31144deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (!dumpAllowed()) {
31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpPermissionDenial(fd, args);
31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // get state of hardware lock
31581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        bool hardwareLocked = dumpTryLock(mHardwareLock);
31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!hardwareLocked) {
31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kHardwareLockedString);
31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mHardwareLock.unlock();
32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        bool locked = dumpTryLock(mLock);
32465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // failed to lock - AudioFlinger is probably deadlocked
32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kDeadlockedString);
32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpClients(fd, args);
33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpInternals(fd, args);
33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // dump playback threads
33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mPlaybackThreads.valueAt(i)->dump(fd, args);
33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // dump record threads
34065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mRecordThreads.size(); i++) {
34165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mRecordThreads.valueAt(i)->dump(fd, args);
34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
344799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        // dump all hardware devs
345799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
346a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
347799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            dev->dump(dev, fd);
34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
349d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
350d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        // dump the serially shared record tee sink
351d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        if (mRecordTeeSource != 0) {
352d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            dumpTee(fd, mRecordTeeSource);
353d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        }
354d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
355d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if (locked) {
356d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            mLock.unlock();
357d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
3589e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
3599e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // append a copy of media.log here by forwarding fd to it, but don't attempt
3609e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // to lookup the service if it's not running, as it will block for a second
3619e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        if (mLogMemoryDealer != 0) {
3629e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten            sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
3639e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten            if (binder != 0) {
3649e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten                fdprintf(fd, "\nmedia.log:\n");
3659e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten                Vector<String16> args;
3669e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten                binder->dump(fd, args);
3679e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten            }
3689e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        }
36965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37398ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kastensp<AudioFlinger::Client> AudioFlinger::registerPid_l(pid_t pid)
37498ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten{
37598ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    // If pid is already in the mClients wp<> map, then use that entry
37698ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    // (for which promote() is always != 0), otherwise create a new entry and Client.
37798ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    sp<Client> client = mClients.valueFor(pid).promote();
37898ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    if (client == 0) {
37998ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        client = new Client(this, pid);
38098ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        mClients.add(pid, client);
38198ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    }
38298ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten
38398ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    return client;
38498ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten}
38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3869e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kastensp<NBLog::Writer> AudioFlinger::newWriter_l(size_t size, const char *name)
3879e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten{
3889e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (mLogMemoryDealer == 0) {
3899e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        return new NBLog::Writer();
3909e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
3919e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<IMemory> shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size));
3929e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<NBLog::Writer> writer = new NBLog::Writer(size, shared);
3939e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
3949e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (binder != 0) {
3959e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        interface_cast<IMediaLogService>(binder)->registerWriter(shared, size, name);
3969e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
3979e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    return writer;
3989e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten}
3999e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
4009e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kastenvoid AudioFlinger::unregisterWriter(const sp<NBLog::Writer>& writer)
4019e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten{
402685ef09bcaf5de6abf2064d552296f70eaec6761Glenn Kasten    if (writer == 0) {
403685ef09bcaf5de6abf2064d552296f70eaec6761Glenn Kasten        return;
404685ef09bcaf5de6abf2064d552296f70eaec6761Glenn Kasten    }
4059e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<IMemory> iMemory(writer->getIMemory());
4069e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (iMemory == 0) {
4079e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        return;
4089e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
4099e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
4109e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (binder != 0) {
4119e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        interface_cast<IMediaLogService>(binder)->unregisterWriter(iMemory);
4129e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // Now the media.log remote reference to IMemory is gone.
4139e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // When our last local reference to IMemory also drops to zero,
4149e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // the IMemory destructor will deallocate the region from mMemoryDealer.
4159e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
4169e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten}
4179e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
41865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// IAudioFlinger interface
41965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
42065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<IAudioTrack> AudioFlinger::createTrack(
422fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten        audio_stream_type_t streamType,
42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t sampleRate,
42458f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
425254af180475346b6186b49c297f340c9c4817511Glenn Kasten        audio_channel_mask_t channelMask,
426e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten        size_t frameCount,
427e0b07179a48ee50fda931d2aa1b3c751d167e4d7Glenn Kasten        IAudioFlinger::track_flags_t *flags,
42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const sp<IMemory>& sharedBuffer,
42972ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output,
4303acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten        pid_t tid,
43165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int *sessionId,
43265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t *status)
43365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<PlaybackThread::Track> track;
43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<TrackHandle> trackHandle;
43665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client;
43765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t lStatus;
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int lSessionId;
43965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
440263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    // client AudioTrack::set already implements AUDIO_STREAM_DEFAULT => AUDIO_STREAM_MUSIC,
441263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    // but if someone uses binder directly they could bypass that and cause us to crash
442263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {
44329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("createTrack() invalid stream type %d", streamType);
44465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        lStatus = BAD_VALUE;
44565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        goto Exit;
44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
44765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
44860a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    // client is responsible for conversion of 8-bit PCM to 16-bit PCM,
44960a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    // and we don't yet support 8.24 or 32-bit PCM
45060a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    if (audio_is_linear_pcm(format) && format != AUDIO_FORMAT_PCM_16_BIT) {
45160a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        ALOGE("createTrack() invalid format %d", format);
45260a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        lStatus = BAD_VALUE;
45360a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        goto Exit;
45460a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    }
45560a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten
45665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
45765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
45865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        PlaybackThread *thread = checkPlaybackThread_l(output);
45939e94f8f723d445447fdee0822291e664b631f60Eric Laurent        PlaybackThread *effectThread = NULL;
46065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
46129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("unknown output thread");
46265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lStatus = BAD_VALUE;
46365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            goto Exit;
46465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
46565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4668d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kasten        pid_t pid = IPCThreadState::self()->getCallingPid();
46798ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        client = registerPid_l(pid);
46865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("createTrack() sessionId: %d", (sessionId == NULL) ? -2 : *sessionId);
470fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) {
471f436fdcf93bd417fd3c9d2a8b19fd221d894b5e3Eric Laurent            // check if an effect chain with the same session ID is present on another
472f436fdcf93bd417fd3c9d2a8b19fd221d894b5e3Eric Laurent            // output thread and move it here.
473de070137f11d346fba77605bd76a44c040a618fcEric Laurent            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
47439e94f8f723d445447fdee0822291e664b631f60Eric Laurent                sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
47539e94f8f723d445447fdee0822291e664b631f60Eric Laurent                if (mPlaybackThreads.keyAt(i) != output) {
47639e94f8f723d445447fdee0822291e664b631f60Eric Laurent                    uint32_t sessions = t->hasAudioSession(*sessionId);
47739e94f8f723d445447fdee0822291e664b631f60Eric Laurent                    if (sessions & PlaybackThread::EFFECT_SESSION) {
47839e94f8f723d445447fdee0822291e664b631f60Eric Laurent                        effectThread = t.get();
479f436fdcf93bd417fd3c9d2a8b19fd221d894b5e3Eric Laurent                        break;
48039e94f8f723d445447fdee0822291e664b631f60Eric Laurent                    }
481de070137f11d346fba77605bd76a44c040a618fcEric Laurent                }
482de070137f11d346fba77605bd76a44c040a618fcEric Laurent            }
48365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lSessionId = *sessionId;
48465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
485de070137f11d346fba77605bd76a44c040a618fcEric Laurent            // if no audio session id is provided, create one here
4867c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            lSessionId = nextUniqueId();
48765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (sessionId != NULL) {
48865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                *sessionId = lSessionId;
48965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
49065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
4913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("createTrack() lSessionId: %d", lSessionId);
49265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
49365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track = thread->createTrack_l(client, streamType, sampleRate, format,
4943acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten                channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, &lStatus);
49539e94f8f723d445447fdee0822291e664b631f60Eric Laurent
49639e94f8f723d445447fdee0822291e664b631f60Eric Laurent        // move effect chain to this output thread if an effect on same session was waiting
49739e94f8f723d445447fdee0822291e664b631f60Eric Laurent        // for a track to be created
49839e94f8f723d445447fdee0822291e664b631f60Eric Laurent        if (lStatus == NO_ERROR && effectThread != NULL) {
49939e94f8f723d445447fdee0822291e664b631f60Eric Laurent            Mutex::Autolock _dl(thread->mLock);
50039e94f8f723d445447fdee0822291e664b631f60Eric Laurent            Mutex::Autolock _sl(effectThread->mLock);
50139e94f8f723d445447fdee0822291e664b631f60Eric Laurent            moveEffectChain_l(lSessionId, effectThread, thread, true);
50239e94f8f723d445447fdee0822291e664b631f60Eric Laurent        }
503a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
504a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        // Look for sync events awaiting for a session to be used.
505a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        for (int i = 0; i < (int)mPendingSyncEvents.size(); i++) {
506a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            if (mPendingSyncEvents[i]->triggerSession() == lSessionId) {
507a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                if (thread->isValidSyncEvent(mPendingSyncEvents[i])) {
5082986460984580833161bdaabc7f17da1005a8961Eric Laurent                    if (lStatus == NO_ERROR) {
509d23eedca9b5a1812891c05d89850ab7ee707040dGlenn Kasten                        (void) track->setSyncEvent(mPendingSyncEvents[i]);
5102986460984580833161bdaabc7f17da1005a8961Eric Laurent                    } else {
5112986460984580833161bdaabc7f17da1005a8961Eric Laurent                        mPendingSyncEvents[i]->cancel();
5122986460984580833161bdaabc7f17da1005a8961Eric Laurent                    }
513a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    mPendingSyncEvents.removeAt(i);
514a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    i--;
515a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                }
516a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            }
517a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
51865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
51965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (lStatus == NO_ERROR) {
52065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        trackHandle = new TrackHandle(track);
52165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
52265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // remove local strong reference to Client before deleting the Track so that the Client
52365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // destructor is called by the TrackBase destructor with mLock held
52465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client.clear();
52565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track.clear();
52665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
52765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
52865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianExit:
529e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (status != NULL) {
53065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        *status = lStatus;
53165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
53265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return trackHandle;
53365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
53465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
53572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenuint32_t AudioFlinger::sampleRate(audio_io_handle_t output) const
53665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
53765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
53865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
53965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
5405ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("sampleRate() unknown thread %d", output);
54165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
54265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
54365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->sampleRate();
54465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
54565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
54672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenint AudioFlinger::channelCount(audio_io_handle_t output) const
54765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
54865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
54965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
55065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
5515ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("channelCount() unknown thread %d", output);
55265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
55365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
55465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->channelCount();
55565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
55665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
55772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenaudio_format_t AudioFlinger::format(audio_io_handle_t output) const
55865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
55965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
56065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
56165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
5625ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("format() unknown thread %d", output);
56358f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        return AUDIO_FORMAT_INVALID;
56465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
56565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->format();
56665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
56765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
56872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastensize_t AudioFlinger::frameCount(audio_io_handle_t output) const
56965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
57065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
57165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
57265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
5735ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("frameCount() unknown thread %d", output);
57465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
57565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
57658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // FIXME currently returns the normal mixer's frame count to avoid confusing legacy callers;
57758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    //       should examine all callers and fix them to handle smaller counts
57865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->frameCount();
57965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
58065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
58172ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenuint32_t AudioFlinger::latency(audio_io_handle_t output) const
58265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
58365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
58465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
58565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
5865ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("latency() unknown thread %d", output);
58765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
58865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
58965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->latency();
59065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
59165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
59265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setMasterVolume(float value)
59365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
594a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
595a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
596a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
597a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
598a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
59965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
60065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
60165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
60265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
60365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
604a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    Mutex::Autolock _l(mLock);
605ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    mMasterVolume = value;
606a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
607ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Set master volume in the HALs which support it.
608ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
609ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AutoMutex lock(mHardwareLock);
610ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
6114ff14bae91075eb274eb1c2975982358946e7e63John Grossman
612ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
613ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (dev->canSetMasterVolume()) {
614ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            dev->hwDevice()->set_master_volume(dev->hwDevice(), value);
615935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent        }
616ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_IDLE;
61765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
61865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
619ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Now set the master volume in each playback thread.  Playback threads
620ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // assigned to HALs which do not have master volume support will apply
621ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // master volume during the mix operation.  Threads with HALs which do
622ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // support master volume will simply ignore the setting.
6238d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i < mPlaybackThreads.size(); i++)
624ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mPlaybackThreads.valueAt(i)->setMasterVolume(value);
62565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
62665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
62765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
62865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
629f78aee70d15daf4690de7e7b4983ee68b0d1381dGlenn Kastenstatus_t AudioFlinger::setMode(audio_mode_t mode)
63065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
631a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
632a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
633a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
634a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
63565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
63765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
63865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
63965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
640930f4caa1e311ef7ff538c421a324396157eb24fGlenn Kasten    if (uint32_t(mode) >= AUDIO_MODE_CNT) {
6415ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Illegal value: setMode(%d)", mode);
64265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
64365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
64465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
64565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    { // scope for the lock
64665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        AutoMutex lock(mHardwareLock);
647ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
64865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mHardwareStatus = AUDIO_HW_SET_MODE;
649ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        ret = dev->set_mode(dev, mode);
65065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mHardwareStatus = AUDIO_HW_IDLE;
65165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
65265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
65365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (NO_ERROR == ret) {
65465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
65565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mMode = mode;
6568d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        for (size_t i = 0; i < mPlaybackThreads.size(); i++)
657e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            mPlaybackThreads.valueAt(i)->setMode(mode);
65865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
65965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ret;
66165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
66265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setMicMute(bool state)
66465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
665a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
666a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
667a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
668a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
669a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
67065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
67165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
67265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
67365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
67465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
67565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mHardwareLock);
676ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
67765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
678ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    ret = dev->set_mic_mute(dev, state);
67965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_IDLE;
68065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ret;
68165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
68265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::getMicMute() const
68465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
685a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
686a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
687a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return false;
688a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
689a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
690fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    bool state = AUDIO_MODE_INVALID;
6912b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    AutoMutex lock(mHardwareLock);
692ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
69365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
694ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    dev->get_mic_mute(dev, &state);
69565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_IDLE;
69665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return state;
69765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
69865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
69965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setMasterMute(bool muted)
70065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
701d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    status_t ret = initCheck();
702d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    if (ret != NO_ERROR) {
703d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman        return ret;
704d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    }
705d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
70665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
70765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
70865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
70965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
71065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
711ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    Mutex::Autolock _l(mLock);
712ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    mMasterMute = muted;
713d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
714ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Set master mute in the HALs which support it.
715ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
716ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AutoMutex lock(mHardwareLock);
717ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
718d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
719ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
720ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (dev->canSetMasterMute()) {
721ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            dev->hwDevice()->set_master_mute(dev->hwDevice(), muted);
722d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman        }
723ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_IDLE;
724d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    }
725d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
726ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Now set the master mute in each playback thread.  Playback threads
727ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // assigned to HALs which do not have master mute support will apply master
728ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // mute during the mix operation.  Threads with HALs which do support master
729ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // mute will simply ignore the setting.
7308d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i < mPlaybackThreads.size(); i++)
731ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mPlaybackThreads.valueAt(i)->setMasterMute(muted);
73265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
73365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
73465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
73565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
73665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianfloat AudioFlinger::masterVolume() const
73765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
7389806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    Mutex::Autolock _l(mLock);
7399806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    return masterVolume_l();
74065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
74165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
74265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::masterMute() const
74365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
7449806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    Mutex::Autolock _l(mLock);
7459806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    return masterMute_l();
74665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
74765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7484ff14bae91075eb274eb1c2975982358946e7e63John Grossmanfloat AudioFlinger::masterVolume_l() const
7494ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
7504ff14bae91075eb274eb1c2975982358946e7e63John Grossman    return mMasterVolume;
7514ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
7524ff14bae91075eb274eb1c2975982358946e7e63John Grossman
753d8f178d613821c3f61a5c5e391eb275339e526a9John Grossmanbool AudioFlinger::masterMute_l() const
754d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman{
755ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    return mMasterMute;
756d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman}
757d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
75872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
75972ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output)
76065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
76165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
76265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
76365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
76465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
76565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
766263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
76729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setStreamVolume() invalid stream %d", stream);
76865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
76965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
77065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
77165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mLock);
77265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = NULL;
77365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (output) {
77465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread = checkPlaybackThread_l(output);
77565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
77665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return BAD_VALUE;
77765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
77865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
77965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
78065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStreamTypes[stream].volume = value;
78165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
78265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
7838d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
784e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value);
78565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
78665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
78765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread->setStreamVolume(stream, value);
78865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
78965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
79165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
79265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
793fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatus_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)
79465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
79565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
79665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
79765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
79865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
79965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
800263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT ||
801fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) {
80229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setStreamMute() invalid stream %d", stream);
80365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
80465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
80565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
806935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    AutoMutex lock(mLock);
80765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStreamTypes[stream].mute = muted;
80865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
809e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
81065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
81265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
81365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenfloat AudioFlinger::streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const
81565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
816263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
81765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0.0f;
81865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
81965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
82065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mLock);
82165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    float volume;
82265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (output) {
82365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        PlaybackThread *thread = checkPlaybackThread_l(output);
82465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
82565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return 0.0f;
82665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
82765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        volume = thread->streamVolume(stream);
82865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
8296637baae4244aec731c4014da72418d330636ae1Glenn Kasten        volume = streamVolume_l(stream);
83065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
83165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
83265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return volume;
83365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
83465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
835fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenbool AudioFlinger::streamMute(audio_stream_type_t stream) const
83665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
837263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
83865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return true;
83965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
84065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8416637baae4244aec731c4014da72418d330636ae1Glenn Kasten    AutoMutex lock(mLock);
8426637baae4244aec731c4014da72418d330636ae1Glenn Kasten    return streamMute_l(stream);
84365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
84465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
84572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
84665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
847827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten    ALOGV("setParameters(): io %d, keyvalue %s, calling pid %d",
848827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten            ioHandle, keyValuePairs.string(), IPCThreadState::self()->getCallingPid());
84981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
85065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
85165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
85265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
85365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
85465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
85565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // ioHandle == 0 means the parameters are global to the audio hardware interface
85665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (ioHandle == 0) {
857a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        Mutex::Autolock _l(mLock);
858799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        status_t final_result = NO_ERROR;
8598abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten        {
860a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            AutoMutex lock(mHardwareLock);
861a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            mHardwareStatus = AUDIO_HW_SET_PARAMETER;
862a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
863a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
864a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                status_t result = dev->set_parameters(dev, keyValuePairs.string());
865a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                final_result = result ?: final_result;
866a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            }
867a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            mHardwareStatus = AUDIO_HW_IDLE;
8688abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten        }
86959bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
87059bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        AudioParameter param = AudioParameter(keyValuePairs);
87159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        String8 value;
87259bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        if (param.get(String8(AUDIO_PARAMETER_KEY_BT_NREC), value) == NO_ERROR) {
873bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent            bool btNrecIsOff = (value == AUDIO_PARAMETER_VALUE_OFF);
874bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent            if (mBtNrecIsOff != btNrecIsOff) {
87559bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                for (size_t i = 0; i < mRecordThreads.size(); i++) {
87659bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                    sp<RecordThread> thread = mRecordThreads.valueAt(i);
877f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                    audio_devices_t device = thread->inDevice();
878510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    bool suspend = audio_is_bluetooth_sco_device(device) && btNrecIsOff;
879510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    // collect all of the thread's session IDs
880510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    KeyedVector<int, bool> ids = thread->sessionIds();
881510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    // suspend effects associated with those session IDs
882510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    for (size_t j = 0; j < ids.size(); ++j) {
883510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                        int sessionId = ids.keyAt(j);
88459bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                        thread->setEffectSuspended(FX_IID_AEC,
88559bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                                                   suspend,
886510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                                                   sessionId);
88759bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                        thread->setEffectSuspended(FX_IID_NS,
88859bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                                                   suspend,
889510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                                                   sessionId);
89059bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                    }
89159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                }
892bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent                mBtNrecIsOff = btNrecIsOff;
89359bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent            }
89459bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        }
89528ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        String8 screenState;
89628ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        if (param.get(String8(AudioParameter::keyScreenState), screenState) == NO_ERROR) {
89728ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten            bool isOff = screenState == "off";
89881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (isOff != (AudioFlinger::mScreenState & 1)) {
89981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                AudioFlinger::mScreenState = ((AudioFlinger::mScreenState & ~1) + 2) | isOff;
90028ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten            }
90128ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        }
902799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        return final_result;
90365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
90465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
90565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // hold a strong ref on thread in case closeOutput() or closeInput() is called
90665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // and the thread is exited once the lock is released
90765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ThreadBase> thread;
90865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
90965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
91065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread = checkPlaybackThread_l(ioHandle);
911d5903ec1332630f2992a6f0d5ca69d13a185c665Glenn Kasten        if (thread == 0) {
91265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            thread = checkRecordThread_l(ioHandle);
9137fc9a6fdf146ded90b51c52f4a05d797294dcb85Glenn Kasten        } else if (thread == primaryPlaybackThread_l()) {
9147c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            // indicate output device change to all input threads for pre processing
9157c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            AudioParameter param = AudioParameter(keyValuePairs);
9167c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            int value;
91789d94e79dad032fb18ddc655e6068e4231d3f0aaEric Laurent            if ((param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) &&
91889d94e79dad032fb18ddc655e6068e4231d3f0aaEric Laurent                    (value != 0)) {
9197c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                for (size_t i = 0; i < mRecordThreads.size(); i++) {
9207c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                    mRecordThreads.valueAt(i)->setParameters(keyValuePairs);
9217c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                }
9227c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            }
92365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
92465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
9257378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten    if (thread != 0) {
9267378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten        return thread->setParameters(keyValuePairs);
92765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
92865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BAD_VALUE;
92965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
93065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
93172ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn KastenString8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& keys) const
93265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
933827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten    ALOGVV("getParameters() io %d, keys %s, calling pid %d",
934827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten            ioHandle, keys.string(), IPCThreadState::self()->getCallingPid());
93565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
936a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    Mutex::Autolock _l(mLock);
937a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
93865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (ioHandle == 0) {
939fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        String8 out_s8;
940fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
941799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
9428abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            char *s;
9438abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            {
9448abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            AutoMutex lock(mHardwareLock);
9458abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            mHardwareStatus = AUDIO_HW_GET_PARAMETER;
946a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
9478abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            s = dev->get_parameters(dev, keys.string());
9488abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            mHardwareStatus = AUDIO_HW_IDLE;
9498abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            }
950ef7740be67a4d7b6b033ebed59c3d4a9c74a2c18John Grossman            out_s8 += String8(s ? s : "");
951799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            free(s);
952799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        }
953fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return out_s8;
95465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
95565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
95665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *playbackThread = checkPlaybackThread_l(ioHandle);
95765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (playbackThread != NULL) {
95865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return playbackThread->getParameters(keys);
95965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
96065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    RecordThread *recordThread = checkRecordThread_l(ioHandle);
96165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (recordThread != NULL) {
96265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return recordThread->getParameters(keys);
96365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
96465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return String8("");
96565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
96665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
967dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kastensize_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format,
968dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten        audio_channel_mask_t channelMask) const
96965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
970a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
971a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
972a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return 0;
973a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
974a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
9752b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    AutoMutex lock(mHardwareLock);
9762b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
977f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    struct audio_config config = {
978f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        sample_rate: sampleRate,
979dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten        channel_mask: channelMask,
980f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        format: format,
981f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    };
982ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
983ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    size_t size = dev->get_input_buffer_size(dev, &config);
9842b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    mHardwareStatus = AUDIO_HW_IDLE;
9852b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    return size;
98665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
98765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
98872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenunsigned int AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const
98965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
99065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
99165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
99265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    RecordThread *recordThread = checkRecordThread_l(ioHandle);
99365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (recordThread != NULL) {
99465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return recordThread->getInputFramesLost();
99565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
99665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return 0;
99765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
99865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
99965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setVoiceVolume(float value)
100065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1001a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
1002a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
1003a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
1004a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
1005a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
100665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
100765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
100865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
100965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
101065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
101165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mHardwareLock);
1012ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
10138abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten    mHardwareStatus = AUDIO_HW_SET_VOICE_VOLUME;
1014ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    ret = dev->set_voice_volume(dev, value);
101565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_IDLE;
101665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
101765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ret;
101865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
101965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102026c77556efc30800466b60b3975bc35a70c8c28bGlenn Kastenstatus_t AudioFlinger::getRenderPosition(size_t *halFrames, size_t *dspFrames,
102172ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output) const
102265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
102365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status;
102465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
102665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *playbackThread = checkPlaybackThread_l(output);
102865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (playbackThread != NULL) {
102965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return playbackThread->getRenderPosition(halFrames, dspFrames);
103065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
103165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BAD_VALUE;
103365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
103465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
103665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
103765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
103965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1040bb001926447d0b7dc71ca8bb3c9856f3136d8f4cGlenn Kasten    pid_t pid = IPCThreadState::self()->getCallingPid();
104165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mNotificationClients.indexOfKey(pid) < 0) {
104265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<NotificationClient> notificationClient = new NotificationClient(this,
104365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                                                            client,
104465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                                                            pid);
10453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("registerClient() client %p, pid %d", notificationClient.get(), pid);
104665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
104765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mNotificationClients.add(pid, notificationClient);
104865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
104965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<IBinder> binder = client->asBinder();
105065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        binder->linkToDeath(notificationClient);
105165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // the config change is always sent from playback or record threads to avoid deadlock
105365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // with AudioSystem::gLock
105465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
1055896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AudioSystem::OUTPUT_OPENED);
105665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
105765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mRecordThreads.size(); i++) {
1059896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            mRecordThreads.valueAt(i)->sendIoConfigEvent(AudioSystem::INPUT_OPENED);
106065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
106165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
106265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
106365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
106465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::removeNotificationClient(pid_t pid)
106565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
106665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
106765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1068a3b09254d44cd8d66ec947abe547538c4cfeaa89Glenn Kasten    mNotificationClients.removeItem(pid);
10693a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
10703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("%d died, releasing its sessions", pid);
10718d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    size_t num = mAudioSessionRefs.size();
10723a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    bool removed = false;
10738d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i< num; ) {
10743a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
1075012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        ALOGV(" pid %d @ %d", ref->mPid, i);
1076012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        if (ref->mPid == pid) {
1077012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten            ALOGV(" removing entry for pid %d session %d", pid, ref->mSessionid);
10783a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            mAudioSessionRefs.removeAt(i);
10793a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            delete ref;
10803a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            removed = true;
10813a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            num--;
10828d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        } else {
10838d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten            i++;
10843a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        }
10853a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
10863a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    if (removed) {
10873a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        purgeStaleEffects_l();
10883a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
108965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
109065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
109165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// audioConfigChanged_l() must be called with AudioFlinger::mLock held
1092b81cc8c6f3eec9edb255ea99b6a6f243585b1e38Glenn Kastenvoid AudioFlinger::audioConfigChanged_l(int event, audio_io_handle_t ioHandle, const void *param2)
109365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
109465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mNotificationClients.size();
109565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < size; i++) {
109684afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioHandle,
109784afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten                                                                               param2);
109865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
109965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
110065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
110165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// removeClient_l() must be called with AudioFlinger::mLock held
110265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::removeClient_l(pid_t pid)
110365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1104827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten    ALOGV("removeClient_l() pid %d, calling pid %d", pid,
110585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            IPCThreadState::self()->getCallingPid());
110665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClients.removeItem(pid);
110765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
110865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1109717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent// getEffectThread_l() must be called with AudioFlinger::mLock held
1110717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurentsp<AudioFlinger::PlaybackThread> AudioFlinger::getEffectThread_l(int sessionId, int EffectId)
1111717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent{
1112717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    sp<PlaybackThread> thread;
1113717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
1114717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
1115717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent        if (mPlaybackThreads.valueAt(i)->getEffect(sessionId, EffectId) != 0) {
1116717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            ALOG_ASSERT(thread == 0);
1117717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            thread = mPlaybackThreads.valueAt(i);
1118717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent        }
1119717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    }
1120717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
1121717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    return thread;
1122717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent}
112365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
112481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
112581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
112665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
112765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
112881784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
112981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    :   RefBase(),
113081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mAudioFlinger(audioFlinger),
113181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // FIXME should be a "k" constant not hard-coded, in .h or ro. property, see 4 lines below
113281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mMemoryDealer(new MemoryDealer(1024*1024, "AudioFlinger::Client")),
113381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPid(pid),
113481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mTimedTrackCount(0)
113565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
113681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
113765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
113865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
113981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Client destructor must be called with AudioFlinger::mLock held
114081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::Client::~Client()
114165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
114281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAudioFlinger->removeClient_l(mPid);
114365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
114465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
114581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<MemoryDealer> AudioFlinger::Client::heap() const
114665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
114781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mMemoryDealer;
114865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
114965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Reserve one of the limited slots for a timed audio track associated
115181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// with this client
115281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::Client::reserveTimedTrack()
115365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
115481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    const int kMaxTimedTracksPerClient = 4;
115565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mTimedTrackLock);
115765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mTimedTrackCount >= kMaxTimedTracksPerClient) {
115981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("can not create timed track - pid %d has exceeded the limit",
116081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent             mPid);
116181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return false;
116265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
116365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
116481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTimedTrackCount++;
116581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return true;
116665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
116765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
116881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Release a slot for a timed audio track
116981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::Client::releaseTimedTrack()
117065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
117181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mTimedTrackLock);
117281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTimedTrackCount--;
1173896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent}
1174896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent
117581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
117681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
117781784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger,
117881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                     const sp<IAudioFlingerClient>& client,
117981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                     pid_t pid)
118081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    : mAudioFlinger(audioFlinger), mPid(pid), mAudioFlingerClient(client)
1181896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent{
118265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
118365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
118481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::NotificationClient::~NotificationClient()
118565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
118665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
118765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
118881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who)
118965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
119081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<NotificationClient> keep(this);
119181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAudioFlinger->removeNotificationClient(mPid);
119281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
119365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
119465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
119581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
119665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
119781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<IAudioRecord> AudioFlinger::openRecord(
119881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_io_handle_t input,
119981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        uint32_t sampleRate,
120081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_format_t format,
120181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_channel_mask_t channelMask,
120281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        size_t frameCount,
120381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        IAudioFlinger::track_flags_t flags,
120481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        pid_t tid,
120581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int *sessionId,
120681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status_t *status)
12071d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent{
120881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<RecordThread::RecordTrack> recordTrack;
120981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<RecordHandle> recordHandle;
121081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<Client> client;
121181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t lStatus;
121281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    RecordThread *thread;
121381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t inFrameCount;
121481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    int lSessionId;
12151d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
121681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // check calling permissions
121781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!recordingAllowed()) {
121881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        lStatus = PERMISSION_DENIED;
121981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
122081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
12211d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
122281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // add client to list
122381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    { // scope for mLock
122481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(mLock);
122581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread = checkRecordThread_l(input);
122681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread == NULL) {
122781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = BAD_VALUE;
122881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            goto Exit;
12291d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        }
12301d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
12318d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kasten        pid_t pid = IPCThreadState::self()->getCallingPid();
123281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        client = registerPid_l(pid);
1233feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
123481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // If no audio session id is provided, create one here
123581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) {
123681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lSessionId = *sessionId;
1237feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        } else {
123881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lSessionId = nextUniqueId();
123981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (sessionId != NULL) {
124081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                *sessionId = lSessionId;
124181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
1242feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
124381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // create new record track.
124481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // The record track uses one track in mHardwareMixerThread by convention.
124581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        recordTrack = thread->createRecordTrack_l(client, sampleRate, format, channelMask,
124681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                  frameCount, lSessionId, flags, tid, &lStatus);
1247feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
124881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (lStatus != NO_ERROR) {
124981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // remove local strong reference to Client before deleting the RecordTrack so that the
125081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Client destructor is called by the TrackBase destructor with mLock held
125181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        client.clear();
125281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        recordTrack.clear();
125381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
1254feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
1255feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
125681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // return to handle to client
125781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    recordHandle = new RecordHandle(recordTrack);
125881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    lStatus = NO_ERROR;
1259feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
126081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentExit:
126181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status) {
126281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        *status = lStatus;
1263feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
126481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return recordHandle;
1265feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
1266feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1267feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
12681d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
126981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
127081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
127181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_module_handle_t AudioFlinger::loadHwModule(const char *name)
127259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
127381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!settingsAllowed()) {
127481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
127581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
127659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    Mutex::Autolock _l(mLock);
127781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return loadHwModule_l(name);
127859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
127959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
128081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// loadHwModule_l() must be called with AudioFlinger::mLock held
128181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
128259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
128381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
128481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
128581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGW("loadHwModule() module %s already loaded", name);
128681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return mAudioHwDevs.keyAt(i);
128759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
128859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
128959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
129081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_hw_device_t *dev;
129159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
129281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    int rc = load_audio_interface(name, &dev);
129381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (rc) {
129481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGI("loadHwModule() error %d loading module %s ", rc, name);
129581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
129659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
129759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
129881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mHardwareStatus = AUDIO_HW_INIT;
129981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    rc = dev->init_check(dev);
130081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mHardwareStatus = AUDIO_HW_IDLE;
130181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (rc) {
130281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGI("loadHwModule() init check error %d for module %s ", rc, name);
130381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
130459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
130559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
130681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // Check and cache this HAL's level of support for master mute and master
130781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // volume.  If this is the first HAL opened, and it supports the get
130881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // methods, use the initial values provided by the HAL as the current
130981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // master mute and volume settings.
131059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
131181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioHwDevice::Flags flags = static_cast<AudioHwDevice::Flags>(0);
131281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {  // scope for auto-lock pattern
131381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AutoMutex lock(mHardwareLock);
131459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
131581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (0 == mAudioHwDevs.size()) {
131681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
131781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (NULL != dev->get_master_volume) {
131881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                float mv;
131981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (OK == dev->get_master_volume(dev, &mv)) {
132081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    mMasterVolume = mv;
132181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                }
132281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
132381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
132481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
132581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (NULL != dev->get_master_mute) {
132681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                bool mm;
132781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (OK == dev->get_master_mute(dev, &mm)) {
132881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    mMasterMute = mm;
132981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                }
133081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
133159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
133281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
133381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
133481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((NULL != dev->set_master_volume) &&
133581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (OK == dev->set_master_volume(dev, mMasterVolume))) {
133681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            flags = static_cast<AudioHwDevice::Flags>(flags |
133781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
133859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
133959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
134081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
134181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((NULL != dev->set_master_mute) &&
134281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (OK == dev->set_master_mute(dev, mMasterMute))) {
134381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            flags = static_cast<AudioHwDevice::Flags>(flags |
134481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
134581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
134659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
134781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mHardwareStatus = AUDIO_HW_IDLE;
134859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
134959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
135081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_module_handle_t handle = nextUniqueId();
135181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAudioHwDevs.add(handle, new AudioHwDevice(name, dev, flags));
135281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
135381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGI("loadHwModule() Loaded %s audio interface from %s (%s) handle %d",
135481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent          name, dev->common.module->name, dev->common.module->id, handle);
135581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
135681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return handle;
135781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
135859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
135959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
136081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
136181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
136281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::getPrimaryOutputSamplingRate()
136359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
136459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    Mutex::Autolock _l(mLock);
136581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = primaryPlaybackThread_l();
136681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return thread != NULL ? thread->sampleRate() : 0;
1367a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent}
136859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
136981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsize_t AudioFlinger::getPrimaryOutputFrameCount()
1370a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent{
137181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
137281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = primaryPlaybackThread_l();
137381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return thread != NULL ? thread->frameCountHAL() : 0;
137459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
137559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
137665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
137765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
137881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
137981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           audio_devices_t *pDevices,
138081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           uint32_t *pSamplingRate,
138181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           audio_format_t *pFormat,
138281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           audio_channel_mask_t *pChannelMask,
138381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           uint32_t *pLatencyMs,
138481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           audio_output_flags_t flags)
138565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
138681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status;
138781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = NULL;
138881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    struct audio_config config = {
138981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sample_rate: pSamplingRate ? *pSamplingRate : 0,
139081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        channel_mask: pChannelMask ? *pChannelMask : 0,
139181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        format: pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT,
139281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    };
139381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_stream_out_t *outStream = NULL;
139481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioHwDevice *outHwDev;
1395ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
139681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %d, Channels %x, flags %x",
139781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              module,
139881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              (pDevices != NULL) ? *pDevices : 0,
139981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              config.sample_rate,
140081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              config.format,
140181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              config.channel_mask,
140281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              flags);
140381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
140481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (pDevices == NULL || *pDevices == 0) {
140581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
1406ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    }
1407ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
140881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
140965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
141081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    outHwDev = findSuitableHwDev_l(module, *pDevices);
141181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (outHwDev == NULL)
141281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
141365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
141481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_hw_device_t *hwDevHal = outHwDev->hwDevice();
141581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_io_handle_t id = nextUniqueId();
141665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
141781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
141865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
141981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status = hwDevHal->open_output_stream(hwDevHal,
142081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          id,
142181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          *pDevices,
142281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          (audio_output_flags_t)flags,
142381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          &config,
142481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          &outStream);
142565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
142681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mHardwareStatus = AUDIO_HW_IDLE;
142781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, "
142881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            "Channels %x, status %d",
142981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            outStream,
143081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.sample_rate,
143181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.format,
143281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.channel_mask,
143381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            status);
143458912562617941964939a4182cda71eaeb153d4bGlenn Kasten
143581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status == NO_ERROR && outStream != NULL) {
143681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream);
143765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
143881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) ||
143981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (config.format != AUDIO_FORMAT_PCM_16_BIT) ||
144081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (config.channel_mask != AUDIO_CHANNEL_OUT_STEREO)) {
144181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            thread = new DirectOutputThread(this, output, id, *pDevices);
144281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("openOutput() created direct output: ID %d thread %p", id, thread);
144381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
144481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            thread = new MixerThread(this, output, id, *pDevices);
144581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("openOutput() created mixer output: ID %d thread %p", id, thread);
144665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
144781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPlaybackThreads.add(id, thread);
144888cbea8a918bbaf5e06e48aadd5af5e81d58d232Glenn Kasten
144981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pSamplingRate != NULL) *pSamplingRate = config.sample_rate;
145081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pFormat != NULL) *pFormat = config.format;
145181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pChannelMask != NULL) *pChannelMask = config.channel_mask;
145281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pLatencyMs != NULL) *pLatencyMs = thread->latency();
145365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
145481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // notify client processes of the new output creation
145581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);
145665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
145781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // the first primary output opened designates the primary hw device
145881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((mPrimaryHardwareDev == NULL) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
145981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGI("Using module %d has the primary audio interface", module);
146081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mPrimaryHardwareDev = outHwDev;
146181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
146281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AutoMutex lock(mHardwareLock);
146381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mHardwareStatus = AUDIO_HW_SET_MODE;
146481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            hwDevHal->set_mode(hwDevHal, mMode);
146581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mHardwareStatus = AUDIO_HW_IDLE;
146681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
146781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return id;
146881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
146965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
147081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return 0;
147165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
147265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
147381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1,
147481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_io_handle_t output2)
147565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
147681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
147781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    MixerThread *thread1 = checkMixerThread_l(output1);
147881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    MixerThread *thread2 = checkMixerThread_l(output2);
147981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
148081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread1 == NULL || thread2 == NULL) {
148181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("openDuplicateOutput() wrong output mixer type for output %d or %d", output1,
148281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                output2);
148381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
148465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
148565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
148681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_io_handle_t id = nextUniqueId();
148781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    DuplicatingThread *thread = new DuplicatingThread(this, thread1, id);
148881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->addOutputTrack(thread2);
148981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mPlaybackThreads.add(id, thread);
149081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // notify client processes of the new output creation
149181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);
149281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return id;
149365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
149465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
149581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::closeOutput(audio_io_handle_t output)
14962bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi{
149781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return closeOutput_nonvirtual(output);
14982bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi}
14992bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi
150081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output)
150165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
150281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // keep strong reference on the playback thread so that
150381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // it is not destroyed while exit() is executed
150481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<PlaybackThread> thread;
150581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
150681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(mLock);
150781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread = checkPlaybackThread_l(output);
150881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread == NULL) {
150981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return BAD_VALUE;
151065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
151165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
151281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("closeOutput() %d", output);
1513de070137f11d346fba77605bd76a44c040a618fcEric Laurent
151481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread->type() == ThreadBase::MIXER) {
151581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
151681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (mPlaybackThreads.valueAt(i)->type() == ThreadBase::DUPLICATING) {
151781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    DuplicatingThread *dupThread =
151881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                            (DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
151981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    dupThread->removeOutputTrack((MixerThread *)thread.get());
1520de070137f11d346fba77605bd76a44c040a618fcEric Laurent                }
1521de070137f11d346fba77605bd76a44c040a618fcEric Laurent            }
1522de070137f11d346fba77605bd76a44c040a618fcEric Laurent        }
152381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, NULL);
152481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPlaybackThreads.removeItem(output);
15253acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    }
152681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->exit();
152781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // The thread entity (active unit of execution) is no longer running here,
152881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // but the ThreadBase container still exists.
15293acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten
153081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread->type() != ThreadBase::DUPLICATING) {
153181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioStreamOut *out = thread->clearOutput();
153281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOG_ASSERT(out != NULL, "out shouldn't be NULL");
153381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // from now on thread->mOutput is NULL
153481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        out->hwDev()->close_output_stream(out->hwDev(), out->stream);
153581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        delete out;
153665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
153781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
153865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
153965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
154081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::suspendOutput(audio_io_handle_t output)
1541e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent{
154281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
154381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = checkPlaybackThread_l(output);
154481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
154581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread == NULL) {
154681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
1547e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent    }
1548e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent
154981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("suspendOutput() %d", output);
155081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->suspend();
1551e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent
155281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
155365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
155465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
155581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::restoreOutput(audio_io_handle_t output)
155665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
15576637baae4244aec731c4014da72418d330636ae1Glenn Kasten    Mutex::Autolock _l(mLock);
155881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = checkPlaybackThread_l(output);
155965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
156081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread == NULL) {
156181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
1562ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    }
156365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
156481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("restoreOutput() %d", output);
156565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
156681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->restore();
156765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
156881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
156965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
157065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
157181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,
157281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          audio_devices_t *pDevices,
157381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          uint32_t *pSamplingRate,
157481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          audio_format_t *pFormat,
157581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          audio_channel_mask_t *pChannelMask)
157665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
157781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status;
157881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    RecordThread *thread = NULL;
157981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    struct audio_config config = {
158081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sample_rate: pSamplingRate ? *pSamplingRate : 0,
158181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        channel_mask: pChannelMask ? *pChannelMask : 0,
158281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        format: pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT,
158381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    };
158481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t reqSamplingRate = config.sample_rate;
158581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_format_t reqFormat = config.format;
158681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_channel_mask_t reqChannels = config.channel_mask;
158781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_stream_in_t *inStream = NULL;
158881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioHwDevice *inHwDev;
158965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
159081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (pDevices == NULL || *pDevices == 0) {
159181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
1592b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    }
1593b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent
159481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
159565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
159681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    inHwDev = findSuitableHwDev_l(module, *pDevices);
159781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (inHwDev == NULL)
159881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
1599fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
160081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_hw_device_t *inHwHal = inHwDev->hwDevice();
160181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_io_handle_t id = nextUniqueId();
1602b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
160381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config,
160481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        &inStream);
160581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, "
160681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            "status %d",
160781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            inStream,
160881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.sample_rate,
160981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.format,
161081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.channel_mask,
161181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            status);
161265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
161381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // If the input could not be opened with the requested parameters and we can handle the
161481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // conversion internally, try to open again with the proposed parameters. The AudioFlinger can
161581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // resample the input and do mono to stereo or stereo to mono conversions on 16 bit PCM inputs.
161681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status == BAD_VALUE &&
161781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        reqFormat == config.format && config.format == AUDIO_FORMAT_PCM_16_BIT &&
161881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        (config.sample_rate <= 2 * reqSamplingRate) &&
161981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        (popcount(config.channel_mask) <= FCC_2) && (popcount(reqChannels) <= FCC_2)) {
162081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("openInput() reopening with proposed sampling rate and channel mask");
162181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        inStream = NULL;
162281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config, &inStream);
162365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
162465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
162581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status == NO_ERROR && inStream != NULL) {
162658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
162781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Try to re-use most recently used Pipe to archive a copy of input for dumpsys,
162881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // or (re-)create if current Pipe is idle and does not match the new format
162981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<NBAIO_Sink> teeSink;
163081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        enum {
163181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            TEE_SINK_NO,    // don't copy input
163281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            TEE_SINK_NEW,   // copy input using a new pipe
163381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            TEE_SINK_OLD,   // copy input using an existing pipe
163481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } kind;
163581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        NBAIO_Format format = Format_from_SR_C(inStream->common.get_sample_rate(&inStream->common),
163681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        popcount(inStream->common.get_channels(&inStream->common)));
1637da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        if (!mTeeSinkInputEnabled) {
1638da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            kind = TEE_SINK_NO;
1639da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        } else if (format == Format_Invalid) {
164081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_NO;
164181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else if (mRecordTeeSink == 0) {
164281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_NEW;
164381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else if (mRecordTeeSink->getStrongCount() != 1) {
164481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_NO;
164581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else if (format == mRecordTeeSink->format()) {
164681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_OLD;
16474adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        } else {
164881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_NEW;
164981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
165081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        switch (kind) {
165181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        case TEE_SINK_NEW: {
1652da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            Pipe *pipe = new Pipe(mTeeSinkInputFrames, format);
165381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t numCounterOffers = 0;
165481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const NBAIO_Format offers[1] = {format};
165581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
165681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOG_ASSERT(index == 0);
165781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PipeReader *pipeReader = new PipeReader(*pipe);
165881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            numCounterOffers = 0;
165981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
166081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOG_ASSERT(index == 0);
166181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mRecordTeeSink = pipe;
166281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mRecordTeeSource = pipeReader;
166381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            teeSink = pipe;
16644adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            }
166581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            break;
166681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        case TEE_SINK_OLD:
166781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            teeSink = mRecordTeeSink;
166881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            break;
166981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        case TEE_SINK_NO:
167081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        default:
167181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            break;
167258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
1673da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
167481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);
167565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
167681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Start record thread
167781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // RecorThread require both input and output device indication to forward to audio
167881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // pre processing modules
167981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread = new RecordThread(this,
168081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                  input,
168181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                  reqSamplingRate,
168281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                  reqChannels,
168381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                  id,
1684d3922f72601d82c6fc067a98916fda0bd1291c5fEric Laurent                                  primaryOutputDevice_l(),
1685d3922f72601d82c6fc067a98916fda0bd1291c5fEric Laurent                                  *pDevices,
1686d3922f72601d82c6fc067a98916fda0bd1291c5fEric Laurent                                  teeSink);
168781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mRecordThreads.add(id, thread);
168881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("openInput() created record thread: ID %d thread %p", id, thread);
168981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pSamplingRate != NULL) *pSamplingRate = reqSamplingRate;
169081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pFormat != NULL) *pFormat = config.format;
169181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pChannelMask != NULL) *pChannelMask = reqChannels;
169265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
169381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // notify client processes of the new input creation
169481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread->audioConfigChanged_l(AudioSystem::INPUT_OPENED);
169581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return id;
16961afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent    }
169781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
169881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return 0;
169965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
170065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
170181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::closeInput(audio_io_handle_t input)
170265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
170381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return closeInput_nonvirtual(input);
170465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
170565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
170681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input)
1707de070137f11d346fba77605bd76a44c040a618fcEric Laurent{
170881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // keep strong reference on the record thread so that
170981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // it is not destroyed while exit() is executed
171081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<RecordThread> thread;
171181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
171281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(mLock);
171381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread = checkRecordThread_l(input);
171481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread == 0) {
171581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return BAD_VALUE;
1716de070137f11d346fba77605bd76a44c040a618fcEric Laurent        }
171781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
171881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("closeInput() %d", input);
171981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audioConfigChanged_l(AudioSystem::INPUT_CLOSED, input, NULL);
172081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mRecordThreads.removeItem(input);
1721de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
172281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->exit();
172381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // The thread entity (active unit of execution) is no longer running here,
172481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // but the ThreadBase container still exists.
1725de070137f11d346fba77605bd76a44c040a618fcEric Laurent
172681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioStreamIn *in = thread->clearInput();
172781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOG_ASSERT(in != NULL, "in shouldn't be NULL");
172881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // from now on thread->mInput is NULL
172981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    in->hwDev()->close_input_stream(in->hwDev(), in->stream);
173081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    delete in;
173165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
173281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
1733b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
1734b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
173581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output)
1736b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent{
1737b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    Mutex::Autolock _l(mLock);
173881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("setStreamOutput() stream %d to output %d", stream, output);
1739b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
174081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
174181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
174281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread->invalidateTracks(stream);
1743b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    }
174481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
174581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
1746b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
1747b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
174881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
174981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentint AudioFlinger::newAudioSessionId()
1750162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent{
175181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return nextUniqueId();
1752162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent}
1753162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent
175481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::acquireAudioSessionId(int audioSession)
1755a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
1756a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    Mutex::Autolock _l(mLock);
175781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    pid_t caller = IPCThreadState::self()->getCallingPid();
175881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("acquiring %d from %d", audioSession, caller);
175981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t num = mAudioSessionRefs.size();
176081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i< num; i++) {
176181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioSessionRef *ref = mAudioSessionRefs.editItemAt(i);
176281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (ref->mSessionid == audioSession && ref->mPid == caller) {
176381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ref->mCnt++;
176481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV(" incremented refcount to %d", ref->mCnt);
176581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return;
1766a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
1767a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
176881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAudioSessionRefs.push(new AudioSessionRef(audioSession, caller));
176981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV(" added new entry for %d", audioSession);
1770a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
1771a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
177281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::releaseAudioSessionId(int audioSession)
177344a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent{
177481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
177581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    pid_t caller = IPCThreadState::self()->getCallingPid();
177681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("releasing %d from %d", audioSession, caller);
177781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t num = mAudioSessionRefs.size();
177881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i< num; i++) {
177981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
178081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (ref->mSessionid == audioSession && ref->mPid == caller) {
178181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ref->mCnt--;
178281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV(" decremented refcount to %d", ref->mCnt);
178381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (ref->mCnt == 0) {
178481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mAudioSessionRefs.removeAt(i);
178581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                delete ref;
178681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                purgeStaleEffects_l();
178744a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent            }
178881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return;
178944a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent        }
179044a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent    }
179181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGW("session id %d not found for pid %d", audioSession, caller);
179244a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent}
179344a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent
179481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::purgeStaleEffects_l() {
179565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
179681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("purging stale effects");
1797fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten
179881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Vector< sp<EffectChain> > chains;
179958912562617941964939a4182cda71eaeb153d4bGlenn Kasten
180081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
180181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
180281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        for (size_t j = 0; j < t->mEffectChains.size(); j++) {
180381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectChain> ec = t->mEffectChains[j];
180481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (ec->sessionId() > AUDIO_SESSION_OUTPUT_MIX) {
180581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                chains.push(ec);
180681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
1807c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        }
180858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
180981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mRecordThreads.size(); i++) {
181081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<RecordThread> t = mRecordThreads.valueAt(i);
181181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        for (size_t j = 0; j < t->mEffectChains.size(); j++) {
181281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectChain> ec = t->mEffectChains[j];
181381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            chains.push(ec);
181481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
1815300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    }
181665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
181781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < chains.size(); i++) {
181881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<EffectChain> ec = chains[i];
181981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int sessionid = ec->sessionId();
182081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<ThreadBase> t = ec->mThread.promote();
182181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (t == 0) {
182281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            continue;
182381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
182481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        size_t numsessionrefs = mAudioSessionRefs.size();
182581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        bool found = false;
182681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        for (size_t k = 0; k < numsessionrefs; k++) {
182781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSessionRef *ref = mAudioSessionRefs.itemAt(k);
182881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (ref->mSessionid == sessionid) {
182981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGV(" session %d still exists for %d with %d refs",
183081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    sessionid, ref->mPid, ref->mCnt);
183181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                found = true;
183281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                break;
183358912562617941964939a4182cda71eaeb153d4bGlenn Kasten            }
183458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
183581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (!found) {
183681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _l (t->mLock);
183781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // remove all effects from the chain
183881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            while (ec->mEffects.size()) {
183981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                sp<EffectModule> effect = ec->mEffects[0];
184081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                effect->unPin();
184181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                t->removeEffect_l(effect);
184281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (effect->purgeHandles()) {
184381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    t->checkSuspendOnEffectEnabled_l(effect, false, effect->sessionId());
184481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                }
184581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                AudioSystem::unregisterEffect(effect->id());
184681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
1847c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        }
184858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
184981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return;
185065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
185165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
185281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
185381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
1854190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten{
185581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mPlaybackThreads.valueFor(output).get();
1856190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten}
1857190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
185881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// checkMixerThread_l() must be called with AudioFlinger::mLock held
185981784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(audio_io_handle_t output) const
186081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
186181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = checkPlaybackThread_l(output);
186281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return thread != NULL && thread->type() != ThreadBase::DIRECT ? (MixerThread *) thread : NULL;
186381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
1864190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
186581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// checkRecordThread_l() must be called with AudioFlinger::mLock held
186681784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(audio_io_handle_t input) const
186781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
186881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mRecordThreads.valueFor(input).get();
186981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
1870190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
187181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::nextUniqueId()
187281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
187381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return android_atomic_inc(&mNextUniqueId);
187481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
187583efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten
187681784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
187737d825e72a6c606553a745da1212590a425996d3Glenn Kasten{
187881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
187981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
188081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioStreamOut *output = thread->getOutput();
188181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (output != NULL && output->audioHwDev == mPrimaryHardwareDev) {
188281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return thread;
188337d825e72a6c606553a745da1212590a425996d3Glenn Kasten        }
188437d825e72a6c606553a745da1212590a425996d3Glenn Kasten    }
188581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NULL;
188637d825e72a6c606553a745da1212590a425996d3Glenn Kasten}
188737d825e72a6c606553a745da1212590a425996d3Glenn Kasten
188881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_devices_t AudioFlinger::primaryOutputDevice_l() const
188965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
189081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = primaryPlaybackThread_l();
1891000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
189281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread == NULL) {
189381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
18949f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten    }
1895000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
189681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return thread->outDevice();
1897000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
1898688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten
189981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<AudioFlinger::SyncEvent> AudioFlinger::createSyncEvent(AudioSystem::sync_event_t type,
190081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                    int triggerSession,
190181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                    int listenerSession,
190281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                    sync_event_callback_t callBack,
190381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                    void *cookie)
190481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
190581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
190673ca0f5837d5448f7a5eb159a09cd0ebe82b4de9Glenn Kasten
190781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<SyncEvent> event = new SyncEvent(type, triggerSession, listenerSession, callBack, cookie);
190881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t playStatus = NAME_NOT_FOUND;
190981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t recStatus = NAME_NOT_FOUND;
191081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
191181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        playStatus = mPlaybackThreads.valueAt(i)->setSyncEvent(event);
191281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (playStatus == NO_ERROR) {
191381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return event;
191481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
191565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
191681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mRecordThreads.size(); i++) {
191781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        recStatus = mRecordThreads.valueAt(i)->setSyncEvent(event);
191881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (recStatus == NO_ERROR) {
191981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return event;
19209f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten        }
192165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
192281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (playStatus == NAME_NOT_FOUND || recStatus == NAME_NOT_FOUND) {
192381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPendingSyncEvents.add(event);
192481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
192581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("createSyncEvent() invalid event %d", event->type());
192681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        event.clear();
192781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
192881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return event;
192965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
193065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
193181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
193281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//  Effect management
193381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
193458912562617941964939a4182cda71eaeb153d4bGlenn Kasten
193558912562617941964939a4182cda71eaeb153d4bGlenn Kasten
193681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::queryNumberEffects(uint32_t *numEffects) const
1937000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
193881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
193981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return EffectQueryNumberEffects(numEffects);
1940000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
1941000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
194281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor) const
194358912562617941964939a4182cda71eaeb153d4bGlenn Kasten{
194481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
194581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return EffectQueryEffect(index, descriptor);
194658912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
194758912562617941964939a4182cda71eaeb153d4bGlenn Kasten
194881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::getEffectDescriptor(const effect_uuid_t *pUuid,
194981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        effect_descriptor_t *descriptor) const
1950000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
195181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
195281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return EffectGetDescriptor(pUuid, descriptor);
1953000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
1954000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
195581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
19568d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kastensp<IEffect> AudioFlinger::createEffect(
195781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        effect_descriptor_t *pDesc,
195881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        const sp<IEffectClient>& effectClient,
195981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int32_t priority,
196081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_io_handle_t io,
196181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int sessionId,
196281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status_t *status,
196381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int *id,
196481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int *enabled)
1965000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
196681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t lStatus = NO_ERROR;
196781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<EffectHandle> handle;
196881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    effect_descriptor_t desc;
1969000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
19708d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kasten    pid_t pid = IPCThreadState::self()->getCallingPid();
197181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d",
197281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            pid, effectClient.get(), priority, sessionId, io);
1973000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
197481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (pDesc == NULL) {
197581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        lStatus = BAD_VALUE;
197681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
1977952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
1978000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
197981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // check audio settings permission for global effects
198081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (sessionId == AUDIO_SESSION_OUTPUT_MIX && !settingsAllowed()) {
198181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        lStatus = PERMISSION_DENIED;
198281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
1983952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
1984000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
198581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // Session AUDIO_SESSION_OUTPUT_STAGE is reserved for output stage effects
198681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // that can only be created by audio policy manager (running in same process)
198781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (sessionId == AUDIO_SESSION_OUTPUT_STAGE && getpid_cached != pid) {
198881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        lStatus = PERMISSION_DENIED;
198981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
1990952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
199165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
199281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (io == 0) {
199381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
199481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // output must be specified by AudioPolicyManager when using session
199581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // AUDIO_SESSION_OUTPUT_STAGE
199681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = BAD_VALUE;
199781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            goto Exit;
199881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
199981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // if the output returned by getOutputForEffect() is removed before we lock the
200081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // mutex below, the call to checkPlaybackThread_l(io) below will detect it
200181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // and we will exit safely
200281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            io = AudioSystem::getOutputForEffect(&desc);
200381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
200465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
200565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
200681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
200781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(mLock);
2008288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
200965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
201081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (!EffectIsNullUuid(&pDesc->uuid)) {
201181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // if uuid is specified, request effect descriptor
201281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = EffectGetDescriptor(&pDesc->uuid, &desc);
201381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (lStatus < 0) {
201481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("createEffect() error %d from EffectGetDescriptor", lStatus);
201581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
201681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
201781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
201881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // if uuid is not specified, look for an available implementation
201981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // of the required type in effect factory
202081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (EffectIsNullUuid(&pDesc->type)) {
202181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("createEffect() no effect type");
202281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                lStatus = BAD_VALUE;
202381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
2024288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
202581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t numEffects = 0;
202681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            effect_descriptor_t d;
202781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            d.flags = 0; // prevent compiler warning
202881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            bool found = false;
2029288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
203081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = EffectQueryNumberEffects(&numEffects);
203181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (lStatus < 0) {
203281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("createEffect() error %d from EffectQueryNumberEffects", lStatus);
203381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
203481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
203581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            for (uint32_t i = 0; i < numEffects; i++) {
203681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                lStatus = EffectQueryEffect(i, &desc);
203781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (lStatus < 0) {
203881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    ALOGW("createEffect() error %d from EffectQueryEffect", lStatus);
203981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    continue;
2040d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                }
204181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (memcmp(&desc.type, &pDesc->type, sizeof(effect_uuid_t)) == 0) {
204281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    // If matching type found save effect descriptor. If the session is
204381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    // 0 and the effect is not auxiliary, continue enumeration in case
204481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    // an auxiliary version of this effect type is available
204581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    found = true;
204681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    d = desc;
204781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    if (sessionId != AUDIO_SESSION_OUTPUT_MIX ||
204881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                            (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
2049d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                        break;
2050d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    }
2051d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                }
2052288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
205381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (!found) {
205481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                lStatus = BAD_VALUE;
205581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("createEffect() effect not found");
205681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
205781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
205881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // For same effect type, chose auxiliary version over insert version if
205981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // connect to output mix (Compliance to OpenSL ES)
206081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (sessionId == AUDIO_SESSION_OUTPUT_MIX &&
206181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    (d.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_AUXILIARY) {
206281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                desc = d;
206358912562617941964939a4182cda71eaeb153d4bGlenn Kasten            }
206458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
206558912562617941964939a4182cda71eaeb153d4bGlenn Kasten
206681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Do not allow auxiliary effects on a session different from 0 (output mix)
206781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (sessionId != AUDIO_SESSION_OUTPUT_MIX &&
206881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent             (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
206981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = INVALID_OPERATION;
207081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            goto Exit;
20713dbe3201479828e84abe02e1fdd0a5d414c0ddb8Eric Laurent        }
207265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
207381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // check recording permission for visualizer
207481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) &&
207581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            !recordingAllowed()) {
207681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = PERMISSION_DENIED;
207781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            goto Exit;
207881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
207965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
208081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // return effect descriptor
208181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        *pDesc = desc;
208265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
208381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // If output is not specified try to find a matching audio session ID in one of the
208481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // output threads.
208581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // If output is 0 here, sessionId is neither SESSION_OUTPUT_STAGE nor SESSION_OUTPUT_MIX
208681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // because of code checking output when entering the function.
208781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Note: io is never 0 when creating an effect on an input
208881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (io == 0) {
208981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // look for the thread where the specified audio session is present
209081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
209181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
209281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    io = mPlaybackThreads.keyAt(i);
209381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    break;
209465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
2095d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            }
209681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (io == 0) {
209781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                for (size_t i = 0; i < mRecordThreads.size(); i++) {
209881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    if (mRecordThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
209981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        io = mRecordThreads.keyAt(i);
210081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        break;
21012986460984580833161bdaabc7f17da1005a8961Eric Laurent                    }
210265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
210365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
210481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // If no output thread contains the requested session ID, default to
210581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // first output. The effect chain will be moved to the correct output
210681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // thread when a track with the same session ID is created
210781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (io == 0 && mPlaybackThreads.size()) {
210881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                io = mPlaybackThreads.keyAt(0);
210981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
211081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("createEffect() got io %d for effect %s", io, desc.name);
211165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
211281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ThreadBase *thread = checkRecordThread_l(io);
211381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread == NULL) {
211481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            thread = checkPlaybackThread_l(io);
211581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (thread == NULL) {
211681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGE("createEffect() unknown output thread");
211781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                lStatus = BAD_VALUE;
211881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
2119288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
2120288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        }
2121288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
212281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<Client> client = registerPid_l(pid);
212358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
212481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // create effect on selected output thread
212581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        handle = thread->createEffect_l(client, effectClient, priority, sessionId,
212681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                &desc, enabled, &lStatus);
212781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (handle != 0 && id != NULL) {
212881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            *id = handle->id();
212965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
213065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
213165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
213281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentExit:
213381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status != NULL) {
213481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        *status = lStatus;
213558912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
213681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return handle;
213766fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten}
213866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
213981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::moveEffects(int sessionId, audio_io_handle_t srcOutput,
214081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_io_handle_t dstOutput)
214165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
214281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("moveEffects() session %d, srcOutput %d, dstOutput %d",
214381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sessionId, srcOutput, dstOutput);
214465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
214581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (srcOutput == dstOutput) {
214681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("moveEffects() same dst and src outputs %d", dstOutput);
214781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return NO_ERROR;
214881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
214981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *srcThread = checkPlaybackThread_l(srcOutput);
215081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (srcThread == NULL) {
215181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("moveEffects() bad srcOutput %d", srcOutput);
215281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
215381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
215481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *dstThread = checkPlaybackThread_l(dstOutput);
215581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (dstThread == NULL) {
215681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("moveEffects() bad dstOutput %d", dstOutput);
215781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
215865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
215965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
216081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _dl(dstThread->mLock);
216181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _sl(srcThread->mLock);
216281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    moveEffectChain_l(sessionId, srcThread, dstThread, false);
216365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
216481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
216565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
216665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
216781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// moveEffectChain_l must be called with both srcThread and dstThread mLocks held
216881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::moveEffectChain_l(int sessionId,
216981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                   AudioFlinger::PlaybackThread *srcThread,
217081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                   AudioFlinger::PlaybackThread *dstThread,
217181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                   bool reRegister)
217265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
217381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("moveEffectChain_l() session %d from thread %p to thread %p",
217481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sessionId, srcThread, dstThread);
217565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
217681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<EffectChain> chain = srcThread->getEffectChain_l(sessionId);
217781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (chain == 0) {
217881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("moveEffectChain_l() effect chain for session %d not on source thread %p",
217981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                sessionId, srcThread);
218081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return INVALID_OPERATION;
218181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
21829ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
218381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // remove chain first. This is useful only if reconfiguring effect chain on same output thread,
218481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // so that a new chain is created with correct parameters when first effect is added. This is
218581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // otherwise unnecessary as removeEffect_l() will remove the chain when last effect is
218681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // removed.
218781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    srcThread->removeEffectChain_l(chain);
21889ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
218981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // transfer all effects one by one so that new effect chain is created on new thread with
219081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // correct buffer sizes and audio parameters and effect engines reconfigured accordingly
219181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_io_handle_t dstOutput = dstThread->id();
219281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<EffectChain> dstChain;
219381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t strategy = 0; // prevent compiler warning
219481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<EffectModule> effect = chain->getEffectFromId_l(0);
219581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    while (effect != 0) {
219681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        srcThread->removeEffect_l(effect);
219781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        dstThread->addEffect_l(effect);
219881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // removeEffect_l() has stopped the effect if it was active so it must be restarted
219981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (effect->state() == EffectModule::ACTIVE ||
220081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                effect->state() == EffectModule::STOPPING) {
220181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            effect->start();
220265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
220381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // if the move request is not received from audio policy manager, the effect must be
220481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // re-registered with the new strategy and output
220581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (dstChain == 0) {
220681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            dstChain = effect->chain().promote();
220781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (dstChain == 0) {
220881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("moveEffectChain_l() cannot get chain from effect %p", effect.get());
220981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                srcThread->addEffect_l(effect);
221081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return NO_INIT;
221165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
221281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            strategy = dstChain->strategy();
221365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
221481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (reRegister) {
221581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSystem::unregisterEffect(effect->id());
221681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSystem::registerEffect(&effect->desc(),
221781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        dstOutput,
221881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        strategy,
221981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        sessionId,
222081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        effect->id());
222181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
222281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        effect = chain->getEffectFromId_l(0);
222358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
222458912562617941964939a4182cda71eaeb153d4bGlenn Kasten
222581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
222665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
222765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2228da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenstruct Entry {
2229da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#define MAX_NAME 32     // %Y%m%d%H%M%S_%d.wav
2230da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    char mName[MAX_NAME];
2231da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten};
2232da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
2233da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenint comparEntry(const void *p1, const void *p2)
2234da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten{
2235da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    return strcmp(((const Entry *) p1)->mName, ((const Entry *) p2)->mName);
2236da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten}
2237da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
2238d06785bebf7e43d4a011b62a252771373ada910cGlenn Kastenvoid AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_handle_t id)
223965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
2240d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    NBAIO_Source *teeSource = source.get();
2241fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten    if (teeSource != NULL) {
2242da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // .wav rotation
2243da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // There is a benign race condition if 2 threads call this simultaneously.
2244da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // They would both traverse the directory, but the result would simply be
2245da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // failures at unlink() which are ignored.  It's also unlikely since
2246da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // normally dumpsys is only done by bugreport or from the command line.
2247da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        char teePath[32+256];
2248da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        strcpy(teePath, "/data/misc/media");
2249da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        size_t teePathLen = strlen(teePath);
2250da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        DIR *dir = opendir(teePath);
2251da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        teePath[teePathLen++] = '/';
2252da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        if (dir != NULL) {
2253da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#define MAX_SORT 20 // number of entries to sort
2254da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#define MAX_KEEP 10 // number of entries to keep
2255da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            struct Entry entries[MAX_SORT];
2256da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            size_t entryCount = 0;
2257da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            while (entryCount < MAX_SORT) {
2258da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                struct dirent de;
2259da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                struct dirent *result = NULL;
2260da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                int rc = readdir_r(dir, &de, &result);
2261da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                if (rc != 0) {
2262da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    ALOGW("readdir_r failed %d", rc);
2263da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    break;
2264da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2265da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                if (result == NULL) {
2266da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    break;
2267da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2268da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                if (result != &de) {
2269da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    ALOGW("readdir_r returned unexpected result %p != %p", result, &de);
2270da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    break;
2271da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2272da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                // ignore non .wav file entries
2273da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                size_t nameLen = strlen(de.d_name);
2274da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                if (nameLen <= 4 || nameLen >= MAX_NAME ||
2275da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                        strcmp(&de.d_name[nameLen - 4], ".wav")) {
2276da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    continue;
2277da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2278da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                strcpy(entries[entryCount++].mName, de.d_name);
2279da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2280da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            (void) closedir(dir);
2281da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            if (entryCount > MAX_KEEP) {
2282da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                qsort(entries, entryCount, sizeof(Entry), comparEntry);
2283da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                for (size_t i = 0; i < entryCount - MAX_KEEP; ++i) {
2284da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    strcpy(&teePath[teePathLen], entries[i].mName);
2285da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    (void) unlink(teePath);
2286da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2287da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2288da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        } else {
2289da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            if (fd >= 0) {
2290da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                fdprintf(fd, "unable to rotate tees in %s: %s\n", teePath, strerror(errno));
2291da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2292da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        }
2293d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        char teeTime[16];
2294fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        struct timeval tv;
2295fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        gettimeofday(&tv, NULL);
2296fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        struct tm tm;
2297fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        localtime_r(&tv.tv_sec, &tm);
2298da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        strftime(teeTime, sizeof(teeTime), "%Y%m%d%H%M%S", &tm);
2299da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        snprintf(&teePath[teePathLen], sizeof(teePath) - teePathLen, "%s_%d.wav", teeTime, id);
2300da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // if 2 dumpsys are done within 1 second, and rotation didn't work, then discard 2nd
2301da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        int teeFd = open(teePath, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, S_IRUSR | S_IWUSR);
2302fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        if (teeFd >= 0) {
2303fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            char wavHeader[44];
2304fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            memcpy(wavHeader,
2305fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn 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",
2306fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                sizeof(wavHeader));
2307fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            NBAIO_Format format = teeSource->format();
2308fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            unsigned channelCount = Format_channelCount(format);
2309fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            ALOG_ASSERT(channelCount <= FCC_2);
23103b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten            uint32_t sampleRate = Format_sampleRate(format);
2311fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[22] = channelCount;       // number of channels
2312fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[24] = sampleRate;         // sample rate
2313fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[25] = sampleRate >> 8;
2314fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[32] = channelCount * 2;   // block alignment
2315fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            write(teeFd, wavHeader, sizeof(wavHeader));
2316fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            size_t total = 0;
2317fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            bool firstRead = true;
2318fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            for (;;) {
2319fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten#define TEE_SINK_READ 1024
2320fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                short buffer[TEE_SINK_READ * FCC_2];
2321fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                size_t count = TEE_SINK_READ;
23222c3b2da3049627264b7c6b449a1622f002210f03John Grossman                ssize_t actual = teeSource->read(buffer, count,
23232c3b2da3049627264b7c6b449a1622f002210f03John Grossman                        AudioBufferProvider::kInvalidPTS);
2324fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                bool wasFirstRead = firstRead;
2325fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                firstRead = false;
2326fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                if (actual <= 0) {
2327fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                    if (actual == (ssize_t) OVERRUN && wasFirstRead) {
2328fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                        continue;
2329fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                    }
2330fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                    break;
2331fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                }
2332a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent                ALOG_ASSERT(actual <= (ssize_t)count);
2333fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                write(teeFd, buffer, actual * channelCount * sizeof(short));
2334fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                total += actual;
2335fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            }
2336fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            lseek(teeFd, (off_t) 4, SEEK_SET);
2337fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            uint32_t temp = 44 + total * channelCount * sizeof(short) - 8;
2338fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            write(teeFd, &temp, sizeof(temp));
2339fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            lseek(teeFd, (off_t) 40, SEEK_SET);
2340fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            temp =  total * channelCount * sizeof(short);
2341fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            write(teeFd, &temp, sizeof(temp));
2342fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            close(teeFd);
2343da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            if (fd >= 0) {
2344da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                fdprintf(fd, "tee copied to %s\n", teePath);
2345da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2346fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        } else {
2347da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            if (fd >= 0) {
2348da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                fdprintf(fd, "unable to create tee %s: %s\n", teePath, strerror(errno));
2349da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2350fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        }
2351fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten    }
2352d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten}
2353d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
235465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
235565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
235665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::onTransact(
235765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
235865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
235965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnAudioFlinger::onTransact(code, data, reply, flags);
236065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
236165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
236265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
2363