summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp40
-rw-r--r--services/audioflinger/AudioFlinger.h4
-rw-r--r--services/audioflinger/FastMixerDumpState.cpp8
-rw-r--r--services/audioflinger/Threads.cpp178
-rw-r--r--services/audioflinger/Threads.h4
5 files changed, 172 insertions, 62 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 940267a..461b5d3 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1957,18 +1957,18 @@ status_t AudioFlinger::restoreOutput(audio_io_handle_t output)
status_t AudioFlinger::openInput(audio_module_handle_t module,
audio_io_handle_t *input,
audio_config_t *config,
- audio_devices_t *device,
+ audio_devices_t *devices,
const String8& address,
audio_source_t source,
audio_input_flags_t flags)
{
Mutex::Autolock _l(mLock);
- if (*device == AUDIO_DEVICE_NONE) {
+ if (*devices == AUDIO_DEVICE_NONE) {
return BAD_VALUE;
}
- sp<RecordThread> thread = openInput_l(module, input, config, *device, address, source, flags);
+ sp<RecordThread> thread = openInput_l(module, input, config, *devices, address, source, flags);
if (thread != 0) {
// notify client processes of the new input creation
@@ -1981,12 +1981,12 @@ status_t AudioFlinger::openInput(audio_module_handle_t module,
sp<AudioFlinger::RecordThread> AudioFlinger::openInput_l(audio_module_handle_t module,
audio_io_handle_t *input,
audio_config_t *config,
- audio_devices_t device,
+ audio_devices_t devices,
const String8& address,
audio_source_t source,
audio_input_flags_t flags)
{
- AudioHwDevice *inHwDev = findSuitableHwDev_l(module, device);
+ AudioHwDevice *inHwDev = findSuitableHwDev_l(module, devices);
if (inHwDev == NULL) {
*input = AUDIO_IO_HANDLE_NONE;
return 0;
@@ -1999,7 +1999,7 @@ sp<AudioFlinger::RecordThread> AudioFlinger::openInput_l(audio_module_handle_t m
audio_config_t halconfig = *config;
audio_hw_device_t *inHwHal = inHwDev->hwDevice();
audio_stream_in_t *inStream = NULL;
- status_t status = inHwHal->open_input_stream(inHwHal, *input, device, &halconfig,
+ status_t status = inHwHal->open_input_stream(inHwHal, *input, devices, &halconfig,
&inStream, flags, address.string(), source);
ALOGV("openInput_l() openInputStream returned input %p, SamplingRate %d"
", Format %#x, Channels %x, flags %#x, status %d addr %s",
@@ -2021,7 +2021,7 @@ sp<AudioFlinger::RecordThread> AudioFlinger::openInput_l(audio_module_handle_t m
// FIXME describe the change proposed by HAL (save old values so we can log them here)
ALOGV("openInput_l() reopening with proposed sampling rate and channel mask");
inStream = NULL;
- status = inHwHal->open_input_stream(inHwHal, *input, device, &halconfig,
+ status = inHwHal->open_input_stream(inHwHal, *input, devices, &halconfig,
&inStream, flags, address.string(), source);
// FIXME log this new status; HAL should not propose any further changes
}
@@ -2086,7 +2086,7 @@ sp<AudioFlinger::RecordThread> AudioFlinger::openInput_l(audio_module_handle_t m
inputStream,
*input,
primaryOutputDevice_l(),
- device
+ devices
#ifdef TEE_SINK
, teeSink
#endif
@@ -2809,13 +2809,13 @@ bool AudioFlinger::updateOrphanEffectChains(const sp<AudioFlinger::EffectModule>
struct Entry {
-#define MAX_NAME 32 // %Y%m%d%H%M%S_%d.wav
- char mName[MAX_NAME];
+#define TEE_MAX_FILENAME 32 // %Y%m%d%H%M%S_%d.wav = 4+2+2+2+2+2+1+1+4+1 = 21
+ char mFileName[TEE_MAX_FILENAME];
};
int comparEntry(const void *p1, const void *p2)
{
- return strcmp(((const Entry *) p1)->mName, ((const Entry *) p2)->mName);
+ return strcmp(((const Entry *) p1)->mFileName, ((const Entry *) p2)->mFileName);
}
#ifdef TEE_SINK
@@ -2834,11 +2834,11 @@ void AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_hand
DIR *dir = opendir(teePath);
teePath[teePathLen++] = '/';
if (dir != NULL) {
-#define MAX_SORT 20 // number of entries to sort
-#define MAX_KEEP 10 // number of entries to keep
- struct Entry entries[MAX_SORT];
+#define TEE_MAX_SORT 20 // number of entries to sort
+#define TEE_MAX_KEEP 10 // number of entries to keep
+ struct Entry entries[TEE_MAX_SORT];
size_t entryCount = 0;
- while (entryCount < MAX_SORT) {
+ while (entryCount < TEE_MAX_SORT) {
struct dirent de;
struct dirent *result = NULL;
int rc = readdir_r(dir, &de, &result);
@@ -2855,17 +2855,17 @@ void AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_hand
}
// ignore non .wav file entries
size_t nameLen = strlen(de.d_name);
- if (nameLen <= 4 || nameLen >= MAX_NAME ||
+ if (nameLen <= 4 || nameLen >= TEE_MAX_FILENAME ||
strcmp(&de.d_name[nameLen - 4], ".wav")) {
continue;
}
- strcpy(entries[entryCount++].mName, de.d_name);
+ strcpy(entries[entryCount++].mFileName, de.d_name);
}
(void) closedir(dir);
- if (entryCount > MAX_KEEP) {
+ if (entryCount > TEE_MAX_KEEP) {
qsort(entries, entryCount, sizeof(Entry), comparEntry);
- for (size_t i = 0; i < entryCount - MAX_KEEP; ++i) {
- strcpy(&teePath[teePathLen], entries[i].mName);
+ for (size_t i = 0; i < entryCount - TEE_MAX_KEEP; ++i) {
+ strcpy(&teePath[teePathLen], entries[i].mFileName);
(void) unlink(teePath);
}
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index f5dec97..7b76185 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -796,6 +796,10 @@ private:
#undef INCLUDING_FROM_AUDIOFLINGER_H
const char *formatToString(audio_format_t format);
+String8 inputFlagsToString(audio_input_flags_t flags);
+String8 outputFlagsToString(audio_output_flags_t flags);
+String8 devicesToString(audio_devices_t devices);
+const char *sourceToString(audio_source_t source);
// ----------------------------------------------------------------------------
diff --git a/services/audioflinger/FastMixerDumpState.cpp b/services/audioflinger/FastMixerDumpState.cpp
index 386b29d..65fbf2b 100644
--- a/services/audioflinger/FastMixerDumpState.cpp
+++ b/services/audioflinger/FastMixerDumpState.cpp
@@ -69,10 +69,10 @@ void FastMixerDumpState::dump(int fd) const
" numTracks=%u writeErrors=%u underruns=%u overruns=%u\n"
" sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n"
" mixPeriod=%.2f ms\n",
- FastMixerState::commandToString(mCommand), mWriteSequence, mFramesWritten,
- mNumTracks, mWriteErrors, mUnderruns, mOverruns,
- mSampleRate, mFrameCount, measuredWarmupMs, mWarmupCycles,
- mixPeriodSec * 1e3);
+ FastMixerState::commandToString(mCommand), mWriteSequence, mFramesWritten,
+ mNumTracks, mWriteErrors, mUnderruns, mOverruns,
+ mSampleRate, mFrameCount, measuredWarmupMs, mWarmupCycles,
+ mixPeriodSec * 1e3);
#ifdef FAST_THREAD_STATISTICS
// find the interval of valid samples
uint32_t bounds = mBounds;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 7451245..c1da6bc 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -335,7 +335,90 @@ const char *AudioFlinger::ThreadBase::threadTypeToString(AudioFlinger::ThreadBas
}
}
-static String8 outputFlagsToString(audio_output_flags_t flags)
+String8 devicesToString(audio_devices_t devices)
+{
+ static const struct mapping {
+ audio_devices_t mDevices;
+ const char * mString;
+ } mappingsOut[] = {
+ AUDIO_DEVICE_OUT_EARPIECE, "EARPIECE",
+ AUDIO_DEVICE_OUT_SPEAKER, "SPEAKER",
+ AUDIO_DEVICE_OUT_WIRED_HEADSET, "WIRED_HEADSET",
+ AUDIO_DEVICE_OUT_WIRED_HEADPHONE, "WIRED_HEADPHONE",
+ AUDIO_DEVICE_OUT_TELEPHONY_TX, "TELEPHONY_TX",
+ AUDIO_DEVICE_NONE, "NONE", // must be last
+ }, mappingsIn[] = {
+ AUDIO_DEVICE_IN_BUILTIN_MIC, "BUILTIN_MIC",
+ AUDIO_DEVICE_IN_WIRED_HEADSET, "WIRED_HEADSET",
+ AUDIO_DEVICE_IN_VOICE_CALL, "VOICE_CALL",
+ AUDIO_DEVICE_IN_REMOTE_SUBMIX, "REMOTE_SUBMIX",
+ AUDIO_DEVICE_NONE, "NONE", // must be last
+ };
+ String8 result;
+ audio_devices_t allDevices = AUDIO_DEVICE_NONE;
+ const mapping *entry;
+ if (devices & AUDIO_DEVICE_BIT_IN) {
+ devices &= ~AUDIO_DEVICE_BIT_IN;
+ entry = mappingsIn;
+ } else {
+ entry = mappingsOut;
+ }
+ for ( ; entry->mDevices != AUDIO_DEVICE_NONE; entry++) {
+ allDevices = (audio_devices_t) (allDevices | entry->mDevices);
+ if (devices & entry->mDevices) {
+ if (!result.isEmpty()) {
+ result.append("|");
+ }
+ result.append(entry->mString);
+ }
+ }
+ if (devices & ~allDevices) {
+ if (!result.isEmpty()) {
+ result.append("|");
+ }
+ result.appendFormat("0x%X", devices & ~allDevices);
+ }
+ if (result.isEmpty()) {
+ result.append(entry->mString);
+ }
+ return result;
+}
+
+String8 inputFlagsToString(audio_input_flags_t flags)
+{
+ static const struct mapping {
+ audio_input_flags_t mFlag;
+ const char * mString;
+ } mappings[] = {
+ AUDIO_INPUT_FLAG_FAST, "FAST",
+ AUDIO_INPUT_FLAG_HW_HOTWORD, "HW_HOTWORD",
+ AUDIO_INPUT_FLAG_NONE, "NONE", // must be last
+ };
+ String8 result;
+ audio_input_flags_t allFlags = AUDIO_INPUT_FLAG_NONE;
+ const mapping *entry;
+ for (entry = mappings; entry->mFlag != AUDIO_INPUT_FLAG_NONE; entry++) {
+ allFlags = (audio_input_flags_t) (allFlags | entry->mFlag);
+ if (flags & entry->mFlag) {
+ if (!result.isEmpty()) {
+ result.append("|");
+ }
+ result.append(entry->mString);
+ }
+ }
+ if (flags & ~allFlags) {
+ if (!result.isEmpty()) {
+ result.append("|");
+ }
+ result.appendFormat("0x%X", flags & ~allFlags);
+ }
+ if (result.isEmpty()) {
+ result.append(entry->mString);
+ }
+ return result;
+}
+
+String8 outputFlagsToString(audio_output_flags_t flags)
{
static const struct mapping {
audio_output_flags_t mFlag;
@@ -345,7 +428,7 @@ static String8 outputFlagsToString(audio_output_flags_t flags)
AUDIO_OUTPUT_FLAG_PRIMARY, "PRIMARY",
AUDIO_OUTPUT_FLAG_FAST, "FAST",
AUDIO_OUTPUT_FLAG_DEEP_BUFFER, "DEEP_BUFFER",
- AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD, "COMPRESS_OFFLOAAD",
+ AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD, "COMPRESS_OFFLOAD",
AUDIO_OUTPUT_FLAG_NON_BLOCKING, "NON_BLOCKING",
AUDIO_OUTPUT_FLAG_HW_AV_SYNC, "HW_AV_SYNC",
AUDIO_OUTPUT_FLAG_NONE, "NONE", // must be last
@@ -374,6 +457,24 @@ static String8 outputFlagsToString(audio_output_flags_t flags)
return result;
}
+const char *sourceToString(audio_source_t source)
+{
+ switch (source) {
+ case AUDIO_SOURCE_DEFAULT: return "default";
+ case AUDIO_SOURCE_MIC: return "mic";
+ case AUDIO_SOURCE_VOICE_UPLINK: return "voice uplink";
+ case AUDIO_SOURCE_VOICE_DOWNLINK: return "voice downlink";
+ case AUDIO_SOURCE_VOICE_CALL: return "voice call";
+ case AUDIO_SOURCE_CAMCORDER: return "camcorder";
+ case AUDIO_SOURCE_VOICE_RECOGNITION: return "voice recognition";
+ case AUDIO_SOURCE_VOICE_COMMUNICATION: return "voice communication";
+ case AUDIO_SOURCE_REMOTE_SUBMIX: return "remote submix";
+ case AUDIO_SOURCE_FM_TUNER: return "FM tuner";
+ case AUDIO_SOURCE_HOTWORD: return "hotword";
+ default: return "unknown";
+ }
+}
+
AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
audio_devices_t outDevice, audio_devices_t inDevice, type_t type)
: Thread(false /*canCallJava*/),
@@ -640,6 +741,7 @@ void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args __u
dprintf(fd, "thread %p may be deadlocked\n", this);
}
+ dprintf(fd, " Thread name: %s\n", mThreadName);
dprintf(fd, " I/O handle: %d\n", mId);
dprintf(fd, " TID: %d\n", getTid());
dprintf(fd, " Standby: %s\n", mStandby ? "yes" : "no");
@@ -663,6 +765,9 @@ void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args __u
} else {
dprintf(fd, " none\n");
}
+ dprintf(fd, " Output device: %#x (%s)\n", mOutDevice, devicesToString(mOutDevice).string());
+ dprintf(fd, " Input device: %#x (%s)\n", mInDevice, devicesToString(mInDevice).string());
+ dprintf(fd, " Audio source: %d (%s)\n", mAudioSource, sourceToString(mAudioSource));
if (locked) {
mLock.unlock();
@@ -696,19 +801,19 @@ void AudioFlinger::ThreadBase::acquireWakeLock(int uid)
String16 AudioFlinger::ThreadBase::getWakeLockTag()
{
switch (mType) {
- case MIXER:
- return String16("AudioMix");
- case DIRECT:
- return String16("AudioDirectOut");
- case DUPLICATING:
- return String16("AudioDup");
- case RECORD:
- return String16("AudioIn");
- case OFFLOAD:
- return String16("AudioOffload");
- default:
- ALOG_ASSERT(false);
- return String16("AudioUnknown");
+ case MIXER:
+ return String16("AudioMix");
+ case DIRECT:
+ return String16("AudioDirectOut");
+ case DUPLICATING:
+ return String16("AudioDup");
+ case RECORD:
+ return String16("AudioIn");
+ case OFFLOAD:
+ return String16("AudioOffload");
+ default:
+ ALOG_ASSERT(false);
+ return String16("AudioUnknown");
}
}
@@ -735,7 +840,7 @@ void AudioFlinger::ThreadBase::acquireWakeLock_l(int uid)
if (status == NO_ERROR) {
mWakeLockToken = binder;
}
- ALOGV("acquireWakeLock_l() %s status %d", mName, status);
+ ALOGV("acquireWakeLock_l() %s status %d", mThreadName, status);
}
}
@@ -748,7 +853,7 @@ void AudioFlinger::ThreadBase::releaseWakeLock()
void AudioFlinger::ThreadBase::releaseWakeLock_l()
{
if (mWakeLockToken != 0) {
- ALOGV("releaseWakeLock_l() %s", mName);
+ ALOGV("releaseWakeLock_l() %s", mThreadName);
if (mPowerManager != 0) {
mPowerManager->releaseWakeLock(mWakeLockToken, 0,
true /* FIXME force oneway contrary to .aidl */);
@@ -769,7 +874,7 @@ void AudioFlinger::ThreadBase::getPowerManager_l() {
sp<IBinder> binder =
defaultServiceManager()->checkService(String16("power"));
if (binder == 0) {
- ALOGW("Thread %s cannot connect to the power manager service", mName);
+ ALOGW("Thread %s cannot connect to the power manager service", mThreadName);
} else {
mPowerManager = interface_cast<IPowerManager>(binder);
binder->linkToDeath(mDeathRecipient);
@@ -789,7 +894,7 @@ void AudioFlinger::ThreadBase::updateWakeLockUids_l(const SortedVector<int> &uid
status_t status;
status = mPowerManager->updateWakeLockUids(mWakeLockToken, uids.size(), uids.array(),
true /* FIXME force oneway contrary to .aidl */);
- ALOGV("acquireWakeLock_l() %s status %d", mName, status);
+ ALOGV("acquireWakeLock_l() %s status %d", mThreadName, status);
}
}
@@ -973,7 +1078,7 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::ThreadBase::createEffect_l(
// mSinkBuffer is not guaranteed to be compatible with effect processing (PCM 16 stereo).
if (mType == DIRECT) {
ALOGW("createEffect_l() Cannot add effect %s on Direct output type thread %s",
- desc->name, mName);
+ desc->name, mThreadName);
lStatus = BAD_VALUE;
goto Exit;
}
@@ -997,7 +1102,8 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::ThreadBase::createEffect_l(
case DUPLICATING:
case RECORD:
default:
- ALOGW("createEffect_l() Cannot add global effect %s on thread %s", desc->name, mName);
+ ALOGW("createEffect_l() Cannot add global effect %s on thread %s",
+ desc->name, mThreadName);
lStatus = BAD_VALUE;
goto Exit;
}
@@ -1262,8 +1368,8 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
// mLatchD, mLatchQ,
mLatchDValid(false), mLatchQValid(false)
{
- snprintf(mName, kNameLength, "AudioOut_%X", id);
- mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mName);
+ snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id);
+ mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
// Assumes constructor is called by AudioFlinger with it's mLock held, but
// it would be safer to explicitly pass initial masterVolume/masterMute as
@@ -1377,6 +1483,9 @@ void AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& ar
void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
{
dprintf(fd, "\nOutput thread %p type %d (%s):\n", this, type(), threadTypeToString(type()));
+
+ dumpBase(fd, args);
+
dprintf(fd, " Normal frame count: %zu\n", mNormalFrameCount);
dprintf(fd, " Last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
dprintf(fd, " Total writes: %d\n", mNumWrites);
@@ -1391,15 +1500,13 @@ void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>&
audio_output_flags_t flags = output != NULL ? output->flags : AUDIO_OUTPUT_FLAG_NONE;
String8 flagsAsString = outputFlagsToString(flags);
dprintf(fd, " AudioStreamOut: %p flags %#x (%s)\n", output, flags, flagsAsString.string());
-
- dumpBase(fd, args);
}
// Thread virtuals
void AudioFlinger::PlaybackThread::onFirstRef()
{
- run(mName, ANDROID_PRIORITY_URGENT_AUDIO);
+ run(mThreadName, ANDROID_PRIORITY_URGENT_AUDIO);
}
// ThreadBase virtuals
@@ -1443,9 +1550,10 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
(
(sharedBuffer != 0)
) ||
- // use case 2: callback handler and frame count is default or at least as large as HAL
+ // use case 2: frame count is default or at least as large as HAL
(
- (tid != -1) &&
+ // we formerly checked for a callback handler (non-0 tid),
+ // but that is no longer required for TRANSFER_OBTAIN mode
((frameCount == 0) ||
(frameCount >= mFrameCount))
)
@@ -5059,8 +5167,8 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
// mFastCaptureNBLogWriter
, mFastTrackAvail(false)
{
- snprintf(mName, kNameLength, "AudioIn_%X", id);
- mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mName);
+ snprintf(mThreadName, kThreadNameLength, "AudioIn_%X", id);
+ mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
readInputParameters_l();
@@ -5201,7 +5309,7 @@ AudioFlinger::RecordThread::~RecordThread()
void AudioFlinger::RecordThread::onFirstRef()
{
- run(mName, PRIORITY_URGENT_AUDIO);
+ run(mThreadName, PRIORITY_URGENT_AUDIO);
}
bool AudioFlinger::RecordThread::threadLoop()
@@ -6049,15 +6157,13 @@ void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& a
{
dprintf(fd, "\nInput thread %p:\n", this);
- if (mActiveTracks.size() > 0) {
- dprintf(fd, " Buffer size: %zu bytes\n", mBufferSize);
- } else {
+ dumpBase(fd, args);
+
+ if (mActiveTracks.size() == 0) {
dprintf(fd, " No active record clients\n");
}
dprintf(fd, " Fast capture thread: %s\n", hasFastCapture() ? "yes" : "no");
dprintf(fd, " Fast track available: %s\n", mFastTrackAvail ? "yes" : "no");
-
- dumpBase(fd, args);
}
void AudioFlinger::RecordThread::dumpTracks(int fd, const Vector<String16>& args __unused)
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index a1ac42c..9350e48 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -432,8 +432,8 @@ protected:
const audio_io_handle_t mId;
Vector< sp<EffectChain> > mEffectChains;
- static const int kNameLength = 16; // prctl(PR_SET_NAME) limit
- char mName[kNameLength];
+ static const int kThreadNameLength = 16; // prctl(PR_SET_NAME) limit
+ char mThreadName[kThreadNameLength]; // guaranteed NUL-terminated
sp<IPowerManager> mPowerManager;
sp<IBinder> mWakeLockToken;
const sp<PMDeathRecipient> mDeathRecipient;