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>
34a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov#include <media/audiohal/DeviceHalInterface.h>
35a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov#include <media/audiohal/DevicesFactoryHalInterface.h>
36a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov#include <media/audiohal/EffectsFactoryHalInterface.h>
3700260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov#include <media/AudioParameter.h>
38913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov#include <media/TypeConverter.h>
3935fec5f61393124c9e13958941637b8fe386385eAndy Hung#include <memunreachable/memunreachable.h>
4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h>
4165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/threads.h>
4238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent#include <utils/Atomic.h>
4365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
44fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <cutils/bitops.h>
4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/properties.h>
4665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4764760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h>
4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioFlinger.h"
5044deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten#include "ServiceUtilities.h"
5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
526770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung#include <media/AudioResamplerPublic.h>
536770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung
549fe94012187a29eeeca2c74e75f121192560fba0Mikhail Naganov#include <system/audio_effects/effect_visualizer.h>
559fe94012187a29eeeca2c74e75f121192560fba0Mikhail Naganov#include <system/audio_effects/effect_ns.h>
569fe94012187a29eeeca2c74e75f121192560fba0Mikhail Naganov#include <system/audio_effects/effect_aec.h>
5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
583b21c50ef95fe4e7ac3426ca14b365749e66ff08Glenn Kasten#include <audio_utils/primitives.h>
593b21c50ef95fe4e7ac3426ca14b365749e66ff08Glenn Kasten
60feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent#include <powermanager/PowerManager.h>
61190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
629e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten#include <media/IMediaLogService.h>
6307b745e166ee62030960ccea37e117caadf71c32Andy Hung#include <media/MemoryLeakTrackUtil.h>
64da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <media/nbaio/Pipe.h>
65da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <media/nbaio/PipeReader.h>
661ab85ec401801ef9a9184650d0f5a1639b45eeb9Glenn Kasten#include <media/AudioParameter.h>
673f273d10817ddb2f792ae043de692efcdf1988aeWei Jia#include <mediautils/BatteryNotifier.h>
684182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten#include <private/android_filesystem_config.h>
69da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
703bd1c87ac0d767566f5da387e90b8a3cd86ecc97rago//#define BUFLOG_NDEBUG 0
713bd1c87ac0d767566f5da387e90b8a3cd86ecc97rago#include <BufLog.h>
723bd1c87ac0d767566f5da387e90b8a3cd86ecc97rago
73fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet#include "TypedLogger.h"
74fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet
7565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
7665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
771c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// Note: the following macro is used for extremely verbose logging message.  In
781c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
791c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// 0; but one side effect of this is to turn all LOGV's as well.  Some messages
801c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// are so verbose that we want to suppress them even when we have ALOG_ASSERT
811c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// turned on.  Do not uncomment the #def below unless you really know what you
821c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// are doing and want to see all of the extremely verbose messages.
831c345196edc61694f29307a1826a64a0d26028dcJohn Grossman//#define VERY_VERY_VERBOSE_LOGGING
841c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#ifdef VERY_VERY_VERBOSE_LOGGING
851c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#define ALOGVV ALOGV
861c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#else
871c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#define ALOGVV(a...) do { } while(0)
881c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#endif
89de070137f11d346fba77605bd76a44c040a618fcEric Laurent
9065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
9165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
92ec1d6b5e17281a066d618f7fcd2b63b3ce11f421Glenn Kastenstatic const char kDeadlockedString[] = "AudioFlinger may be deadlocked\n";
93ec1d6b5e17281a066d618f7fcd2b63b3ce11f421Glenn Kastenstatic const char kHardwareLockedString[] = "Hardware lock is taken\n";
94021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurentstatic const char kClientLockedString[] = "Client lock is taken\n";
954a3d5c23f79189eb7ab9f31c440c7da5b15947a2Mikhail Naganovstatic const char kNoEffectsFactory[] = "Effects Factory is absent\n";
9665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9758912562617941964939a4182cda71eaeb153d4bGlenn Kasten
984ff14bae91075eb274eb1c2975982358946e7e63John Grossmannsecs_t AudioFlinger::mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
997cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurent
10081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::mScreenState;
1013ed292031dc50c56110cdadb1e3778117e3be76aGlenn Kasten
102fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent
10346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
104da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenbool AudioFlinger::mTeeSinkInputEnabled = false;
105da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenbool AudioFlinger::mTeeSinkOutputEnabled = false;
106da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenbool AudioFlinger::mTeeSinkTrackEnabled = false;
107da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
108da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastensize_t AudioFlinger::mTeeSinkInputFrames = kTeeSinkInputFramesDefault;
109da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastensize_t AudioFlinger::mTeeSinkOutputFrames = kTeeSinkOutputFramesDefault;
110da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastensize_t AudioFlinger::mTeeSinkTrackFrames = kTeeSinkTrackFramesDefault;
11146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
112da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
113813e2a74853bde19e37d878c596a044b3f299efcEric Laurent// In order to avoid invalidating offloaded tracks each time a Visualizer is turned on and off
114813e2a74853bde19e37d878c596a044b3f299efcEric Laurent// we define a minimum time during which a global effect is considered enabled.
115813e2a74853bde19e37d878c596a044b3f299efcEric Laurentstatic const nsecs_t kMinGlobalEffectEnabletimeNs = seconds(7200);
116813e2a74853bde19e37d878c596a044b3f299efcEric Laurent
117fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric LaurentMutex gLock;
118fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurentwp<AudioFlinger> gAudioFlinger;
119fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent
1203ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten// Keep a strong reference to media.log service around forever.
1213ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten// The service is within our parent process so it can never die in a way that we could observe.
1223ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten// These two variables are const after initialization.
1233ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kastenstatic sp<IBinder> sMediaLogServiceAsBinder;
1243ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kastenstatic sp<IMediaLogService> sMediaLogService;
1253ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten
1263ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kastenstatic pthread_once_t sMediaLogOnce = PTHREAD_ONCE_INIT;
1273ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten
1283ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kastenstatic void sMediaLogInit()
1293ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten{
1303ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten    sMediaLogServiceAsBinder = defaultServiceManager()->getService(String16("media.log"));
1313ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten    if (sMediaLogServiceAsBinder != 0) {
1323ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten        sMediaLogService = interface_cast<IMediaLogService>(sMediaLogServiceAsBinder);
1333ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten    }
1343ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten}
1353ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten
13665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
13765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
138913d06c099bd689375483a839e11057ccf284d1cMikhail Naganovstd::string formatToString(audio_format_t format) {
139913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov    std::string result;
140913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov    FormatConverter::toString(format, result);
141913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov    return result;
142b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen}
143b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen
14465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
14565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
14665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::AudioFlinger()
14765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    : BnAudioFlinger(),
148dcdfaecc1fa630a799e1fdb508a9b92da55abc36Nicolas Roulet      mMediaLogNotifier(new AudioFlinger::MediaLogNotifier()),
1494ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mPrimaryHardwareDev(NULL),
1509ea65d0f4a564478343b1a722fae4ce5883670c3Glenn Kasten      mAudioHwDevs(NULL),
1517d6c35bf132a46c0a8a9826491882495fc98bd8cGlenn Kasten      mHardwareStatus(AUDIO_HW_IDLE),
1524ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mMasterVolume(1.0f),
1534ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mMasterMute(false),
154d2e67e1ef59921101fd7b047e2acf84e5d16d66eGlenn Kasten      // mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX),
1554ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mMode(AUDIO_MODE_INVALID),
1564182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten      mBtNrecIsOff(false),
1574182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten      mIsLowRamDevice(true),
158813e2a74853bde19e37d878c596a044b3f299efcEric Laurent      mIsDeviceTypeKnown(false),
1594ea00a25cf85877b48ebd1e15a657cfaab29af58Glenn Kasten      mGlobalEffectEnableTime(0),
16072e3f39146fce4686bd96f11057c051bea376dfbEric Laurent      mSystemReady(false)
16165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
162d2e67e1ef59921101fd7b047e2acf84e5d16d66eGlenn Kasten    // unsigned instead of audio_unique_id_use_t, because ++ operator is unavailable for enum
163d2e67e1ef59921101fd7b047e2acf84e5d16d66eGlenn Kasten    for (unsigned use = AUDIO_UNIQUE_ID_USE_UNSPECIFIED; use < AUDIO_UNIQUE_ID_USE_MAX; use++) {
164d2e67e1ef59921101fd7b047e2acf84e5d16d66eGlenn Kasten        // zero ID has a special meaning, so unavailable
165d2e67e1ef59921101fd7b047e2acf84e5d16d66eGlenn Kasten        mNextUniqueIds[use] = AUDIO_UNIQUE_ID_USE_MAX;
166d2e67e1ef59921101fd7b047e2acf84e5d16d66eGlenn Kasten    }
167d2e67e1ef59921101fd7b047e2acf84e5d16d66eGlenn Kasten
168949a926cadbc961fbb649c91d76d7aee8ea4d7bdGlenn Kasten    getpid_cached = getpid();
169ae0cff1d48b2cd10aeff9627398faf684894eeceGlenn Kasten    const bool doLog = property_get_bool("ro.test_harness", false);
1709e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (doLog) {
171b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten        mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters",
172b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten                MemoryHeapBase::READ_ONLY);
1733ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten        (void) pthread_once(&sMediaLogOnce, sMediaLogInit);
1749e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
1751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent
1763f273d10817ddb2f792ae043de692efcdf1988aeWei Jia    // reset battery stats.
1773f273d10817ddb2f792ae043de692efcdf1988aeWei Jia    // if the audio service has crashed, battery stats could be left
1783f273d10817ddb2f792ae043de692efcdf1988aeWei Jia    // in bad state, reset the state upon service start.
1793f273d10817ddb2f792ae043de692efcdf1988aeWei Jia    BatteryNotifier::getInstance().noteResetAudio();
1803f273d10817ddb2f792ae043de692efcdf1988aeWei Jia
181e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov    mDevicesFactoryHal = DevicesFactoryHalInterface::create();
1824a3d5c23f79189eb7ab9f31c440c7da5b15947a2Mikhail Naganov    mEffectsFactoryHal = EffectsFactoryHalInterface::create();
1834a3d5c23f79189eb7ab9f31c440c7da5b15947a2Mikhail Naganov
184dcdfaecc1fa630a799e1fdb508a9b92da55abc36Nicolas Roulet    mMediaLogNotifier->run("MediaLogNotifier");
185dcdfaecc1fa630a799e1fdb508a9b92da55abc36Nicolas Roulet
18646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
1879a00399340c7c129714dff96f1ab59045fe43056Glenn Kasten    char value[PROPERTY_VALUE_MAX];
188da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    (void) property_get("ro.debuggable", value, "0");
189da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    int debuggable = atoi(value);
190da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    int teeEnabled = 0;
191da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (debuggable) {
192da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        (void) property_get("af.tee", value, "0");
193da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        teeEnabled = atoi(value);
194da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    }
195f66b42242342017c26eb97de544dae31dd2537caGlenn Kasten    // FIXME symbolic constants here
1966e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (teeEnabled & 1) {
197da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        mTeeSinkInputEnabled = true;
1986e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
1996e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (teeEnabled & 2) {
200da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        mTeeSinkOutputEnabled = true;
2016e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
2026e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (teeEnabled & 4) {
203da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        mTeeSinkTrackEnabled = true;
2046e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
20546909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
2065a61d2f277af3098fc10b2881babca16391362daDima Zavin}
2075a61d2f277af3098fc10b2881babca16391362daDima Zavin
2085a61d2f277af3098fc10b2881babca16391362daDima Zavinvoid AudioFlinger::onFirstRef()
2095a61d2f277af3098fc10b2881babca16391362daDima Zavin{
210935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    Mutex::Autolock _l(mLock);
211935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent
212799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    /* TODO: move all this work into an Init() function */
2134ff14bae91075eb274eb1c2975982358946e7e63John Grossman    char val_str[PROPERTY_VALUE_MAX] = { 0 };
2144ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
2154ff14bae91075eb274eb1c2975982358946e7e63John Grossman        uint32_t int_val;
2164ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (1 == sscanf(val_str, "%u", &int_val)) {
2174ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mStandbyTimeInNsecs = milliseconds(int_val);
2184ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGI("Using %u mSec as standby time.", int_val);
2194ff14bae91075eb274eb1c2975982358946e7e63John Grossman        } else {
2204ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
2214ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGI("Using default %u mSec as standby time.",
2224ff14bae91075eb274eb1c2975982358946e7e63John Grossman                    (uint32_t)(mStandbyTimeInNsecs / 1000000));
2234ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
2244ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
22565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent    mPatchPanel = new PatchPanel(this);
227deb0335714cabc906098fb1d971d992027267fc6Andy Hung
228a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    mMode = AUDIO_MODE_NORMAL;
229fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent
230fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent    gAudioFlinger = this;
23165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
23265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
23365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::~AudioFlinger()
23465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
23565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!mRecordThreads.isEmpty()) {
236c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten        // closeInput_nonvirtual() will remove specified entry from mRecordThreads
237d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten        closeInput_nonvirtual(mRecordThreads.keyAt(0));
23865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
23965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!mPlaybackThreads.isEmpty()) {
240c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten        // closeOutput_nonvirtual() will remove specified entry from mPlaybackThreads
241d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten        closeOutput_nonvirtual(mPlaybackThreads.keyAt(0));
24265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
243799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
2442b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
2452b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten        // no mHardwareLock needed, as there are no other references to this
246a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        delete mAudioHwDevs.valueAt(i);
24765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
248481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten
249481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten    // Tell media.log service about any old writers that still need to be unregistered
2503ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten    if (sMediaLogService != 0) {
2513ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten        for (size_t count = mUnregisteredWriters.size(); count > 0; count--) {
2523ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten            sp<IMemory> iMemory(mUnregisteredWriters.top()->getIMemory());
2533ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten            mUnregisteredWriters.pop();
2543ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten            sMediaLogService->unregisterWriter(iMemory);
255481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten        }
256481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten    }
25765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
25865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
259fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent//static
2606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent__attribute__ ((visibility ("default")))
261fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurentstatus_t MmapStreamInterface::openMmapStream(MmapStreamInterface::stream_direction_t direction,
262fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent                                             const audio_attributes_t *attr,
263fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent                                             audio_config_base_t *config,
264fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent                                             const MmapStreamInterface::Client& client,
265fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent                                             audio_port_handle_t *deviceId,
266fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent                                             const sp<MmapStreamCallback>& callback,
267fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent                                             sp<MmapStreamInterface>& interface)
268fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent{
269fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent    sp<AudioFlinger> af;
270fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent    {
271fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent        Mutex::Autolock _l(gLock);
272fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent        af = gAudioFlinger.promote();
273fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent    }
274fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent    status_t ret = NO_INIT;
275fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent    if (af != 0) {
276fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent        ret = af->openMmapStream(
277fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent                direction, attr, config, client, deviceId, callback, interface);
278fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent    }
279fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent    return ret;
280fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent}
281fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent
2826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t direction,
2836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                      const audio_attributes_t *attr,
2846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                      audio_config_base_t *config,
2856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                      const MmapStreamInterface::Client& client,
2866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                      audio_port_handle_t *deviceId,
2876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                      const sp<MmapStreamCallback>& callback,
2886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                      sp<MmapStreamInterface>& interface)
289fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent{
290fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent    status_t ret = initCheck();
291fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent    if (ret != NO_ERROR) {
292fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent        return ret;
293fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent    }
294fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent
2956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    audio_session_t sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
2966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT;
2976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    audio_io_handle_t io;
2986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
2996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
3006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        audio_config_t fullConfig = AUDIO_CONFIG_INITIALIZER;
3016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        fullConfig.sample_rate = config->sample_rate;
3026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        fullConfig.channel_mask = config->channel_mask;
3036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        fullConfig.format = config->format;
3046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        ret = AudioSystem::getOutputForAttr(attr, &io,
3056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                            sessionId,
3066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                            &streamType, client.clientUid,
3076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                            &fullConfig,
308d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten                                            (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ |
309d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten                                                    AUDIO_OUTPUT_FLAG_DIRECT),
3106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                            *deviceId, &portId);
3116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    } else {
3126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        ret = AudioSystem::getInputForAttr(attr, &io,
3136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                              sessionId,
3146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                              client.clientPid,
3156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                              client.clientUid,
3166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                              config,
3176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                              AUDIO_INPUT_FLAG_MMAP_NOIRQ, *deviceId, &portId);
3186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    }
3196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    if (ret != NO_ERROR) {
3206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        return ret;
3216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    }
3226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
3236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    // at this stage, a MmapThread was created when openOutput() or openInput() was called by
3246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    // audio policy manager and we can retrieve it
3256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    sp<MmapThread> thread = mMmapThreads.valueFor(io);
3266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    if (thread != 0) {
3276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        interface = new MmapThreadHandle(thread);
3286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        thread->configure(attr, streamType, sessionId, callback, portId);
3296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    } else {
3306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        ret = NO_INIT;
3316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    }
3326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
3336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    ALOGV("%s done status %d portId %d", __FUNCTION__, ret, portId);
3346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
335fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent    return ret;
336fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent}
337fc23520d9c3f15e28baa81de5f7dfa6c1b0af426Eric Laurent
338a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentstatic const char * const audio_interfaces[] = {
339a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_PRIMARY,
340a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_A2DP,
341a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_USB,
342a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent};
343a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent#define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0])))
344a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
345062e67a26e0553dd142be622821f493df541f0c6Phil BurkAudioHwDevice* AudioFlinger::findSuitableHwDev_l(
346ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_module_handle_t module,
347ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_devices_t devices)
348799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin{
349a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    // if module is 0, the request comes from an old policy manager and we should load
350a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    // well known modules
351a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    if (module == 0) {
352a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        ALOGW("findSuitableHwDev_l() loading well know audio hw modules");
353a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) {
354a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            loadHwModule_l(audio_interfaces[i]);
355a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        }
356f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        // then try to find a module supporting the requested device.
357f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
358f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            AudioHwDevice *audioHwDevice = mAudioHwDevs.valueAt(i);
359e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov            sp<DeviceHalInterface> dev = audioHwDevice->hwDevice();
360e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov            uint32_t supportedDevices;
361e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov            if (dev->getSupportedDevices(&supportedDevices) == OK &&
362e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov                    (supportedDevices & devices) == devices) {
363f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                return audioHwDevice;
364e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov            }
365f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        }
366a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    } else {
367a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        // check a match for the requested module handle
368ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(module);
369ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (audioHwDevice != NULL) {
370ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            return audioHwDevice;
371a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        }
372a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    }
373a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
374799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return NULL;
375799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin}
37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3770f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid AudioFlinger::dumpClients(int fd, const Vector<String16>& args __unused)
37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("Clients:\n");
38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mClients.size(); ++i) {
38577c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        sp<Client> client = mClients.valueAt(i).promote();
38677c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        if (client != 0) {
38777c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            snprintf(buffer, SIZE, "  pid: %d\n", client->pid());
38877c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            result.append(buffer);
38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
3913a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
392d1b28d41dbda203ffb420ba2e36cbe736b163ff8Eric Laurent    result.append("Notification Clients:\n");
393d1b28d41dbda203ffb420ba2e36cbe736b163ff8Eric Laurent    for (size_t i = 0; i < mNotificationClients.size(); ++i) {
394d1b28d41dbda203ffb420ba2e36cbe736b163ff8Eric Laurent        snprintf(buffer, SIZE, "  pid: %d\n", mNotificationClients.keyAt(i));
395d1b28d41dbda203ffb420ba2e36cbe736b163ff8Eric Laurent        result.append(buffer);
396d1b28d41dbda203ffb420ba2e36cbe736b163ff8Eric Laurent    }
397d1b28d41dbda203ffb420ba2e36cbe736b163ff8Eric Laurent
3983a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    result.append("Global session refs:\n");
399b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen    result.append("  session   pid count\n");
4003a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    for (size_t i = 0; i < mAudioSessionRefs.size(); i++) {
4013a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        AudioSessionRef *r = mAudioSessionRefs[i];
402b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen        snprintf(buffer, SIZE, "  %7d %5d %5d\n", r->mSessionid, r->mPid, r->mCnt);
4033a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        result.append(buffer);
4043a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
40565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
40665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4090f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid AudioFlinger::dumpInternals(int fd, const Vector<String16>& args __unused)
41065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
41165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
41265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
41365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
414a4454b4765c5905f14186893b0688be375642283Glenn Kasten    hardware_call_state hardwareStatus = mHardwareStatus;
41565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4164ff14bae91075eb274eb1c2975982358946e7e63John Grossman    snprintf(buffer, SIZE, "Hardware status: %d\n"
4174ff14bae91075eb274eb1c2975982358946e7e63John Grossman                           "Standby Time mSec: %u\n",
4184ff14bae91075eb274eb1c2975982358946e7e63John Grossman                            hardwareStatus,
4194ff14bae91075eb274eb1c2975982358946e7e63John Grossman                            (uint32_t)(mStandbyTimeInNsecs / 1000000));
42065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4240f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args __unused)
42565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
42665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
42965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Permission Denial: "
43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "can't dump AudioFlinger from pid=%d, uid=%d\n",
43165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingPid(),
43265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingUid());
43365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
43665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::dumpTryLock(Mutex& mutex)
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
43965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
44065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
44165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
44265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
44365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
44465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
4457dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten        usleep(kDumpLockSleepUs);
44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
44765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
44865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::dump(int fd, const Vector<String16>& args)
45165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
45244deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (!dumpAllowed()) {
45365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpPermissionDenial(fd, args);
45465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
45565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // get state of hardware lock
45681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        bool hardwareLocked = dumpTryLock(mHardwareLock);
45765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!hardwareLocked) {
45865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kHardwareLockedString);
45965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
46065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
46165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mHardwareLock.unlock();
46265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
46365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
46481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        bool locked = dumpTryLock(mLock);
46565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
46665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // failed to lock - AudioFlinger is probably deadlocked
46765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
46865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kDeadlockedString);
46965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
47065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
47165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
472021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent        bool clientLocked = dumpTryLock(mClientLock);
473021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent        if (!clientLocked) {
474021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent            String8 result(kClientLockedString);
475021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent            write(fd, result.string(), result.size());
476021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent        }
477d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
4781dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov        if (mEffectsFactoryHal != 0) {
4794a3d5c23f79189eb7ab9f31c440c7da5b15947a2Mikhail Naganov            mEffectsFactoryHal->dumpEffects(fd);
4804a3d5c23f79189eb7ab9f31c440c7da5b15947a2Mikhail Naganov        } else {
4814a3d5c23f79189eb7ab9f31c440c7da5b15947a2Mikhail Naganov            String8 result(kNoEffectsFactory);
4824a3d5c23f79189eb7ab9f31c440c7da5b15947a2Mikhail Naganov            write(fd, result.string(), result.size());
4834a3d5c23f79189eb7ab9f31c440c7da5b15947a2Mikhail Naganov        }
484d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
48565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpClients(fd, args);
486021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent        if (clientLocked) {
487021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent            mClientLock.unlock();
488021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent        }
489021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent
49065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpInternals(fd, args);
49165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
49265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // dump playback threads
49365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
49465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mPlaybackThreads.valueAt(i)->dump(fd, args);
49565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
49665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
49765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // dump record threads
49865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mRecordThreads.size(); i++) {
49965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mRecordThreads.valueAt(i)->dump(fd, args);
50065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
50165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        // dump mmap threads
5036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        for (size_t i = 0; i < mMmapThreads.size(); i++) {
5046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent            mMmapThreads.valueAt(i)->dump(fd, args);
5056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        }
5066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
507aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        // dump orphan effect chains
508aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        if (mOrphanEffectChains.size() != 0) {
509aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            write(fd, "  Orphan Effect Chains\n", strlen("  Orphan Effect Chains\n"));
510aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            for (size_t i = 0; i < mOrphanEffectChains.size(); i++) {
511aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent                mOrphanEffectChains.valueAt(i)->dump(fd, args);
512aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            }
513aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        }
514799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        // dump all hardware devs
515799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
516e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov            sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
517e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov            dev->dump(fd);
51865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
519d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
52046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
521d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        // dump the serially shared record tee sink
522d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        if (mRecordTeeSource != 0) {
523d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            dumpTee(fd, mRecordTeeSource);
524d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        }
52546909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
526d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
5273bd1c87ac0d767566f5da387e90b8a3cd86ecc97rago        BUFLOG_RESET;
5283bd1c87ac0d767566f5da387e90b8a3cd86ecc97rago
529d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if (locked) {
530d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            mLock.unlock();
531d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
5329e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
5339e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // append a copy of media.log here by forwarding fd to it, but don't attempt
5349e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        // to lookup the service if it's not running, as it will block for a second
5353ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten        if (sMediaLogServiceAsBinder != 0) {
5363ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten            dprintf(fd, "\nmedia.log:\n");
5373ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten            Vector<String16> args;
5383ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten            sMediaLogServiceAsBinder->dump(fd, args);
5399e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        }
54035fec5f61393124c9e13958941637b8fe386385eAndy Hung
54135fec5f61393124c9e13958941637b8fe386385eAndy Hung        // check for optional arguments
54207b745e166ee62030960ccea37e117caadf71c32Andy Hung        bool dumpMem = false;
54335fec5f61393124c9e13958941637b8fe386385eAndy Hung        bool unreachableMemory = false;
54435fec5f61393124c9e13958941637b8fe386385eAndy Hung        for (const auto &arg : args) {
54507b745e166ee62030960ccea37e117caadf71c32Andy Hung            if (arg == String16("-m")) {
54607b745e166ee62030960ccea37e117caadf71c32Andy Hung                dumpMem = true;
54707b745e166ee62030960ccea37e117caadf71c32Andy Hung            } else if (arg == String16("--unreachable")) {
54835fec5f61393124c9e13958941637b8fe386385eAndy Hung                unreachableMemory = true;
54935fec5f61393124c9e13958941637b8fe386385eAndy Hung            }
55035fec5f61393124c9e13958941637b8fe386385eAndy Hung        }
55135fec5f61393124c9e13958941637b8fe386385eAndy Hung
55207b745e166ee62030960ccea37e117caadf71c32Andy Hung        if (dumpMem) {
55307b745e166ee62030960ccea37e117caadf71c32Andy Hung            dprintf(fd, "\nDumping memory:\n");
55407b745e166ee62030960ccea37e117caadf71c32Andy Hung            std::string s = dumpMemoryAddresses(100 /* limit */);
55507b745e166ee62030960ccea37e117caadf71c32Andy Hung            write(fd, s.c_str(), s.size());
55607b745e166ee62030960ccea37e117caadf71c32Andy Hung        }
55735fec5f61393124c9e13958941637b8fe386385eAndy Hung        if (unreachableMemory) {
55835fec5f61393124c9e13958941637b8fe386385eAndy Hung            dprintf(fd, "\nDumping unreachable memory:\n");
55935fec5f61393124c9e13958941637b8fe386385eAndy Hung            // TODO - should limit be an argument parameter?
56007b745e166ee62030960ccea37e117caadf71c32Andy Hung            std::string s = GetUnreachableMemoryString(true /* contents */, 100 /* limit */);
56135fec5f61393124c9e13958941637b8fe386385eAndy Hung            write(fd, s.c_str(), s.size());
56235fec5f61393124c9e13958941637b8fe386385eAndy Hung        }
56365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
56465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
56565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
56665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
567021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurentsp<AudioFlinger::Client> AudioFlinger::registerPid(pid_t pid)
56898ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten{
569021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent    Mutex::Autolock _cl(mClientLock);
57098ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    // If pid is already in the mClients wp<> map, then use that entry
57198ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    // (for which promote() is always != 0), otherwise create a new entry and Client.
57298ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    sp<Client> client = mClients.valueFor(pid).promote();
57398ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    if (client == 0) {
57498ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        client = new Client(this, pid);
57598ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        mClients.add(pid, client);
57698ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    }
57798ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten
57898ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    return client;
57998ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten}
58065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5819e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kastensp<NBLog::Writer> AudioFlinger::newWriter_l(size_t size, const char *name)
5829e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten{
5833ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten    // If there is no memory allocated for logs, return a dummy writer that does nothing.
5843ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten    // Similarly if we can't contact the media.log service, also return a dummy writer.
5853ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten    if (mLogMemoryDealer == 0 || sMediaLogService == 0) {
586481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten        return new NBLog::Writer();
5879e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
588481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten    sp<IMemory> shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size));
589481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten    // If allocation fails, consult the vector of previously unregistered writers
590481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten    // and garbage-collect one or more them until an allocation succeeds
591481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten    if (shared == 0) {
592481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten        Mutex::Autolock _l(mUnregisteredWritersLock);
593481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten        for (size_t count = mUnregisteredWriters.size(); count > 0; count--) {
594481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten            {
595481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten                // Pick the oldest stale writer to garbage-collect
596481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten                sp<IMemory> iMemory(mUnregisteredWriters[0]->getIMemory());
597481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten                mUnregisteredWriters.removeAt(0);
5983ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten                sMediaLogService->unregisterWriter(iMemory);
599481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten                // Now the media.log remote reference to IMemory is gone.  When our last local
600481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten                // reference to IMemory also drops to zero at end of this block,
601481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten                // the IMemory destructor will deallocate the region from mLogMemoryDealer.
602481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten            }
603481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten            // Re-attempt the allocation
604481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten            shared = mLogMemoryDealer->allocate(NBLog::Timeline::sharedSize(size));
605481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten            if (shared != 0) {
606481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten                goto success;
607481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten            }
608481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten        }
609481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten        // Even after garbage-collecting all old writers, there is still not enough memory,
610481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten        // so return a dummy writer
611481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten        return new NBLog::Writer();
612481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten    }
613481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kastensuccess:
614535e161e2e404dffb8389dd331be0132704b6d82Glenn Kasten    NBLog::Shared *sharedRawPtr = (NBLog::Shared *) shared->pointer();
615535e161e2e404dffb8389dd331be0132704b6d82Glenn Kasten    new((void *) sharedRawPtr) NBLog::Shared(); // placement new here, but the corresponding
616535e161e2e404dffb8389dd331be0132704b6d82Glenn Kasten                                                // explicit destructor not needed since it is POD
6173ac24a14e36085bb26b65652e11747deda0f1e18Glenn Kasten    sMediaLogService->registerWriter(shared, size, name);
618535e161e2e404dffb8389dd331be0132704b6d82Glenn Kasten    return new NBLog::Writer(shared, size);
6199e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten}
6209e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
6219e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kastenvoid AudioFlinger::unregisterWriter(const sp<NBLog::Writer>& writer)
6229e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten{
623685ef09bcaf5de6abf2064d552296f70eaec6761Glenn Kasten    if (writer == 0) {
624685ef09bcaf5de6abf2064d552296f70eaec6761Glenn Kasten        return;
625685ef09bcaf5de6abf2064d552296f70eaec6761Glenn Kasten    }
6269e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    sp<IMemory> iMemory(writer->getIMemory());
6279e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    if (iMemory == 0) {
6289e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten        return;
6299e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten    }
630481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten    // Rather than removing the writer immediately, append it to a queue of old writers to
631481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten    // be garbage-collected later.  This allows us to continue to view old logs for a while.
632481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten    Mutex::Autolock _l(mUnregisteredWritersLock);
633481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten    mUnregisteredWriters.push(writer);
6349e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten}
6359e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten
63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// IAudioFlinger interface
63765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
63865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
63965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<IAudioTrack> AudioFlinger::createTrack(
640fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten        audio_stream_type_t streamType,
64165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t sampleRate,
64258f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
643254af180475346b6186b49c297f340c9c4817511Glenn Kasten        audio_channel_mask_t channelMask,
64474935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten        size_t *frameCount,
645050677873c10d4da308ac222f8533c96cca3207eEric Laurent        audio_output_flags_t *flags,
64665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const sp<IMemory>& sharedBuffer,
64772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output,
6489ea77cdba8c422940adb57a790b44ac04fe0353fHaynes Mathew George        pid_t pid,
6493acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten        pid_t tid,
650d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten        audio_session_t *sessionId,
651462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen        int clientUid,
65220b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent        status_t *status,
65320b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent        audio_port_handle_t portId)
65465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
65565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<PlaybackThread::Track> track;
65665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<TrackHandle> trackHandle;
65765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client;
65865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t lStatus;
659d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten    audio_session_t lSessionId;
66065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6619ea77cdba8c422940adb57a790b44ac04fe0353fHaynes Mathew George    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
6629ea77cdba8c422940adb57a790b44ac04fe0353fHaynes Mathew George    if (pid == -1 || !isTrustedCallingUid(callingUid)) {
6639ea77cdba8c422940adb57a790b44ac04fe0353fHaynes Mathew George        const pid_t callingPid = IPCThreadState::self()->getCallingPid();
6649ea77cdba8c422940adb57a790b44ac04fe0353fHaynes Mathew George        ALOGW_IF(pid != -1 && pid != callingPid,
6659ea77cdba8c422940adb57a790b44ac04fe0353fHaynes Mathew George                 "%s uid %d pid %d tried to pass itself off as pid %d",
6669ea77cdba8c422940adb57a790b44ac04fe0353fHaynes Mathew George                 __func__, callingUid, callingPid, pid);
6679ea77cdba8c422940adb57a790b44ac04fe0353fHaynes Mathew George        pid = callingPid;
6689ea77cdba8c422940adb57a790b44ac04fe0353fHaynes Mathew George    }
6699ea77cdba8c422940adb57a790b44ac04fe0353fHaynes Mathew George
670263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    // client AudioTrack::set already implements AUDIO_STREAM_DEFAULT => AUDIO_STREAM_MUSIC,
671263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    // but if someone uses binder directly they could bypass that and cause us to crash
672263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {
67329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("createTrack() invalid stream type %d", streamType);
67465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        lStatus = BAD_VALUE;
67565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        goto Exit;
67665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
67765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
67853b5d098b7d5d4412b9b9fe08daaf84c56b716e9Glenn Kasten    // further sample rate checks are performed by createTrack_l() depending on the thread type
67953b5d098b7d5d4412b9b9fe08daaf84c56b716e9Glenn Kasten    if (sampleRate == 0) {
68053b5d098b7d5d4412b9b9fe08daaf84c56b716e9Glenn Kasten        ALOGE("createTrack() invalid sample rate %u", sampleRate);
68153b5d098b7d5d4412b9b9fe08daaf84c56b716e9Glenn Kasten        lStatus = BAD_VALUE;
68253b5d098b7d5d4412b9b9fe08daaf84c56b716e9Glenn Kasten        goto Exit;
68353b5d098b7d5d4412b9b9fe08daaf84c56b716e9Glenn Kasten    }
68453b5d098b7d5d4412b9b9fe08daaf84c56b716e9Glenn Kasten
68553b5d098b7d5d4412b9b9fe08daaf84c56b716e9Glenn Kasten    // further channel mask checks are performed by createTrack_l() depending on the thread type
68653b5d098b7d5d4412b9b9fe08daaf84c56b716e9Glenn Kasten    if (!audio_is_output_channel(channelMask)) {
68753b5d098b7d5d4412b9b9fe08daaf84c56b716e9Glenn Kasten        ALOGE("createTrack() invalid channel mask %#x", channelMask);
68853b5d098b7d5d4412b9b9fe08daaf84c56b716e9Glenn Kasten        lStatus = BAD_VALUE;
68953b5d098b7d5d4412b9b9fe08daaf84c56b716e9Glenn Kasten        goto Exit;