1 /*
2 **
3 ** Copyright 2008, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 //#define LOG_NDEBUG 0
19 #define LOG_TAG "AudioRecord"
20
21 #include <inttypes.h>
22 #include <android-base/macros.h>
23 #include <android-base/stringprintf.h>
24 #include <sys/resource.h>
25
26 #include <audio_utils/format.h>
27 #include <audiomanager/AudioManager.h>
28 #include <audiomanager/IAudioManager.h>
29 #include <binder/Binder.h>
30 #include <binder/IPCThreadState.h>
31 #include <binder/IServiceManager.h>
32 #include <media/AudioRecord.h>
33 #include <utils/Log.h>
34 #include <private/media/AudioTrackShared.h>
35 #include <processgroup/sched_policy.h>
36 #include <media/IAudioFlinger.h>
37 #include <media/MediaMetricsItem.h>
38 #include <media/TypeConverter.h>
39
40 #define WAIT_PERIOD_MS 10
41
42 namespace android {
43
44 using ::android::base::StringPrintf;
45 using android::content::AttributionSourceState;
46 using aidl_utils::statusTFromBinderStatus;
47
48 // ---------------------------------------------------------------------------
49
50 // static
getMinFrameCount(size_t * frameCount,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask)51 status_t AudioRecord::getMinFrameCount(
52 size_t* frameCount,
53 uint32_t sampleRate,
54 audio_format_t format,
55 audio_channel_mask_t channelMask)
56 {
57 if (frameCount == NULL) {
58 return BAD_VALUE;
59 }
60
61 size_t size;
62 status_t status = AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size);
63 if (status != NO_ERROR) {
64 ALOGE("%s(): AudioSystem could not query the input buffer size for"
65 " sampleRate %u, format %#x, channelMask %#x; status %d",
66 __func__, sampleRate, format, channelMask, status);
67 return status;
68 }
69
70 // We double the size of input buffer for ping pong use of record buffer.
71 // Assumes audio_is_linear_pcm(format)
72 const auto sampleSize = audio_channel_count_from_in_mask(channelMask) *
73 audio_bytes_per_sample(format);
74 if (sampleSize == 0 || ((*frameCount = (size * 2) / sampleSize) == 0)) {
75 ALOGE("%s(): Unsupported configuration: sampleRate %u, format %#x, channelMask %#x",
76 __func__, sampleRate, format, channelMask);
77 return BAD_VALUE;
78 }
79
80 return NO_ERROR;
81 }
82
83 // ---------------------------------------------------------------------------
84
gather(const AudioRecord * record)85 void AudioRecord::MediaMetrics::gather(const AudioRecord *record)
86 {
87 #define MM_PREFIX "android.media.audiorecord." // avoid cut-n-paste errors.
88
89 // Java API 28 entries, do not change.
90 mMetricsItem->setCString(MM_PREFIX "encoding", toString(record->mFormat).c_str());
91 mMetricsItem->setCString(MM_PREFIX "source", toString(record->mAttributes.source).c_str());
92 mMetricsItem->setInt32(MM_PREFIX "latency", (int32_t)record->mLatency); // bad estimate.
93 mMetricsItem->setInt32(MM_PREFIX "samplerate", (int32_t)record->mSampleRate);
94 mMetricsItem->setInt32(MM_PREFIX "channels", (int32_t)record->mChannelCount);
95
96 // Non-API entries, these can change.
97 mMetricsItem->setInt32(MM_PREFIX "portId", (int32_t)record->mPortId);
98 mMetricsItem->setInt32(MM_PREFIX "frameCount", (int32_t)record->mFrameCount);
99 mMetricsItem->setCString(MM_PREFIX "attributes", toString(record->mAttributes).c_str());
100 mMetricsItem->setInt64(MM_PREFIX "channelMask", (int64_t)record->mChannelMask);
101
102 // log total duration recording, including anything currently running.
103 int64_t activeNs = 0;
104 if (mStartedNs != 0) {
105 activeNs = systemTime() - mStartedNs;
106 }
107 mMetricsItem->setDouble(MM_PREFIX "durationMs", (mDurationNs + activeNs) * 1e-6);
108 mMetricsItem->setInt64(MM_PREFIX "startCount", (int64_t)mCount);
109
110 if (mLastError != NO_ERROR) {
111 mMetricsItem->setInt32(MM_PREFIX "lastError.code", (int32_t)mLastError);
112 mMetricsItem->setCString(MM_PREFIX "lastError.at", mLastErrorFunc.c_str());
113 }
114 mMetricsItem->setCString(MM_PREFIX "logSessionId", record->mLogSessionId.c_str());
115 }
116
stateToString(bool active)117 static const char *stateToString(bool active) {
118 return active ? "ACTIVE" : "STOPPED";
119 }
120
121 // hand the user a snapshot of the metrics.
getMetrics(mediametrics::Item * & item)122 status_t AudioRecord::getMetrics(mediametrics::Item * &item)
123 {
124 mMediaMetrics.gather(this);
125 mediametrics::Item *tmp = mMediaMetrics.dup();
126 if (tmp == nullptr) {
127 return BAD_VALUE;
128 }
129 item = tmp;
130 return NO_ERROR;
131 }
132
AudioRecord(const AttributionSourceState & client)133 AudioRecord::AudioRecord(const AttributionSourceState &client)
134 : mActive(false), mStatus(NO_INIT), mClientAttributionSource(client),
135 mSessionId(AUDIO_SESSION_ALLOCATE), mPreviousPriority(ANDROID_PRIORITY_NORMAL),
136 mPreviousSchedulingGroup(SP_DEFAULT), mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
137 mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE), mSelectedMicDirection(MIC_DIRECTION_UNSPECIFIED),
138 mSelectedMicFieldDimension(MIC_FIELD_DIMENSION_DEFAULT)
139 {
140 }
141
AudioRecord(audio_source_t inputSource,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask,const AttributionSourceState & client,size_t frameCount,legacy_callback_t callback,void * user,uint32_t notificationFrames,audio_session_t sessionId,transfer_type transferType,audio_input_flags_t flags,const audio_attributes_t * pAttributes,audio_port_handle_t selectedDeviceId,audio_microphone_direction_t selectedMicDirection,float microphoneFieldDimension)142 AudioRecord::AudioRecord(
143 audio_source_t inputSource,
144 uint32_t sampleRate,
145 audio_format_t format,
146 audio_channel_mask_t channelMask,
147 const AttributionSourceState& client,
148 size_t frameCount,
149 legacy_callback_t callback,
150 void* user,
151 uint32_t notificationFrames,
152 audio_session_t sessionId,
153 transfer_type transferType,
154 audio_input_flags_t flags,
155 const audio_attributes_t* pAttributes,
156 audio_port_handle_t selectedDeviceId,
157 audio_microphone_direction_t selectedMicDirection,
158 float microphoneFieldDimension)
159 : mActive(false),
160 mStatus(NO_INIT),
161 mClientAttributionSource(client),
162 mSessionId(AUDIO_SESSION_ALLOCATE),
163 mPreviousPriority(ANDROID_PRIORITY_NORMAL),
164 mPreviousSchedulingGroup(SP_DEFAULT),
165 mProxy(NULL)
166 {
167 uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(mClientAttributionSource.uid));
168 pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(mClientAttributionSource.pid));
169 (void)set(inputSource, sampleRate, format, channelMask, frameCount, callback, user,
170 notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
171 uid, pid, pAttributes, selectedDeviceId, selectedMicDirection,
172 microphoneFieldDimension);
173 }
174
AudioRecord(audio_source_t inputSource,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask,const AttributionSourceState & client,size_t frameCount,const wp<IAudioRecordCallback> & callback,uint32_t notificationFrames,audio_session_t sessionId,transfer_type transferType,audio_input_flags_t flags,const audio_attributes_t * pAttributes,audio_port_handle_t selectedDeviceId,audio_microphone_direction_t selectedMicDirection,float microphoneFieldDimension)175 AudioRecord::AudioRecord(
176 audio_source_t inputSource,
177 uint32_t sampleRate,
178 audio_format_t format,
179 audio_channel_mask_t channelMask,
180 const AttributionSourceState& client,
181 size_t frameCount,
182 const wp<IAudioRecordCallback>& callback,
183 uint32_t notificationFrames,
184 audio_session_t sessionId,
185 transfer_type transferType,
186 audio_input_flags_t flags,
187 const audio_attributes_t* pAttributes,
188 audio_port_handle_t selectedDeviceId,
189 audio_microphone_direction_t selectedMicDirection,
190 float microphoneFieldDimension)
191 : mActive(false),
192 mStatus(NO_INIT),
193 mClientAttributionSource(client),
194 mSessionId(AUDIO_SESSION_ALLOCATE),
195 mPreviousPriority(ANDROID_PRIORITY_NORMAL),
196 mPreviousSchedulingGroup(SP_DEFAULT),
197 mProxy(nullptr)
198 {
199 uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(mClientAttributionSource.uid));
200 pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(mClientAttributionSource.pid));
201 (void)set(inputSource, sampleRate, format, channelMask, frameCount, callback,
202 notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
203 uid, pid, pAttributes, selectedDeviceId, selectedMicDirection,
204 microphoneFieldDimension);
205 }
206
~AudioRecord()207 AudioRecord::~AudioRecord()
208 {
209 mMediaMetrics.gather(this);
210
211 mediametrics::LogItem(mMetricsId)
212 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_DTOR)
213 .set(AMEDIAMETRICS_PROP_CALLERNAME,
214 mCallerName.empty()
215 ? AMEDIAMETRICS_PROP_CALLERNAME_VALUE_UNKNOWN
216 : mCallerName.c_str())
217 .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)mStatus)
218 .record();
219
220 stopAndJoinCallbacks(); // checks mStatus
221
222 if (mStatus == NO_ERROR) {
223 IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this);
224 mAudioRecord.clear();
225 mCblkMemory.clear();
226 mBufferMemory.clear();
227 IPCThreadState::self()->flushCommands();
228 ALOGV("%s(%d): releasing session id %d",
229 __func__, mPortId, mSessionId);
230 pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(mClientAttributionSource.pid));
231 AudioSystem::releaseAudioSessionId(mSessionId, pid);
232 }
233 }
234
stopAndJoinCallbacks()235 void AudioRecord::stopAndJoinCallbacks() {
236 // Prevent nullptr crash if it did not open properly.
237 if (mStatus != NO_ERROR) return;
238
239 // Make sure that callback function exits in the case where
240 // it is looping on buffer empty condition in obtainBuffer().
241 // Otherwise the callback thread will never exit.
242 stop();
243 if (mAudioRecordThread != 0) {
244 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h
245 mProxy->interrupt();
246 mAudioRecordThread->requestExitAndWait();
247 mAudioRecordThread.clear();
248 }
249
250 AutoMutex lock(mLock);
251 if (mDeviceCallback != 0 && mInput != AUDIO_IO_HANDLE_NONE) {
252 // This may not stop all of these device callbacks!
253 // TODO: Add some sort of protection.
254 AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
255 mDeviceCallback.clear();
256 }
257 }
258 namespace {
259 class LegacyCallbackWrapper : public AudioRecord::IAudioRecordCallback {
260 const AudioRecord::legacy_callback_t mCallback;
261 void* const mData;
262
263 public:
LegacyCallbackWrapper(AudioRecord::legacy_callback_t callback,void * user)264 LegacyCallbackWrapper(AudioRecord::legacy_callback_t callback, void* user)
265 : mCallback(callback), mData(user) {}
266
onMoreData(const AudioRecord::Buffer & buffer)267 size_t onMoreData(const AudioRecord::Buffer& buffer) override {
268 AudioRecord::Buffer copy = buffer;
269 mCallback(AudioRecord::EVENT_MORE_DATA, mData, ©);
270 return copy.size();
271 }
272
onOverrun()273 void onOverrun() override { mCallback(AudioRecord::EVENT_OVERRUN, mData, nullptr); }
274
onMarker(uint32_t markerPosition)275 void onMarker(uint32_t markerPosition) override {
276 mCallback(AudioRecord::EVENT_MARKER, mData, &markerPosition);
277 }
278
onNewPos(uint32_t newPos)279 void onNewPos(uint32_t newPos) override {
280 mCallback(AudioRecord::EVENT_NEW_POS, mData, &newPos);
281 }
282
onNewIAudioRecord()283 void onNewIAudioRecord() override {
284 mCallback(AudioRecord::EVENT_NEW_IAUDIORECORD, mData, nullptr);
285 }
286 };
287 } // namespace
288
set(audio_source_t inputSource,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask,size_t frameCount,const wp<IAudioRecordCallback> & callback,uint32_t notificationFrames,bool threadCanCallJava,audio_session_t sessionId,transfer_type transferType,audio_input_flags_t flags,uid_t uid,pid_t pid,const audio_attributes_t * pAttributes,audio_port_handle_t selectedDeviceId,audio_microphone_direction_t selectedMicDirection,float microphoneFieldDimension,int32_t maxSharedAudioHistoryMs)289 status_t AudioRecord::set(
290 audio_source_t inputSource,
291 uint32_t sampleRate,
292 audio_format_t format,
293 audio_channel_mask_t channelMask,
294 size_t frameCount,
295 const wp<IAudioRecordCallback>& callback,
296 uint32_t notificationFrames,
297 bool threadCanCallJava,
298 audio_session_t sessionId,
299 transfer_type transferType,
300 audio_input_flags_t flags,
301 uid_t uid,
302 pid_t pid,
303 const audio_attributes_t* pAttributes,
304 audio_port_handle_t selectedDeviceId,
305 audio_microphone_direction_t selectedMicDirection,
306 float microphoneFieldDimension,
307 int32_t maxSharedAudioHistoryMs)
308 {
309 status_t status = NO_ERROR;
310 LOG_ALWAYS_FATAL_IF(mInitialized, "%s: should not be called twice", __func__);
311 mInitialized = true;
312 // Note mPortId is not valid until the track is created, so omit mPortId in ALOG for set.
313 ALOGV("%s(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
314 "notificationFrames %u, sessionId %d, transferType %d, flags %#x, attributionSource %s"
315 "uid %d, pid %d",
316 __func__,
317 inputSource, sampleRate, format, channelMask, frameCount, notificationFrames,
318 sessionId, transferType, flags, mClientAttributionSource.toString().c_str(), uid, pid);
319
320 // TODO b/182392553: refactor or remove
321 pid_t callingPid = IPCThreadState::self()->getCallingPid();
322 pid_t myPid = getpid();
323 pid_t adjPid = pid;
324 if (pid == -1 || (callingPid != myPid)) {
325 adjPid = callingPid;
326 }
327 mClientAttributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(adjPid));
328
329 uid_t adjUid = uid;
330 if (uid == -1 || (callingPid != myPid)) {
331 adjUid = IPCThreadState::self()->getCallingUid();
332 }
333 mClientAttributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(adjUid));
334
335 mTracker.reset(new RecordingActivityTracker());
336
337 mSelectedDeviceId = selectedDeviceId;
338 mSelectedMicDirection = selectedMicDirection;
339 mSelectedMicFieldDimension = microphoneFieldDimension;
340 mMaxSharedAudioHistoryMs = maxSharedAudioHistoryMs;
341
342 std::string errorMessage;
343 // Copy the state variables early so they are available for error reporting.
344 if (pAttributes == nullptr) {
345 mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
346 mAttributes.source = inputSource;
347 if (inputSource == AUDIO_SOURCE_VOICE_COMMUNICATION
348 || inputSource == AUDIO_SOURCE_CAMCORDER) {
349 mAttributes.flags = static_cast<audio_flags_mask_t>(
350 mAttributes.flags | AUDIO_FLAG_CAPTURE_PRIVATE);
351 }
352 } else {
353 // stream type shouldn't be looked at, this track has audio attributes
354 memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));
355 ALOGV("%s: Building AudioRecord with attributes: source=%d flags=0x%x tags=[%s]",
356 __func__, mAttributes.source, mAttributes.flags, mAttributes.tags);
357 }
358 mSampleRate = sampleRate;
359 if (format == AUDIO_FORMAT_DEFAULT) {
360 format = AUDIO_FORMAT_PCM_16_BIT;
361 }
362 if (!audio_is_linear_pcm(format)) {
363 // Compressed capture requires direct
364 flags = (audio_input_flags_t) (flags | AUDIO_INPUT_FLAG_DIRECT);
365 ALOGI("%s(): Format %#x is not linear pcm. Setting DIRECT, using flags %#x", __func__,
366 format, flags);
367 }
368 mFormat = format;
369 mChannelMask = channelMask;
370 mSessionId = sessionId;
371 ALOGV("%s: mSessionId %d", __func__, mSessionId);
372 mOrigFlags = mFlags = flags;
373
374 mTransfer = transferType;
375 switch (mTransfer) {
376 case TRANSFER_DEFAULT:
377 if (callback == nullptr || threadCanCallJava) {
378 mTransfer = TRANSFER_SYNC;
379 } else {
380 mTransfer = TRANSFER_CALLBACK;
381 }
382 break;
383 case TRANSFER_CALLBACK:
384 if (callback == nullptr) {
385 errorMessage = StringPrintf(
386 "%s: Transfer type TRANSFER_CALLBACK but callback == nullptr", __func__);
387 status = BAD_VALUE;
388 goto error;
389 }
390 break;
391 case TRANSFER_OBTAIN:
392 case TRANSFER_SYNC:
393 break;
394 default:
395 errorMessage = StringPrintf("%s: Invalid transfer type %d", __func__, mTransfer);
396 status = BAD_VALUE;
397 goto error;
398 }
399
400 // invariant that mAudioRecord != 0 is true only after set() returns successfully
401 if (mAudioRecord != 0) {
402 errorMessage = StringPrintf("%s: Track already in use", __func__);
403 status = INVALID_OPERATION;
404 goto error;
405 }
406
407 if (!audio_is_valid_format(mFormat)) {
408 errorMessage = StringPrintf("%s: Format %#x is not valid", __func__, mFormat);
409 status = BAD_VALUE;
410 goto error;
411 }
412
413 if (!audio_is_input_channel(mChannelMask)) {
414 errorMessage = StringPrintf("%s: Invalid channel mask %#x", __func__, mChannelMask);
415 status = BAD_VALUE;
416 goto error;
417 }
418
419 mChannelCount = audio_channel_count_from_in_mask(mChannelMask);
420
421 if (audio_is_linear_pcm(mFormat)) {
422 mFrameSize = mChannelCount * audio_bytes_per_sample(mFormat);
423 } else {
424 mFrameSize = sizeof(uint8_t);
425 }
426
427 // mFrameCount is initialized in createRecord_l
428 mReqFrameCount = frameCount;
429
430 mNotificationFramesReq = notificationFrames;
431 // mNotificationFramesAct is initialized in createRecord_l
432
433 mCallback = callback;
434 if (mCallback != nullptr) {
435 mAudioRecordThread = new AudioRecordThread(*this);
436 mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO);
437 // thread begins in paused state, and will not reference us until start()
438 }
439
440 // create the IAudioRecord
441 {
442 AutoMutex lock(mLock);
443 status = createRecord_l(0 /*epoch*/);
444 }
445
446 ALOGV("%s(%d): status %d", __func__, mPortId, status);
447
448 if (status != NO_ERROR) {
449 if (mAudioRecordThread != 0) {
450 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h
451 mAudioRecordThread->requestExitAndWait();
452 mAudioRecordThread.clear();
453 }
454 // bypass error message to avoid logging twice (createRecord_l logs the error).
455 goto exit;
456 }
457
458 // TODO: add audio hardware input latency here
459 mLatency = (1000LL * mFrameCount) / mSampleRate;
460 mMarkerPosition = 0;
461 mMarkerReached = false;
462 mNewPosition = 0;
463 mUpdatePeriod = 0;
464 AudioSystem::acquireAudioSessionId(mSessionId, adjPid, adjUid);
465 mSequence = 1;
466 mObservedSequence = mSequence;
467 mInOverrun = false;
468 mFramesRead = 0;
469 mFramesReadServerOffset = 0;
470
471 error:
472 if (status != NO_ERROR) {
473 mMediaMetrics.markError(status, __FUNCTION__);
474 ALOGE_IF(!errorMessage.empty(), "%s", errorMessage.c_str());
475 reportError(status, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE, errorMessage.c_str());
476 }
477 exit:
478 mStatus = status;
479 return status;
480 }
481
set(audio_source_t inputSource,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask,size_t frameCount,legacy_callback_t callback,void * user,uint32_t notificationFrames,bool threadCanCallJava,audio_session_t sessionId,transfer_type transferType,audio_input_flags_t flags,uid_t uid,pid_t pid,const audio_attributes_t * pAttributes,audio_port_handle_t selectedDeviceId,audio_microphone_direction_t selectedMicDirection,float microphoneFieldDimension,int32_t maxSharedAudioHistoryMs)482 status_t AudioRecord::set(
483 audio_source_t inputSource,
484 uint32_t sampleRate,
485 audio_format_t format,
486 audio_channel_mask_t channelMask,
487 size_t frameCount,
488 legacy_callback_t callback,
489 void* user,
490 uint32_t notificationFrames,
491 bool threadCanCallJava,
492 audio_session_t sessionId,
493 transfer_type transferType,
494 audio_input_flags_t flags,
495 uid_t uid,
496 pid_t pid,
497 const audio_attributes_t* pAttributes,
498 audio_port_handle_t selectedDeviceId,
499 audio_microphone_direction_t selectedMicDirection,
500 float microphoneFieldDimension,
501 int32_t maxSharedAudioHistoryMs)
502 {
503 if (callback != nullptr) {
504 mLegacyCallbackWrapper = sp<LegacyCallbackWrapper>::make(callback, user);
505 } else if (user) {
506 LOG_ALWAYS_FATAL("Callback data provided without callback pointer!");
507 }
508 return set(inputSource, sampleRate, format, channelMask, frameCount, mLegacyCallbackWrapper,
509 notificationFrames, threadCanCallJava, sessionId, transferType, flags, uid, pid,
510 pAttributes, selectedDeviceId, selectedMicDirection, microphoneFieldDimension,
511 maxSharedAudioHistoryMs);
512 }
513 // -------------------------------------------------------------------------
514
start(AudioSystem::sync_event_t event,audio_session_t triggerSession)515 status_t AudioRecord::start(AudioSystem::sync_event_t event, audio_session_t triggerSession)
516 {
517 const int64_t beginNs = systemTime();
518 ALOGV("%s(%d): sync event %d trigger session %d", __func__, mPortId, event, triggerSession);
519 AutoMutex lock(mLock);
520
521 status_t status = NO_ERROR;
522 mediametrics::Defer defer([&] {
523 mediametrics::LogItem(mMetricsId)
524 .set(AMEDIAMETRICS_PROP_CALLERNAME,
525 mCallerName.empty()
526 ? AMEDIAMETRICS_PROP_CALLERNAME_VALUE_UNKNOWN
527 : mCallerName.c_str())
528 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_START)
529 .set(AMEDIAMETRICS_PROP_EXECUTIONTIMENS, (int64_t)(systemTime() - beginNs))
530 .set(AMEDIAMETRICS_PROP_STATE, stateToString(mActive))
531 .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)status)
532 .record(); });
533
534 if (mActive) {
535 return status;
536 }
537
538 // discard data in buffer
539 const uint32_t framesFlushed = mProxy->flush();
540 mFramesReadServerOffset -= mFramesRead + framesFlushed;
541 mFramesRead = 0;
542 mProxy->clearTimestamp(); // timestamp is invalid until next server push
543 mPreviousTimestamp.clear();
544 mTimestampRetrogradePositionReported = false;
545 mTimestampRetrogradeTimeReported = false;
546
547 // reset current position as seen by client to 0
548 mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition());
549 // force refresh of remaining frames by processAudioBuffer() as last
550 // read before stop could be partial.
551 mRefreshRemaining = true;
552
553 mNewPosition = mProxy->getPosition() + mUpdatePeriod;
554 int32_t flags = android_atomic_acquire_load(&mCblk->mFlags);
555
556 // we reactivate markers (mMarkerPosition != 0) as the position is reset to 0.
557 // This is legacy behavior. This is not done in stop() to avoid a race condition
558 // where the last marker event is issued twice.
559 mMarkerReached = false;
560 // mActive is checked by restoreRecord_l
561 mActive = true;
562
563 if (!(flags & CBLK_INVALID)) {
564 status = statusTFromBinderStatus(mAudioRecord->start(event, triggerSession));
565 if (status == DEAD_OBJECT) {
566 flags |= CBLK_INVALID;
567 }
568 }
569 if (flags & CBLK_INVALID) {
570 status = restoreRecord_l("start");
571 }
572
573 // Call these directly because we are already holding the lock.
574 mAudioRecord->setPreferredMicrophoneDirection(mSelectedMicDirection);
575 mAudioRecord->setPreferredMicrophoneFieldDimension(mSelectedMicFieldDimension);
576
577 if (status != NO_ERROR) {
578 mActive = false;
579 ALOGE("%s(%d): status %d", __func__, mPortId, status);
580 mMediaMetrics.markError(status, __FUNCTION__);
581 } else {
582 mTracker->recordingStarted();
583 sp<AudioRecordThread> t = mAudioRecordThread;
584 if (t != 0) {
585 t->resume();
586 } else {
587 mPreviousPriority = getpriority(PRIO_PROCESS, 0);
588 get_sched_policy(0, &mPreviousSchedulingGroup);
589 androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
590 }
591
592 // we've successfully started, log that time
593 mMediaMetrics.logStart(systemTime());
594 }
595 return status;
596 }
597
stop()598 void AudioRecord::stop()
599 {
600 const int64_t beginNs = systemTime();
601 AutoMutex lock(mLock);
602 mediametrics::Defer defer([&] {
603 mediametrics::LogItem(mMetricsId)
604 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_STOP)
605 .set(AMEDIAMETRICS_PROP_EXECUTIONTIMENS, (int64_t)(systemTime() - beginNs))
606 .set(AMEDIAMETRICS_PROP_STATE, stateToString(mActive))
607 .record(); });
608
609 ALOGV("%s(%d): mActive:%d\n", __func__, mPortId, mActive);
610 if (!mActive) {
611 return;
612 }
613
614 mActive = false;
615 mProxy->interrupt();
616 mAudioRecord->stop();
617 mTracker->recordingStopped();
618
619 // Note: legacy handling - stop does not clear record marker and
620 // periodic update position; we update those on start().
621
622 sp<AudioRecordThread> t = mAudioRecordThread;
623 if (t != 0) {
624 t->pause();
625 } else {
626 setpriority(PRIO_PROCESS, 0, mPreviousPriority);
627 set_sched_policy(0, mPreviousSchedulingGroup);
628 }
629
630 // we've successfully started, log that time
631 mMediaMetrics.logStop(systemTime());
632 }
633
stopped() const634 bool AudioRecord::stopped() const
635 {
636 AutoMutex lock(mLock);
637 return !mActive;
638 }
639
setMarkerPosition(uint32_t marker)640 status_t AudioRecord::setMarkerPosition(uint32_t marker)
641 {
642 AutoMutex lock(mLock);
643 // The only purpose of setting marker position is to get a callback
644 if (mCallback == nullptr) {
645 return INVALID_OPERATION;
646 }
647
648 mMarkerPosition = marker;
649 mMarkerReached = false;
650
651 sp<AudioRecordThread> t = mAudioRecordThread;
652 if (t != 0) {
653 t->wake();
654 }
655 return NO_ERROR;
656 }
657
getMarkerPosition(uint32_t * marker) const658 status_t AudioRecord::getMarkerPosition(uint32_t *marker) const
659 {
660 if (marker == NULL) {
661 return BAD_VALUE;
662 }
663
664 AutoMutex lock(mLock);
665 mMarkerPosition.getValue(marker);
666
667 return NO_ERROR;
668 }
669
setPositionUpdatePeriod(uint32_t updatePeriod)670 status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
671 {
672 AutoMutex lock(mLock);
673 // The only purpose of setting position update period is to get a callback
674 if (mCallback == nullptr) {
675 return INVALID_OPERATION;
676 }
677
678 mNewPosition = mProxy->getPosition() + updatePeriod;
679 mUpdatePeriod = updatePeriod;
680
681 sp<AudioRecordThread> t = mAudioRecordThread;
682 if (t != 0) {
683 t->wake();
684 }
685 return NO_ERROR;
686 }
687
getPositionUpdatePeriod(uint32_t * updatePeriod) const688 status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const
689 {
690 if (updatePeriod == NULL) {
691 return BAD_VALUE;
692 }
693
694 AutoMutex lock(mLock);
695 *updatePeriod = mUpdatePeriod;
696
697 return NO_ERROR;
698 }
699
getPosition(uint32_t * position) const700 status_t AudioRecord::getPosition(uint32_t *position) const
701 {
702 if (position == NULL) {
703 return BAD_VALUE;
704 }
705
706 AutoMutex lock(mLock);
707 mProxy->getPosition().getValue(position);
708
709 return NO_ERROR;
710 }
711
getInputFramesLost() const712 uint32_t AudioRecord::getInputFramesLost() const
713 {
714 // no need to check mActive, because if inactive this will return 0, which is what we want
715 return AudioSystem::getInputFramesLost(getInputPrivate());
716 }
717
getTimestamp(ExtendedTimestamp * timestamp)718 status_t AudioRecord::getTimestamp(ExtendedTimestamp *timestamp)
719 {
720 if (timestamp == nullptr) {
721 return BAD_VALUE;
722 }
723 AutoMutex lock(mLock);
724 status_t status = mProxy->getTimestamp(timestamp);
725 if (status == OK) {
726 timestamp->mPosition[ExtendedTimestamp::LOCATION_CLIENT] = mFramesRead;
727 timestamp->mTimeNs[ExtendedTimestamp::LOCATION_CLIENT] = 0;
728 if (!audio_is_linear_pcm(mFormat)) {
729 // Don't do retrograde corrections or server offset if track is
730 // compressed
731 return OK;
732 }
733 // server side frame offset in case AudioRecord has been restored.
734 for (int i = ExtendedTimestamp::LOCATION_SERVER;
735 i < ExtendedTimestamp::LOCATION_MAX; ++i) {
736 if (timestamp->mTimeNs[i] >= 0) {
737 timestamp->mPosition[i] += mFramesReadServerOffset;
738 }
739 }
740
741 bool timestampRetrogradeTimeReported = false;
742 bool timestampRetrogradePositionReported = false;
743 for (int i = 0; i < ExtendedTimestamp::LOCATION_MAX; ++i) {
744 if (timestamp->mTimeNs[i] >= 0 && mPreviousTimestamp.mTimeNs[i] >= 0) {
745 if (timestamp->mTimeNs[i] < mPreviousTimestamp.mTimeNs[i]) {
746 if (!mTimestampRetrogradeTimeReported) {
747 ALOGD("%s: retrograde time adjusting [%d] current:%lld to previous:%lld",
748 __func__, i, (long long)timestamp->mTimeNs[i],
749 (long long)mPreviousTimestamp.mTimeNs[i]);
750 timestampRetrogradeTimeReported = true;
751 }
752 timestamp->mTimeNs[i] = mPreviousTimestamp.mTimeNs[i];
753 }
754 if (timestamp->mPosition[i] < mPreviousTimestamp.mPosition[i]) {
755 if (!mTimestampRetrogradePositionReported) {
756 ALOGD("%s: retrograde position"
757 " adjusting [%d] current:%lld to previous:%lld",
758 __func__, i, (long long)timestamp->mPosition[i],
759 (long long)mPreviousTimestamp.mPosition[i]);
760 timestampRetrogradePositionReported = true;
761 }
762 timestamp->mPosition[i] = mPreviousTimestamp.mPosition[i];
763 }
764 }
765 }
766 mPreviousTimestamp = *timestamp;
767 if (timestampRetrogradeTimeReported) {
768 mTimestampRetrogradeTimeReported = true;
769 }
770 if (timestampRetrogradePositionReported) {
771 mTimestampRetrogradePositionReported = true;
772 }
773 }
774 return status;
775 }
776
777 // ---- Explicit Routing ---------------------------------------------------
setInputDevice(audio_port_handle_t deviceId)778 status_t AudioRecord::setInputDevice(audio_port_handle_t deviceId) {
779 AutoMutex lock(mLock);
780 ALOGV("%s(%d): deviceId=%d mSelectedDeviceId=%d",
781 __func__, mPortId, deviceId, mSelectedDeviceId);
782 if (mSelectedDeviceId != deviceId) {
783 mSelectedDeviceId = deviceId;
784 if (mStatus == NO_ERROR) {
785 // stop capture so that audio policy manager does not reject the new instance start request
786 // as only one capture can be active at a time.
787 if (mAudioRecord != 0 && mActive) {
788 mAudioRecord->stop();
789 }
790 android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
791 mProxy->interrupt();
792 }
793 }
794 return NO_ERROR;
795 }
796
getInputDevice()797 audio_port_handle_t AudioRecord::getInputDevice() {
798 AutoMutex lock(mLock);
799 return mSelectedDeviceId;
800 }
801
802 // must be called with mLock held
updateRoutedDeviceId_l()803 void AudioRecord::updateRoutedDeviceId_l()
804 {
805 // if the record is inactive, do not update actual device as the input stream maybe routed
806 // from a device not relevant to this client because of other active use cases.
807 if (!mActive) {
808 return;
809 }
810 if (mInput != AUDIO_IO_HANDLE_NONE) {
811 audio_port_handle_t deviceId = AudioSystem::getDeviceIdForIo(mInput);
812 if (deviceId != AUDIO_PORT_HANDLE_NONE) {
813 mRoutedDeviceId = deviceId;
814 }
815 }
816 }
817
getRoutedDeviceId()818 audio_port_handle_t AudioRecord::getRoutedDeviceId() {
819 AutoMutex lock(mLock);
820 updateRoutedDeviceId_l();
821 return mRoutedDeviceId;
822 }
823
dump(int fd,const Vector<String16> & args __unused) const824 status_t AudioRecord::dump(int fd, const Vector<String16>& args __unused) const
825 {
826 String8 result;
827
828 result.append(" AudioRecord::dump\n");
829 result.appendFormat(" id(%d) status(%d), active(%d), session Id(%d)\n",
830 mPortId, mStatus, mActive, mSessionId);
831 result.appendFormat(" flags(%#x), req. flags(%#x), audio source(%d)\n",
832 mFlags, mOrigFlags, mAttributes.source);
833 result.appendFormat(" format(%#x), channel mask(%#x), channel count(%u), sample rate(%u)\n",
834 mFormat, mChannelMask, mChannelCount, mSampleRate);
835 result.appendFormat(" frame count(%zu), req. frame count(%zu)\n",
836 mFrameCount, mReqFrameCount);
837 result.appendFormat(" notif. frame count(%u), req. notif. frame count(%u)\n",
838 mNotificationFramesAct, mNotificationFramesReq);
839 result.appendFormat(" input(%d), latency(%u), selected device Id(%d), routed device Id(%d)\n",
840 mInput, mLatency, mSelectedDeviceId, mRoutedDeviceId);
841 result.appendFormat(" mic direction(%d) mic field dimension(%f)",
842 mSelectedMicDirection, mSelectedMicFieldDimension);
843 ::write(fd, result.string(), result.size());
844 return NO_ERROR;
845 }
846
847 // -------------------------------------------------------------------------
848 // TODO Move this macro to a common header file for enum to string conversion in audio framework.
849 #define MEDIA_CASE_ENUM(name) case name: return #name
convertTransferToText(transfer_type transferType)850 const char * AudioRecord::convertTransferToText(transfer_type transferType) {
851 switch (transferType) {
852 MEDIA_CASE_ENUM(TRANSFER_DEFAULT);
853 MEDIA_CASE_ENUM(TRANSFER_CALLBACK);
854 MEDIA_CASE_ENUM(TRANSFER_OBTAIN);
855 MEDIA_CASE_ENUM(TRANSFER_SYNC);
856 default:
857 return "UNRECOGNIZED";
858 }
859 }
860
861 // must be called with mLock held
createRecord_l(const Modulo<uint32_t> & epoch)862 status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch)
863 {
864 const int64_t beginNs = systemTime();
865 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
866 IAudioFlinger::CreateRecordInput input;
867 IAudioFlinger::CreateRecordOutput output;
868 [[maybe_unused]] audio_session_t originalSessionId;
869 void *iMemPointer;
870 audio_track_cblk_t* cblk;
871 status_t status;
872 static const int32_t kMaxCreateAttempts = 3;
873 int32_t remainingAttempts = kMaxCreateAttempts;
874 std::string errorMessage;
875
876 if (audioFlinger == 0) {
877 errorMessage = StringPrintf("%s(%d): Could not get audioflinger", __func__, mPortId);
878 status = NO_INIT;
879 goto exit;
880 }
881
882 // mFlags (not mOrigFlags) is modified depending on whether fast request is accepted.
883 // After fast request is denied, we will request again if IAudioRecord is re-created.
884
885 // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
886 // we must release it ourselves if anything goes wrong.
887
888 // Client can only express a preference for FAST. Server will perform additional tests.
889 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
890 bool useCaseAllowed =
891 // any of these use cases:
892 // use case 1: callback transfer mode
893 (mTransfer == TRANSFER_CALLBACK) ||
894 // use case 2: blocking read mode
895 // The default buffer capacity at 48 kHz is 2048 frames, or ~42.6 ms.
896 // That's enough for double-buffering with our standard 20 ms rule of thumb for
897 // the minimum period of a non-SCHED_FIFO thread.
898 // This is needed so that AAudio apps can do a low latency non-blocking read from a
899 // callback running with SCHED_FIFO.
900 (mTransfer == TRANSFER_SYNC) ||
901 // use case 3: obtain/release mode
902 (mTransfer == TRANSFER_OBTAIN);
903 if (!useCaseAllowed) {
904 ALOGD("%s(%d): AUDIO_INPUT_FLAG_FAST denied, incompatible transfer = %s",
905 __func__, mPortId,
906 convertTransferToText(mTransfer));
907 mFlags = (audio_input_flags_t) (mFlags & ~(AUDIO_INPUT_FLAG_FAST |
908 AUDIO_INPUT_FLAG_RAW));
909 }
910 }
911
912 input.attr = mAttributes;
913 input.config.sample_rate = mSampleRate;
914 input.config.channel_mask = mChannelMask;
915 input.config.format = mFormat;
916 input.clientInfo.attributionSource = mClientAttributionSource;
917 input.clientInfo.clientTid = -1;
918 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
919 if (mAudioRecordThread != 0) {
920 input.clientInfo.clientTid = mAudioRecordThread->getTid();
921 }
922 }
923 input.riid = mTracker->getRiid();
924
925 input.flags = mFlags;
926 // The notification frame count is the period between callbacks, as suggested by the client
927 // but moderated by the server. For record, the calculations are done entirely on server side.
928 input.frameCount = mReqFrameCount;
929 input.notificationFrameCount = mNotificationFramesReq;
930 input.selectedDeviceId = mSelectedDeviceId;
931 input.sessionId = mSessionId;
932 originalSessionId = mSessionId;
933 input.maxSharedAudioHistoryMs = mMaxSharedAudioHistoryMs;
934
935 do {
936 media::CreateRecordResponse response;
937 status = audioFlinger->createRecord(VALUE_OR_FATAL(input.toAidl()), response);
938 output = VALUE_OR_FATAL(IAudioFlinger::CreateRecordOutput::fromAidl(response));
939 if (status == NO_ERROR) {
940 break;
941 }
942 if (status != FAILED_TRANSACTION || --remainingAttempts <= 0) {
943 errorMessage = StringPrintf(
944 "%s(%d): AudioFlinger could not create record track, status: %d",
945 __func__, mPortId, status);
946 goto exit;
947 }
948 // FAILED_TRANSACTION happens under very specific conditions causing a state mismatch
949 // between audio policy manager and audio flinger during the input stream open sequence
950 // and can be recovered by retrying.
951 // Leave time for race condition to clear before retrying and randomize delay
952 // to reduce the probability of concurrent retries in locked steps.
953 usleep((20 + rand() % 30) * 10000);
954 } while (1);
955
956 ALOG_ASSERT(output.audioRecord != 0);
957
958 // AudioFlinger now owns the reference to the I/O handle,
959 // so we are no longer responsible for releasing it.
960
961 mAwaitBoost = false;
962 if (output.flags & AUDIO_INPUT_FLAG_FAST) {
963 ALOGI("%s(%d): AUDIO_INPUT_FLAG_FAST successful; frameCount %zu -> %zu",
964 __func__, mPortId,
965 mReqFrameCount, output.frameCount);
966 mAwaitBoost = true;
967 }
968 mFlags = output.flags;
969 mRoutedDeviceId = output.selectedDeviceId;
970 mSessionId = output.sessionId;
971 mSampleRate = output.sampleRate;
972 mServerConfig = output.serverConfig;
973 mServerFrameSize = audio_bytes_per_frame(
974 audio_channel_count_from_in_mask(mServerConfig.channel_mask), mServerConfig.format);
975 mServerSampleSize = audio_bytes_per_sample(mServerConfig.format);
976
977 if (output.cblk == 0) {
978 errorMessage = StringPrintf("%s(%d): Could not get control block", __func__, mPortId);
979 status = NO_INIT;
980 goto exit;
981 }
982 // TODO: Using unsecurePointer() has some associated security pitfalls
983 // (see declaration for details).
984 // Either document why it is safe in this case or address the
985 // issue (e.g. by copying).
986 iMemPointer = output.cblk ->unsecurePointer();
987 if (iMemPointer == NULL) {
988 errorMessage = StringPrintf(
989 "%s(%d): Could not get control block pointer", __func__, mPortId);
990 status = NO_INIT;
991 goto exit;
992 }
993 cblk = static_cast<audio_track_cblk_t*>(iMemPointer);
994
995 // Starting address of buffers in shared memory.
996 // The buffers are either immediately after the control block,
997 // or in a separate area at discretion of server.
998 void *buffers;
999 if (output.buffers == 0) {
1000 buffers = cblk + 1;
1001 } else {
1002 // TODO: Using unsecurePointer() has some associated security pitfalls
1003 // (see declaration for details).
1004 // Either document why it is safe in this case or address the
1005 // issue (e.g. by copying).
1006 buffers = output.buffers->unsecurePointer();
1007 if (buffers == NULL) {
1008 errorMessage = StringPrintf(
1009 "%s(%d): Could not get buffer pointer", __func__, mPortId);
1010 status = NO_INIT;
1011 goto exit;
1012 }
1013 }
1014
1015 // invariant that mAudioRecord != 0 is true only after set() returns successfully
1016 if (mAudioRecord != 0) {
1017 IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this);
1018 mDeathNotifier.clear();
1019 }
1020 mAudioRecord = output.audioRecord;
1021 mCblkMemory = output.cblk;
1022 mBufferMemory = output.buffers;
1023 IPCThreadState::self()->flushCommands();
1024
1025 mCblk = cblk;
1026 // note that output.frameCount is the (possibly revised) value of mReqFrameCount
1027 if (output.frameCount < mReqFrameCount || (mReqFrameCount == 0 && output.frameCount == 0)) {
1028 ALOGW("%s(%d): Requested frameCount %zu but received frameCount %zu",
1029 __func__, output.portId,
1030 mReqFrameCount, output.frameCount);
1031 }
1032
1033 // Make sure that application is notified with sufficient margin before overrun.
1034 // The computation is done on server side.
1035 if (mNotificationFramesReq > 0 && output.notificationFrameCount != mNotificationFramesReq) {
1036 ALOGW("%s(%d): Server adjusted notificationFrames from %u to %zu for frameCount %zu",
1037 __func__, output.portId,
1038 mNotificationFramesReq, output.notificationFrameCount, output.frameCount);
1039 }
1040 mNotificationFramesAct = (uint32_t)output.notificationFrameCount;
1041 if (mServerConfig.format != mFormat && mCallback != nullptr) {
1042 mFormatConversionBufRaw = std::make_unique<uint8_t[]>(mNotificationFramesAct * mFrameSize);
1043 mFormatConversionBuffer.raw = mFormatConversionBufRaw.get();
1044 }
1045
1046 //mInput != input includes the case where mInput == AUDIO_IO_HANDLE_NONE for first creation
1047 if (mDeviceCallback != 0) {
1048 if (mInput != AUDIO_IO_HANDLE_NONE) {
1049 AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
1050 }
1051 AudioSystem::addAudioDeviceCallback(this, output.inputId, output.portId);
1052 }
1053
1054 if (!mSharedAudioPackageName.empty()) {
1055 mAudioRecord->shareAudioHistory(mSharedAudioPackageName, mSharedAudioStartMs);
1056 }
1057
1058 mPortId = output.portId;
1059 // We retain a copy of the I/O handle, but don't own the reference
1060 mInput = output.inputId;
1061 mRefreshRemaining = true;
1062
1063 mFrameCount = output.frameCount;
1064 // If IAudioRecord is re-created, don't let the requested frameCount
1065 // decrease. This can confuse clients that cache frameCount().
1066 if (mFrameCount > mReqFrameCount) {
1067 mReqFrameCount = mFrameCount;
1068 }
1069
1070 // update proxy
1071 mProxy = new AudioRecordClientProxy(cblk, buffers, mFrameCount, mServerFrameSize);
1072 mProxy->setEpoch(epoch);
1073 mProxy->setMinimum(mNotificationFramesAct);
1074
1075 mDeathNotifier = new DeathNotifier(this);
1076 IInterface::asBinder(mAudioRecord)->linkToDeath(mDeathNotifier, this);
1077
1078 mMetricsId = std::string(AMEDIAMETRICS_KEY_PREFIX_AUDIO_RECORD) + std::to_string(mPortId);
1079 mediametrics::LogItem(mMetricsId)
1080 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE)
1081 .set(AMEDIAMETRICS_PROP_EXECUTIONTIMENS, (int64_t)(systemTime() - beginNs))
1082 // the following are immutable (at least until restore)
1083 .set(AMEDIAMETRICS_PROP_FLAGS, toString(mFlags).c_str())
1084 .set(AMEDIAMETRICS_PROP_ORIGINALFLAGS, toString(mOrigFlags).c_str())
1085 .set(AMEDIAMETRICS_PROP_SESSIONID, (int32_t)mSessionId)
1086 .set(AMEDIAMETRICS_PROP_TRACKID, mPortId)
1087 .set(AMEDIAMETRICS_PROP_LOGSESSIONID, mLogSessionId)
1088 .set(AMEDIAMETRICS_PROP_SOURCE, toString(mAttributes.source).c_str())
1089 .set(AMEDIAMETRICS_PROP_THREADID, (int32_t)output.inputId)
1090 .set(AMEDIAMETRICS_PROP_SELECTEDDEVICEID, (int32_t)mSelectedDeviceId)
1091 .set(AMEDIAMETRICS_PROP_ROUTEDDEVICEID, (int32_t)mRoutedDeviceId)
1092 .set(AMEDIAMETRICS_PROP_ENCODING, toString(mFormat).c_str())
1093 .set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
1094 .set(AMEDIAMETRICS_PROP_FRAMECOUNT, (int32_t)mFrameCount)
1095 .set(AMEDIAMETRICS_PROP_SAMPLERATE, (int32_t)mSampleRate)
1096 // the following are NOT immutable
1097 .set(AMEDIAMETRICS_PROP_STATE, stateToString(mActive))
1098 .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)status)
1099 .set(AMEDIAMETRICS_PROP_SELECTEDMICDIRECTION, (int32_t)mSelectedMicDirection)
1100 .set(AMEDIAMETRICS_PROP_SELECTEDMICFIELDDIRECTION, (double)mSelectedMicFieldDimension)
1101 .record();
1102
1103 exit:
1104 if (status != NO_ERROR) {
1105 ALOGE_IF(!errorMessage.empty(), "%s", errorMessage.c_str());
1106 reportError(status, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE, errorMessage.c_str());
1107 }
1108
1109 mStatus = status;
1110 // sp<IAudioTrack> track destructor will cause releaseOutput() to be called by AudioFlinger
1111 return status;
1112 }
1113
1114 // Report error associated with the event and some configuration details.
reportError(status_t status,const char * event,const char * message) const1115 void AudioRecord::reportError(status_t status, const char *event, const char *message) const
1116 {
1117 if (status == NO_ERROR) return;
1118 // We report error on the native side because some callers do not come
1119 // from Java.
1120 // Ensure these variables are initialized in set().
1121 mediametrics::LogItem(AMEDIAMETRICS_KEY_AUDIO_RECORD_ERROR)
1122 .set(AMEDIAMETRICS_PROP_EVENT, event)
1123 .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)status)
1124 .set(AMEDIAMETRICS_PROP_STATUSMESSAGE, message)
1125 .set(AMEDIAMETRICS_PROP_ORIGINALFLAGS, toString(mOrigFlags).c_str())
1126 .set(AMEDIAMETRICS_PROP_SESSIONID, (int32_t)mSessionId)
1127 .set(AMEDIAMETRICS_PROP_SOURCE, toString(mAttributes.source).c_str())
1128 .set(AMEDIAMETRICS_PROP_SELECTEDDEVICEID, (int32_t)mSelectedDeviceId)
1129 .set(AMEDIAMETRICS_PROP_ENCODING, toString(mFormat).c_str())
1130 .set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
1131 .set(AMEDIAMETRICS_PROP_FRAMECOUNT, (int32_t)mFrameCount)
1132 .set(AMEDIAMETRICS_PROP_SAMPLERATE, (int32_t)mSampleRate)
1133 .record();
1134 }
1135
obtainBuffer(Buffer * audioBuffer,int32_t waitCount,size_t * nonContig)1136 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount, size_t *nonContig)
1137 {
1138 if (audioBuffer == NULL) {
1139 if (nonContig != NULL) {
1140 *nonContig = 0;
1141 }
1142 return BAD_VALUE;
1143 }
1144 if (mTransfer != TRANSFER_OBTAIN) {
1145 audioBuffer->frameCount = 0;
1146 audioBuffer->mSize = 0;
1147 audioBuffer->raw = NULL;
1148 if (nonContig != NULL) {
1149 *nonContig = 0;
1150 }
1151 return INVALID_OPERATION;
1152 }
1153
1154 const struct timespec *requested;
1155 struct timespec timeout;
1156 if (waitCount == -1) {
1157 requested = &ClientProxy::kForever;
1158 } else if (waitCount == 0) {
1159 requested = &ClientProxy::kNonBlocking;
1160 } else if (waitCount > 0) {
1161 time_t ms = WAIT_PERIOD_MS * (time_t) waitCount;
1162 timeout.tv_sec = ms / 1000;
1163 timeout.tv_nsec = (long) (ms % 1000) * 1000000;
1164 requested = &timeout;
1165 } else {
1166 ALOGE("%s(%d): invalid waitCount %d", __func__, mPortId, waitCount);
1167 requested = NULL;
1168 }
1169 return obtainBuffer(audioBuffer, requested, NULL /*elapsed*/, nonContig);
1170 }
1171
obtainBuffer(Buffer * audioBuffer,const struct timespec * requested,struct timespec * elapsed,size_t * nonContig)1172 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *requested,
1173 struct timespec *elapsed, size_t *nonContig)
1174 {
1175 // previous and new IAudioRecord sequence numbers are used to detect track re-creation
1176 uint32_t oldSequence = 0;
1177
1178 Proxy::Buffer buffer;
1179 status_t status = NO_ERROR;
1180
1181 static const int32_t kMaxTries = 5;
1182 int32_t tryCounter = kMaxTries;
1183
1184 do {
1185 // obtainBuffer() is called with mutex unlocked, so keep extra references to these fields to
1186 // keep them from going away if another thread re-creates the track during obtainBuffer()
1187 sp<AudioRecordClientProxy> proxy;
1188 sp<IMemory> iMem;
1189 sp<IMemory> bufferMem;
1190 {
1191 // start of lock scope
1192 AutoMutex lock(mLock);
1193
1194 uint32_t newSequence = mSequence;
1195 // did previous obtainBuffer() fail due to media server death or voluntary invalidation?
1196 if (status == DEAD_OBJECT) {
1197 // re-create track, unless someone else has already done so
1198 if (newSequence == oldSequence) {
1199 if (!audio_is_linear_pcm(mFormat)) {
1200 // If compressed capture, don't attempt to restore the track.
1201 // Return a DEAD_OBJECT error and let the caller recreate.
1202 tryCounter = 0;
1203 } else {
1204 status = restoreRecord_l("obtainBuffer");
1205 }
1206 if (status != NO_ERROR) {
1207 buffer.mFrameCount = 0;
1208 buffer.mRaw = NULL;
1209 buffer.mNonContig = 0;
1210 break;
1211 }
1212 }
1213 }
1214 oldSequence = newSequence;
1215
1216 // Keep the extra references
1217 proxy = mProxy;
1218 iMem = mCblkMemory;
1219 bufferMem = mBufferMemory;
1220
1221 // Non-blocking if track is stopped
1222 if (!mActive) {
1223 requested = &ClientProxy::kNonBlocking;
1224 }
1225
1226 } // end of lock scope
1227
1228 buffer.mFrameCount = audioBuffer->frameCount;
1229 // FIXME starts the requested timeout and elapsed over from scratch
1230 status = proxy->obtainBuffer(&buffer, requested, elapsed);
1231
1232 } while ((status == DEAD_OBJECT) && (tryCounter-- > 0));
1233
1234 audioBuffer->frameCount = buffer.mFrameCount;
1235 audioBuffer->mSize = buffer.mFrameCount * mServerFrameSize;
1236 audioBuffer->raw = buffer.mRaw;
1237 audioBuffer->sequence = oldSequence;
1238 if (nonContig != NULL) {
1239 *nonContig = buffer.mNonContig;
1240 }
1241 return status;
1242 }
1243
releaseBuffer(const Buffer * audioBuffer)1244 void AudioRecord::releaseBuffer(const Buffer* audioBuffer)
1245 {
1246 // FIXME add error checking on mode, by adding an internal version
1247
1248 size_t stepCount = audioBuffer->frameCount;
1249 if (stepCount == 0) {
1250 return;
1251 }
1252
1253 Proxy::Buffer buffer;
1254 buffer.mFrameCount = stepCount;
1255 buffer.mRaw = audioBuffer->raw;
1256
1257 AutoMutex lock(mLock);
1258 if (audioBuffer->sequence != mSequence) {
1259 // This Buffer came from a different IAudioRecord instance, so ignore the releaseBuffer
1260 ALOGD("%s is no-op due to IAudioRecord sequence mismatch %u != %u",
1261 __func__, audioBuffer->sequence, mSequence);
1262 return;
1263 }
1264 mInOverrun = false;
1265 mProxy->releaseBuffer(&buffer);
1266
1267 // the server does not automatically disable recorder on overrun, so no need to restart
1268 }
1269
getInputPrivate() const1270 audio_io_handle_t AudioRecord::getInputPrivate() const
1271 {
1272 AutoMutex lock(mLock);
1273 return mInput;
1274 }
1275
1276 // -------------------------------------------------------------------------
1277
read(void * buffer,size_t userSize,bool blocking)1278 ssize_t AudioRecord::read(void* buffer, size_t userSize, bool blocking)
1279 {
1280 if (mTransfer != TRANSFER_SYNC) {
1281 return INVALID_OPERATION;
1282 }
1283
1284 if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
1285 // Validation. user is most-likely passing an error code, and it would
1286 // make the return value ambiguous (actualSize vs error).
1287 ALOGE("%s(%d) (buffer=%p, size=%zu (%zu)",
1288 __func__, mPortId, buffer, userSize, userSize);
1289 return BAD_VALUE;
1290 }
1291
1292 ssize_t read = 0;
1293 Buffer audioBuffer;
1294
1295 while (userSize >= mFrameSize) {
1296 audioBuffer.frameCount = userSize / mFrameSize;
1297
1298 status_t err = obtainBuffer(&audioBuffer,
1299 blocking ? &ClientProxy::kForever : &ClientProxy::kNonBlocking);
1300 if (err < 0) {
1301 if (read > 0) {
1302 break;
1303 }
1304 if (err == TIMED_OUT || err == -EINTR) {
1305 err = WOULD_BLOCK;
1306 }
1307 return ssize_t(err);
1308 }
1309
1310 size_t bytesRead = audioBuffer.frameCount * mFrameSize;
1311 memcpy_by_audio_format(buffer, mFormat, audioBuffer.raw, mServerConfig.format,
1312 audioBuffer.mSize / mServerSampleSize);
1313 buffer = ((char *) buffer) + bytesRead;
1314 userSize -= bytesRead;
1315 read += bytesRead;
1316
1317 releaseBuffer(&audioBuffer);
1318 }
1319 if (read > 0) {
1320 mFramesRead += read / mFrameSize;
1321 // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time.
1322 }
1323 return read;
1324 }
1325
1326 // -------------------------------------------------------------------------
1327
processAudioBuffer()1328 nsecs_t AudioRecord::processAudioBuffer()
1329 {
1330 mLock.lock();
1331 const sp<IAudioRecordCallback> callback = mCallback.promote();
1332 if (!callback) {
1333 mCallback = nullptr;
1334 mLock.unlock();
1335 return NS_NEVER;
1336 }
1337 if (mAwaitBoost) {
1338 mAwaitBoost = false;
1339 mLock.unlock();
1340 static const int32_t kMaxTries = 5;
1341 int32_t tryCounter = kMaxTries;
1342 uint32_t pollUs = 10000;
1343 do {
1344 int policy = sched_getscheduler(0) & ~SCHED_RESET_ON_FORK;
1345 if (policy == SCHED_FIFO || policy == SCHED_RR) {
1346 break;
1347 }
1348 usleep(pollUs);
1349 pollUs <<= 1;
1350 } while (tryCounter-- > 0);
1351 if (tryCounter < 0) {
1352 ALOGE("%s(%d): did not receive expected priority boost on time", __func__, mPortId);
1353 }
1354 // Run again immediately
1355 return 0;
1356 }
1357
1358 // Can only reference mCblk while locked
1359 int32_t flags = android_atomic_and(~CBLK_OVERRUN, &mCblk->mFlags);
1360
1361 // Check for track invalidation
1362 if (flags & CBLK_INVALID) {
1363 (void) restoreRecord_l("processAudioBuffer");
1364 mLock.unlock();
1365 // Run again immediately, but with a new IAudioRecord
1366 return 0;
1367 }
1368
1369 bool active = mActive;
1370
1371 // Manage overrun callback, must be done under lock to avoid race with releaseBuffer()
1372 bool newOverrun = false;
1373 if (flags & CBLK_OVERRUN) {
1374 if (!mInOverrun) {
1375 mInOverrun = true;
1376 newOverrun = true;
1377 }
1378 }
1379
1380 // Get current position of server
1381 Modulo<uint32_t> position(mProxy->getPosition());
1382
1383 // Manage marker callback
1384 bool markerReached = false;
1385 Modulo<uint32_t> markerPosition(mMarkerPosition);
1386 // FIXME fails for wraparound, need 64 bits
1387 if (!mMarkerReached && markerPosition.value() > 0 && position >= markerPosition) {
1388 mMarkerReached = markerReached = true;
1389 }
1390
1391 // Determine the number of new position callback(s) that will be needed, while locked
1392 size_t newPosCount = 0;
1393 Modulo<uint32_t> newPosition(mNewPosition);
1394 uint32_t updatePeriod = mUpdatePeriod;
1395 // FIXME fails for wraparound, need 64 bits
1396 if (updatePeriod > 0 && position >= newPosition) {
1397 newPosCount = ((position - newPosition).value() / updatePeriod) + 1;
1398 mNewPosition += updatePeriod * newPosCount;
1399 }
1400
1401 // Cache other fields that will be needed soon
1402 uint32_t notificationFrames = mNotificationFramesAct;
1403 if (mRefreshRemaining) {
1404 mRefreshRemaining = false;
1405 mRemainingFrames = notificationFrames;
1406 mRetryOnPartialBuffer = false;
1407 }
1408 size_t misalignment = mProxy->getMisalignment();
1409 uint32_t sequence = mSequence;
1410
1411 // These fields don't need to be cached, because they are assigned only by set():
1412 // mTransfer, mCallback, mUserData, mSampleRate, mFrameSize
1413
1414 mLock.unlock();
1415
1416 // perform callbacks while unlocked
1417 if (newOverrun) {
1418 callback->onOverrun();
1419
1420 }
1421 if (markerReached) {
1422 callback->onMarker(markerPosition.value());
1423 }
1424 while (newPosCount > 0) {
1425 callback->onNewPos(newPosition.value());
1426 newPosition += updatePeriod;
1427 newPosCount--;
1428 }
1429 if (mObservedSequence != sequence) {
1430 mObservedSequence = sequence;
1431 callback->onNewIAudioRecord();
1432 }
1433
1434 // if inactive, then don't run me again until re-started
1435 if (!active) {
1436 return NS_INACTIVE;
1437 }
1438
1439 // Compute the estimated time until the next timed event (position, markers)
1440 uint32_t minFrames = ~0;
1441 if (!markerReached && position < markerPosition) {
1442 minFrames = (markerPosition - position).value();
1443 }
1444 if (updatePeriod > 0) {
1445 uint32_t remaining = (newPosition - position).value();
1446 if (remaining < minFrames) {
1447 minFrames = remaining;
1448 }
1449 }
1450
1451 // If > 0, poll periodically to recover from a stuck server. A good value is 2.
1452 static const uint32_t kPoll = 0;
1453 if (kPoll > 0 && mTransfer == TRANSFER_CALLBACK && kPoll * notificationFrames < minFrames) {
1454 minFrames = kPoll * notificationFrames;
1455 }
1456
1457 // Convert frame units to time units
1458 nsecs_t ns = NS_WHENEVER;
1459 if (minFrames != (uint32_t) ~0) {
1460 // This "fudge factor" avoids soaking CPU, and compensates for late progress by server
1461 static const nsecs_t kFudgeNs = 10000000LL; // 10 ms
1462 ns = ((minFrames * 1000000000LL) / mSampleRate) + kFudgeNs;
1463 }
1464
1465 // If not supplying data by EVENT_MORE_DATA, then we're done
1466 if (mTransfer != TRANSFER_CALLBACK) {
1467 return ns;
1468 }
1469
1470 struct timespec timeout;
1471 const struct timespec *requested = &ClientProxy::kForever;
1472 if (ns != NS_WHENEVER) {
1473 timeout.tv_sec = ns / 1000000000LL;
1474 timeout.tv_nsec = ns % 1000000000LL;
1475 ALOGV("%s(%d): timeout %ld.%03d",
1476 __func__, mPortId, timeout.tv_sec, (int) timeout.tv_nsec / 1000000);
1477 requested = &timeout;
1478 }
1479
1480 size_t readFrames = 0;
1481 while (mRemainingFrames > 0) {
1482
1483 Buffer audioBuffer;
1484 audioBuffer.frameCount = mRemainingFrames;
1485 size_t nonContig;
1486 status_t err = obtainBuffer(&audioBuffer, requested, NULL, &nonContig);
1487 LOG_ALWAYS_FATAL_IF((err != NO_ERROR) != (audioBuffer.frameCount == 0),
1488 "%s(%d): obtainBuffer() err=%d frameCount=%zu",
1489 __func__, mPortId, err, audioBuffer.frameCount);
1490 requested = &ClientProxy::kNonBlocking;
1491 size_t avail = audioBuffer.frameCount + nonContig;
1492 ALOGV("%s(%d): obtainBuffer(%u) returned %zu = %zu + %zu err %d",
1493 __func__, mPortId, mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err);
1494 if (err != NO_ERROR) {
1495 if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR) {
1496 break;
1497 }
1498 ALOGE("%s(%d): Error %d obtaining an audio buffer, giving up.",
1499 __func__, mPortId, err);
1500 return NS_NEVER;
1501 }
1502
1503 if (mRetryOnPartialBuffer) {
1504 mRetryOnPartialBuffer = false;
1505 if (avail < mRemainingFrames) {
1506 int64_t myns = ((mRemainingFrames - avail) *
1507 1100000000LL) / mSampleRate;
1508 if (ns < 0 || myns < ns) {
1509 ns = myns;
1510 }
1511 return ns;
1512 }
1513 }
1514
1515 Buffer* buffer = &audioBuffer;
1516 if (mServerConfig.format != mFormat) {
1517 buffer = &mFormatConversionBuffer;
1518 buffer->frameCount = audioBuffer.frameCount;
1519 buffer->mSize = buffer->frameCount * mFrameSize;
1520 buffer->sequence = audioBuffer.sequence;
1521 memcpy_by_audio_format(buffer->raw, mFormat, audioBuffer.raw,
1522 mServerConfig.format, audioBuffer.size() / mServerSampleSize);
1523 }
1524
1525 const size_t reqSize = buffer->size();
1526 const size_t readSize = callback->onMoreData(*buffer);
1527 buffer->mSize = readSize;
1528
1529 // Validate on returned size
1530 if (ssize_t(readSize) < 0 || readSize > reqSize) {
1531 ALOGE("%s(%d): EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
1532 __func__, mPortId, reqSize, ssize_t(readSize));
1533 return NS_NEVER;
1534 }
1535
1536 if (readSize == 0) {
1537 // The callback is done consuming buffers
1538 // Keep this thread going to handle timed events and
1539 // still try to provide more data in intervals of WAIT_PERIOD_MS
1540 // but don't just loop and block the CPU, so wait
1541 return WAIT_PERIOD_MS * 1000000LL;
1542 }
1543
1544 size_t releasedFrames = readSize / mFrameSize;
1545 audioBuffer.frameCount = releasedFrames;
1546 mRemainingFrames -= releasedFrames;
1547 if (misalignment >= releasedFrames) {
1548 misalignment -= releasedFrames;
1549 } else {
1550 misalignment = 0;
1551 }
1552
1553 releaseBuffer(&audioBuffer);
1554 readFrames += releasedFrames;
1555
1556 // FIXME here is where we would repeat EVENT_MORE_DATA again on same advanced buffer
1557 // if callback doesn't like to accept the full chunk
1558 if (readSize < reqSize) {
1559 continue;
1560 }
1561
1562 // There could be enough non-contiguous frames available to satisfy the remaining request
1563 if (mRemainingFrames <= nonContig) {
1564 continue;
1565 }
1566
1567 #if 0
1568 // This heuristic tries to collapse a series of EVENT_MORE_DATA that would total to a
1569 // sum <= notificationFrames. It replaces that series by at most two EVENT_MORE_DATA
1570 // that total to a sum == notificationFrames.
1571 if (0 < misalignment && misalignment <= mRemainingFrames) {
1572 mRemainingFrames = misalignment;
1573 return (mRemainingFrames * 1100000000LL) / mSampleRate;
1574 }
1575 #endif
1576
1577 }
1578 if (readFrames > 0) {
1579 AutoMutex lock(mLock);
1580 mFramesRead += readFrames;
1581 // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time.
1582 }
1583 mRemainingFrames = notificationFrames;
1584 mRetryOnPartialBuffer = true;
1585
1586 // A lot has transpired since ns was calculated, so run again immediately and re-calculate
1587 return 0;
1588 }
1589
restoreRecord_l(const char * from)1590 status_t AudioRecord::restoreRecord_l(const char *from)
1591 {
1592 status_t result = NO_ERROR; // logged: make sure to set this before returning.
1593 const int64_t beginNs = systemTime();
1594 mediametrics::Defer defer([&] {
1595 mediametrics::LogItem(mMetricsId)
1596 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_RESTORE)
1597 .set(AMEDIAMETRICS_PROP_EXECUTIONTIMENS, (int64_t)(systemTime() - beginNs))
1598 .set(AMEDIAMETRICS_PROP_STATE, stateToString(mActive))
1599 .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)result)
1600 .set(AMEDIAMETRICS_PROP_WHERE, from)
1601 .record(); });
1602
1603 ALOGW("%s(%d): dead IAudioRecord, creating a new one from %s()", __func__, mPortId, from);
1604 ++mSequence;
1605
1606 const int INITIAL_RETRIES = 3;
1607 int retries = INITIAL_RETRIES;
1608 retry:
1609 if (retries < INITIAL_RETRIES) {
1610 // refresh the audio configuration cache in this process to make sure we get new
1611 // input parameters and new IAudioRecord in createRecord_l()
1612 AudioSystem::clearAudioConfigCache();
1613 }
1614 mFlags = mOrigFlags;
1615
1616 // if the new IAudioRecord is created, createRecord_l() will modify the
1617 // following member variables: mAudioRecord, mCblkMemory, mCblk, mBufferMemory.
1618 // It will also delete the strong references on previous IAudioRecord and IMemory
1619 Modulo<uint32_t> position(mProxy->getPosition());
1620 mNewPosition = position + mUpdatePeriod;
1621 result = createRecord_l(position);
1622
1623 if (result == NO_ERROR) {
1624 if (mActive) {
1625 // callback thread or sync event hasn't changed
1626 // FIXME this fails if we have a new AudioFlinger instance
1627 result = statusTFromBinderStatus(mAudioRecord->start(
1628 AudioSystem::SYNC_EVENT_SAME, AUDIO_SESSION_NONE));
1629 }
1630 mFramesReadServerOffset = mFramesRead; // server resets to zero so we need an offset.
1631 }
1632
1633 if (result != NO_ERROR) {
1634 ALOGW("%s(%d): failed status %d, retries %d", __func__, mPortId, result, retries);
1635 if (--retries > 0) {
1636 // leave time for an eventual race condition to clear before retrying
1637 usleep(500000);
1638 goto retry;
1639 }
1640 // if no retries left, set invalid bit to force restoring at next occasion
1641 // and avoid inconsistent active state on client and server sides
1642 if (mCblk != nullptr) {
1643 android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
1644 }
1645 }
1646
1647 return result;
1648 }
1649
addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)1650 status_t AudioRecord::addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback)
1651 {
1652 if (callback == 0) {
1653 ALOGW("%s(%d): adding NULL callback!", __func__, mPortId);
1654 return BAD_VALUE;
1655 }
1656 AutoMutex lock(mLock);
1657 if (mDeviceCallback.unsafe_get() == callback.get()) {
1658 ALOGW("%s(%d): adding same callback!", __func__, mPortId);
1659 return INVALID_OPERATION;
1660 }
1661 status_t status = NO_ERROR;
1662 if (mInput != AUDIO_IO_HANDLE_NONE) {
1663 if (mDeviceCallback != 0) {
1664 ALOGW("%s(%d): callback already present!", __func__, mPortId);
1665 AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
1666 }
1667 status = AudioSystem::addAudioDeviceCallback(this, mInput, mPortId);
1668 }
1669 mDeviceCallback = callback;
1670 return status;
1671 }
1672
removeAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)1673 status_t AudioRecord::removeAudioDeviceCallback(
1674 const sp<AudioSystem::AudioDeviceCallback>& callback)
1675 {
1676 if (callback == 0) {
1677 ALOGW("%s(%d): removing NULL callback!", __func__, mPortId);
1678 return BAD_VALUE;
1679 }
1680 AutoMutex lock(mLock);
1681 if (mDeviceCallback.unsafe_get() != callback.get()) {
1682 ALOGW("%s(%d): removing different callback!", __func__, mPortId);
1683 return INVALID_OPERATION;
1684 }
1685 mDeviceCallback.clear();
1686 if (mInput != AUDIO_IO_HANDLE_NONE) {
1687 AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
1688 }
1689 return NO_ERROR;
1690 }
1691
onAudioDeviceUpdate(audio_io_handle_t audioIo,audio_port_handle_t deviceId)1692 void AudioRecord::onAudioDeviceUpdate(audio_io_handle_t audioIo,
1693 audio_port_handle_t deviceId)
1694 {
1695 sp<AudioSystem::AudioDeviceCallback> callback;
1696 {
1697 AutoMutex lock(mLock);
1698 if (audioIo != mInput) {
1699 return;
1700 }
1701 callback = mDeviceCallback.promote();
1702 // only update device if the record is active as route changes due to other use cases are
1703 // irrelevant for this client
1704 if (mActive) {
1705 mRoutedDeviceId = deviceId;
1706 }
1707 }
1708 if (callback.get() != nullptr) {
1709 callback->onAudioDeviceUpdate(mInput, mRoutedDeviceId);
1710 }
1711 }
1712
1713 // -------------------------------------------------------------------------
1714
getActiveMicrophones(std::vector<media::MicrophoneInfo> * activeMicrophones)1715 status_t AudioRecord::getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones)
1716 {
1717 AutoMutex lock(mLock);
1718 std::vector<media::MicrophoneInfoData> mics;
1719 status_t status = statusTFromBinderStatus(mAudioRecord->getActiveMicrophones(&mics));
1720 activeMicrophones->resize(mics.size());
1721 for (size_t i = 0; status == OK && i < mics.size(); ++i) {
1722 status = activeMicrophones->at(i).readFromParcelable(mics[i]);
1723 }
1724 return status;
1725 }
1726
setPreferredMicrophoneDirection(audio_microphone_direction_t direction)1727 status_t AudioRecord::setPreferredMicrophoneDirection(audio_microphone_direction_t direction)
1728 {
1729 AutoMutex lock(mLock);
1730 if (mSelectedMicDirection == direction) {
1731 // NOP
1732 return OK;
1733 }
1734
1735 mSelectedMicDirection = direction;
1736 if (mAudioRecord == 0) {
1737 // the internal AudioRecord hasn't be created yet, so just stash the attribute.
1738 return OK;
1739 } else {
1740 return statusTFromBinderStatus(mAudioRecord->setPreferredMicrophoneDirection(direction));
1741 }
1742 }
1743
setPreferredMicrophoneFieldDimension(float zoom)1744 status_t AudioRecord::setPreferredMicrophoneFieldDimension(float zoom) {
1745 AutoMutex lock(mLock);
1746 if (mSelectedMicFieldDimension == zoom) {
1747 // NOP
1748 return OK;
1749 }
1750
1751 mSelectedMicFieldDimension = zoom;
1752 if (mAudioRecord == 0) {
1753 // the internal AudioRecord hasn't be created yet, so just stash the attribute.
1754 return OK;
1755 } else {
1756 return statusTFromBinderStatus(mAudioRecord->setPreferredMicrophoneFieldDimension(zoom));
1757 }
1758 }
1759
setLogSessionId(const char * logSessionId)1760 void AudioRecord::setLogSessionId(const char *logSessionId)
1761 {
1762 AutoMutex lock(mLock);
1763 if (logSessionId == nullptr) logSessionId = ""; // an empty string is an unset session id.
1764 if (mLogSessionId == logSessionId) return;
1765
1766 mLogSessionId = logSessionId;
1767 mediametrics::LogItem(mMetricsId)
1768 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_SETLOGSESSIONID)
1769 .set(AMEDIAMETRICS_PROP_LOGSESSIONID, logSessionId)
1770 .record();
1771 }
1772
shareAudioHistory(const std::string & sharedPackageName,int64_t sharedStartMs)1773 status_t AudioRecord::shareAudioHistory(const std::string& sharedPackageName,
1774 int64_t sharedStartMs)
1775 {
1776 AutoMutex lock(mLock);
1777 if (mAudioRecord == 0) {
1778 return NO_INIT;
1779 }
1780 status_t status = statusTFromBinderStatus(
1781 mAudioRecord->shareAudioHistory(sharedPackageName, sharedStartMs));
1782 if (status == NO_ERROR) {
1783 mSharedAudioPackageName = sharedPackageName;
1784 mSharedAudioStartMs = sharedStartMs;
1785 }
1786 return status;
1787 }
1788
1789 // =========================================================================
1790
binderDied(const wp<IBinder> & who __unused)1791 void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who __unused)
1792 {
1793 sp<AudioRecord> audioRecord = mAudioRecord.promote();
1794 if (audioRecord != 0) {
1795 AutoMutex lock(audioRecord->mLock);
1796 audioRecord->mProxy->binderDied();
1797 }
1798 }
1799
1800 // =========================================================================
1801
AudioRecordThread(AudioRecord & receiver)1802 AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver)
1803 : Thread(true /* bCanCallJava */) // binder recursion on restoreRecord_l() may call Java.
1804 , mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL),
1805 mIgnoreNextPausedInt(false)
1806 {
1807 }
1808
~AudioRecordThread()1809 AudioRecord::AudioRecordThread::~AudioRecordThread()
1810 {
1811 }
1812
threadLoop()1813 bool AudioRecord::AudioRecordThread::threadLoop()
1814 {
1815 {
1816 AutoMutex _l(mMyLock);
1817 if (mPaused) {
1818 // TODO check return value and handle or log
1819 mMyCond.wait(mMyLock);
1820 // caller will check for exitPending()
1821 return true;
1822 }
1823 if (mIgnoreNextPausedInt) {
1824 mIgnoreNextPausedInt = false;
1825 mPausedInt = false;
1826 }
1827 if (mPausedInt) {
1828 if (mPausedNs > 0) {
1829 // TODO check return value and handle or log
1830 (void) mMyCond.waitRelative(mMyLock, mPausedNs);
1831 } else {
1832 // TODO check return value and handle or log
1833 mMyCond.wait(mMyLock);
1834 }
1835 mPausedInt = false;
1836 return true;
1837 }
1838 }
1839 if (exitPending()) {
1840 return false;
1841 }
1842 nsecs_t ns = mReceiver.processAudioBuffer();
1843 switch (ns) {
1844 case 0:
1845 return true;
1846 case NS_INACTIVE:
1847 pauseInternal();
1848 return true;
1849 case NS_NEVER:
1850 return false;
1851 case NS_WHENEVER:
1852 // Event driven: call wake() when callback notifications conditions change.
1853 ns = INT64_MAX;
1854 FALLTHROUGH_INTENDED;
1855 default:
1856 LOG_ALWAYS_FATAL_IF(ns < 0, "%s() returned %lld", __func__, (long long)ns);
1857 pauseInternal(ns);
1858 return true;
1859 }
1860 }
1861
requestExit()1862 void AudioRecord::AudioRecordThread::requestExit()
1863 {
1864 // must be in this order to avoid a race condition
1865 Thread::requestExit();
1866 resume();
1867 }
1868
pause()1869 void AudioRecord::AudioRecordThread::pause()
1870 {
1871 AutoMutex _l(mMyLock);
1872 mPaused = true;
1873 }
1874
resume()1875 void AudioRecord::AudioRecordThread::resume()
1876 {
1877 AutoMutex _l(mMyLock);
1878 mIgnoreNextPausedInt = true;
1879 if (mPaused || mPausedInt) {
1880 mPaused = false;
1881 mPausedInt = false;
1882 mMyCond.signal();
1883 }
1884 }
1885
wake()1886 void AudioRecord::AudioRecordThread::wake()
1887 {
1888 AutoMutex _l(mMyLock);
1889 if (!mPaused) {
1890 // wake() might be called while servicing a callback - ignore the next
1891 // pause time and call processAudioBuffer.
1892 mIgnoreNextPausedInt = true;
1893 if (mPausedInt && mPausedNs > 0) {
1894 // audio record is active and internally paused with timeout.
1895 mPausedInt = false;
1896 mMyCond.signal();
1897 }
1898 }
1899 }
1900
pauseInternal(nsecs_t ns)1901 void AudioRecord::AudioRecordThread::pauseInternal(nsecs_t ns)
1902 {
1903 AutoMutex _l(mMyLock);
1904 mPausedInt = true;
1905 mPausedNs = ns;
1906 }
1907
1908 // -------------------------------------------------------------------------
1909
1910 } // namespace android
1911