AudioFlinger.cpp revision 2fc14730e4697a6f456b4631549c9981f6b0b115
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
22153b9fe667e6e78e0218ff0159353097428c7657Glenn Kasten#include "Configuration.h"
23da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <dirent.h>
2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <math.h>
2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <signal.h>
2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/time.h>
2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/resource.h>
2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
299ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang#include <binder/IPCThreadState.h>
3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h>
3165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h>
32d8e6fd35ec2b59ee7d873daf1f1d9d348221c7bcGlenn Kasten#include <utils/Trace.h>
3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/Parcel.h>
3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h>
3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/threads.h>
3638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent#include <utils/Atomic.h>
3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <cutils/bitops.h>
3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/properties.h>
4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4164760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h>
427394a4f358fa9908a9f0a7c954b65c399f4268e6Dima Zavin#include <hardware/audio.h>
4365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioMixer.h"
4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioFlinger.h"
4644deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten#include "ServiceUtilities.h"
4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/EffectsFactoryApi.h>
496d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent#include <audio_effects/effect_visualizer.h>
5059bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent#include <audio_effects/effect_ns.h>
5159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent#include <audio_effects/effect_aec.h>
5265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
533b21c50ef95fe4e7ac3426ca14b365749e66ff08Glenn Kasten#include <audio_utils/primitives.h>
543b21c50ef95fe4e7ac3426ca14b365749e66ff08Glenn Kasten
55feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent#include <powermanager/PowerManager.h>
56190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
574ff14bae91075eb274eb1c2975982358946e7e63John Grossman#include <common_time/cc_helper.h>
5858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
599e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten#include <media/IMediaLogService.h>
609e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
61da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <media/nbaio/Pipe.h>
62da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <media/nbaio/PipeReader.h>
631ab85ec401801ef9a9184650d0f5a1639b45eeb9Glenn Kasten#include <media/AudioParameter.h>
644182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten#include <private/android_filesystem_config.h>
65da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
6765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
681c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// Note: the following macro is used for extremely verbose logging message.  In
691c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
701c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// 0; but one side effect of this is to turn all LOGV's as well.  Some messages
711c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// are so verbose that we want to suppress them even when we have ALOG_ASSERT
721c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// turned on.  Do not uncomment the #def below unless you really know what you
731c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// are doing and want to see all of the extremely verbose messages.
741c345196edc61694f29307a1826a64a0d26028dcJohn Grossman//#define VERY_VERY_VERBOSE_LOGGING
751c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#ifdef VERY_VERY_VERBOSE_LOGGING
761c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#define ALOGVV ALOGV
771c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#else
781c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#define ALOGVV(a...) do { } while(0)
791c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#endif
80de070137f11d346fba77605bd76a44c040a618fcEric Laurent
8165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
8265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
83ec1d6b5e17281a066d618f7fcd2b63b3ce11f421Glenn Kastenstatic const char kDeadlockedString[] = "AudioFlinger may be deadlocked\n";
84ec1d6b5e17281a066d618f7fcd2b63b3ce11f421Glenn Kastenstatic const char kHardwareLockedString[] = "Hardware lock is taken\n";
8565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
874ff14bae91075eb274eb1c2975982358946e7e63John Grossmannsecs_t AudioFlinger::mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
887cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurent
8981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::mScreenState;
903ed292031dc50c56110cdadb1e3778117e3be76aGlenn Kasten
9146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
92da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenbool AudioFlinger::mTeeSinkInputEnabled = false;
93da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenbool AudioFlinger::mTeeSinkOutputEnabled = false;
94da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenbool AudioFlinger::mTeeSinkTrackEnabled = false;
95da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
96da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastensize_t AudioFlinger::mTeeSinkInputFrames = kTeeSinkInputFramesDefault;
97da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastensize_t AudioFlinger::mTeeSinkOutputFrames = kTeeSinkOutputFramesDefault;
98da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastensize_t AudioFlinger::mTeeSinkTrackFrames = kTeeSinkTrackFramesDefault;
9946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
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),
1424182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten      mBtNrecIsOff(false),
1434182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten      mIsLowRamDevice(true),
1444182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten      mIsDeviceTypeKnown(false)
14565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
146949a926cadbc961fbb649c91d76d7aee8ea4d7bdGlenn Kasten    getpid_cached = getpid();
1479e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    char value[PROPERTY_VALUE_MAX];
1489e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    bool doLog = (property_get("ro.test_harness", value, "0") > 0) && (atoi(value) == 1);
1499e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (doLog) {
1509e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters");
1519e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
15246909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
153da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    (void) property_get("ro.debuggable", value, "0");
154da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    int debuggable = atoi(value);
155da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    int teeEnabled = 0;
156da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (debuggable) {
157da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        (void) property_get("af.tee", value, "0");
158da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        teeEnabled = atoi(value);
159da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    }
160da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (teeEnabled & 1)
161da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        mTeeSinkInputEnabled = true;
162da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (teeEnabled & 2)
163da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        mTeeSinkOutputEnabled = true;
164da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (teeEnabled & 4)
165da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        mTeeSinkTrackEnabled = true;
16646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
1675a61d2f277af3098fc10b2881babca16391362daDima Zavin}
1685a61d2f277af3098fc10b2881babca16391362daDima Zavin
1695a61d2f277af3098fc10b2881babca16391362daDima Zavinvoid AudioFlinger::onFirstRef()
1705a61d2f277af3098fc10b2881babca16391362daDima Zavin{
171799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    int rc = 0;
172fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
173935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    Mutex::Autolock _l(mLock);
174935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent
175799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    /* TODO: move all this work into an Init() function */
1764ff14bae91075eb274eb1c2975982358946e7e63John Grossman    char val_str[PROPERTY_VALUE_MAX] = { 0 };
1774ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
1784ff14bae91075eb274eb1c2975982358946e7e63John Grossman        uint32_t int_val;
1794ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (1 == sscanf(val_str, "%u", &int_val)) {
1804ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mStandbyTimeInNsecs = milliseconds(int_val);
1814ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGI("Using %u mSec as standby time.", int_val);
1824ff14bae91075eb274eb1c2975982358946e7e63John Grossman        } else {
1834ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
1844ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGI("Using default %u mSec as standby time.",
1854ff14bae91075eb274eb1c2975982358946e7e63John Grossman                    (uint32_t)(mStandbyTimeInNsecs / 1000000));
1864ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
1874ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
18865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
189a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    mMode = AUDIO_MODE_NORMAL;
19065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
19165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
19265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::~AudioFlinger()
19365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
19465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!mRecordThreads.isEmpty()) {
195c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten        // closeInput_nonvirtual() will remove specified entry from mRecordThreads
196d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten        closeInput_nonvirtual(mRecordThreads.keyAt(0));
19765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
19865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!mPlaybackThreads.isEmpty()) {
199c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten        // closeOutput_nonvirtual() will remove specified entry from mPlaybackThreads
200d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten        closeOutput_nonvirtual(mPlaybackThreads.keyAt(0));
20165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
202799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
2032b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
2042b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten        // no mHardwareLock needed, as there are no other references to this
205a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        audio_hw_device_close(mAudioHwDevs.valueAt(i)->hwDevice());
206a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        delete mAudioHwDevs.valueAt(i);
20765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
20865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
20965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
210a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentstatic const char * const audio_interfaces[] = {
211a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_PRIMARY,
212a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_A2DP,
213a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_USB,
214a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent};
215a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent#define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0])))
216a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
217ee578c0330319f04a48bccbdb26b53fea0388d04John GrossmanAudioFlinger::AudioHwDevice* AudioFlinger::findSuitableHwDev_l(
218ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_module_handle_t module,
219ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_devices_t devices)
220799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin{
221a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    // if module is 0, the request comes from an old policy manager and we should load
222a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    // well known modules
223a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    if (module == 0) {
224a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        ALOGW("findSuitableHwDev_l() loading well know audio hw modules");
225a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) {
226a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            loadHwModule_l(audio_interfaces[i]);
227a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        }
228f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        // then try to find a module supporting the requested device.
229f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
230f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            AudioHwDevice *audioHwDevice = mAudioHwDevs.valueAt(i);
231f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            audio_hw_device_t *dev = audioHwDevice->hwDevice();
232f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            if ((dev->get_supported_devices != NULL) &&
233f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                    (dev->get_supported_devices(dev) & devices) == devices)
234f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                return audioHwDevice;
235f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        }
236a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    } else {
237a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        // check a match for the requested module handle
238ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(module);
239ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (audioHwDevice != NULL) {
240ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            return audioHwDevice;
241a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        }
242a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    }
243a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
244799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return NULL;
245799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin}
24665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
247be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
24865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
24965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
25065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
25265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
25365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("Clients:\n");
25465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mClients.size(); ++i) {
25577c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        sp<Client> client = mClients.valueAt(i).promote();
25677c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        if (client != 0) {
25777c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            snprintf(buffer, SIZE, "  pid: %d\n", client->pid());
25877c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            result.append(buffer);
25965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
26065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
2613a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
2623a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    result.append("Global session refs:\n");
263012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten    result.append(" session pid count\n");
2643a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    for (size_t i = 0; i < mAudioSessionRefs.size(); i++) {
2653a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        AudioSessionRef *r = mAudioSessionRefs[i];
266012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        snprintf(buffer, SIZE, " %7d %3d %3d\n", r->mSessionid, r->mPid, r->mCnt);
2673a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        result.append(buffer);
2683a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
26965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
27065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
27165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
27265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
273be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
27465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
27665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
27765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
278a4454b4765c5905f14186893b0688be375642283Glenn Kasten    hardware_call_state hardwareStatus = mHardwareStatus;
27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2804ff14bae91075eb274eb1c2975982358946e7e63John Grossman    snprintf(buffer, SIZE, "Hardware status: %d\n"
2814ff14bae91075eb274eb1c2975982358946e7e63John Grossman                           "Standby Time mSec: %u\n",
2824ff14bae91075eb274eb1c2975982358946e7e63John Grossman                            hardwareStatus,
2834ff14bae91075eb274eb1c2975982358946e7e63John Grossman                            (uint32_t)(mStandbyTimeInNsecs / 1000000));
28465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
28565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
28665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
28765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
288be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
29165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Permission Denial: "
29465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "can't dump AudioFlinger from pid=%d, uid=%d\n",
29565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingPid(),
29665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingUid());
29765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::dumpTryLock(Mutex& mutex)
30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
3097dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten        usleep(kDumpLockSleepUs);
31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::dump(int fd, const Vector<String16>& args)
31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
31644deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (!dumpAllowed()) {
31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpPermissionDenial(fd, args);
31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // get state of hardware lock
32081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        bool hardwareLocked = dumpTryLock(mHardwareLock);
32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!hardwareLocked) {
32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kHardwareLockedString);
32365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
32465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mHardwareLock.unlock();
32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        bool locked = dumpTryLock(mLock);
32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // failed to lock - AudioFlinger is probably deadlocked
33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kDeadlockedString);
33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpClients(fd, args);
33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpInternals(fd, args);
33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // dump playback threads
34065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
34165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mPlaybackThreads.valueAt(i)->dump(fd, args);
34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
34465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // dump record threads
34565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mRecordThreads.size(); i++) {
34665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mRecordThreads.valueAt(i)->dump(fd, args);
34765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
349799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        // dump all hardware devs
350799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
351a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
352799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            dev->dump(dev, fd);
35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
354d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
35546909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
356d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        // dump the serially shared record tee sink
357d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        if (mRecordTeeSource != 0) {
358d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            dumpTee(fd, mRecordTeeSource);
359d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        }
36046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
361d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
362d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if (locked) {
363d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            mLock.unlock();
364d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
3659e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
3669e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // append a copy of media.log here by forwarding fd to it, but don't attempt
3679e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // to lookup the service if it's not running, as it will block for a second
3689e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        if (mLogMemoryDealer != 0) {
3699e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten            sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
3709e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten            if (binder != 0) {
3719e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten                fdprintf(fd, "\nmedia.log:\n");
3729e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten                Vector<String16> args;
3739e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten                binder->dump(fd, args);
3749e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten            }
3759e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        }
37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38098ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kastensp<AudioFlinger::Client> AudioFlinger::registerPid_l(pid_t pid)
38198ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten{
38298ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    // If pid is already in the mClients wp<> map, then use that entry
38398ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    // (for which promote() is always != 0), otherwise create a new entry and Client.
38498ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    sp<Client> client = mClients.valueFor(pid).promote();
38598ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    if (client == 0) {
38698ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        client = new Client(this, pid);
38798ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        mClients.add(pid, client);
38898ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    }
38998ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten
39098ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    return client;
39198ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten}
39265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3939e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kastensp<NBLog::Writer> AudioFlinger::newWriter_l(size_t size, const char *name)
3949e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten{
3959e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (mLogMemoryDealer == 0) {
3969e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        return new NBLog::Writer();
3979e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
3989e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<IMemory> shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size));
3999e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<NBLog::Writer> writer = new NBLog::Writer(size, shared);
4009e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
4019e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (binder != 0) {
4029e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        interface_cast<IMediaLogService>(binder)->registerWriter(shared, size, name);
4039e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
4049e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    return writer;
4059e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten}
4069e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
4079e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kastenvoid AudioFlinger::unregisterWriter(const sp<NBLog::Writer>& writer)
4089e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten{
409685ef09bcaf5de6abf2064d552296f70eaec6761Glenn Kasten    if (writer == 0) {
410685ef09bcaf5de6abf2064d552296f70eaec6761Glenn Kasten        return;
411685ef09bcaf5de6abf2064d552296f70eaec6761Glenn Kasten    }
4129e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<IMemory> iMemory(writer->getIMemory());
4139e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (iMemory == 0) {
4149e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        return;
4159e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
4169e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
4179e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (binder != 0) {
4189e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        interface_cast<IMediaLogService>(binder)->unregisterWriter(iMemory);
4199e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // Now the media.log remote reference to IMemory is gone.
4209e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // When our last local reference to IMemory also drops to zero,
4219e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // the IMemory destructor will deallocate the region from mMemoryDealer.
4229e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
4239e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten}
4249e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
42565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// IAudioFlinger interface
42665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<IAudioTrack> AudioFlinger::createTrack(
429fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten        audio_stream_type_t streamType,
43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t sampleRate,
43158f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
432254af180475346b6186b49c297f340c9c4817511Glenn Kasten        audio_channel_mask_t channelMask,
433e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten        size_t frameCount,
434e0b07179a48ee50fda931d2aa1b3c751d167e4d7Glenn Kasten        IAudioFlinger::track_flags_t *flags,
43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const sp<IMemory>& sharedBuffer,
43672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output,
4373acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten        pid_t tid,
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int *sessionId,
439d054c32443a493513ab63529b0c8b1aca290278cGlenn Kasten        String8& name,
44065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t *status)
44165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
44265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<PlaybackThread::Track> track;
44365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<TrackHandle> trackHandle;
44465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client;
44565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t lStatus;
44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int lSessionId;
44765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
448263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    // client AudioTrack::set already implements AUDIO_STREAM_DEFAULT => AUDIO_STREAM_MUSIC,
449263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    // but if someone uses binder directly they could bypass that and cause us to crash
450263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {
45129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("createTrack() invalid stream type %d", streamType);
45265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        lStatus = BAD_VALUE;
45365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        goto Exit;
45465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
45565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
45660a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    // client is responsible for conversion of 8-bit PCM to 16-bit PCM,
45760a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    // and we don't yet support 8.24 or 32-bit PCM
45860a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    if (audio_is_linear_pcm(format) && format != AUDIO_FORMAT_PCM_16_BIT) {
45960a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        ALOGE("createTrack() invalid format %d", format);
46060a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        lStatus = BAD_VALUE;
46160a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        goto Exit;
46260a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    }
46360a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten
46465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
46565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
46665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        PlaybackThread *thread = checkPlaybackThread_l(output);
46739e94f8f723d445447fdee0822291e664b631f60Eric Laurent        PlaybackThread *effectThread = NULL;
46865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
469c9b2e20f7c9a71e07ef398152709c76079decbcdGlenn Kasten            ALOGE("no playback thread found for output handle %d", output);
47065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lStatus = BAD_VALUE;
47165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            goto Exit;
47265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
47365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4748d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kasten        pid_t pid = IPCThreadState::self()->getCallingPid();
47598ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        client = registerPid_l(pid);
47665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("createTrack() sessionId: %d", (sessionId == NULL) ? -2 : *sessionId);
478fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) {
479f436fdcf93bd417fd3c9d2a8b19fd221d894b5e3Eric Laurent            // check if an effect chain with the same session ID is present on another
480f436fdcf93bd417fd3c9d2a8b19fd221d894b5e3Eric Laurent            // output thread and move it here.
481de070137f11d346fba77605bd76a44c040a618fcEric Laurent            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
48239e94f8f723d445447fdee0822291e664b631f60Eric Laurent                sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
48339e94f8f723d445447fdee0822291e664b631f60Eric Laurent                if (mPlaybackThreads.keyAt(i) != output) {
48439e94f8f723d445447fdee0822291e664b631f60Eric Laurent                    uint32_t sessions = t->hasAudioSession(*sessionId);
48539e94f8f723d445447fdee0822291e664b631f60Eric Laurent                    if (sessions & PlaybackThread::EFFECT_SESSION) {
48639e94f8f723d445447fdee0822291e664b631f60Eric Laurent                        effectThread = t.get();
487f436fdcf93bd417fd3c9d2a8b19fd221d894b5e3Eric Laurent                        break;
48839e94f8f723d445447fdee0822291e664b631f60Eric Laurent                    }
489de070137f11d346fba77605bd76a44c040a618fcEric Laurent                }
490de070137f11d346fba77605bd76a44c040a618fcEric Laurent            }
49165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lSessionId = *sessionId;
49265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
493de070137f11d346fba77605bd76a44c040a618fcEric Laurent            // if no audio session id is provided, create one here
4947c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            lSessionId = nextUniqueId();
49565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (sessionId != NULL) {
49665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                *sessionId = lSessionId;
49765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
49865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
4993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("createTrack() lSessionId: %d", lSessionId);
50065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
50165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track = thread->createTrack_l(client, streamType, sampleRate, format,
5023acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten                channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, &lStatus);
5032fc14730e4697a6f456b4631549c9981f6b0b115Glenn Kasten        // we don't abort yet if lStatus != NO_ERROR; there is still work to be done regardless
50439e94f8f723d445447fdee0822291e664b631f60Eric Laurent
50539e94f8f723d445447fdee0822291e664b631f60Eric Laurent        // move effect chain to this output thread if an effect on same session was waiting
50639e94f8f723d445447fdee0822291e664b631f60Eric Laurent        // for a track to be created
50739e94f8f723d445447fdee0822291e664b631f60Eric Laurent        if (lStatus == NO_ERROR && effectThread != NULL) {
5082fc14730e4697a6f456b4631549c9981f6b0b115Glenn Kasten            // no risk of deadlock because AudioFlinger::mLock is held
50939e94f8f723d445447fdee0822291e664b631f60Eric Laurent            Mutex::Autolock _dl(thread->mLock);
51039e94f8f723d445447fdee0822291e664b631f60Eric Laurent            Mutex::Autolock _sl(effectThread->mLock);
51139e94f8f723d445447fdee0822291e664b631f60Eric Laurent            moveEffectChain_l(lSessionId, effectThread, thread, true);
51239e94f8f723d445447fdee0822291e664b631f60Eric Laurent        }
513a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
514a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        // Look for sync events awaiting for a session to be used.
515a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        for (int i = 0; i < (int)mPendingSyncEvents.size(); i++) {
516a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            if (mPendingSyncEvents[i]->triggerSession() == lSessionId) {
517a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                if (thread->isValidSyncEvent(mPendingSyncEvents[i])) {
5182986460984580833161bdaabc7f17da1005a8961Eric Laurent                    if (lStatus == NO_ERROR) {
519d23eedca9b5a1812891c05d89850ab7ee707040dGlenn Kasten                        (void) track->setSyncEvent(mPendingSyncEvents[i]);
5202986460984580833161bdaabc7f17da1005a8961Eric Laurent                    } else {
5212986460984580833161bdaabc7f17da1005a8961Eric Laurent                        mPendingSyncEvents[i]->cancel();
5222986460984580833161bdaabc7f17da1005a8961Eric Laurent                    }
523a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    mPendingSyncEvents.removeAt(i);
524a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    i--;
525a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                }
526a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            }
527a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
52865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
52965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (lStatus == NO_ERROR) {
530d054c32443a493513ab63529b0c8b1aca290278cGlenn Kasten        // s for server's pid, n for normal mixer name, f for fast index
531d054c32443a493513ab63529b0c8b1aca290278cGlenn Kasten        name = String8::format("s:%d;n:%d;f:%d", getpid_cached, track->name() - AudioMixer::TRACK0,
532d054c32443a493513ab63529b0c8b1aca290278cGlenn Kasten                track->fastIndex());
53365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        trackHandle = new TrackHandle(track);
53465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
53565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // remove local strong reference to Client before deleting the Track so that the Client
53665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // destructor is called by the TrackBase destructor with mLock held
53765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client.clear();
53865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track.clear();
53965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
54065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
54165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianExit:
5429156ef3e11b68cc4b6d3cea77f1f63673855a6d1Glenn Kasten    *status = lStatus;
54365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return trackHandle;
54465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
54565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
54672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenuint32_t AudioFlinger::sampleRate(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("sampleRate() unknown thread %d", output);
55265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
55365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
55465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->sampleRate();
55565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
55665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
55772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenint AudioFlinger::channelCount(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("channelCount() unknown thread %d", output);
56365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
56465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
56565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->channelCount();
56665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
56765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
56872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenaudio_format_t AudioFlinger::format(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("format() unknown thread %d", output);
57458f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        return AUDIO_FORMAT_INVALID;
57565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
57665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->format();
57765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
57865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
57972ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastensize_t AudioFlinger::frameCount(audio_io_handle_t output) const
58065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
58165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
58265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
58365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
5845ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("frameCount() unknown thread %d", output);
58565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
58665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
58758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // FIXME currently returns the normal mixer's frame count to avoid confusing legacy callers;
58858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    //       should examine all callers and fix them to handle smaller counts
58965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->frameCount();
59065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
59165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
59272ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenuint32_t AudioFlinger::latency(audio_io_handle_t output) const
59365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
59465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
59565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
59665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
597c9b2e20f7c9a71e07ef398152709c76079decbcdGlenn Kasten        ALOGW("latency(): no playback thread found for output handle %d", output);
59865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
59965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
60065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->latency();
60165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
60265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
60365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setMasterVolume(float value)
60465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
605a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
606a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
607a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
608a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
609a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
61065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
61165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
61265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
61365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
61465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
615a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    Mutex::Autolock _l(mLock);
616ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    mMasterVolume = value;
617a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
618ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Set master volume in the HALs which support it.
619ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
620ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AutoMutex lock(mHardwareLock);
621ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
6224ff14bae91075eb274eb1c2975982358946e7e63John Grossman
623ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
624ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (dev->canSetMasterVolume()) {
625ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            dev->hwDevice()->set_master_volume(dev->hwDevice(), value);
626935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent        }
627ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_IDLE;
62865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
62965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
630ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Now set the master volume in each playback thread.  Playback threads
631ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // assigned to HALs which do not have master volume support will apply
632ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // master volume during the mix operation.  Threads with HALs which do
633ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // support master volume will simply ignore the setting.
6348d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i < mPlaybackThreads.size(); i++)
635ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mPlaybackThreads.valueAt(i)->setMasterVolume(value);
63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
63765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
63865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
63965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
640f78aee70d15daf4690de7e7b4983ee68b0d1381dGlenn Kastenstatus_t AudioFlinger::setMode(audio_mode_t mode)
64165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
642a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
643a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
644a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
645a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
64665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
64765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
64865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
64965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
65065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
651930f4caa1e311ef7ff538c421a324396157eb24fGlenn Kasten    if (uint32_t(mode) >= AUDIO_MODE_CNT) {
6525ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Illegal value: setMode(%d)", mode);
65365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
65465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
65565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
65665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    { // scope for the lock
65765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        AutoMutex lock(mHardwareLock);
658ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
65965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mHardwareStatus = AUDIO_HW_SET_MODE;
660ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        ret = dev->set_mode(dev, mode);
66165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mHardwareStatus = AUDIO_HW_IDLE;
66265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
66365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (NO_ERROR == ret) {
66565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mMode = mode;
6678d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        for (size_t i = 0; i < mPlaybackThreads.size(); i++)
668e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            mPlaybackThreads.valueAt(i)->setMode(mode);
66965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
67065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
67165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ret;
67265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
67365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
67465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setMicMute(bool state)
67565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
676a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
677a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
678a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
679a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
680a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
68165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
68265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
68465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
68565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
68665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mHardwareLock);
687ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
68865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
689ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    ret = dev->set_mic_mute(dev, state);
69065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_IDLE;
69165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ret;
69265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
69365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
69465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::getMicMute() const
69565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
696a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
697a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
698a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return false;
699a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
700a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
701fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    bool state = AUDIO_MODE_INVALID;
7022b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    AutoMutex lock(mHardwareLock);
703ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
70465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
705ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    dev->get_mic_mute(dev, &state);
70665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_IDLE;
70765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return state;
70865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
70965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
71065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setMasterMute(bool muted)
71165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
712d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    status_t ret = initCheck();
713d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    if (ret != NO_ERROR) {
714d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman        return ret;
715d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    }
716d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
71765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
71865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
71965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
72065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
72165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
722ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    Mutex::Autolock _l(mLock);
723ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    mMasterMute = muted;
724d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
725ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Set master mute in the HALs which support it.
726ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
727ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AutoMutex lock(mHardwareLock);
728ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
729d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
730ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
731ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (dev->canSetMasterMute()) {
732ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            dev->hwDevice()->set_master_mute(dev->hwDevice(), muted);
733d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman        }
734ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_IDLE;
735d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    }
736d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
737ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Now set the master mute in each playback thread.  Playback threads
738ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // assigned to HALs which do not have master mute support will apply master
739ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // mute during the mix operation.  Threads with HALs which do support master
740ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // mute will simply ignore the setting.
7418d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i < mPlaybackThreads.size(); i++)
742ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mPlaybackThreads.valueAt(i)->setMasterMute(muted);
74365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
74465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
74565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
74665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
74765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianfloat AudioFlinger::masterVolume() const
74865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
7499806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    Mutex::Autolock _l(mLock);
7509806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    return masterVolume_l();
75165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
75265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
75365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::masterMute() const
75465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
7559806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    Mutex::Autolock _l(mLock);
7569806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    return masterMute_l();
75765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
75865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7594ff14bae91075eb274eb1c2975982358946e7e63John Grossmanfloat AudioFlinger::masterVolume_l() const
7604ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
7614ff14bae91075eb274eb1c2975982358946e7e63John Grossman    return mMasterVolume;
7624ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
7634ff14bae91075eb274eb1c2975982358946e7e63John Grossman
764d8f178d613821c3f61a5c5e391eb275339e526a9John Grossmanbool AudioFlinger::masterMute_l() const
765d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman{
766ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    return mMasterMute;
767d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman}
768d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
76972ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
77072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output)
77165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
77265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
77365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
77465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
77565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
77665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
777263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
77829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setStreamVolume() invalid stream %d", stream);
77965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
78065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
78165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
78265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mLock);
78365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = NULL;
78465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (output) {
78565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread = checkPlaybackThread_l(output);
78665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
78765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return BAD_VALUE;
78865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
78965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
79065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStreamTypes[stream].volume = value;
79265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
7948d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
795e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value);
79665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
79765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
79865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread->setStreamVolume(stream, value);
79965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
80065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
80165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
80265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
80365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
804fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatus_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)
80565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
80665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
80765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
80865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
80965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
81065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
811263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT ||
812fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) {
81329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setStreamMute() invalid stream %d", stream);
81465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
81565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
81665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
817935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    AutoMutex lock(mLock);
81865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStreamTypes[stream].mute = muted;
81965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
820e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
82165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
82265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
82365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
82465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
82572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenfloat AudioFlinger::streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const
82665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
827263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
82865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0.0f;
82965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
83065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
83165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mLock);
83265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    float volume;
83365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (output) {
83465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        PlaybackThread *thread = checkPlaybackThread_l(output);
83565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
83665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return 0.0f;
83765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
83865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        volume = thread->streamVolume(stream);
83965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
8406637baae4244aec731c4014da72418d330636ae1Glenn Kasten        volume = streamVolume_l(stream);
84165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
84265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
84365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return volume;
84465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
84565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
846fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenbool AudioFlinger::streamMute(audio_stream_type_t stream) const
84765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
848263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
84965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return true;
85065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
85165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8526637baae4244aec731c4014da72418d330636ae1Glenn Kasten    AutoMutex lock(mLock);
8536637baae4244aec731c4014da72418d330636ae1Glenn Kasten    return streamMute_l(stream);
85465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
85565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
85672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
85765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
858827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten    ALOGV("setParameters(): io %d, keyvalue %s, calling pid %d",
859827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten            ioHandle, keyValuePairs.string(), IPCThreadState::self()->getCallingPid());
86081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
86165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
86265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
86365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
86465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
86565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
86665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // ioHandle == 0 means the parameters are global to the audio hardware interface
86765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (ioHandle == 0) {
868a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        Mutex::Autolock _l(mLock);
869799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        status_t final_result = NO_ERROR;
8708abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten        {
871a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            AutoMutex lock(mHardwareLock);
872a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            mHardwareStatus = AUDIO_HW_SET_PARAMETER;
873a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
874a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
875a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                status_t result = dev->set_parameters(dev, keyValuePairs.string());
876a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                final_result = result ?: final_result;
877a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            }
878a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            mHardwareStatus = AUDIO_HW_IDLE;
8798abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten        }
88059bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
88159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        AudioParameter param = AudioParameter(keyValuePairs);
88259bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        String8 value;
88359bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        if (param.get(String8(AUDIO_PARAMETER_KEY_BT_NREC), value) == NO_ERROR) {
884bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent            bool btNrecIsOff = (value == AUDIO_PARAMETER_VALUE_OFF);
885bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent            if (mBtNrecIsOff != btNrecIsOff) {
88659bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                for (size_t i = 0; i < mRecordThreads.size(); i++) {
88759bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                    sp<RecordThread> thread = mRecordThreads.valueAt(i);
888f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                    audio_devices_t device = thread->inDevice();
889510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    bool suspend = audio_is_bluetooth_sco_device(device) && btNrecIsOff;
890510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    // collect all of the thread's session IDs
891510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    KeyedVector<int, bool> ids = thread->sessionIds();
892510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    // suspend effects associated with those session IDs
893510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    for (size_t j = 0; j < ids.size(); ++j) {
894510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                        int sessionId = ids.keyAt(j);
89559bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                        thread->setEffectSuspended(FX_IID_AEC,
89659bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                                                   suspend,
897510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                                                   sessionId);
89859bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                        thread->setEffectSuspended(FX_IID_NS,
89959bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                                                   suspend,
900510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                                                   sessionId);
90159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                    }
90259bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                }
903bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent                mBtNrecIsOff = btNrecIsOff;
90459bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent            }
90559bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        }
90628ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        String8 screenState;
90728ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        if (param.get(String8(AudioParameter::keyScreenState), screenState) == NO_ERROR) {
90828ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten            bool isOff = screenState == "off";
90981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (isOff != (AudioFlinger::mScreenState & 1)) {
91081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                AudioFlinger::mScreenState = ((AudioFlinger::mScreenState & ~1) + 2) | isOff;
91128ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten            }
91228ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        }
913799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        return final_result;
91465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
91565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
91665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // hold a strong ref on thread in case closeOutput() or closeInput() is called
91765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // and the thread is exited once the lock is released
91865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ThreadBase> thread;
91965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
92065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
92165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread = checkPlaybackThread_l(ioHandle);
922d5903ec1332630f2992a6f0d5ca69d13a185c665Glenn Kasten        if (thread == 0) {
92365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            thread = checkRecordThread_l(ioHandle);
9247fc9a6fdf146ded90b51c52f4a05d797294dcb85Glenn Kasten        } else if (thread == primaryPlaybackThread_l()) {
9257c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            // indicate output device change to all input threads for pre processing
9267c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            AudioParameter param = AudioParameter(keyValuePairs);
9277c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            int value;
92889d94e79dad032fb18ddc655e6068e4231d3f0aaEric Laurent            if ((param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) &&
92989d94e79dad032fb18ddc655e6068e4231d3f0aaEric Laurent                    (value != 0)) {
9307c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                for (size_t i = 0; i < mRecordThreads.size(); i++) {
9317c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                    mRecordThreads.valueAt(i)->setParameters(keyValuePairs);
9327c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                }
9337c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            }
93465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
93565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
9367378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten    if (thread != 0) {
9377378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten        return thread->setParameters(keyValuePairs);
93865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
93965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BAD_VALUE;
94065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
94165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
94272ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn KastenString8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& keys) const
94365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
944827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten    ALOGVV("getParameters() io %d, keys %s, calling pid %d",
945827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten            ioHandle, keys.string(), IPCThreadState::self()->getCallingPid());
94665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
947a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    Mutex::Autolock _l(mLock);
948a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
94965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (ioHandle == 0) {
950fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        String8 out_s8;
951fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
952799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
9538abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            char *s;
9548abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            {
9558abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            AutoMutex lock(mHardwareLock);
9568abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            mHardwareStatus = AUDIO_HW_GET_PARAMETER;
957a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
9588abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            s = dev->get_parameters(dev, keys.string());
9598abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            mHardwareStatus = AUDIO_HW_IDLE;
9608abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            }
961ef7740be67a4d7b6b033ebed59c3d4a9c74a2c18John Grossman            out_s8 += String8(s ? s : "");
962799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            free(s);
963799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        }
964fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return out_s8;
96565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
96665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
96765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *playbackThread = checkPlaybackThread_l(ioHandle);
96865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (playbackThread != NULL) {
96965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return playbackThread->getParameters(keys);
97065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
97165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    RecordThread *recordThread = checkRecordThread_l(ioHandle);
97265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (recordThread != NULL) {
97365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return recordThread->getParameters(keys);
97465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
97565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return String8("");
97665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
97765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
978dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kastensize_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format,
979dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten        audio_channel_mask_t channelMask) const
98065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
981a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
982a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
983a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return 0;
984a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
985a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
9862b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    AutoMutex lock(mHardwareLock);
9872b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
988ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    struct audio_config config;
989ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    memset(&config, 0, sizeof(config));
990ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    config.sample_rate = sampleRate;
991ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    config.channel_mask = channelMask;
992ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    config.format = format;
993ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
994ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
995ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    size_t size = dev->get_input_buffer_size(dev, &config);
9962b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    mHardwareStatus = AUDIO_HW_IDLE;
9972b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    return size;
99865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
99965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
100072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenunsigned int AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const
100165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
100265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
100365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
100465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    RecordThread *recordThread = checkRecordThread_l(ioHandle);
100565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (recordThread != NULL) {
100665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return recordThread->getInputFramesLost();
100765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
100865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return 0;
100965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
101065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
101165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setVoiceVolume(float value)
101265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1013a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
1014a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
1015a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
1016a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
1017a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
101865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
101965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
102065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
102165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
102265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mHardwareLock);
1024ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
10258abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten    mHardwareStatus = AUDIO_HW_SET_VOICE_VOLUME;
1026ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    ret = dev->set_voice_volume(dev, value);
102765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_IDLE;
102865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ret;
103065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
103165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103226c77556efc30800466b60b3975bc35a70c8c28bGlenn Kastenstatus_t AudioFlinger::getRenderPosition(size_t *halFrames, size_t *dspFrames,
103372ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output) const
103465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
103565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status;
103665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
103865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *playbackThread = checkPlaybackThread_l(output);
104065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (playbackThread != NULL) {
104165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return playbackThread->getRenderPosition(halFrames, dspFrames);
104265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
104365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
104465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BAD_VALUE;
104565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
104665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
104765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
104865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
104965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
105165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1052bb001926447d0b7dc71ca8bb3c9856f3136d8f4cGlenn Kasten    pid_t pid = IPCThreadState::self()->getCallingPid();
105365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mNotificationClients.indexOfKey(pid) < 0) {
105465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<NotificationClient> notificationClient = new NotificationClient(this,
105565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                                                            client,
105665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                                                            pid);
10573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("registerClient() client %p, pid %d", notificationClient.get(), pid);
105865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mNotificationClients.add(pid, notificationClient);
106065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
106165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<IBinder> binder = client->asBinder();
106265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        binder->linkToDeath(notificationClient);
106365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
106465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // the config change is always sent from playback or record threads to avoid deadlock
106565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // with AudioSystem::gLock
106665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
1067896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AudioSystem::OUTPUT_OPENED);
106865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
106965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
107065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mRecordThreads.size(); i++) {
1071896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            mRecordThreads.valueAt(i)->sendIoConfigEvent(AudioSystem::INPUT_OPENED);
107265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
107365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
107465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
107565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
107665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::removeNotificationClient(pid_t pid)
107765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
107865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
107965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1080a3b09254d44cd8d66ec947abe547538c4cfeaa89Glenn Kasten    mNotificationClients.removeItem(pid);
10813a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
10823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("%d died, releasing its sessions", pid);
10838d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    size_t num = mAudioSessionRefs.size();
10843a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    bool removed = false;
10858d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i< num; ) {
10863a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
1087012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        ALOGV(" pid %d @ %d", ref->mPid, i);
1088012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        if (ref->mPid == pid) {
1089012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten            ALOGV(" removing entry for pid %d session %d", pid, ref->mSessionid);
10903a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            mAudioSessionRefs.removeAt(i);
10913a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            delete ref;
10923a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            removed = true;
10933a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            num--;
10948d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        } else {
10958d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten            i++;
10963a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        }
10973a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
10983a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    if (removed) {
10993a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        purgeStaleEffects_l();
11003a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
110165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
110265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
110365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// audioConfigChanged_l() must be called with AudioFlinger::mLock held
1104b81cc8c6f3eec9edb255ea99b6a6f243585b1e38Glenn Kastenvoid AudioFlinger::audioConfigChanged_l(int event, audio_io_handle_t ioHandle, const void *param2)
110565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
110665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mNotificationClients.size();
110765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < size; i++) {
110884afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioHandle,
110984afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten                                                                               param2);
111065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
111165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
111265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
111365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// removeClient_l() must be called with AudioFlinger::mLock held
111465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::removeClient_l(pid_t pid)
111565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1116827e5f1237757aee78b677efcf0f7c44fd0dd3d8Glenn Kasten    ALOGV("removeClient_l() pid %d, calling pid %d", pid,
111785ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            IPCThreadState::self()->getCallingPid());
111865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClients.removeItem(pid);
111965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
112065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1121717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent// getEffectThread_l() must be called with AudioFlinger::mLock held
1122717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurentsp<AudioFlinger::PlaybackThread> AudioFlinger::getEffectThread_l(int sessionId, int EffectId)
1123717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent{
1124717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    sp<PlaybackThread> thread;
1125717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
1126717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
1127717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent        if (mPlaybackThreads.valueAt(i)->getEffect(sessionId, EffectId) != 0) {
1128717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            ALOG_ASSERT(thread == 0);
1129717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            thread = mPlaybackThreads.valueAt(i);
1130717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent        }
1131717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    }
1132717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
1133717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    return thread;
1134717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent}
113565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
113681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
113781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
113865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
113965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
114081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
114181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    :   RefBase(),
114281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mAudioFlinger(audioFlinger),
114381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // FIXME should be a "k" constant not hard-coded, in .h or ro. property, see 4 lines below
114481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mMemoryDealer(new MemoryDealer(1024*1024, "AudioFlinger::Client")),
114581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPid(pid),
114681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mTimedTrackCount(0)
114765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
114881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
114965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
115065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Client destructor must be called with AudioFlinger::mLock held
115281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::Client::~Client()
115365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
115481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAudioFlinger->removeClient_l(mPid);
115565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
115665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<MemoryDealer> AudioFlinger::Client::heap() const
115865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
115981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mMemoryDealer;
116065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
116165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
116281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Reserve one of the limited slots for a timed audio track associated
116381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// with this client
116481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::Client::reserveTimedTrack()
116565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
116681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    const int kMaxTimedTracksPerClient = 4;
116765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
116881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mTimedTrackLock);
116965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
117081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mTimedTrackCount >= kMaxTimedTracksPerClient) {
117181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("can not create timed track - pid %d has exceeded the limit",
117281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent             mPid);
117381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return false;
117465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
117565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
117681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTimedTrackCount++;
117781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return true;
117865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
117965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
118081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Release a slot for a timed audio track
118181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::Client::releaseTimedTrack()
118265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
118381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mTimedTrackLock);
118481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTimedTrackCount--;
1185896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent}
1186896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent
118781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
118881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
118981784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger,
119081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                     const sp<IAudioFlingerClient>& client,
119181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                     pid_t pid)
119281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    : mAudioFlinger(audioFlinger), mPid(pid), mAudioFlingerClient(client)
1193896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent{
119465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
119565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
119681784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::NotificationClient::~NotificationClient()
119765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
119865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
119965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
120081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who)
120165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
120281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<NotificationClient> keep(this);
120381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAudioFlinger->removeNotificationClient(mPid);
120481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
120565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
120665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
120781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
120865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
120981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<IAudioRecord> AudioFlinger::openRecord(
121081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_io_handle_t input,
121181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        uint32_t sampleRate,
121281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_format_t format,
121381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_channel_mask_t channelMask,
121481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        size_t frameCount,
1215eeca32671896739e84050da5992d5f151a1629deGlenn Kasten        IAudioFlinger::track_flags_t *flags,
121681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        pid_t tid,
121781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int *sessionId,
121881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status_t *status)
12191d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent{
122081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<RecordThread::RecordTrack> recordTrack;
122181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<RecordHandle> recordHandle;
122281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<Client> client;
122381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t lStatus;
122481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    RecordThread *thread;
122581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t inFrameCount;
122681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    int lSessionId;
12271d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
122881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // check calling permissions
122981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!recordingAllowed()) {
123081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        lStatus = PERMISSION_DENIED;
123181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
123281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
12331d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
1234291bb6d8947c5b0c062f0895d623c529259bfa39Glenn Kasten    if (format != AUDIO_FORMAT_PCM_16_BIT) {
1235291bb6d8947c5b0c062f0895d623c529259bfa39Glenn Kasten        ALOGE("openRecord() invalid format %d", format);
1236291bb6d8947c5b0c062f0895d623c529259bfa39Glenn Kasten        lStatus = BAD_VALUE;
1237291bb6d8947c5b0c062f0895d623c529259bfa39Glenn Kasten        goto Exit;
1238291bb6d8947c5b0c062f0895d623c529259bfa39Glenn Kasten    }
1239291bb6d8947c5b0c062f0895d623c529259bfa39Glenn Kasten
124081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // add client to list
124181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    { // scope for mLock
124281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(mLock);
124381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread = checkRecordThread_l(input);
124481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread == NULL) {
124581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = BAD_VALUE;
124681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            goto Exit;
12471d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        }
12481d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
12498d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kasten        pid_t pid = IPCThreadState::self()->getCallingPid();
125081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        client = registerPid_l(pid);
1251feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
125281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // If no audio session id is provided, create one here
125381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) {
125481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lSessionId = *sessionId;
1255feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        } else {
125681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lSessionId = nextUniqueId();
125781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (sessionId != NULL) {
125881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                *sessionId = lSessionId;
125981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
1260feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
126181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // create new record track.
126281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // The record track uses one track in mHardwareMixerThread by convention.
126381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        recordTrack = thread->createRecordTrack_l(client, sampleRate, format, channelMask,
1264ddb0ccf3fb6fe8da8c71a6deb30561b821f3c0a2Glenn Kasten                                                  frameCount, lSessionId, flags, tid, &lStatus);
1265feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
126681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (lStatus != NO_ERROR) {
126781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // remove local strong reference to Client before deleting the RecordTrack so that the
126881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Client destructor is called by the TrackBase destructor with mLock held
126981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        client.clear();
127081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        recordTrack.clear();
127181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
1272feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
1273feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
12742fc14730e4697a6f456b4631549c9981f6b0b115Glenn Kasten    // return handle to client
127581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    recordHandle = new RecordHandle(recordTrack);
1276feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
127781784c37c61b09289654b979567a42bf73cd2b12Eric LaurentExit:
12789156ef3e11b68cc4b6d3cea77f1f63673855a6d1Glenn Kasten    *status = lStatus;
127981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return recordHandle;
1280feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
1281feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1282feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
12831d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
128481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
128581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
128681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_module_handle_t AudioFlinger::loadHwModule(const char *name)
128759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
128881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!settingsAllowed()) {
128981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
129081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
129159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    Mutex::Autolock _l(mLock);
129281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return loadHwModule_l(name);
129359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
129459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
129581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// loadHwModule_l() must be called with AudioFlinger::mLock held
129681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
129759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
129881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
129981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
130081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGW("loadHwModule() module %s already loaded", name);
130181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return mAudioHwDevs.keyAt(i);
130259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
130359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
130459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
130581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_hw_device_t *dev;
130659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
130781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    int rc = load_audio_interface(name, &dev);
130881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (rc) {
130981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGI("loadHwModule() error %d loading module %s ", rc, name);
131081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
131159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
131259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
131381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mHardwareStatus = AUDIO_HW_INIT;
131481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    rc = dev->init_check(dev);
131581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mHardwareStatus = AUDIO_HW_IDLE;
131681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (rc) {
131781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGI("loadHwModule() init check error %d for module %s ", rc, name);
131881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
131959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
132059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
132181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // Check and cache this HAL's level of support for master mute and master
132281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // volume.  If this is the first HAL opened, and it supports the get
132381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // methods, use the initial values provided by the HAL as the current
132481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // master mute and volume settings.
132559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
132681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioHwDevice::Flags flags = static_cast<AudioHwDevice::Flags>(0);
132781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {  // scope for auto-lock pattern
132881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AutoMutex lock(mHardwareLock);
132959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
133081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (0 == mAudioHwDevs.size()) {
133181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
133281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (NULL != dev->get_master_volume) {
133381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                float mv;
133481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (OK == dev->get_master_volume(dev, &mv)) {
133581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    mMasterVolume = mv;
133681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                }
133781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
133881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
133981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
134081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (NULL != dev->get_master_mute) {
134181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                bool mm;
134281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (OK == dev->get_master_mute(dev, &mm)) {
134381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    mMasterMute = mm;
134481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                }
134581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
134659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
134781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
134881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
134981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((NULL != dev->set_master_volume) &&
135081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (OK == dev->set_master_volume(dev, mMasterVolume))) {
135181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            flags = static_cast<AudioHwDevice::Flags>(flags |
135281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
135359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
135459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
135581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
135681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((NULL != dev->set_master_mute) &&
135781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (OK == dev->set_master_mute(dev, mMasterMute))) {
135881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            flags = static_cast<AudioHwDevice::Flags>(flags |
135981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
136081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
136159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
136281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mHardwareStatus = AUDIO_HW_IDLE;
136359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
136459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
136581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_module_handle_t handle = nextUniqueId();
136681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAudioHwDevs.add(handle, new AudioHwDevice(name, dev, flags));
136781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
136881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGI("loadHwModule() Loaded %s audio interface from %s (%s) handle %d",
136981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent          name, dev->common.module->name, dev->common.module->id, handle);
137081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
137181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return handle;
137281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
137359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
137459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
137581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
137681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
137781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::getPrimaryOutputSamplingRate()
137859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
137959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    Mutex::Autolock _l(mLock);
138081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = primaryPlaybackThread_l();
138181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return thread != NULL ? thread->sampleRate() : 0;
1382a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent}
138359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
138481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsize_t AudioFlinger::getPrimaryOutputFrameCount()
1385a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent{
138681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
138781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = primaryPlaybackThread_l();
138881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return thread != NULL ? thread->frameCountHAL() : 0;
138959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
139059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
139165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
139265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
13934182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kastenstatus_t AudioFlinger::setLowRamDevice(bool isLowRamDevice)
13944182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten{
13954182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten    uid_t uid = IPCThreadState::self()->getCallingUid();
13964182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten    if (uid != AID_SYSTEM) {
13974182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten        return PERMISSION_DENIED;
13984182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten    }
13994182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten    Mutex::Autolock _l(mLock);
14004182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten    if (mIsDeviceTypeKnown) {
14014182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten        return INVALID_OPERATION;
14024182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten    }
14034182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten    mIsLowRamDevice = isLowRamDevice;
14044182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten    mIsDeviceTypeKnown = true;
14054182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten    return NO_ERROR;
14064182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten}
14074182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten
14084182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten// ----------------------------------------------------------------------------
14094182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten
141081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
141181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           audio_devices_t *pDevices,
141281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           uint32_t *pSamplingRate,
141381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           audio_format_t *pFormat,
141481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           audio_channel_mask_t *pChannelMask,
141581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                           uint32_t *pLatencyMs,
1416ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                                           audio_output_flags_t flags,
1417ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                                           const audio_offload_info_t *offloadInfo)
141865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
141981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = NULL;
1420ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    struct audio_config config;
1421fb872cc6f77f6d74011fab703b3edd7023c736cbGlenn Kasten    memset(&config, 0, sizeof(config));
1422ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;
1423ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;
1424ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;
1425937098b9b564a779ff1c8c2d9e60769ee5c69810Glenn Kasten    if (offloadInfo != NULL) {
1426ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald        config.offload_info = *offloadInfo;
1427ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    }
1428ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
142981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_stream_out_t *outStream = NULL;
143081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioHwDevice *outHwDev;
1431ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
1432bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %#08x, Channels %x, flags %x",
143381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              module,
143481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              (pDevices != NULL) ? *pDevices : 0,
143581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              config.sample_rate,
143681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              config.format,
143781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              config.channel_mask,
143881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              flags);
1439bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    ALOGV("openOutput(), offloadInfo %p version 0x%04x",
1440bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent          offloadInfo, offloadInfo == NULL ? -1 : offloadInfo->version );
144181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
144281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (pDevices == NULL || *pDevices == 0) {
144381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
1444ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    }
1445ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
144681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
144765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
144881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    outHwDev = findSuitableHwDev_l(module, *pDevices);
144981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (outHwDev == NULL)
145081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
145165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
145281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_hw_device_t *hwDevHal = outHwDev->hwDevice();
145381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_io_handle_t id = nextUniqueId();
145465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
145581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
145665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
145734542acfa25c6413c87a94b6f7cc315a0c496277Glenn Kasten    status_t status = hwDevHal->open_output_stream(hwDevHal,
145881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          id,
145981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          *pDevices,
146081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          (audio_output_flags_t)flags,
146181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          &config,
146281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          &outStream);
146365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
146481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mHardwareStatus = AUDIO_HW_IDLE;
1465bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %#08x, "
146681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            "Channels %x, status %d",
146781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            outStream,
146881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.sample_rate,
146981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.format,
147081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.channel_mask,
147181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            status);
147258912562617941964939a4182cda71eaeb153d4bGlenn Kasten
147381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status == NO_ERROR && outStream != NULL) {
1474bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream, flags);
147565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1476bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
1477bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            thread = new OffloadThread(this, output, id, *pDevices);
1478bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            ALOGV("openOutput() created offload output: ID %d thread %p", id, thread);
1479bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) ||
148081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (config.format != AUDIO_FORMAT_PCM_16_BIT) ||
148181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (config.channel_mask != AUDIO_CHANNEL_OUT_STEREO)) {
148281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            thread = new DirectOutputThread(this, output, id, *pDevices);
148381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("openOutput() created direct output: ID %d thread %p", id, thread);
148481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
148581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            thread = new MixerThread(this, output, id, *pDevices);
148681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("openOutput() created mixer output: ID %d thread %p", id, thread);
148765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
148881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPlaybackThreads.add(id, thread);
148988cbea8a918bbaf5e06e48aadd5af5e81d58d232Glenn Kasten
14907c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        if (pSamplingRate != NULL) {
14917c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten            *pSamplingRate = config.sample_rate;
14927c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        }
14937c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        if (pFormat != NULL) {
14947c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten            *pFormat = config.format;
14957c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        }
14967c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        if (pChannelMask != NULL) {
14977c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten            *pChannelMask = config.channel_mask;
14987c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        }
14997c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        if (pLatencyMs != NULL) {
15007c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten            *pLatencyMs = thread->latency();
15017c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        }
150265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
150381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // notify client processes of the new output creation
150481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);
150565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
150681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // the first primary output opened designates the primary hw device
150781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((mPrimaryHardwareDev == NULL) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
150881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGI("Using module %d has the primary audio interface", module);
150981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mPrimaryHardwareDev = outHwDev;
151081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
151181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AutoMutex lock(mHardwareLock);
151281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mHardwareStatus = AUDIO_HW_SET_MODE;
151381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            hwDevHal->set_mode(hwDevHal, mMode);
151481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mHardwareStatus = AUDIO_HW_IDLE;
151581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
151681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return id;
151781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
151865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
151981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return 0;
152065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
152165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
152281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1,
152381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_io_handle_t output2)
152465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
152581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
152681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    MixerThread *thread1 = checkMixerThread_l(output1);
152781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    MixerThread *thread2 = checkMixerThread_l(output2);
152881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
152981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread1 == NULL || thread2 == NULL) {
153081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("openDuplicateOutput() wrong output mixer type for output %d or %d", output1,
153181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                output2);
153281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
153365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
153465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
153581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_io_handle_t id = nextUniqueId();
153681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    DuplicatingThread *thread = new DuplicatingThread(this, thread1, id);
153781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->addOutputTrack(thread2);
153881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mPlaybackThreads.add(id, thread);
153981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // notify client processes of the new output creation
154081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);
154181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return id;
154265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
154365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
154481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::closeOutput(audio_io_handle_t output)
15452bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi{
154681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return closeOutput_nonvirtual(output);
15472bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi}
15482bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi
154981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output)
155065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
155181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // keep strong reference on the playback thread so that
155281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // it is not destroyed while exit() is executed
155381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<PlaybackThread> thread;
155481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
155581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(mLock);
155681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread = checkPlaybackThread_l(output);
155781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread == NULL) {
155881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return BAD_VALUE;
155965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
156065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
156181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("closeOutput() %d", output);
1562de070137f11d346fba77605bd76a44c040a618fcEric Laurent
156381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread->type() == ThreadBase::MIXER) {
156481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
156581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (mPlaybackThreads.valueAt(i)->type() == ThreadBase::DUPLICATING) {
156681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    DuplicatingThread *dupThread =
156781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                            (DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
156881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    dupThread->removeOutputTrack((MixerThread *)thread.get());
1569bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
1570de070137f11d346fba77605bd76a44c040a618fcEric Laurent                }
1571de070137f11d346fba77605bd76a44c040a618fcEric Laurent            }
1572de070137f11d346fba77605bd76a44c040a618fcEric Laurent        }
1573bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
1574bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
157581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPlaybackThreads.removeItem(output);
1576bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        // save all effects to the default thread
1577bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (mPlaybackThreads.size()) {
1578bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            PlaybackThread *dstThread = checkPlaybackThread_l(mPlaybackThreads.keyAt(0));
1579bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (dstThread != NULL) {
1580bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // audioflinger lock is held here so the acquisition order of thread locks does not
1581bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // matter
1582bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                Mutex::Autolock _dl(dstThread->mLock);
1583bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                Mutex::Autolock _sl(thread->mLock);
1584bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                Vector< sp<EffectChain> > effectChains = thread->getEffectChains_l();
1585bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                for (size_t i = 0; i < effectChains.size(); i ++) {
1586bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    moveEffectChain_l(effectChains[i]->sessionId(), thread.get(), dstThread, true);
1587bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                }
1588bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
1589bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        }
1590bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, NULL);
15913acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    }
159281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->exit();
159381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // The thread entity (active unit of execution) is no longer running here,
159481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // but the ThreadBase container still exists.
15953acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten
159681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread->type() != ThreadBase::DUPLICATING) {
159781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioStreamOut *out = thread->clearOutput();
159881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOG_ASSERT(out != NULL, "out shouldn't be NULL");
159981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // from now on thread->mOutput is NULL
160081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        out->hwDev()->close_output_stream(out->hwDev(), out->stream);
160181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        delete out;
160265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
160381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
160465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
160565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
160681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::suspendOutput(audio_io_handle_t output)
1607e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent{
160881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
160981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = checkPlaybackThread_l(output);
161081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
161181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread == NULL) {
161281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
1613e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent    }
1614e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent
161581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("suspendOutput() %d", output);
161681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->suspend();
1617e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent
161881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
161965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
162065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
162181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::restoreOutput(audio_io_handle_t output)
162265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
16236637baae4244aec731c4014da72418d330636ae1Glenn Kasten    Mutex::Autolock _l(mLock);
162481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = checkPlaybackThread_l(output);
162565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
162681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread == NULL) {
162781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
1628ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    }
162965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
163081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("restoreOutput() %d", output);
163165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
163281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->restore();
163365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
163481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
163565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
163665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
163781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,
163881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          audio_devices_t *pDevices,
163981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          uint32_t *pSamplingRate,
164081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          audio_format_t *pFormat,
164181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                          audio_channel_mask_t *pChannelMask)
164265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
164381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status;
164481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    RecordThread *thread = NULL;
1645ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    struct audio_config config;
1646fb872cc6f77f6d74011fab703b3edd7023c736cbGlenn Kasten    memset(&config, 0, sizeof(config));
1647ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;
1648ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;
1649ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;
1650ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
165181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t reqSamplingRate = config.sample_rate;
165281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_format_t reqFormat = config.format;
1653f506e9495f2b2123b3bec7d42ec8ef13c6213ee8Glenn Kasten    audio_channel_mask_t reqChannelMask = config.channel_mask;
165481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_stream_in_t *inStream = NULL;
165581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioHwDevice *inHwDev;
165665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
165781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (pDevices == NULL || *pDevices == 0) {
165881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
1659b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    }
1660b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent
166181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
166265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
166381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    inHwDev = findSuitableHwDev_l(module, *pDevices);
166481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (inHwDev == NULL)
166581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
1666fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
166781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_hw_device_t *inHwHal = inHwDev->hwDevice();
166881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_io_handle_t id = nextUniqueId();
1669b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
167081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config,
167181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        &inStream);
167281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, "
167381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            "status %d",
167481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            inStream,
167581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.sample_rate,
167681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.format,
167781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            config.channel_mask,
167881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            status);
167965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
168081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // If the input could not be opened with the requested parameters and we can handle the
168181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // conversion internally, try to open again with the proposed parameters. The AudioFlinger can
168281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // resample the input and do mono to stereo or stereo to mono conversions on 16 bit PCM inputs.
168381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status == BAD_VALUE &&
168481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        reqFormat == config.format && config.format == AUDIO_FORMAT_PCM_16_BIT &&
168581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        (config.sample_rate <= 2 * reqSamplingRate) &&
1686f506e9495f2b2123b3bec7d42ec8ef13c6213ee8Glenn Kasten        (popcount(config.channel_mask) <= FCC_2) && (popcount(reqChannelMask) <= FCC_2)) {
168781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("openInput() reopening with proposed sampling rate and channel mask");
168881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        inStream = NULL;
168981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config, &inStream);
169065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
169165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
169281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status == NO_ERROR && inStream != NULL) {
169358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
169446909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
169581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Try to re-use most recently used Pipe to archive a copy of input for dumpsys,
169681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // or (re-)create if current Pipe is idle and does not match the new format
169781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<NBAIO_Sink> teeSink;
169881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        enum {
169981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            TEE_SINK_NO,    // don't copy input
170081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            TEE_SINK_NEW,   // copy input using a new pipe
170181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            TEE_SINK_OLD,   // copy input using an existing pipe
170281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } kind;
170381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        NBAIO_Format format = Format_from_SR_C(inStream->common.get_sample_rate(&inStream->common),
170481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        popcount(inStream->common.get_channels(&inStream->common)));
1705da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        if (!mTeeSinkInputEnabled) {
1706da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            kind = TEE_SINK_NO;
1707da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        } else if (format == Format_Invalid) {
170881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_NO;
170981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else if (mRecordTeeSink == 0) {
171081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_NEW;
171181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else if (mRecordTeeSink->getStrongCount() != 1) {
171281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_NO;
171381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else if (format == mRecordTeeSink->format()) {
171481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_OLD;
17154adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        } else {
171681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            kind = TEE_SINK_NEW;
171781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
171881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        switch (kind) {
171981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        case TEE_SINK_NEW: {
1720da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            Pipe *pipe = new Pipe(mTeeSinkInputFrames, format);
172181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t numCounterOffers = 0;
172281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const NBAIO_Format offers[1] = {format};
172381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
172481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOG_ASSERT(index == 0);
172581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PipeReader *pipeReader = new PipeReader(*pipe);
172681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            numCounterOffers = 0;
172781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
172881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOG_ASSERT(index == 0);
172981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mRecordTeeSink = pipe;
173081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mRecordTeeSource = pipeReader;
173181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            teeSink = pipe;
17324adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            }
173381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            break;
173481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        case TEE_SINK_OLD:
173581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            teeSink = mRecordTeeSink;
173681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            break;
173781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        case TEE_SINK_NO:
173881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        default:
173981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            break;
174058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
174146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
1742da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
174381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);
174465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
174581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Start record thread
174634af02647b387a252fb02bab8e2cb9f7bd9c8abbGlenn Kasten        // RecordThread requires both input and output device indication to forward to audio
174781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // pre processing modules
174881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread = new RecordThread(this,
174981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                  input,
175081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                  reqSamplingRate,
1751f506e9495f2b2123b3bec7d42ec8ef13c6213ee8Glenn Kasten                                  reqChannelMask,
175281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                  id,
1753d3922f72601d82c6fc067a98916fda0bd1291c5fEric Laurent                                  primaryOutputDevice_l(),
175446909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                                  *pDevices
175546909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
175646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                                  , teeSink
175746909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
175846909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                                  );
175981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mRecordThreads.add(id, thread);
176081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("openInput() created record thread: ID %d thread %p", id, thread);
17617c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        if (pSamplingRate != NULL) {
17627c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten            *pSamplingRate = reqSamplingRate;
17637c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        }
17647c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        if (pFormat != NULL) {
17657c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten            *pFormat = config.format;
17667c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        }
17677c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        if (pChannelMask != NULL) {
1768f506e9495f2b2123b3bec7d42ec8ef13c6213ee8Glenn Kasten            *pChannelMask = reqChannelMask;
17697c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten        }
177065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
177181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // notify client processes of the new input creation
177281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread->audioConfigChanged_l(AudioSystem::INPUT_OPENED);
177381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return id;
17741afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent    }
177581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
177681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return 0;
177765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
177865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
177981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::closeInput(audio_io_handle_t input)
178065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
178181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return closeInput_nonvirtual(input);
178265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
178365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
178481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input)
1785de070137f11d346fba77605bd76a44c040a618fcEric Laurent{
178681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // keep strong reference on the record thread so that
178781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // it is not destroyed while exit() is executed
178881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<RecordThread> thread;
178981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
179081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(mLock);
179181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread = checkRecordThread_l(input);
179281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread == 0) {
179381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return BAD_VALUE;
1794de070137f11d346fba77605bd76a44c040a618fcEric Laurent        }
179581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
179681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("closeInput() %d", input);
179781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audioConfigChanged_l(AudioSystem::INPUT_CLOSED, input, NULL);
179881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mRecordThreads.removeItem(input);
1799de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
180081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    thread->exit();
180181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // The thread entity (active unit of execution) is no longer running here,
180281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // but the ThreadBase container still exists.
1803de070137f11d346fba77605bd76a44c040a618fcEric Laurent
180481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioStreamIn *in = thread->clearInput();
180581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOG_ASSERT(in != NULL, "in shouldn't be NULL");
180681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // from now on thread->mInput is NULL
180781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    in->hwDev()->close_input_stream(in->hwDev(), in->stream);
180881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    delete in;
180965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
181081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
1811b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
1812b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
181381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output)
1814b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent{
1815b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    Mutex::Autolock _l(mLock);
181681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("setStreamOutput() stream %d to output %d", stream, output);
1817b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
181881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
181981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
182081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread->invalidateTracks(stream);
1821b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    }
182281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
182381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
1824b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
1825b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
182681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
182781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentint AudioFlinger::newAudioSessionId()
1828162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent{
182981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return nextUniqueId();
1830162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent}
1831162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent
183281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::acquireAudioSessionId(int audioSession)
1833a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
1834a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    Mutex::Autolock _l(mLock);
183581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    pid_t caller = IPCThreadState::self()->getCallingPid();
183681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("acquiring %d from %d", audioSession, caller);
183781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t num = mAudioSessionRefs.size();
183881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i< num; i++) {
183981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioSessionRef *ref = mAudioSessionRefs.editItemAt(i);
184081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (ref->mSessionid == audioSession && ref->mPid == caller) {
184181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ref->mCnt++;
184281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV(" incremented refcount to %d", ref->mCnt);
184381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return;
1844a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
1845a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
184681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAudioSessionRefs.push(new AudioSessionRef(audioSession, caller));
184781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV(" added new entry for %d", audioSession);
1848a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
1849a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
185081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::releaseAudioSessionId(int audioSession)
185144a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent{
185281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
185381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    pid_t caller = IPCThreadState::self()->getCallingPid();
185481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("releasing %d from %d", audioSession, caller);
185581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t num = mAudioSessionRefs.size();
185681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i< num; i++) {
185781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
185881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (ref->mSessionid == audioSession && ref->mPid == caller) {
185981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ref->mCnt--;
186081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV(" decremented refcount to %d", ref->mCnt);
186181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (ref->mCnt == 0) {
186281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mAudioSessionRefs.removeAt(i);
186381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                delete ref;
186481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                purgeStaleEffects_l();
186544a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent            }
186681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return;
186744a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent        }
186844a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent    }
186981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGW("session id %d not found for pid %d", audioSession, caller);
187044a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent}
187144a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent
187281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::purgeStaleEffects_l() {
187365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
187481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("purging stale effects");
1875fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten
187681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Vector< sp<EffectChain> > chains;
187758912562617941964939a4182cda71eaeb153d4bGlenn Kasten
187881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
187981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
188081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        for (size_t j = 0; j < t->mEffectChains.size(); j++) {
188181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectChain> ec = t->mEffectChains[j];
188281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (ec->sessionId() > AUDIO_SESSION_OUTPUT_MIX) {
188381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                chains.push(ec);
188481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
1885c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        }
188658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
188781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mRecordThreads.size(); i++) {
188881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<RecordThread> t = mRecordThreads.valueAt(i);
188981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        for (size_t j = 0; j < t->mEffectChains.size(); j++) {
189081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectChain> ec = t->mEffectChains[j];
189181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            chains.push(ec);
189281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
1893300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    }
189465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
189581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < chains.size(); i++) {
189681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<EffectChain> ec = chains[i];
189781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int sessionid = ec->sessionId();
189881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<ThreadBase> t = ec->mThread.promote();
189981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (t == 0) {
190081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            continue;
190181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
190281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        size_t numsessionrefs = mAudioSessionRefs.size();
190381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        bool found = false;
190481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        for (size_t k = 0; k < numsessionrefs; k++) {
190581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSessionRef *ref = mAudioSessionRefs.itemAt(k);
190681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (ref->mSessionid == sessionid) {
190781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGV(" session %d still exists for %d with %d refs",
190881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    sessionid, ref->mPid, ref->mCnt);
190981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                found = true;
191081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                break;
191158912562617941964939a4182cda71eaeb153d4bGlenn Kasten            }
191258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
191381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (!found) {
191481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _l (t->mLock);
191581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // remove all effects from the chain
191681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            while (ec->mEffects.size()) {
191781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                sp<EffectModule> effect = ec->mEffects[0];
191881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                effect->unPin();
191981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                t->removeEffect_l(effect);
192081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (effect->purgeHandles()) {
192181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    t->checkSuspendOnEffectEnabled_l(effect, false, effect->sessionId());
192281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                }
192381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                AudioSystem::unregisterEffect(effect->id());
192481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
1925c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        }
192658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
192781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return;
192865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
192965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
193081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
193181784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
1932190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten{
193381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mPlaybackThreads.valueFor(output).get();
1934190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten}
1935190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
193681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// checkMixerThread_l() must be called with AudioFlinger::mLock held
193781784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(audio_io_handle_t output) const
193881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
193981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = checkPlaybackThread_l(output);
194081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return thread != NULL && thread->type() != ThreadBase::DIRECT ? (MixerThread *) thread : NULL;
194181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
1942190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
194381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// checkRecordThread_l() must be called with AudioFlinger::mLock held
194481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(audio_io_handle_t input) const
194581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
194681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mRecordThreads.valueFor(input).get();
194781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
1948190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
194981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::nextUniqueId()
195081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
195181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return android_atomic_inc(&mNextUniqueId);
195281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
195383efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten
195481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
195537d825e72a6c606553a745da1212590a425996d3Glenn Kasten{
195681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
195781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
195881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioStreamOut *output = thread->getOutput();
195981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (output != NULL && output->audioHwDev == mPrimaryHardwareDev) {
196081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return thread;
196137d825e72a6c606553a745da1212590a425996d3Glenn Kasten        }
196237d825e72a6c606553a745da1212590a425996d3Glenn Kasten    }
196381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NULL;
196437d825e72a6c606553a745da1212590a425996d3Glenn Kasten}
196537d825e72a6c606553a745da1212590a425996d3Glenn Kasten
196681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentaudio_devices_t AudioFlinger::primaryOutputDevice_l() const
196765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
196881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *thread = primaryPlaybackThread_l();
1969000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
197081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread == NULL) {
197181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
19729f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten    }
1973000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
197481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return thread->outDevice();
1975000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
1976688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten
197781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<AudioFlinger::SyncEvent> AudioFlinger::createSyncEvent(AudioSystem::sync_event_t type,
197881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                    int triggerSession,
197981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                    int listenerSession,
198081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                    sync_event_callback_t callBack,
198181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                    void *cookie)
198281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
198381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
198473ca0f5837d5448f7a5eb159a09cd0ebe82b4de9Glenn Kasten
198581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<SyncEvent> event = new SyncEvent(type, triggerSession, listenerSession, callBack, cookie);
198681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t playStatus = NAME_NOT_FOUND;
198781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t recStatus = NAME_NOT_FOUND;
198881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
198981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        playStatus = mPlaybackThreads.valueAt(i)->setSyncEvent(event);
199081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (playStatus == NO_ERROR) {
199181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return event;
199281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
199365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
199481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < mRecordThreads.size(); i++) {
199581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        recStatus = mRecordThreads.valueAt(i)->setSyncEvent(event);
199681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (recStatus == NO_ERROR) {
199781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return event;
19989f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten        }
199965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
200081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (playStatus == NAME_NOT_FOUND || recStatus == NAME_NOT_FOUND) {
200181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPendingSyncEvents.add(event);
200281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
200381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("createSyncEvent() invalid event %d", event->type());
200481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        event.clear();
200581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
200681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return event;
200765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
200865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
200981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
201081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//  Effect management
201181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
201258912562617941964939a4182cda71eaeb153d4bGlenn Kasten
201358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
201481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::queryNumberEffects(uint32_t *numEffects) const
2015000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
201681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
201781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return EffectQueryNumberEffects(numEffects);
2018000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
2019000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
202081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor) const
202158912562617941964939a4182cda71eaeb153d4bGlenn Kasten{
202281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
202381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return EffectQueryEffect(index, descriptor);
202458912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
202558912562617941964939a4182cda71eaeb153d4bGlenn Kasten
202681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::getEffectDescriptor(const effect_uuid_t *pUuid,
202781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        effect_descriptor_t *descriptor) const
2028000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
202981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mLock);
203081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return EffectGetDescriptor(pUuid, descriptor);
2031000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
2032000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
203381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
20348d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kastensp<IEffect> AudioFlinger::createEffect(
203581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        effect_descriptor_t *pDesc,
203681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        const sp<IEffectClient>& effectClient,
203781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int32_t priority,
203881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_io_handle_t io,
203981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int sessionId,
204081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status_t *status,
204181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int *id,
204281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int *enabled)
2043000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
204481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t lStatus = NO_ERROR;
204581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<EffectHandle> handle;
204681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    effect_descriptor_t desc;
2047000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
20488d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kasten    pid_t pid = IPCThreadState::self()->getCallingPid();
204981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d",
205081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            pid, effectClient.get(), priority, sessionId, io);
2051000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
205281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (pDesc == NULL) {
205381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        lStatus = BAD_VALUE;
205481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
2055952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
2056000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
205781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // check audio settings permission for global effects
205881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (sessionId == AUDIO_SESSION_OUTPUT_MIX && !settingsAllowed()) {
205981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        lStatus = PERMISSION_DENIED;
206081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
2061952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
2062000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
206381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // Session AUDIO_SESSION_OUTPUT_STAGE is reserved for output stage effects
206481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // that can only be created by audio policy manager (running in same process)
206581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (sessionId == AUDIO_SESSION_OUTPUT_STAGE && getpid_cached != pid) {
206681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        lStatus = PERMISSION_DENIED;
206781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto Exit;
2068952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
206965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
207081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (io == 0) {
207181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
207281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // output must be specified by AudioPolicyManager when using session
207381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // AUDIO_SESSION_OUTPUT_STAGE
207481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = BAD_VALUE;
207581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            goto Exit;
207681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
207781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // if the output returned by getOutputForEffect() is removed before we lock the
207881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // mutex below, the call to checkPlaybackThread_l(io) below will detect it
207981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // and we will exit safely
208081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            io = AudioSystem::getOutputForEffect(&desc);
208181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
208265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
208365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
208481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
208581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(mLock);
2086288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
208765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
208881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (!EffectIsNullUuid(&pDesc->uuid)) {
208981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // if uuid is specified, request effect descriptor
209081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = EffectGetDescriptor(&pDesc->uuid, &desc);
209181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (lStatus < 0) {
209281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("createEffect() error %d from EffectGetDescriptor", lStatus);
209381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
209481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
209581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
209681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // if uuid is not specified, look for an available implementation
209781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // of the required type in effect factory
209881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (EffectIsNullUuid(&pDesc->type)) {
209981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("createEffect() no effect type");
210081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                lStatus = BAD_VALUE;
210181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
2102288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
210381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t numEffects = 0;
210481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            effect_descriptor_t d;
210581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            d.flags = 0; // prevent compiler warning
210681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            bool found = false;
2107288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
210881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = EffectQueryNumberEffects(&numEffects);
210981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (lStatus < 0) {
211081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("createEffect() error %d from EffectQueryNumberEffects", lStatus);
211181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
211281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
211381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            for (uint32_t i = 0; i < numEffects; i++) {
211481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                lStatus = EffectQueryEffect(i, &desc);
211581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (lStatus < 0) {
211681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    ALOGW("createEffect() error %d from EffectQueryEffect", lStatus);
211781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    continue;
2118d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                }
211981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (memcmp(&desc.type, &pDesc->type, sizeof(effect_uuid_t)) == 0) {
212081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    // If matching type found save effect descriptor. If the session is
212181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    // 0 and the effect is not auxiliary, continue enumeration in case
212281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    // an auxiliary version of this effect type is available
212381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    found = true;
212481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    d = desc;
212581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    if (sessionId != AUDIO_SESSION_OUTPUT_MIX ||
212681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                            (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
2127d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                        break;
2128d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    }
2129d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                }
2130288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
213181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (!found) {
213281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                lStatus = BAD_VALUE;
213381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("createEffect() effect not found");
213481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
213581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
213681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // For same effect type, chose auxiliary version over insert version if
213781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // connect to output mix (Compliance to OpenSL ES)
213881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (sessionId == AUDIO_SESSION_OUTPUT_MIX &&
213981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    (d.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_AUXILIARY) {
214081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                desc = d;
214158912562617941964939a4182cda71eaeb153d4bGlenn Kasten            }
214258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
214358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
214481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Do not allow auxiliary effects on a session different from 0 (output mix)
214581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (sessionId != AUDIO_SESSION_OUTPUT_MIX &&
214681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent             (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
214781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = INVALID_OPERATION;
214881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            goto Exit;
21493dbe3201479828e84abe02e1fdd0a5d414c0ddb8Eric Laurent        }
215065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
215181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // check recording permission for visualizer
215281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) &&
215381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            !recordingAllowed()) {
215481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            lStatus = PERMISSION_DENIED;
215581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            goto Exit;
215681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
215765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
215881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // return effect descriptor
215981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        *pDesc = desc;
216065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
216181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // If output is not specified try to find a matching audio session ID in one of the
216281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // output threads.
216381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // If output is 0 here, sessionId is neither SESSION_OUTPUT_STAGE nor SESSION_OUTPUT_MIX
216481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // because of code checking output when entering the function.
216581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Note: io is never 0 when creating an effect on an input
216681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (io == 0) {
216781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // look for the thread where the specified audio session is present
216881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
216981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
217081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    io = mPlaybackThreads.keyAt(i);
217181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    break;
217265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
2173d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            }
217481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (io == 0) {
217581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                for (size_t i = 0; i < mRecordThreads.size(); i++) {
217681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    if (mRecordThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
217781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        io = mRecordThreads.keyAt(i);
217881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        break;
21792986460984580833161bdaabc7f17da1005a8961Eric Laurent                    }
218065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
218165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
218281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // If no output thread contains the requested session ID, default to
218381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // first output. The effect chain will be moved to the correct output
218481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // thread when a track with the same session ID is created
218581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (io == 0 && mPlaybackThreads.size()) {
218681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                io = mPlaybackThreads.keyAt(0);
218781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
218881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("createEffect() got io %d for effect %s", io, desc.name);
218965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
219081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ThreadBase *thread = checkRecordThread_l(io);
219181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread == NULL) {
219281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            thread = checkPlaybackThread_l(io);
219381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (thread == NULL) {
219481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGE("createEffect() unknown output thread");
219581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                lStatus = BAD_VALUE;
219681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                goto Exit;
2197288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
2198288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        }
2199288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
220081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<Client> client = registerPid_l(pid);
220158912562617941964939a4182cda71eaeb153d4bGlenn Kasten
220281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // create effect on selected output thread
220381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        handle = thread->createEffect_l(client, effectClient, priority, sessionId,
220481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                &desc, enabled, &lStatus);
220581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (handle != 0 && id != NULL) {
220681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            *id = handle->id();
220765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
220865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
220965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
221081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentExit:
22119156ef3e11b68cc4b6d3cea77f1f63673855a6d1Glenn Kasten    *status = lStatus;
221281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return handle;
221366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten}
221466fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
221581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::moveEffects(int sessionId, audio_io_handle_t srcOutput,
221681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        audio_io_handle_t dstOutput)
221765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
221881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("moveEffects() session %d, srcOutput %d, dstOutput %d",
221981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sessionId, srcOutput, dstOutput);
222065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
222181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (srcOutput == dstOutput) {
222281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("moveEffects() same dst and src outputs %d", dstOutput);
222381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return NO_ERROR;
222481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
222581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *srcThread = checkPlaybackThread_l(srcOutput);
222681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (srcThread == NULL) {
222781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("moveEffects() bad srcOutput %d", srcOutput);
222881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
222981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
223081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread *dstThread = checkPlaybackThread_l(dstOutput);
223181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (dstThread == NULL) {
223281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("moveEffects() bad dstOutput %d", dstOutput);
223381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
223465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
223565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
223681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _dl(dstThread->mLock);
223781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _sl(srcThread->mLock);
223881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    moveEffectChain_l(sessionId, srcThread, dstThread, false);
223965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
224081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
224165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
224265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
224381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// moveEffectChain_l must be called with both srcThread and dstThread mLocks held
224481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::moveEffectChain_l(int sessionId,
224581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                   AudioFlinger::PlaybackThread *srcThread,
224681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                   AudioFlinger::PlaybackThread *dstThread,
224781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                   bool reRegister)
224865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
224981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("moveEffectChain_l() session %d from thread %p to thread %p",
225081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sessionId, srcThread, dstThread);
225165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
225281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<EffectChain> chain = srcThread->getEffectChain_l(sessionId);
225381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (chain == 0) {
225481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("moveEffectChain_l() effect chain for session %d not on source thread %p",
225581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                sessionId, srcThread);
225681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return INVALID_OPERATION;
225781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
22589ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
225981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // remove chain first. This is useful only if reconfiguring effect chain on same output thread,
226081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // so that a new chain is created with correct parameters when first effect is added. This is
226181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // otherwise unnecessary as removeEffect_l() will remove the chain when last effect is
226281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // removed.
226381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    srcThread->removeEffectChain_l(chain);
22649ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
226581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // transfer all effects one by one so that new effect chain is created on new thread with
226681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // correct buffer sizes and audio parameters and effect engines reconfigured accordingly
226781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    audio_io_handle_t dstOutput = dstThread->id();
226881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<EffectChain> dstChain;
226981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t strategy = 0; // prevent compiler warning
227081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<EffectModule> effect = chain->getEffectFromId_l(0);
227181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    while (effect != 0) {
227281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        srcThread->removeEffect_l(effect);
227381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        dstThread->addEffect_l(effect);
227481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // removeEffect_l() has stopped the effect if it was active so it must be restarted
227581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (effect->state() == EffectModule::ACTIVE ||
227681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                effect->state() == EffectModule::STOPPING) {
227781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            effect->start();
227865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
227981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // if the move request is not received from audio policy manager, the effect must be
228081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // re-registered with the new strategy and output
228181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (dstChain == 0) {
228281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            dstChain = effect->chain().promote();
228381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (dstChain == 0) {
228481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("moveEffectChain_l() cannot get chain from effect %p", effect.get());
228581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                srcThread->addEffect_l(effect);
228681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return NO_INIT;
228765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
228881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            strategy = dstChain->strategy();
228965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
229081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (reRegister) {
229181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSystem::unregisterEffect(effect->id());
229281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSystem::registerEffect(&effect->desc(),
229381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        dstOutput,
229481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        strategy,
229581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        sessionId,
229681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        effect->id());
229781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
229881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        effect = chain->getEffectFromId_l(0);
229958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
230058912562617941964939a4182cda71eaeb153d4bGlenn Kasten
230181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
230265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
230365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2304da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenstruct Entry {
2305da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#define MAX_NAME 32     // %Y%m%d%H%M%S_%d.wav
2306da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    char mName[MAX_NAME];
2307da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten};
2308da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
2309da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenint comparEntry(const void *p1, const void *p2)
2310da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten{
2311da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    return strcmp(((const Entry *) p1)->mName, ((const Entry *) p2)->mName);
2312da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten}
2313da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
231446909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
2315d06785bebf7e43d4a011b62a252771373ada910cGlenn Kastenvoid AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_handle_t id)
231665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
2317d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    NBAIO_Source *teeSource = source.get();
2318fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten    if (teeSource != NULL) {
2319da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // .wav rotation
2320da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // There is a benign race condition if 2 threads call this simultaneously.
2321da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // They would both traverse the directory, but the result would simply be
2322da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // failures at unlink() which are ignored.  It's also unlikely since
2323da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // normally dumpsys is only done by bugreport or from the command line.
2324da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        char teePath[32+256];
2325da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        strcpy(teePath, "/data/misc/media");
2326da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        size_t teePathLen = strlen(teePath);
2327da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        DIR *dir = opendir(teePath);
2328da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        teePath[teePathLen++] = '/';
2329da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        if (dir != NULL) {
2330da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#define MAX_SORT 20 // number of entries to sort
2331da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#define MAX_KEEP 10 // number of entries to keep
2332da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            struct Entry entries[MAX_SORT];
2333da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            size_t entryCount = 0;
2334da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            while (entryCount < MAX_SORT) {
2335da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                struct dirent de;
2336da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                struct dirent *result = NULL;
2337da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                int rc = readdir_r(dir, &de, &result);
2338da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                if (rc != 0) {
2339da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    ALOGW("readdir_r failed %d", rc);
2340da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    break;
2341da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2342da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                if (result == NULL) {
2343da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    break;
2344da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2345da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                if (result != &de) {
2346da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    ALOGW("readdir_r returned unexpected result %p != %p", result, &de);
2347da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    break;
2348da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2349da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                // ignore non .wav file entries
2350da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                size_t nameLen = strlen(de.d_name);
2351da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                if (nameLen <= 4 || nameLen >= MAX_NAME ||
2352da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                        strcmp(&de.d_name[nameLen - 4], ".wav")) {
2353da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    continue;
2354da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2355da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                strcpy(entries[entryCount++].mName, de.d_name);
2356da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2357da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            (void) closedir(dir);
2358da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            if (entryCount > MAX_KEEP) {
2359da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                qsort(entries, entryCount, sizeof(Entry), comparEntry);
2360da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                for (size_t i = 0; i < entryCount - MAX_KEEP; ++i) {
2361da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    strcpy(&teePath[teePathLen], entries[i].mName);
2362da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                    (void) unlink(teePath);
2363da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                }
2364da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2365da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        } else {
2366da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            if (fd >= 0) {
2367da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                fdprintf(fd, "unable to rotate tees in %s: %s\n", teePath, strerror(errno));
2368da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2369da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        }
2370d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        char teeTime[16];
2371fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        struct timeval tv;
2372fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        gettimeofday(&tv, NULL);
2373fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        struct tm tm;
2374fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        localtime_r(&tv.tv_sec, &tm);
2375da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        strftime(teeTime, sizeof(teeTime), "%Y%m%d%H%M%S", &tm);
2376da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        snprintf(&teePath[teePathLen], sizeof(teePath) - teePathLen, "%s_%d.wav", teeTime, id);
2377da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        // if 2 dumpsys are done within 1 second, and rotation didn't work, then discard 2nd
2378da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        int teeFd = open(teePath, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, S_IRUSR | S_IWUSR);
2379fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        if (teeFd >= 0) {
2380fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            char wavHeader[44];
2381fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            memcpy(wavHeader,
2382fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn 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",
2383fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                sizeof(wavHeader));
2384fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            NBAIO_Format format = teeSource->format();
2385fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            unsigned channelCount = Format_channelCount(format);
2386fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            ALOG_ASSERT(channelCount <= FCC_2);
23873b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten            uint32_t sampleRate = Format_sampleRate(format);
2388fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[22] = channelCount;       // number of channels
2389fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[24] = sampleRate;         // sample rate
2390fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[25] = sampleRate >> 8;
2391fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[32] = channelCount * 2;   // block alignment
2392fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            write(teeFd, wavHeader, sizeof(wavHeader));
2393fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            size_t total = 0;
2394fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            bool firstRead = true;
2395fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            for (;;) {
2396fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten#define TEE_SINK_READ 1024
2397fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                short buffer[TEE_SINK_READ * FCC_2];
2398fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                size_t count = TEE_SINK_READ;
23992c3b2da3049627264b7c6b449a1622f002210f03John Grossman                ssize_t actual = teeSource->read(buffer, count,
24002c3b2da3049627264b7c6b449a1622f002210f03John Grossman                        AudioBufferProvider::kInvalidPTS);
2401fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                bool wasFirstRead = firstRead;
2402fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                firstRead = false;
2403fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                if (actual <= 0) {
2404fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                    if (actual == (ssize_t) OVERRUN && wasFirstRead) {
2405fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                        continue;
2406fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                    }
2407fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                    break;
2408fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                }
2409a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent                ALOG_ASSERT(actual <= (ssize_t)count);
2410fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                write(teeFd, buffer, actual * channelCount * sizeof(short));
2411fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                total += actual;
2412fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            }
2413fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            lseek(teeFd, (off_t) 4, SEEK_SET);
2414fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            uint32_t temp = 44 + total * channelCount * sizeof(short) - 8;
2415fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            write(teeFd, &temp, sizeof(temp));
2416fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            lseek(teeFd, (off_t) 40, SEEK_SET);
2417fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            temp =  total * channelCount * sizeof(short);
2418fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            write(teeFd, &temp, sizeof(temp));
2419fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            close(teeFd);
2420da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            if (fd >= 0) {
2421da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                fdprintf(fd, "tee copied to %s\n", teePath);
2422da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2423fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        } else {
2424da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            if (fd >= 0) {
2425da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten                fdprintf(fd, "unable to create tee %s: %s\n", teePath, strerror(errno));
2426da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten            }
2427fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        }
2428fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten    }
2429d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten}
243046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
2431d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
243265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
243365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
243465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::onTransact(
243565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
243665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
243765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnAudioFlinger::onTransact(code, data, reply, flags);
243865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
243965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
244065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
2441