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;
}