summaryrefslogtreecommitdiffstats
path: root/media/libmedia/AudioRecord.cpp
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2014-01-13 10:21:48 -0800
committerGlenn Kasten <gkasten@google.com>2014-01-24 13:19:59 -0800
commit38e905b3cbba4da443d799b16999989781afc6d8 (patch)
tree47b872b97f1af95c3e0ceefb1f8d56c9ae7a67fc /media/libmedia/AudioRecord.cpp
parentf0002d142e6d24c5438600b2c259679de710f8ac (diff)
downloadframeworks_av-38e905b3cbba4da443d799b16999989781afc6d8.zip
frameworks_av-38e905b3cbba4da443d799b16999989781afc6d8.tar.gz
frameworks_av-38e905b3cbba4da443d799b16999989781afc6d8.tar.bz2
Refactor code related to I/O handles to reduce chance for leaks
The AudioRecord input handle code was refactored earlier to fix a potential handle leak, and to simplify the code: > Change-Id: I124dce344b1d11c2dd66ca5e2c9aec0c52c230e2 This changelist refactors AudioTrack similarly, and adds further cleanup of both AudioTrack and AudioRecord. We attempt to implement the rules for referencing counting I/O handles, but there is still the possibility of a handle leak if the client process dies after allocating the handle reference but before releasing it. That issue is being tracked separately. Details: - AudioSystem::getOutput() is now called within createTrack_l - restoreTrack_l was missing offload info now it has the info available, but is not yet being called for offloaded tracks - AudioTrack::getOutput() is now const - Remove getOutput_l() Change-Id: I44a0a623d24fc5847bcac0939c276400568adbca
Diffstat (limited to 'media/libmedia/AudioRecord.cpp')
-rw-r--r--media/libmedia/AudioRecord.cpp21
1 files changed, 18 insertions, 3 deletions
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 0673079..a999e7e 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -244,7 +244,7 @@ status_t AudioRecord::set(
// create the IAudioRecord
status = openRecord_l(0 /*epoch*/);
- if (status) {
+ if (status != NO_ERROR) {
return status;
}
@@ -463,6 +463,9 @@ status_t AudioRecord::openRecord_l(size_t epoch)
ALOGE("Could not get audio input for record source %d", mInputSource);
return BAD_VALUE;
}
+ {
+ // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
+ // we must release it ourselves if anything goes wrong.
size_t temp = mFrameCount; // temp may be replaced by a revised value of frameCount,
// but we will still need the original value also
@@ -480,9 +483,11 @@ status_t AudioRecord::openRecord_l(size_t epoch)
if (record == 0 || status != NO_ERROR) {
ALOGE("AudioFlinger could not create record track, status: %d", status);
- AudioSystem::releaseInput(input);
- return status;
+ goto release;
}
+ // AudioFlinger now owns the reference to the I/O handle,
+ // so we are no longer responsible for releasing it.
+
sp<IMemory> iMem = record->getCblk();
if (iMem == 0) {
ALOGE("Could not get control block");
@@ -497,6 +502,8 @@ status_t AudioRecord::openRecord_l(size_t epoch)
mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this);
mDeathNotifier.clear();
}
+
+ // We retain a copy of the I/O handle, but don't own the reference
mInput = input;
mAudioRecord = record;
mCblkMemory = iMem;
@@ -540,6 +547,14 @@ status_t AudioRecord::openRecord_l(size_t epoch)
mAudioRecord->asBinder()->linkToDeath(mDeathNotifier, this);
return NO_ERROR;
+ }
+
+release:
+ AudioSystem::releaseInput(input);
+ if (status == NO_ERROR) {
+ status = NO_INIT;
+ }
+ return status;
}
status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)