Revert "refactor AudioRecord and AudioFlinger openRecord()"
This reverts commit 3e1acc0c58b337dec4054d78c28b48b2e77e0784.
bug: 70388312
Change-Id: I6782d6eceeece1bad998b02af26c0119da70a13d
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index aeb32bb..9cb0357 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -674,11 +674,7 @@
audio_session_t sessionId = input.sessionId;
if (sessionId == AUDIO_SESSION_ALLOCATE) {
sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
- } else if (audio_unique_id_get_use(sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
- lStatus = BAD_VALUE;
- goto Exit;
}
-
output.sessionId = sessionId;
output.outputId = AUDIO_IO_HANDLE_NONE;
output.selectedDeviceId = input.selectedDeviceId;
@@ -1572,144 +1568,120 @@
// ----------------------------------------------------------------------------
-sp<media::IAudioRecord> AudioFlinger::createRecord(const CreateRecordInput& input,
- CreateRecordOutput& output,
- status_t *status)
+sp<media::IAudioRecord> AudioFlinger::openRecord(
+ audio_io_handle_t input,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ const String16& opPackageName,
+ size_t *frameCount,
+ audio_input_flags_t *flags,
+ pid_t pid,
+ pid_t tid,
+ int clientUid,
+ audio_session_t *sessionId,
+ size_t *notificationFrames,
+ sp<IMemory>& cblk,
+ sp<IMemory>& buffers,
+ status_t *status,
+ audio_port_handle_t portId)
{
sp<RecordThread::RecordTrack> recordTrack;
sp<RecordHandle> recordHandle;
sp<Client> client;
status_t lStatus;
- audio_session_t sessionId = input.sessionId;
- audio_port_handle_t portId;
+ audio_session_t lSessionId;
- output.cblk.clear();
- output.buffers.clear();
+ cblk.clear();
+ buffers.clear();
- bool updatePid = (input.clientInfo.clientPid == -1);
+ bool updatePid = (pid == -1);
const uid_t callingUid = IPCThreadState::self()->getCallingUid();
- uid_t clientUid = input.clientInfo.clientUid;
if (!isTrustedCallingUid(callingUid)) {
- ALOGW_IF(clientUid != callingUid,
- "%s uid %d tried to pass itself off as %d",
- __FUNCTION__, callingUid, clientUid);
+ ALOGW_IF((uid_t)clientUid != callingUid,
+ "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid);
clientUid = callingUid;
updatePid = true;
}
- pid_t clientPid = input.clientInfo.clientPid;
+
if (updatePid) {
const pid_t callingPid = IPCThreadState::self()->getCallingPid();
- ALOGW_IF(clientPid != -1 && clientPid != callingPid,
+ ALOGW_IF(pid != -1 && pid != callingPid,
"%s uid %d pid %d tried to pass itself off as pid %d",
- __func__, callingUid, callingPid, clientPid);
- clientPid = callingPid;
+ __func__, callingUid, callingPid, pid);
+ pid = callingPid;
}
// check calling permissions
- if (!recordingAllowed(input.opPackageName, input.clientInfo.clientTid, clientUid)) {
- ALOGE("createRecord() permission denied: recording not allowed");
+ if (!recordingAllowed(opPackageName, tid, clientUid)) {
+ ALOGE("openRecord() permission denied: recording not allowed");
lStatus = PERMISSION_DENIED;
goto Exit;
}
+
+ // further sample rate checks are performed by createRecordTrack_l()
+ if (sampleRate == 0) {
+ ALOGE("openRecord() invalid sample rate %u", sampleRate);
+ lStatus = BAD_VALUE;
+ goto Exit;
+ }
+
// we don't yet support anything other than linear PCM
- if (!audio_is_valid_format(input.config.format) || !audio_is_linear_pcm(input.config.format)) {
- ALOGE("createRecord() invalid format %#x", input.config.format);
+ if (!audio_is_valid_format(format) || !audio_is_linear_pcm(format)) {
+ ALOGE("openRecord() invalid format %#x", format);
lStatus = BAD_VALUE;
goto Exit;
}
// further channel mask checks are performed by createRecordTrack_l()
- if (!audio_is_input_channel(input.config.channel_mask)) {
- ALOGE("createRecord() invalid channel mask %#x", input.config.channel_mask);
+ if (!audio_is_input_channel(channelMask)) {
+ ALOGE("openRecord() invalid channel mask %#x", channelMask);
lStatus = BAD_VALUE;
goto Exit;
}
- if (sessionId == AUDIO_SESSION_ALLOCATE) {
- sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
- } else if (audio_unique_id_get_use(sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
- lStatus = BAD_VALUE;
- goto Exit;
- }
-
- output.sessionId = sessionId;
- output.inputId = AUDIO_IO_HANDLE_NONE;
- output.selectedDeviceId = input.selectedDeviceId;
- output.flags = input.flags;
-
- client = registerPid(clientPid);
-
- // Not a conventional loop, but a retry loop for at most two iterations total.
- // Try first maybe with FAST flag then try again without FAST flag if that fails.
- // Exits loop via break on no error of got exit on error
- // The sp<> references will be dropped when re-entering scope.
- // The lack of indentation is deliberate, to reduce code churn and ease merges.
- for (;;) {
- lStatus = AudioSystem::getInputForAttr(&input.attr, &output.inputId,
- sessionId,
- // FIXME compare to AudioTrack
- clientPid,
- clientUid,
- &input.config,
- output.flags, &output.selectedDeviceId, &portId);
-
{
Mutex::Autolock _l(mLock);
- RecordThread *thread = checkRecordThread_l(output.inputId);
+ RecordThread *thread = checkRecordThread_l(input);
if (thread == NULL) {
- ALOGE("createRecord() checkRecordThread_l failed");
+ ALOGE("openRecord() checkRecordThread_l failed");
lStatus = BAD_VALUE;
goto Exit;
}
- ALOGV("createRecord() lSessionId: %d input %d", sessionId, output.inputId);
+ client = registerPid(pid);
- output.sampleRate = input.config.sample_rate;
- output.frameCount = input.frameCount;
- output.notificationFrameCount = input.notificationFrameCount;
+ if (sessionId != NULL && *sessionId != AUDIO_SESSION_ALLOCATE) {
+ if (audio_unique_id_get_use(*sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
+ lStatus = BAD_VALUE;
+ goto Exit;
+ }
+ lSessionId = *sessionId;
+ } else {
+ // if no audio session id is provided, create one here
+ lSessionId = (audio_session_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+ if (sessionId != NULL) {
+ *sessionId = lSessionId;
+ }
+ }
+ ALOGV("openRecord() lSessionId: %d input %d", lSessionId, input);
- recordTrack = thread->createRecordTrack_l(client, &output.sampleRate,
- input.config.format, input.config.channel_mask,
- &output.frameCount, sessionId,
- &output.notificationFrameCount,
- clientUid, &output.flags,
- input.clientInfo.clientTid,
- &lStatus, portId);
+ recordTrack = thread->createRecordTrack_l(client, sampleRate, format, channelMask,
+ frameCount, lSessionId, notificationFrames,
+ clientUid, flags, tid, &lStatus, portId);
LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0));
- // lStatus == BAD_TYPE means FAST flag was rejected: request a new input from
- // audio policy manager without FAST constraint
- if (lStatus == BAD_TYPE) {
- AudioSystem::releaseInput(output.inputId, sessionId);
- recordTrack.clear();
- continue;
+ if (lStatus == NO_ERROR) {
+ // Check if one effect chain was awaiting for an AudioRecord to be created on this
+ // session and move it to this thread.
+ sp<EffectChain> chain = getOrphanEffectChain_l(lSessionId);
+ if (chain != 0) {
+ Mutex::Autolock _l(thread->mLock);
+ thread->addEffectChain_l(chain);
+ }
}
-
- if (lStatus != NO_ERROR) {
- recordTrack.clear();
- goto Exit;
- }
-
- // Check if one effect chain was awaiting for an AudioRecord to be created on this
- // session and move it to this thread.
- sp<EffectChain> chain = getOrphanEffectChain_l(sessionId);
- if (chain != 0) {
- Mutex::Autolock _l(thread->mLock);
- thread->addEffectChain_l(chain);
- }
- break;
- }
- // End of retry loop.
- // The lack of indentation is deliberate, to reduce code churn and ease merges.
}
- output.cblk = recordTrack->getCblk();
- output.buffers = recordTrack->getBuffers();
-
- // return handle to client
- recordHandle = new RecordHandle(recordTrack);
-
-Exit:
if (lStatus != NO_ERROR) {
// remove local strong reference to Client before deleting the RecordTrack so that the
// Client destructor is called by the TrackBase destructor with mClientLock held
@@ -1719,8 +1691,17 @@
Mutex::Autolock _cl(mClientLock);
client.clear();
}
+ recordTrack.clear();
+ goto Exit;
}
+ cblk = recordTrack->getCblk();
+ buffers = recordTrack->getBuffers();
+
+ // return handle to client
+ recordHandle = new RecordHandle(recordTrack);
+
+Exit:
*status = lStatus;
return recordHandle;
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index bc73ffd..506420c 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -118,9 +118,23 @@
CreateTrackOutput& output,
status_t *status);
- virtual sp<media::IAudioRecord> createRecord(const CreateRecordInput& input,
- CreateRecordOutput& output,
- status_t *status);
+ virtual sp<media::IAudioRecord> openRecord(
+ audio_io_handle_t input,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ const String16& opPackageName,
+ size_t *pFrameCount,
+ audio_input_flags_t *flags,
+ pid_t pid,
+ pid_t tid,
+ int clientUid,
+ audio_session_t *sessionId,
+ size_t *notificationFrames,
+ sp<IMemory>& cblk,
+ sp<IMemory>& buffers,
+ status_t *status /*non-NULL*/,
+ audio_port_handle_t portId);
virtual uint32_t sampleRate(audio_io_handle_t ioHandle) const;
virtual audio_format_t format(audio_io_handle_t output) const;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 7636df6..b2a1e18 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -6708,12 +6708,12 @@
// RecordThread::createRecordTrack_l() must be called with AudioFlinger::mLock held
sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRecordTrack_l(
const sp<AudioFlinger::Client>& client,
- uint32_t *pSampleRate,
+ uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
size_t *pFrameCount,
audio_session_t sessionId,
- size_t *pNotificationFrameCount,
+ size_t *notificationFrames,
uid_t uid,
audio_input_flags_t *flags,
pid_t tid,
@@ -6721,30 +6721,16 @@
audio_port_handle_t portId)
{
size_t frameCount = *pFrameCount;
- size_t notificationFrameCount = *pNotificationFrameCount;
sp<RecordTrack> track;
status_t lStatus;
audio_input_flags_t inputFlags = mInput->flags;
- audio_input_flags_t requestedFlags = *flags;
- uint32_t sampleRate;
-
- lStatus = initCheck();
- if (lStatus != NO_ERROR) {
- ALOGE("createRecordTrack_l() audio driver not initialized");
- goto Exit;
- }
-
- if (*pSampleRate == 0) {
- *pSampleRate = mSampleRate;
- }
- sampleRate = *pSampleRate;
// special case for FAST flag considered OK if fast capture is present
if (hasFastCapture()) {
inputFlags = (audio_input_flags_t)(inputFlags | AUDIO_INPUT_FLAG_FAST);
}
- // Check if requested flags are compatible with input stream flags
+ // Check if requested flags are compatible with output stream flags
if ((*flags & inputFlags) != *flags) {
ALOGW("createRecordTrack_l(): mismatch between requested flags (%08x) and"
" input flags (%08x)",
@@ -6799,20 +6785,12 @@
}
}
- // If FAST or RAW flags were corrected, ask caller to request new input from audio policy
- if ((*flags & AUDIO_INPUT_FLAG_FAST) !=
- (requestedFlags & AUDIO_INPUT_FLAG_FAST)) {
- *flags = (audio_input_flags_t) (*flags & ~(AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW));
- lStatus = BAD_TYPE;
- goto Exit;
- }
-
// compute track buffer size in frames, and suggest the notification frame count
if (*flags & AUDIO_INPUT_FLAG_FAST) {
// fast track: frame count is exactly the pipe depth
frameCount = mPipeFramesP2;
// ignore requested notificationFrames, and always notify exactly once every HAL buffer
- notificationFrameCount = mFrameCount;
+ *notificationFrames = mFrameCount;
} else {
// not fast track: max notification period is resampled equivalent of one HAL buffer time
// or 20 ms if there is a fast capture
@@ -6831,12 +6809,17 @@
const size_t minFrameCount = maxNotificationFrames *
max(kMinNotifications, minNotificationsByMs);
frameCount = max(frameCount, minFrameCount);
- if (notificationFrameCount == 0 || notificationFrameCount > maxNotificationFrames) {
- notificationFrameCount = maxNotificationFrames;
+ if (*notificationFrames == 0 || *notificationFrames > maxNotificationFrames) {
+ *notificationFrames = maxNotificationFrames;
}
}
*pFrameCount = frameCount;
- *pNotificationFrameCount = notificationFrameCount;
+
+ lStatus = initCheck();
+ if (lStatus != NO_ERROR) {
+ ALOGE("createRecordTrack_l() audio driver not initialized");
+ goto Exit;
+ }
{ // scope for mLock
Mutex::Autolock _l(mLock);
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 17f26c5..c7b60d6 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1327,12 +1327,12 @@
sp<AudioFlinger::RecordThread::RecordTrack> createRecordTrack_l(
const sp<AudioFlinger::Client>& client,
- uint32_t *pSampleRate,
+ uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
size_t *pFrameCount,
audio_session_t sessionId,
- size_t *pNotificationFrameCount,
+ size_t *notificationFrames,
uid_t uid,
audio_input_flags_t *flags,
pid_t tid,
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index a3ea756..d4ce0b4 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -192,7 +192,7 @@
// where for AudioTrack (but not AudioRecord),
// 8-bit PCM samples are stored as 16-bit
const size_t mFrameCount;// size of track buffer given at createTrack() or
- // createRecord(), and then adjusted as needed
+ // openRecord(), and then adjusted as needed
const audio_session_t mSessionId;
uid_t mUid;